rfe1744575 - cfg_file.y bugs (mf)
rfe1738167 - build on c5 still fails (bc) More -kkv cleanup on cvs macros
This commit is contained in:
parent
c241ca0b35
commit
e971c621d2
@ -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
100
Makefile.in
Normal 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
411
auth.c
Normal 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
30
auth.h
Normal 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
195
cfg_file.l
Normal 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
655
cfg_file.y
Normal 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
102
cfg_kwords.h
Normal 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
154
client.c
Normal 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;
|
||||
}
|