bb747e6e36
Mask or set the high bit of the nonce according to this value. Properly initialize the nonce in little-endian mode
296 lines
6.6 KiB
C
296 lines
6.6 KiB
C
/*
|
|
VTun - Virtual Tunnel over TCP/IP network.
|
|
|
|
Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com>
|
|
|
|
VTun has been derived from VPPP package by Maxim Krasnyansky.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
*/
|
|
|
|
/*
|
|
* $Id: main.c,v 1.9.2.7 2013/07/07 20:31:22 mtbishop Exp $
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <fcntl.h>
|
|
#include <syslog.h>
|
|
#include <sys/mman.h>
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_SODIUM
|
|
#include <sodium.h>
|
|
#endif
|
|
|
|
#include "vtun.h"
|
|
#include "lib.h"
|
|
#include "compat.h"
|
|
|
|
#define OPTSTRING "mif:P:L:t:npq"
|
|
#ifdef HAVE_WORKING_FORK
|
|
# define SERVOPT_STRING "s"
|
|
#else
|
|
# define SERVOPT_STRING ""
|
|
#endif
|
|
|
|
/* Global options for the server and client */
|
|
struct vtun_opts vtun;
|
|
struct vtun_host default_host;
|
|
|
|
static void write_pid(void);
|
|
static void reread_config(int sig);
|
|
static void usage(void);
|
|
|
|
extern int optind,opterr,optopt;
|
|
extern char *optarg;
|
|
|
|
/* for the NATHack bit. Is our UDP session connected? */
|
|
int is_rmt_fd_connected=1;
|
|
|
|
int main(int argc, char *argv[], char *env[])
|
|
{
|
|
int daemon, sock, fd, opt;
|
|
#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
|
|
int dofork;
|
|
#endif
|
|
struct vtun_host *host = NULL;
|
|
struct sigaction sa;
|
|
char *hst;
|
|
|
|
/* Configure default settings */
|
|
daemon = 1; sock = 0;
|
|
#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
|
|
dofork = 1;
|
|
#endif
|
|
|
|
vtun.cfg_file = VTUN_CONFIG_FILE;
|
|
vtun.persist = -1;
|
|
vtun.timeout = -1;
|
|
|
|
/* Dup strings because parser will try to free them */
|
|
vtun.ppp = strdup("/usr/sbin/pppd");
|
|
vtun.ifcfg = strdup("/sbin/ifconfig");
|
|
vtun.route = strdup("/sbin/route");
|
|
vtun.fwall = strdup("/sbin/ipchains");
|
|
vtun.iproute = strdup("/sbin/ip");
|
|
|
|
vtun.svr_name = NULL;
|
|
vtun.svr_addr = NULL;
|
|
vtun.bind_addr.port = -1;
|
|
vtun.svr = 0;
|
|
vtun.svr_type = -1;
|
|
vtun.syslog = LOG_DAEMON;
|
|
|
|
/* Initialize default host options */
|
|
memset(&default_host, 0, sizeof(default_host));
|
|
default_host.flags = VTUN_TTY | VTUN_TCP;
|
|
default_host.multi = VTUN_MULTI_ALLOW;
|
|
default_host.timeout = VTUN_CONNECT_TIMEOUT;
|
|
default_host.ka_interval = 30;
|
|
default_host.ka_maxfail = 4;
|
|
default_host.loc_fd = default_host.rmt_fd = -1;
|
|
|
|
/* Start logging to syslog and stderr */
|
|
openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
|
|
|
|
while( (opt=getopt(argc,argv,OPTSTRING SERVOPT_STRING)) != EOF ){
|
|
switch(opt){
|
|
case 'm':
|
|
if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
|
|
perror("Unable to mlockall()");
|
|
exit(-1);
|
|
}
|
|
break;
|
|
case 'i':
|
|
vtun.svr_type = VTUN_INETD;
|
|
#ifdef HAVE_WORKING_FORK
|
|
case 's':
|
|
#endif
|
|
vtun.svr = 1;
|
|
break;
|
|
case 'L':
|
|
vtun.svr_addr = strdup(optarg);
|
|
break;
|
|
case 'P':
|
|
vtun.bind_addr.port = atoi(optarg);
|
|
break;
|
|
case 'f':
|
|
vtun.cfg_file = strdup(optarg);
|
|
break;
|
|
case 'n':
|
|
daemon = 0;
|
|
break;
|
|
case 'p':
|
|
vtun.persist = 1;
|
|
break;
|
|
case 't':
|
|
vtun.timeout = atoi(optarg);
|
|
break;
|
|
case 'q':
|
|
vtun.quiet = 1;
|
|
break;
|
|
default:
|
|
usage();
|
|
exit(1);
|
|
}
|
|
}
|
|
reread_config(0);
|
|
|
|
if (vtun.syslog != LOG_DAEMON) {
|
|
/* Restart logging to syslog using specified facility */
|
|
closelog();
|
|
openlog("vtund", LOG_PID|LOG_NDELAY|LOG_PERROR, vtun.syslog);
|
|
}
|
|
|
|
clear_nat_hack_flags(vtun.svr);
|
|
|
|
if(!vtun.svr){
|
|
if( argc - optind < 2 ){
|
|
usage();
|
|
exit(1);
|
|
}
|
|
hst = argv[optind++];
|
|
|
|
if( !(host = find_host(hst)) ){
|
|
vtun_syslog(LOG_ERR,"Host %s not found in %s", hst, vtun.cfg_file);
|
|
exit(1);
|
|
}
|
|
|
|
vtun.svr_name = strdup(argv[optind]);
|
|
}
|
|
|
|
/*
|
|
* Now fill uninitialized fields of the options structure
|
|
* with default values.
|
|
*/
|
|
if(vtun.bind_addr.port == -1)
|
|
vtun.bind_addr.port = VTUN_PORT;
|
|
if(vtun.persist == -1)
|
|
vtun.persist = 0;
|
|
if(vtun.timeout == -1)
|
|
vtun.timeout = VTUN_TIMEOUT;
|
|
|
|
switch( vtun.svr_type ){
|
|
case -1:
|
|
vtun.svr_type = VTUN_STAND_ALONE;
|
|
break;
|
|
case VTUN_INETD:
|
|
sock = dup(0);
|
|
#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
|
|
dofork = 0;
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
#ifdef HAVE_SODIUM
|
|
if (sodium_init() != 0) {
|
|
abort();
|
|
}
|
|
#endif
|
|
|
|
if( daemon ){
|
|
#ifdef HAVE_WORKING_FORK
|
|
if( dofork && fork() )
|
|
exit(0);
|
|
#elif defined(HAVE_WORKING_VFORK)
|
|
if( dofork && vfork() )
|
|
exit(0);
|
|
#endif
|
|
|
|
/* Direct stdin,stdout,stderr to '/dev/null' */
|
|
fd = open("/dev/null", O_RDWR);
|
|
close(0); dup(fd);
|
|
close(1); dup(fd);
|
|
close(2); dup(fd);
|
|
close(fd);
|
|
|
|
setsid();
|
|
|
|
chdir("/");
|
|
}
|
|
|
|
if(vtun.svr){
|
|
memset(&sa,0,sizeof(sa));
|
|
sa.sa_handler=reread_config;
|
|
sigaction(SIGHUP,&sa,NULL);
|
|
|
|
init_title(argc,argv,env,"vtund[s]: ");
|
|
|
|
if( vtun.svr_type == VTUN_STAND_ALONE ){
|
|
#ifdef HAVE_WORKING_FORK
|
|
write_pid();
|
|
#else
|
|
vtun_syslog(LOG_ERR,"Standalone server is not supported. Use -i");
|
|
exit(1);
|
|
#endif
|
|
}
|
|
|
|
server(sock);
|
|
} else {
|
|
init_title(argc,argv,env,"vtund[c]: ");
|
|
client(host);
|
|
}
|
|
|
|
closelog();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Very simple PID file creation function. Used by server.
|
|
* Overrides existing file.
|
|
*/
|
|
static void write_pid(void)
|
|
{
|
|
FILE *f;
|
|
|
|
if( !(f=fopen(VTUN_PID_FILE,"w")) ){
|
|
vtun_syslog(LOG_ERR,"Can't write PID file %s", VTUN_PID_FILE);
|
|
return;
|
|
}
|
|
|
|
fprintf(f,"%d",(int)getpid());
|
|
fclose(f);
|
|
}
|
|
|
|
static void reread_config(int sig)
|
|
{
|
|
if( !read_config(vtun.cfg_file) ){
|
|
vtun_syslog(LOG_ERR,"No hosts defined");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
static void usage(void)
|
|
{
|
|
printf("VTun ver %s\n", VTUN_VER);
|
|
printf("Usage: \n");
|
|
printf(" Server:\n");
|
|
#ifdef HAVE_WORKING_FORK
|
|
printf("\tvtund <-s|-i> [-f file] [-P port] [-L local address]\n");
|
|
#else
|
|
printf("\tvtund <-i> [-f file] [-P port] [-L local address]\n");
|
|
#endif
|
|
printf(" Client:\n");
|
|
/* I don't think these work. I'm disabling the suggestion - bish 20050601*/
|
|
printf("\tvtund [-f file] " /* [-P port] [-L local address] */
|
|
"[-q] [-p] [-m] [-t timeout] <host profile> <server address>\n");
|
|
}
|