diff --git a/ChangeLog b/ChangeLog index 09b30cb..3b7c0a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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) diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..a93731f --- /dev/null +++ b/Makefile.in @@ -0,0 +1,100 @@ +# +# VTun - Virtual Tunnel over TCP/IP network. +# +# Copyright (C) 1998-2000 Maxim Krasnyansky +# +# 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. diff --git a/auth.c b/auth.c new file mode 100644 index 0000000..7a0fc44 --- /dev/null +++ b/auth.c @@ -0,0 +1,411 @@ +/* + VTun - Virtual Tunnel over TCP/IP network. + + Copyright (C) 1998-2000 Maxim Krasnyansky + + 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 for the good idea. + * + * Jim Yonan, 05/24/2001 + * gen_chal rewrite to use better random number generator + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#include "vtun.h" +#include "lib.h" +#include "lock.h" +#include "auth.h" + +/* Encryption and Decryption of the challenge key */ +#ifdef HAVE_SSL + +#include +#include +#include + +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: + * 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 *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> 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 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; +} diff --git a/auth.h b/auth.h new file mode 100644 index 0000000..9366034 --- /dev/null +++ b/auth.h @@ -0,0 +1,30 @@ +/* + VTun - Virtual Tunnel over TCP/IP network. + + Copyright (C) 1998-2000 Maxim Krasnyansky + + 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); diff --git a/cfg_file.l b/cfg_file.l new file mode 100644 index 0000000..87647a1 --- /dev/null +++ b/cfg_file.l @@ -0,0 +1,195 @@ +%{ +/* + VTun - Virtual Tunnel over TCP/IP network. + + Copyright (C) 1998-2000 Maxim Krasnyansky + + 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 + +#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) */ + +{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; + } + +