rfe1744575 - cfg_file.y bugs (mf)

rfe1738167 - build on c5 still fails (bc)
More -kkv cleanup on cvs macros
This commit is contained in:
mtbishop 2007-06-29 05:25:45 +00:00
parent c241ca0b35
commit e971c621d2
44 changed files with 6990 additions and 4 deletions

View File

@ -1,3 +1,7 @@
3.0.2:
rfe1744575 - cfg_file.y bugs (mf)
rfe1738167 - build on c5 still fails (bc)
3.0.1:
rfe1602625 - fix build for lzo2 (bc,db,ruzsi)
rfe780607 - new debian rc scripts (surgo)

100
Makefile.in Normal file
View File

@ -0,0 +1,100 @@
#
# VTun - Virtual Tunnel over TCP/IP network.
#
# Copyright (C) 1998-2000 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: Makefile.in,v 1.11.2.1 2007/06/29 05:26:33 mtbishop Exp $
#
CC = @CC@
CFLAGS = @CFLAGS@ @CPPFLAGS@
LDFLAGS = @LIBS@
YACC = @YACC@
YACCFLAGS = -d
LEX = @LEX@
LEXFLAGS = -t
INSTALL = @INSTALL@
INSTALL_OWNER = -o root -g 0
prefix = @prefix@
exec_prefix = @exec_prefix@
SBIN_DIR = @sbindir@
MAN_DIR = @mandir@
ETC_DIR = @sysconfdir@
VAR_DIR = @localstatedir@
PID_FILE = ${VAR_DIR}/run/vtund.pid
CFG_FILE = ${ETC_DIR}/vtund.conf
STAT_DIR = ${VAR_DIR}/log/vtund
LOCK_DIR = ${VAR_DIR}/lock/vtund
DEFS = -DVTUN_CONFIG_FILE=\"$(CFG_FILE)\" -DVTUN_PID_FILE=\"$(PID_FILE)\" \
-DVTUN_STAT_DIR=\"$(STAT_DIR)\" -DVTUN_LOCK_DIR=\"$(LOCK_DIR)\"
OBJS = main.o cfg_file.tab.o cfg_file.lex.o server.o client.o lib.o \
llist.o auth.o tunnel.o lock.o netlib.o \
tun_dev.o tap_dev.o pty_dev.o pipe_dev.o \
tcp_proto.o udp_proto.o \
linkfd.o lfd_shaper.o lfd_zlib.o lfd_lzo.o lfd_encrypt.o
CONFIGURE_FILES = Makefile config.status config.cache config.h config.log
%.o: %.c vtun.h lib.h
$(CC) $(CFLAGS) $(DEFS) -c $<
vtund: $(OBJS)
$(CC) $(CFLAGS) -o vtund $(OBJS) $(LFD_OBJS) $(LDFLAGS)
cfg_file.tab.c: cfg_file.y cfg_kwords.h config.h
$(YACC) $(YACCFLAGS) -b cfg_file cfg_file.y
cfg_file.lex.c: cfg_file.l cfg_kwords.h config.h
$(LEX) $(LEXFLAGS) cfg_file.l > cfg_file.lex.c
depend:
makedepend -- $(CFLAGS) -- *.c
clean:
rm -f core cfg_file.tab.* cfg_file.lex.* *.o *~ *.bak vtund
distclean: clean
rm -f $(CONFIGURE_FILES)
rm -f `cat vtun.drivers`
install_man:
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(MAN_DIR)/man8
$(INSTALL) -m 644 $(INSTALL_OWNER) vtund.8 $(DESTDIR)$(MAN_DIR)/man8
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(MAN_DIR)/man5
$(INSTALL) -m 644 $(INSTALL_OWNER) vtund.conf.5 $(DESTDIR)$(MAN_DIR)/man5
rm -f $(DESTDIR)$(MAN_DIR)/man8/vtun.8
ln -s vtund.8 $(DESTDIR)$(MAN_DIR)/man8/vtun.8
install_config:
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(ETC_DIR)
if [ ! -f $(ETC_DIR)/vtund.conf ]; then \
$(INSTALL) -m 600 $(INSTALL_OWNER) vtund.conf $(DESTDIR)$(ETC_DIR); \
fi
install: vtund install_config install_man
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(VAR_DIR)/run
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(STAT_DIR)
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(LOCK_DIR)
$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(SBIN_DIR)
$(INSTALL) -m 755 $(INSTALL_OWNER) vtund $(DESTDIR)$(SBIN_DIR)
# DO NOT DELETE THIS LINE -- make depend depends on it.

411
auth.c Normal file
View File

@ -0,0 +1,411 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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: auth.c,v 1.9.2.1 2007/06/29 05:25:45 mtbishop Exp $
*/
/*
* Challenge based authentication.
* Thanx to Chris Todd<christ@insynq.com> for the good idea.
*
* Jim Yonan, 05/24/2001
* gen_chal rewrite to use better random number generator
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <syslog.h>
#include <time.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "vtun.h"
#include "lib.h"
#include "lock.h"
#include "auth.h"
/* Encryption and Decryption of the challenge key */
#ifdef HAVE_SSL
#include <openssl/md5.h>
#include <openssl/blowfish.h>
#include <openssl/rand.h>
void gen_chal(char *buf)
{
RAND_bytes(buf, VTUN_CHAL_SIZE);
}
void encrypt_chal(char *chal, char *pwd)
{
register int i;
BF_KEY key;
BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
BF_ecb_encrypt(chal + i, chal + i, &key, BF_ENCRYPT);
}
void decrypt_chal(char *chal, char *pwd)
{
register int i;
BF_KEY key;
BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
BF_ecb_encrypt(chal + i, chal + i, &key, BF_DECRYPT);
}
#else /* HAVE_SSL */
void encrypt_chal(char *chal, char *pwd)
{
char * xor_msk = pwd;
register int i, xor_len = strlen(xor_msk);
for(i=0; i < VTUN_CHAL_SIZE; i++)
chal[i] ^= xor_msk[i%xor_len];
}
void inline decrypt_chal(char *chal, char *pwd)
{
encrypt_chal(chal, pwd);
}
/* Generate PSEUDO random challenge key. */
void gen_chal(char *buf)
{
register int i;
srand(time(NULL));
for(i=0; i < VTUN_CHAL_SIZE; i++)
buf[i] = (unsigned int)(255.0 * rand()/RAND_MAX);
}
#endif /* HAVE_SSL */
/*
* Functions to convert binary flags to character string.
* string format: <CS64>
* C - compression, S - speed for shaper and so on.
*/
char *bf2cf(struct vtun_host *host)
{
static char str[20], *ptr = str;
*(ptr++) = '<';
switch( host->flags & VTUN_PROT_MASK ){
case VTUN_TCP:
*(ptr++) = 'T';
break;
case VTUN_UDP:
*(ptr++) = 'U';
break;
}
switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TTY:
*(ptr++) = 't';
break;
case VTUN_PIPE:
*(ptr++) = 'p';
break;
case VTUN_ETHER:
*(ptr++) = 'e';
break;
case VTUN_TUN:
*(ptr++) = 'u';
break;
}
if( (host->flags & VTUN_SHAPE) /* && host->spd_in */)
ptr += sprintf(ptr,"S%d",host->spd_in);
if( host->flags & VTUN_ZLIB )
ptr += sprintf(ptr,"C%d", host->zlevel);
if( host->flags & VTUN_LZO )
ptr += sprintf(ptr,"L%d", host->zlevel);
if( host->flags & VTUN_KEEP_ALIVE )
*(ptr++) = 'K';
if( host->flags & VTUN_ENCRYPT )
ptr += sprintf(ptr,"E%d", host->cipher);
strcat(ptr,">");
return str;
}
/* return 1 on success, otherwise 0 */
int cf2bf(char *str, struct vtun_host *host)
{
char *ptr, *p;
int s;
if( (ptr = strchr(str,'<')) ){
ptr++;
while(*ptr){
switch(*ptr++){
case 't':
host->flags |= VTUN_TTY;
break;
case 'p':
host->flags |= VTUN_PIPE;
break;
case 'e':
host->flags |= VTUN_ETHER;
break;
case 'u':
host->flags |= VTUN_TUN;
break;
case 'U':
host->flags &= ~VTUN_PROT_MASK;
host->flags |= VTUN_UDP;
break;
case 'T':
host->flags &= ~VTUN_PROT_MASK;
host->flags |= VTUN_TCP;
break;
case 'K':
host->flags |= VTUN_KEEP_ALIVE;
break;
case 'C':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
host->flags |= VTUN_ZLIB;
host->zlevel = s;
ptr = p;
break;
case 'L':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
host->flags |= VTUN_LZO;
host->zlevel = s;
ptr = p;
break;
case 'E':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
host->flags |= VTUN_ENCRYPT;
host->cipher = s;
ptr = p;
break;
case 'S':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0;
if( s ){
host->flags |= VTUN_SHAPE;
host->spd_out = s;
}
ptr = p;
break;
case '>':
return 1;
default:
return 0;
}
}
}
return 0;
}
/*
* Functions to convert binary key data to character string.
* string format: <char_data>
*/
char *cl2cs(char *chal)
{
static char str[VTUN_CHAL_SIZE*2+3], *chr="abcdefghijklmnop";
register char *ptr = str;
register int i;
*(ptr++) = '<';
for(i=0; i<VTUN_CHAL_SIZE; i++){
*(ptr++) = chr[ ((chal[i] & 0xf0) >> 4) ];
*(ptr++) = chr[ (chal[i] & 0x0f) ];
}
*(ptr++) = '>';
*ptr = '\0';
return str;
}
int cs2cl(char *str, char *chal)
{
register char *ptr = str;
register int i;
if( !(ptr = strchr(str,'<')) )
return 0;
ptr++;
if( !strtok(ptr,">") || strlen(ptr) != VTUN_CHAL_SIZE*2 )
return 0;
for(i=0; i<VTUN_CHAL_SIZE && *ptr; i++, ptr+=2) {
chal[i] = (*ptr - 'a') << 4;
chal[i] |= *(ptr+1) - 'a';
}
return 1;
}
/* Authentication (Server side) */
struct vtun_host * auth_server(int fd)
{
char chal_req[VTUN_CHAL_SIZE], chal_res[VTUN_CHAL_SIZE];
char buf[VTUN_MESG_SIZE], *str1, *str2;
struct vtun_host *h = NULL;
char *host = NULL;
int stage;
set_title("authentication");
print_p(fd,"VTUN server ver %s\n",VTUN_VER);
stage = ST_HOST;
while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
buf[sizeof(buf)-1]='\0';
strtok(buf,"\r\n");
if( !(str1=strtok(buf," :")) )
break;
if( !(str2=strtok(NULL," :")) )
break;
switch( stage ){
case ST_HOST:
if( !strcmp(str1,"HOST") ){
host = strdup(str2);
gen_chal(chal_req);
print_p(fd,"OK CHAL: %s\n", cl2cs(chal_req));
stage = ST_CHAL;
continue;
}
break;
case ST_CHAL:
if( !strcmp(str1,"CHAL") ){
if( !cs2cl(str2,chal_res) )
break;
if( !(h = find_host(host)) )
break;
decrypt_chal(chal_res, h->passwd);
if( !memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
/* Auth successeful. */
/* Lock host */
if( lock_host(h) < 0 ){
/* Multiple connections are denied */
h = NULL;
break;
}
print_p(fd,"OK FLAGS: %s\n", bf2cf(h));
} else
h = NULL;
}
break;
}
break;
}
if( host )
free(host);
if( !h )
print_p(fd,"ERR\n");
return h;
}
/* Authentication (Client side) */
int auth_client(int fd, struct vtun_host *host)
{
char buf[VTUN_MESG_SIZE], chal[VTUN_CHAL_SIZE];
int stage, success=0 ;
stage = ST_INIT;
while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
buf[sizeof(buf)-1]='\0';
switch( stage ){
case ST_INIT:
if( !strncmp(buf,"VTUN",4) ){
stage = ST_HOST;
print_p(fd,"HOST: %s\n",host->host);
continue;
}
break;
case ST_HOST:
if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){
stage = ST_CHAL;
encrypt_chal(chal,host->passwd);
print_p(fd,"CHAL: %s\n", cl2cs(chal));
continue;
}
break;
case ST_CHAL:
if( !strncmp(buf,"OK",2) && cf2bf(buf,host) )
success = 1;
break;
}
break;
}
return success;
}

30
auth.h Normal file
View File

@ -0,0 +1,30 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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: auth.h,v 1.3.2.1 2007/06/29 05:25:47 mtbishop Exp $
*/
#define VTUN_CHAL_SIZE 16
#define ST_INIT 0
#define ST_HOST 1
#define ST_CHAL 2
struct vtun_host * auth_server(int fd);
int auth_client(int fd, struct vtun_host *host);

195
cfg_file.l Normal file
View File

@ -0,0 +1,195 @@
%{
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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: cfg_file.l,v 1.4.2.1 2007/06/29 05:25:49 mtbishop Exp $
*/
#include "config.h"
#include <string.h>
#include "vtun.h"
#include "cfg_file.tab.h"
#include "cfg_kwords.h"
/* static buffer for strings */
char str_buf[255];
int find_keyword(struct kword *kw, char *str);
#define ECHO {;}
#define YY_DECL int yylex(void)
/* Push and pop parser state */
static int stack[16];
static int ptr = 0;
#define PUSH_STATE() \
do { \
if( ptr == 16 ){ \
yyerror("To many pushes to parser's state stack"); \
return K_ERROR; \
} \
stack[ptr++] = YY_START; \
} while(0)
#define POP_STATE() \
do { \
if( !ptr ){ \
yyerror("To many pops from parser's state stack"); \
return K_ERROR; \
} \
BEGIN(stack[--ptr]); \
} while(0)
int cfg_error(const char *ftm, ...);
int yyerror(char *str);
%}
num [0-9]+
dnum {num}:{num}
word [A-Za-z0-9\-\_+=\!\$\#\%\&\*\^\@@\\\~\.]+
wordnm {word}:{num}
kword [A-Za-z0-9\_\-]+
comment \#.*\n
fname [A-Za-z0-9\_\.\-]+
path (\/{fname})+
string \".*\"
%x OPTION PARAM
%%
<*>[ \t] ; /* Skip spaces and tabs (All stages) */
<*>\n { lineno++; } /* (All stages) */
<INITIAL,OPTION>{comment} { lineno++; } /* Skip comments */
{kword} {
int kw = find_keyword(cfg_keyword,yytext);
if( kw != -1 )
return kw;
/* Keyword not found, means host definition. */
yylval.str = yytext;
return K_HOST;
}
{word} {
yylval.str = yytext;
return K_ERROR;
}
<*>\{ {
PUSH_STATE();
BEGIN(OPTION);
return *yytext;
}
<*>\} {
POP_STATE();
return *yytext;
}
<OPTION>{word} {
int kw = find_keyword(cfg_keyword,yytext);
if( kw != -1 ){
/* Option found, switch to PARAM stage */
PUSH_STATE();
BEGIN(PARAM);
return kw;
}
yylval.str = yytext;
return K_ERROR;
}
<PARAM>{string} {
if(yyleng > sizeof(str_buf)-1){
yyerror("string to long");
return 0;
}
strncpy(str_buf, yytext+1, yyleng-2);
str_buf[yyleng-2] = '\0';
yylval.str = str_buf;
return STRING;
}
<PARAM>{dnum} {
char *ptr = strchr(yytext,':') + 1;
yylval.dnum.num1 = atoi(yytext);
yylval.dnum.num2 = atoi(ptr);
return DNUM;
}
<PARAM>{num} {
yylval.num = atoi(yytext);
return NUM;
}
<PARAM>{word} {
int kw = find_keyword(cfg_param,yytext);
if( kw != -1 ){
/* Special parameter found (yes,no,etc) */
yylval.num = kw;
return NUM;
}
yylval.str = yytext;
return WORD;
}
<PARAM>{wordnm} {
char *ptr = strchr(yytext,':'); *ptr='\0';
yylval.dnum.num1 = find_keyword(cfg_param,yytext);
yylval.dnum.num2 = atoi(++ptr);
return DNUM;
}
<PARAM>{path} {
yylval.str = yytext;
return PATH;
}
<PARAM>\; {
POP_STATE();
}
<*>. { /* Garbage (All stages) */
cfg_error("Invalid character \'%s\'", yytext);
}
%%
int yywrap(void)
{
return 1;
}
int find_keyword(struct kword *kw, char *str)
{
while( kw->str ){
if( !strncmp(str,kw->str,20) )
return kw->type;
kw++;
}
return -1;
}

655
cfg_file.y Normal file
View File

@ -0,0 +1,655 @@
%{
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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: cfg_file.y,v 1.8.2.1 2007/06/29 05:25:51 mtbishop Exp $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include "compat.h"
#include "vtun.h"
#include "lib.h"
int lineno = 1;
struct vtun_host *parse_host;
extern struct vtun_host default_host;
llist *parse_cmds;
struct vtun_cmd parse_cmd;
llist host_list;
int cfg_error(const char *fmt, ...);
int add_cmd(llist *cmds, char *prog, char *args, int flags);
void *cp_cmd(void *d, void *u);
int free_cmd(void *d, void *u);
void copy_addr(struct vtun_host *to, struct vtun_host *from);
int free_host(void *d, void *u);
void free_addr(struct vtun_host *h);
void free_host_list(void);
int parse_syslog(char *facility);
int yyparse(void);
int yylex(void);
int yyerror(char *s);
#define YYERROR_VERBOSE 1
%}
%union {
char *str;
int num;
struct { int num1; int num2; } dnum;
}
%expect 20
%token K_OPTIONS K_DEFAULT K_PORT K_BINDADDR K_PERSIST K_TIMEOUT
%token K_PASSWD K_PROG K_PPP K_SPEED K_IFCFG K_FWALL K_ROUTE K_DEVICE
%token K_MULTI K_SRCADDR K_IFACE K_ADDR
%token K_TYPE K_PROT K_COMPRESS K_ENCRYPT K_KALIVE K_STAT
%token K_UP K_DOWN K_SYSLOG K_IPROUTE
%token <str> K_HOST K_ERROR
%token <str> WORD PATH STRING
%token <num> NUM
%token <dnum> DNUM
%%
config:
| config statement
;
statement: '\n'
| K_OPTIONS '{' options '}'
| K_DEFAULT {
parse_host = &default_host;
}
'{' host_options '}'
| K_HOST {
if( !(parse_host = malloc(sizeof(struct vtun_host))) ){
yyerror("No memory for the host");
YYABORT;
}
/* Fill new host struct with default values.
* MUST dup strings to be able to reread config.
*/
memcpy(parse_host, &default_host, sizeof(struct vtun_host));
parse_host->host = strdup($1);
parse_host->passwd = NULL;
/* Copy local address */
copy_addr(parse_host, &default_host);
llist_copy(&default_host.up,&parse_host->up,cp_cmd,NULL);
llist_copy(&default_host.down,&parse_host->down,cp_cmd,NULL);
}
'{' host_options '}'
{
/* Check if session definition is complete */
if (!parse_host->passwd) {
cfg_error("Ignored incomplete session definition '%s'", parse_host->host);
free_host(parse_host, NULL);
free(parse_host);
} else {
/* Add host to the list */
llist_add(&host_list, (void *)parse_host);
}
}
| K_ERROR {
cfg_error("Invalid clause '%s'",$1);
YYABORT;
}
;
options:
option
| options option
;
/* Don't override command line options */
option: '\n'
| K_PORT NUM {
if(vtun.bind_addr.port == -1)
vtun.bind_addr.port = $2;
}
| K_BINDADDR '{' bindaddr_option '}'
| K_IFACE STRING {
if(vtun.svr_addr == NULL)
vtun.svr_addr = strdup($2);
}
| K_TYPE NUM {
if(vtun.svr_type == -1)
vtun.svr_type = $2;
}
| K_TIMEOUT NUM {
if(vtun.timeout == -1)
vtun.timeout = $2;
}
| K_PPP PATH {
free(vtun.ppp);
vtun.ppp = strdup($2);
}
| K_IFCFG PATH {
free(vtun.ifcfg);
vtun.ifcfg = strdup($2);
}
| K_ROUTE PATH {
free(vtun.route);
vtun.route = strdup($2);
}
| K_FWALL PATH {
free(vtun.fwall);
vtun.fwall = strdup($2);
}
| K_IPROUTE PATH {
free(vtun.iproute);
vtun.iproute = strdup($2);
}
| K_SYSLOG syslog_opt
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
bindaddr_option:
K_ADDR WORD {
vtun.bind_addr.name = strdup($2);
vtun.bind_addr.type = VTUN_ADDR_NAME;
}
| K_IFACE WORD {
vtun.bind_addr.name = strdup($2);
vtun.bind_addr.type = VTUN_ADDR_IFACE;
}
| K_IFACE STRING {
vtun.bind_addr.name = strdup($2);
vtun.bind_addr.type = VTUN_ADDR_IFACE;
}
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
syslog_opt:
NUM {
vtun.syslog = $1;
}
| WORD {
if (parse_syslog($1)) {
cfg_error("Unknown syslog facility '%s'", $1);
YYABORT;
}
}
| K_ERROR {
cfg_error("Unknown syslog option '%s'",$1);
YYABORT;
}
;
host_options:
host_option
| host_options host_option
;
/* Host options. Must free strings first, because they
* could be strduped from default_host */
host_option: '\n'
| K_PASSWD WORD {
free(parse_host->passwd);
parse_host->passwd = strdup($2);
}
| K_DEVICE WORD {
free(parse_host->dev);
parse_host->dev = strdup($2);
}
| K_MULTI NUM {
parse_host->multi = $2;
}
| K_TIMEOUT NUM {
parse_host->timeout = $2;
}
| K_SPEED NUM {
if( $2 ){
parse_host->spd_in = parse_host->spd_out = $2;
parse_host->flags |= VTUN_SHAPE;
} else
parse_host->flags &= ~VTUN_SHAPE;
}
| K_SPEED DNUM {
if( yylval.dnum.num1 || yylval.dnum.num2 ){
parse_host->spd_out = yylval.dnum.num1;
parse_host->spd_in = yylval.dnum.num2;
parse_host->flags |= VTUN_SHAPE;
} else
parse_host->flags &= ~VTUN_SHAPE;
}
| K_COMPRESS {
parse_host->flags &= ~(VTUN_ZLIB | VTUN_LZO);
}
compress
| K_ENCRYPT NUM {
if( $2 ){
parse_host->flags |= VTUN_ENCRYPT;
parse_host->cipher = $2;
} else
parse_host->flags &= ~VTUN_ENCRYPT;
}
| K_KALIVE {
parse_host->flags &= ~VTUN_KEEP_ALIVE;
}
keepalive
| K_STAT NUM {
if( $2 )
parse_host->flags |= VTUN_STAT;
else
parse_host->flags &= ~VTUN_STAT;
}
| K_PERSIST NUM {
parse_host->persist = $2;
if(vtun.persist == -1)
vtun.persist = $2;
}
| K_TYPE NUM {
parse_host->flags &= ~VTUN_TYPE_MASK;
parse_host->flags |= $2;
}
| K_PROT NUM {
parse_host->flags &= ~VTUN_PROT_MASK;
parse_host->flags |= $2;
}
| K_SRCADDR '{' srcaddr_options '}'
| K_UP {
parse_cmds = &parse_host->up;
llist_free(parse_cmds, free_cmd, NULL);
} '{' command_options '}'
| K_DOWN {
parse_cmds = &parse_host->down;
llist_free(parse_cmds, free_cmd, NULL);
} '{' command_options '}'
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
compress:
NUM {
if( $1 ){
parse_host->flags |= VTUN_ZLIB;
parse_host->zlevel = $1;
}
}
| DNUM {
parse_host->flags |= yylval.dnum.num1;
parse_host->zlevel = yylval.dnum.num2;
}
| K_ERROR {
cfg_error("Unknown compression '%s'",$1);
YYABORT;
}
;
keepalive:
NUM {
if( $1 )
parse_host->flags |= VTUN_KEEP_ALIVE;
}
| DNUM {
if( yylval.dnum.num1 ){
parse_host->flags |= VTUN_KEEP_ALIVE;
parse_host->ka_interval = yylval.dnum.num1;
parse_host->ka_failure = yylval.dnum.num2;
}
}
| K_ERROR {
cfg_error("Unknown keepalive option '%s'",$1);
YYABORT;
}
;
srcaddr_options: /* empty */
| srcaddr_option
| srcaddr_options srcaddr_option
;
srcaddr_option:
K_ADDR WORD {
free_addr(parse_host);
parse_host->src_addr.name = strdup($2);
parse_host->src_addr.type = VTUN_ADDR_NAME;
}
| K_IFACE WORD {
free_addr(parse_host);
parse_host->src_addr.name = strdup($2);
parse_host->src_addr.type = VTUN_ADDR_IFACE;
}
| K_IFACE STRING {
free_addr(parse_host);
parse_host->src_addr.name = strdup($2);
parse_host->src_addr.type = VTUN_ADDR_IFACE;
}
| K_PORT NUM {
parse_host->src_addr.port = $2;
}
| K_ERROR {
cfg_error("Unknown option '%s'",$1);
YYABORT;
}
;
command_options: /* empty */
| command_option
| command_options command_option
;
command_option: '\n'
| K_PROG {
memset(&parse_cmd, 0, sizeof(struct vtun_cmd));
}
prog_options {
add_cmd(parse_cmds, parse_cmd.prog,
parse_cmd.args, parse_cmd.flags);
}
| K_PPP STRING {
add_cmd(parse_cmds, strdup(vtun.ppp), strdup($2),
VTUN_CMD_DELAY);
}
| K_IFCFG STRING {
add_cmd(parse_cmds, strdup(vtun.ifcfg),strdup($2),
VTUN_CMD_WAIT);
}
| K_ROUTE STRING {
add_cmd(parse_cmds, strdup(vtun.route),strdup($2),
VTUN_CMD_WAIT);
}
| K_FWALL STRING {
add_cmd(parse_cmds, strdup(vtun.fwall),strdup($2),
VTUN_CMD_WAIT);
}
| K_IPROUTE STRING {
add_cmd(parse_cmds, strdup(vtun.iproute),strdup($2),
VTUN_CMD_WAIT);
}
| K_ERROR {
cfg_error("Unknown cmd '%s'",$1);
YYABORT;
}
;
prog_options:
prog_option
| prog_options prog_option
;
prog_option:
PATH {
parse_cmd.prog = strdup($1);
}
| STRING {
parse_cmd.args = strdup($1);
}
| NUM {
parse_cmd.flags = $1;
}
;
%%
int yyerror(char *s)
{
vtun_syslog(LOG_ERR, "%s line %d\n", s, lineno);
return 0;
}
int cfg_error(const char *fmt, ...)
{
char buf[255];
va_list ap;
/* print the argument string */
va_start(ap, fmt);
vsnprintf(buf,sizeof(buf),fmt,ap);
va_end(ap);
yyerror(buf);
return 0;
}
int add_cmd(llist *cmds, char *prog, char *args, int flags)
{
struct vtun_cmd *cmd;
if( !(cmd = malloc(sizeof(struct vtun_cmd))) ){
yyerror("No memory for the command");
return -1;
}
memset(cmd, 0, sizeof(struct vtun_cmd));
cmd->prog = prog;
cmd->args = args;
cmd->flags = flags;
llist_add(cmds, cmd);
return 0;
}
void *cp_cmd(void *d, void *u)
{
struct vtun_cmd *cmd = d, *cmd_copy;
if( !(cmd_copy = malloc(sizeof(struct vtun_cmd))) ){
yyerror("No memory to copy the command");
return NULL;
}
cmd_copy->prog = strdup(cmd->prog);
cmd_copy->args = strdup(cmd->args);
cmd_copy->flags = cmd->flags;
return cmd_copy;
}
int free_cmd(void *d, void *u)
{
struct vtun_cmd *cmd = d;
free(cmd->prog);
free(cmd->args);
free(cmd);
return 0;
}
void copy_addr(struct vtun_host *to, struct vtun_host *from)
{
if( from->src_addr.type ){
to->src_addr.type = from->src_addr.type;
to->src_addr.name = strdup(from->src_addr.name);
}
to->src_addr.port = from->src_addr.port;
}
void free_addr(struct vtun_host *h)
{
if( h->src_addr.type ){
h->src_addr.type = 0;
free(h->src_addr.name);
}
}
int free_host(void *d, void *u)
{
struct vtun_host *h = d;
if (u && !strcmp(h->host, u))
return 1;
free(h->host);
free(h->passwd);
llist_free(&h->up, free_cmd, NULL);
llist_free(&h->down, free_cmd, NULL);
free_addr(h);
return 0;
}
/* Find host in the hosts list.
* NOTE: This function can be called only once since it deallocates hosts list.
*/
inline struct vtun_host* find_host(char *host)
{
return (struct vtun_host *)llist_free(&host_list, free_host, host);
}
inline void free_host_list(void)
{
llist_free(&host_list, free_host, NULL);
}
static struct {
char *c_name;
int c_val;
} syslog_names[] = {
{ "auth", LOG_AUTH },
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "news", LOG_NEWS },
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
int parse_syslog(char *facility)
{
int i;
for (i=0; syslog_names[i].c_name;i++) {
if (!strcmp(syslog_names[i].c_name, facility)) {
vtun.syslog = syslog_names[i].c_val;
return(0);
}
}
return -1;
}
/*
* Read config file.
*/
int read_config(char *file)
{
static int cfg_loaded = 0;
extern FILE *yyin;
if( cfg_loaded ){
free_host_list();
vtun_syslog(LOG_INFO,"Reloading configuration file");
}
cfg_loaded = 1;
llist_init(&host_list);
if( !(yyin = fopen(file,"r")) ){
vtun_syslog(LOG_ERR,"Can not open %s", file);
return -1;
}
yyparse();
free_host(&default_host, NULL);
fclose(yyin);
return !llist_empty(&host_list);
}

102
cfg_kwords.h Normal file
View File

@ -0,0 +1,102 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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: cfg_kwords.h,v 1.6.2.1 2007/06/29 05:25:53 mtbishop Exp $
*/
extern int lineno;
struct kword {
char *str;
int type;
};
struct kword cfg_keyword[] = {
{ "options", K_OPTIONS },
{ "default", K_DEFAULT },
{ "up", K_UP },
{ "down", K_DOWN },
{ "port", K_PORT },
{ "srcaddr", K_SRCADDR },
{ "addr", K_ADDR },
{ "iface", K_IFACE },
{ "bindaddr", K_BINDADDR },
{ "persist", K_PERSIST },
{ "multi", K_MULTI },
{ "iface", K_IFACE },
{ "timeout", K_TIMEOUT },
{ "passwd", K_PASSWD },
{ "password", K_PASSWD },
{ "program", K_PROG },
{ "speed", K_SPEED },
{ "compress", K_COMPRESS },
{ "encrypt", K_ENCRYPT },
{ "type", K_TYPE },
{ "proto", K_PROT },
{ "device", K_DEVICE },
{ "ppp", K_PPP },
{ "ifconfig", K_IFCFG },
{ "ifcfg", K_IFCFG },
{ "firewall", K_FWALL },
{ "route", K_ROUTE },
{ "ip", K_IPROUTE },
{ "keepalive",K_KALIVE },
{ "stat", K_STAT },
{ "syslog", K_SYSLOG },
{ NULL , 0 }
};
struct kword cfg_param[] = {
{ "yes", 1 },
{ "no", 0 },
{ "allow", 1 },
{ "deny", 0 },
{ "enable", 1 },
{ "disable", 0 },
{ "tty", VTUN_TTY },
{ "pipe", VTUN_PIPE },
{ "ether", VTUN_ETHER },
{ "tun", VTUN_TUN },
{ "tcp", VTUN_TCP },
{ "udp", VTUN_UDP },
{ "lzo", VTUN_LZO },
{ "zlib", VTUN_ZLIB },
{ "wait", 1 },
{ "killold", VTUN_MULTI_KILL },
{ "inetd", VTUN_INETD },
{ "stand", VTUN_STAND_ALONE },
{ "keep", VTUN_PERSIST_KEEPIF },
{ "blowfish128ecb", VTUN_ENC_BF128ECB },
{ "blowfish128cbc", VTUN_ENC_BF128CBC },
{ "blowfish128cfb", VTUN_ENC_BF128CFB },
{ "blowfish128ofb", VTUN_ENC_BF128OFB },
{ "blowfish256ecb", VTUN_ENC_BF256ECB },
{ "blowfish256cbc", VTUN_ENC_BF256CBC },
{ "blowfish256cfb", VTUN_ENC_BF256CFB },
{ "blowfish256ofb", VTUN_ENC_BF256OFB },
{ "aes128ecb", VTUN_ENC_AES128ECB },
{ "aes128cbc", VTUN_ENC_AES128CBC },
{ "aes128cfb", VTUN_ENC_AES128CFB },
{ "aes128ofb", VTUN_ENC_AES128OFB },
{ "aes256ecb", VTUN_ENC_AES256ECB },
{ "aes256cbc", VTUN_ENC_AES256CBC },
{ "aes256cfb", VTUN_ENC_AES256CFB },
{ "aes256ofb", VTUN_ENC_AES256OFB },
{ NULL , 0 }
};

154
client.c Normal file
View File

@ -0,0 +1,154 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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: client.c,v 1.11.2.1 2007/06/29 05:25:57 mtbishop Exp $
*/
#include "config.h"
#include "vtun_socks.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "vtun.h"
#include "lib.h"
#include "llist.h"
#include "auth.h"
#include "compat.h"
#include "netlib.h"
static volatile sig_atomic_t client_term;
static void sig_term(int sig)
{
vtun_syslog(LOG_INFO,"Terminated");
client_term = VTUN_SIG_TERM;
}
void client(struct vtun_host *host)
{
struct sockaddr_in my_addr,svr_addr;
struct sigaction sa;
int s, opt, reconnect;
vtun_syslog(LOG_INFO,"VTun client ver %s started",VTUN_VER);
memset(&sa,0,sizeof(sa));
sa.sa_handler=SIG_IGN;
sa.sa_flags = SA_NOCLDWAIT;
sigaction(SIGHUP,&sa,NULL);
sigaction(SIGQUIT,&sa,NULL);
sigaction(SIGPIPE,&sa,NULL);
sigaction(SIGCHLD,&sa,NULL);
sa.sa_handler=sig_term;
sigaction(SIGTERM,&sa,NULL);
sigaction(SIGINT,&sa,NULL);
client_term = 0; reconnect = 0;
while( (!client_term) || (client_term == VTUN_SIG_HUP) ){
if( reconnect && (client_term != VTUN_SIG_HUP) ){
if( vtun.persist || host->persist ){
/* Persist mode. Sleep and reconnect. */
sleep(5);
} else {
/* Exit */
break;
}
} else {
reconnect = 1;
}
set_title("%s init initializing", host->host);
/* Set server address */
if( server_addr(&svr_addr, host) < 0 )
continue;
/* Set local address */
if( local_addr(&my_addr, host, 0) < 0 )
continue;
/* We have to create socket again every time
* we want to connect, since STREAM sockets
* can be successfully connected only once.
*/
if( (s = socket(AF_INET,SOCK_STREAM,0))==-1 ){
vtun_syslog(LOG_ERR,"Can't create socket. %s(%d)",
strerror(errno), errno);
continue;
}
/* Required when client is forced to bind to specific port */
opt=1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){
vtun_syslog(LOG_ERR,"Can't bind socket. %s(%d)",
strerror(errno), errno);
continue;
}
/*
* Clear speed and flags which will be supplied by server.
*/
host->spd_in = host->spd_out = 0;
host->flags &= VTUN_CLNT_MASK;
io_init();
set_title("%s connecting to %s", host->host, vtun.svr_name);
vtun_syslog(LOG_INFO,"Connecting to %s", vtun.svr_name);
if( connect_t(s,(struct sockaddr *) &svr_addr, host->timeout) ){
vtun_syslog(LOG_INFO,"Connect to %s failed. %s(%d)", vtun.svr_name,
strerror(errno), errno);
} else {
if( auth_client(s, host) ){
vtun_syslog(LOG_INFO,"Session %s[%s] opened",host->host,vtun.svr_name);
host->rmt_fd = s;
/* Start the tunnel */
client_term = tunnel(host);
vtun_syslog(LOG_INFO,"Session %s[%s] closed",host->host,vtun.svr_name);
} else {
vtun_syslog(LOG_INFO,"Connection denied by %s",vtun.svr_name);
}
}
close(s);
free_sopt(&host->sopt);
}
vtun_syslog(LOG_INFO, "Exit");
return;
}

33
compat.h Normal file
View File

@ -0,0 +1,33 @@
/*
VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2000 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