--- auth.c +++ auth.c @@ -23,6 +23,10 @@ /* * Challenge based authentication. * Thanx to Chris Todd for the good idea. + * + * Artur R. Czechowski , 02/17/2002 + * Add support for connectin ssl to non-ssl vtuns (sslauth option) + * Use /dev/random in non-ssl gen_chal (if possible) */ #include "config.h" @@ -55,34 +59,57 @@ #include "lock.h" #include "auth.h" -/* Encryption and Decryption of the challenge key */ #ifdef HAVE_SSL #include #include #include +#endif /* HAVE_SSL */ + +/* Okay, start the "blue-wire" non-ssl auth patch stuff */ +void nonssl_encrypt_chal(char *chal, char *pwd) +{ + char *xor_msk = pwd; + register int i, xor_len = strlen(xor_msk); + + syslog(LOG_INFO, "Use nonSSL-aware challenge/response"); + for(i=0; i < VTUN_CHAL_SIZE; i++) + chal[i] ^= xor_msk[i%xor_len]; +} + +inline void nonssl_decrypt_chal(char *chal, char *pwd) +{ + nonssl_encrypt_chal(chal, pwd); +} +/* Mostly ended here, other than a couple replaced #ifdefs */ + +/* Encryption and Decryption of the challenge-key */ +#ifdef HAVE_SSL + static void gen_chal(char *buf) { RAND_bytes(buf, VTUN_CHAL_SIZE); } -static void encrypt_chal(char *chal, char *pwd) +static void ssl_encrypt_chal(char *chal, char *pwd) { register int i; BF_KEY key; + syslog(LOG_INFO, "Use SSL-aware challenge/response"); 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); } -static void decrypt_chal(char *chal, char *pwd) +static void ssl_decrypt_chal(char *chal, char *pwd) { register int i; BF_KEY key; + syslog(LOG_INFO, "Use SSL-aware challenge/response"); BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL)); for(i=0; i < VTUN_CHAL_SIZE; i += 8 ) @@ -91,30 +118,43 @@ #else /* HAVE_SSL */ -static 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]; -} - -static void inline decrypt_chal(char *chal, char *pwd) -{ - encrypt_chal(chal, pwd); -} - /* Generate PSEUDO random challenge key. */ static void gen_chal(char *buf) { register int i; - - srand(time(NULL)); + unsigned int seed; + char *pseed; + int fd,cnt,len; + + if((fd=open("/dev/random",O_RDONLY))!=-1) { + pseed=(char *)&seed; + len=cnt=sizeof(seed); + while(cnt>0) { + cnt=read(fd,pseed,len); + len=len-cnt; + pseed=pseed+cnt; + } + } else { + seed=time(NULL); + } + srand(seed); for(i=0; i < VTUN_CHAL_SIZE; i++) buf[i] = (unsigned int)(255.0 * rand()/RAND_MAX); } + +void ssl_encrypt_chal(char *chal, char *pwd) +{ + syslog(LOG_ERR,"Cannot use `sslauth yes' without SSL support - fallback to `sslauth no'"); + nonssl_encrypt_chal(chal,pwd); +} + +void ssl_decrypt_chal(char *chal, char *pwd) +{ + syslog(LOG_ERR,"Cannot use `sslauth yes' without SSL support - fallback to `sslauth no'"); + nonssl_decrypt_chal(chal,pwd); +} + #endif /* HAVE_SSL */ /* @@ -358,7 +398,11 @@ if( !(h = find_host(host)) ) break; - decrypt_chal(chal_res, h->passwd); + if (h->sslauth) { + ssl_decrypt_chal(chal_res, h->passwd); + } else { + nonssl_decrypt_chal(chal_res, h->passwd); + } if( !memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){ /* Auth successeful. */ @@ -410,7 +454,11 @@ if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){ stage = ST_CHAL; - encrypt_chal(chal,host->passwd); + if (host->sslauth) { + ssl_encrypt_chal(chal,host->passwd); + } else { + nonssl_encrypt_chal(chal,host->passwd); + } print_p(fd,"CHAL: %s\n", cl2cs(chal)); continue; --- cfg_file.y +++ cfg_file.y @@ -74,7 +74,7 @@ %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_NAT_HACK K_COMPRESS K_ENCRYPT K_KALIVE K_STAT +%token K_TYPE K_PROT K_NAT_HACK K_COMPRESS K_ENCRYPT K_KALIVE K_STAT K_SSLAUTH %token K_UP K_DOWN K_SYSLOG K_IPROUTE %token K_HOST K_ERROR @@ -285,6 +285,13 @@ } compress + | K_SSLAUTH NUM { + parse_host->sslauth = $2; + + if(vtun.sslauth == -1) + vtun.sslauth = $2; + } + | K_ENCRYPT NUM { if( $2 ){ parse_host->flags |= VTUN_ENCRYPT; --- cfg_kwords.h +++ cfg_kwords.h @@ -37,6 +37,7 @@ { "addr", K_ADDR }, { "iface", K_IFACE }, { "bindaddr", K_BINDADDR }, + { "sslauth", K_SSLAUTH }, { "persist", K_PERSIST }, { "multi", K_MULTI }, { "iface", K_IFACE }, --- main.c +++ main.c @@ -79,6 +79,7 @@ vtun.cfg_file = VTUN_CONFIG_FILE; vtun.persist = -1; vtun.timeout = -1; + vtun.sslauth = -1; /* Dup strings because parser will try to free them */ vtun.ppp = strdup("/usr/sbin/pppd"); @@ -101,6 +102,11 @@ default_host.ka_interval = 30; default_host.ka_maxfail = 4; default_host.loc_fd = default_host.rmt_fd = -1; +#ifdef HAVE_SSL + default_host.sslauth = 1; +#else /* HAVE_SSL */ + default_host.sslauth = 0; +#endif /* HAVE_SSL */ /* Start logging to syslog and stderr */ openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); @@ -181,6 +187,16 @@ vtun.persist = 0; if(vtun.timeout == -1) vtun.timeout = VTUN_TIMEOUT; + /* + * Want to save behaviour from older version: stronger authentication + * if compiled with --enable-ssl, weaker otherwise + */ + if(vtun.sslauth == -1) +#ifdef HAVE_SSL + vtun.sslauth = 1; +#else /* HAVE_SSL */ + vtun.sslauth = 0; +#endif /* HAVE_SSL */ switch( vtun.svr_type ){ case -1: --- vtun.h +++ vtun.h @@ -100,6 +100,9 @@ int rmt_fd; int loc_fd; + /* SSL strong auth */ + int sslauth; + /* Persist mode */ int persist; @@ -205,6 +208,7 @@ struct vtun_opts { int timeout; int persist; + int sslauth; char *cfg_file;