if the password supplied is 32 bit long, we should use it AS if

This commit is contained in:
Vincent Malguy 2015-10-09 18:00:06 +02:00
parent 17058b59af
commit 502ba4ac9b
3 changed files with 101 additions and 90 deletions

110
auth.c
View File

@ -1,9 +1,9 @@
/* /*
VTun - Virtual Tunnel over TCP/IP network. VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com> Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky. VTun has been derived from VPPP package by Maxim Krasnyansky.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,12 +18,12 @@
/* /*
* $Id: auth.c,v 1.9.2.5 2013/07/07 19:54:20 mtbishop Exp $ * $Id: auth.c,v 1.9.2.5 2013/07/07 19:54:20 mtbishop Exp $
*/ */
/* /*
* Challenge based authentication. * Challenge based authentication.
* Thanx to Chris Todd<christ@insynq.com> for the good idea. * Thanx to Chris Todd<christ@insynq.com> for the good idea.
*/ */
#include "config.h" #include "config.h"
@ -63,6 +63,8 @@ static int derive_key(struct vtun_host *host)
{ {
unsigned char salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; unsigned char salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
int ret = -1; int ret = -1;
size_t bin_len;
const char ** const hex_end;
if (host->key != NULL) { if (host->key != NULL) {
return 0; return 0;
@ -70,17 +72,27 @@ static int derive_key(struct vtun_host *host)
if ((host->key = sodium_malloc(HOST_KEYBYTES)) == NULL) { if ((host->key = sodium_malloc(HOST_KEYBYTES)) == NULL) {
return -1; return -1;
} }
sodium_hex2bin(host->key, HOST_KEYBYTES,host->passwd,
strlen(host->passwd), "", &bin_len, hex_end);
if (bin_len == HOST_KEYBYTES) {
vtun_syslog(LOG_ERR,"supplied password is long enough to be the secret");
return 0;
}
vtun_syslog(LOG_ERR,"supplied password is %i bits, adjusting it to 32 bits", bin_len);
memset(salt, 0xd1, sizeof salt); memset(salt, 0xd1, sizeof salt);
if (crypto_pwhash_scryptsalsa208sha256 if (crypto_pwhash_scryptsalsa208sha256
(host->key, HOST_KEYBYTES, host->passwd, strlen(host->passwd), salt, (host->key, HOST_KEYBYTES, host->passwd, strlen(host->passwd), salt,
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) == 0) { crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) == 0) {
ret = 0; ret = 0;
} }
sodium_memzero(host->passwd, strlen(host->passwd));
free(host->passwd); sodium_memzero(host->passwd, strlen(host->passwd));
host->passwd = NULL; free(host->passwd);
vtun_syslog(LOG_DEBUG,"Key ready for host %s.", host->host); host->passwd = NULL;
vtun_syslog(LOG_DEBUG,"Key ready for host %s.", host->host);
return ret; return ret;
} }
@ -96,11 +108,11 @@ static void auth_chal(char *chal, const struct vtun_host *host)
host->key, HOST_KEYBYTES); host->key, HOST_KEYBYTES);
} }
/* /*
* Functions to convert binary flags to character string. * Functions to convert binary flags to character string.
* string format: <CS64> * string format: <CS64>
* C - compression, S - speed for shaper and so on. * C - compression, S - speed for shaper and so on.
*/ */
static char *bf2cf(struct vtun_host *host) static char *bf2cf(struct vtun_host *host)
{ {
@ -120,12 +132,12 @@ static char *bf2cf(struct vtun_host *host)
switch( host->flags & VTUN_TYPE_MASK ){ switch( host->flags & VTUN_TYPE_MASK ){
case VTUN_TTY: case VTUN_TTY:
*(ptr++) = 't'; *(ptr++) = 't';
break; break;
case VTUN_PIPE: case VTUN_PIPE:
*(ptr++) = 'p'; *(ptr++) = 'p';
break; break;
case VTUN_ETHER: case VTUN_ETHER:
*(ptr++) = 'e'; *(ptr++) = 'e';
@ -134,7 +146,7 @@ static char *bf2cf(struct vtun_host *host)
case VTUN_TUN: case VTUN_TUN:
*(ptr++) = 'u'; *(ptr++) = 'u';
break; break;
} }
if( (host->flags & VTUN_SHAPE) /* && host->spd_in */) if( (host->flags & VTUN_SHAPE) /* && host->spd_in */)
ptr += sprintf(ptr,"S%d",host->spd_in); ptr += sprintf(ptr,"S%d",host->spd_in);
@ -157,7 +169,7 @@ static char *bf2cf(struct vtun_host *host)
return str; return str;
} }
/* return 1 on success, otherwise 0 /* return 1 on success, otherwise 0
Example: Example:
FLAGS: <TuE1> FLAGS: <TuE1>
*/ */
@ -167,10 +179,10 @@ static int cf2bf(char *str, struct vtun_host *host)
char *ptr, *p; char *ptr, *p;
int s; int s;
if( (ptr = strchr(str,'<')) ){ if( (ptr = strchr(str,'<')) ){
vtun_syslog(LOG_DEBUG,"Remote Server sends %s.", ptr); vtun_syslog(LOG_DEBUG,"Remote Server sends %s.", ptr);
ptr++; ptr++;
while(*ptr){ while(*ptr){
switch(*ptr++){ switch(*ptr++){
case 't': case 't':
host->flags |= VTUN_TTY; host->flags |= VTUN_TTY;
@ -196,17 +208,17 @@ static int cf2bf(char *str, struct vtun_host *host)
host->flags |= VTUN_KEEP_ALIVE; host->flags |= VTUN_KEEP_ALIVE;
break; break;
case 'C': case 'C':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p) if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0; return 0;
host->flags |= VTUN_ZLIB; host->flags |= VTUN_ZLIB;
host->zlevel = s; host->zlevel = s;
ptr = p; ptr = p;
break; break;
case 'L': case 'L':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p) if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0; return 0;
host->flags |= VTUN_LZO; host->flags |= VTUN_LZO;
host->zlevel = s; host->zlevel = s;
ptr = p; ptr = p;
break; break;
case 'E': case 'E':
@ -221,11 +233,11 @@ static int cf2bf(char *str, struct vtun_host *host)
ptr = p; ptr = p;
break; break;
case 'S': case 'S':
if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p) if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p)
return 0; return 0;
if( s ){ if( s ){
host->flags |= VTUN_SHAPE; host->flags |= VTUN_SHAPE;
host->spd_out = s; host->spd_out = s;
} }
ptr = p; ptr = p;
break; break;
@ -242,10 +254,10 @@ static int cf2bf(char *str, struct vtun_host *host)
return 0; return 0;
} }
/* /*
* Functions to convert binary key data to character string. * Functions to convert binary key data to character string.
* string format: <char_data> * string format: <char_data>
*/ */
static char *cl2cs(char *chal) static char *cl2cs(char *chal)
{ {
@ -255,9 +267,9 @@ static char *cl2cs(char *chal)
*(ptr++) = '<'; *(ptr++) = '<';
for(i=0; i<VTUN_CHAL_SIZE; i++){ for(i=0; i<VTUN_CHAL_SIZE; i++){
*(ptr++) = chr[ ((chal[i] & 0xf0) >> 4) ]; *(ptr++) = chr[ ((chal[i] & 0xf0) >> 4) ];
*(ptr++) = chr[ (chal[i] & 0x0f) ]; *(ptr++) = chr[ (chal[i] & 0x0f) ];
} }
*(ptr++) = '>'; *(ptr++) = '>';
*ptr = '\0'; *ptr = '\0';
@ -270,24 +282,24 @@ static int cs2cl(char *str, char *chal)
register char *ptr = str; register char *ptr = str;
register int i; register int i;
if( !(ptr = strchr(str,'<')) ) if( !(ptr = strchr(str,'<')) )
return 0; return 0;
ptr++; ptr++;
if( !strtok(ptr,">") || strlen(ptr) != VTUN_CHAL_SIZE*2 ) if( !strtok(ptr,">") || strlen(ptr) != VTUN_CHAL_SIZE*2 )
return 0; return 0;
for(i=0; i<VTUN_CHAL_SIZE && *ptr; i++, ptr+=2) { for(i=0; i<VTUN_CHAL_SIZE && *ptr; i++, ptr+=2) {
chal[i] = (*ptr - 'a') << 4; chal[i] = (*ptr - 'a') << 4;
chal[i] |= *(ptr+1) - 'a'; chal[i] |= *(ptr+1) - 'a';
} }
return 1; return 1;
} }
/* Authentication (Server side) */ /* Authentication (Server side) */
struct vtun_host * auth_server(int fd) struct vtun_host * auth_server(int fd)
{ {
char chal_req[VTUN_CHAL_SIZE], chal_res[VTUN_CHAL_SIZE]; char chal_req[VTUN_CHAL_SIZE], chal_res[VTUN_CHAL_SIZE];
char buf[VTUN_MESG_SIZE], *str1, *str2; char buf[VTUN_MESG_SIZE], *str1, *str2;
struct vtun_host *h = NULL; struct vtun_host *h = NULL;
char *host = NULL; char *host = NULL;
@ -323,23 +335,23 @@ struct vtun_host * auth_server(int fd)
case ST_CHAL: case ST_CHAL:
if( !strcmp(str1,"CHAL") ){ if( !strcmp(str1,"CHAL") ){
if( !cs2cl(str2,chal_res) ) if( !cs2cl(str2,chal_res) )
break; break;
if( !(h = find_host(host)) ) if( !(h = find_host(host)) )
break; break;
derive_key(h); derive_key(h);
auth_chal(chal_req, h); auth_chal(chal_req, h);
if( !sodium_memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){ if( !sodium_memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
/* Auth successeful. */ /* Auth successeful. */
/* Lock host */ /* Lock host */
if( lock_host(h) < 0 ){ if( lock_host(h) < 0 ){
/* Multiple connections are denied */ /* Multiple connections are denied */
h = NULL; h = NULL;
break; break;
} }
print_p(fd,"OK FLAGS: %s\n", bf2cf(h)); print_p(fd,"OK FLAGS: %s\n", bf2cf(h));
} else } else
h = NULL; h = NULL;
} }
@ -352,7 +364,7 @@ struct vtun_host * auth_server(int fd)
free(host); free(host);
if( !h ) if( !h )
print_p(fd,"ERR\n"); print_p(fd,"ERR\n");
return h; return h;
} }
@ -362,7 +374,7 @@ int auth_client(int fd, struct vtun_host *host)
{ {
char buf[VTUN_MESG_SIZE], chal[VTUN_CHAL_SIZE]; char buf[VTUN_MESG_SIZE], chal[VTUN_CHAL_SIZE];
int stage, success=0 ; int stage, success=0 ;
stage = ST_INIT; stage = ST_INIT;
while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){ while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
@ -374,7 +386,7 @@ int auth_client(int fd, struct vtun_host *host)
print_p(fd,"HOST: %s\n",host->host); print_p(fd,"HOST: %s\n",host->host);
continue; continue;
} }
break; break;
case ST_HOST: case ST_HOST:
if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){ if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){
@ -385,8 +397,8 @@ int auth_client(int fd, struct vtun_host *host)
continue; continue;
} }
break; break;
case ST_CHAL: case ST_CHAL:
if( !strncmp(buf,"OK",2) && cf2bf(buf,host) ) if( !strncmp(buf,"OK",2) && cf2bf(buf,host) )
success = 1; success = 1;

48
main.c
View File

@ -1,9 +1,9 @@
/* /*
VTun - Virtual Tunnel over TCP/IP network. VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com> Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky. VTun has been derived from VPPP package by Maxim Krasnyansky.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
/* /*
* $Id: main.c,v 1.9.2.7 2013/07/07 20:31:22 mtbishop Exp $ * $Id: main.c,v 1.9.2.7 2013/07/07 20:31:22 mtbishop Exp $
*/ */
#include "config.h" #include "config.h"
@ -62,7 +62,7 @@ extern int optind,opterr,optopt;
extern char *optarg; extern char *optarg;
/* for the NATHack bit. Is our UDP session connected? */ /* for the NATHack bit. Is our UDP session connected? */
int is_rmt_fd_connected=1; int is_rmt_fd_connected=1;
int main(int argc, char *argv[], char *env[]) int main(int argc, char *argv[], char *env[])
{ {
@ -83,13 +83,13 @@ int main(int argc, char *argv[], char *env[])
vtun.cfg_file = VTUN_CONFIG_FILE; vtun.cfg_file = VTUN_CONFIG_FILE;
vtun.persist = -1; vtun.persist = -1;
vtun.timeout = -1; vtun.timeout = -1;
/* Dup strings because parser will try to free them */ /* Dup strings because parser will try to free them */
vtun.ppp = strdup("/usr/sbin/pppd"); vtun.ppp = strdup("/usr/sbin/pppd");
vtun.ifcfg = strdup("/sbin/ifconfig"); vtun.ifcfg = strdup("/sbin/ifconfig");
vtun.route = strdup("/sbin/route"); vtun.route = strdup("/sbin/route");
vtun.fwall = strdup("/sbin/ipchains"); vtun.fwall = strdup("/sbin/ipchains");
vtun.iproute = strdup("/sbin/ip"); vtun.iproute = strdup("/sbin/ip");
vtun.svr_name = NULL; vtun.svr_name = NULL;
vtun.svr_addr = NULL; vtun.svr_addr = NULL;
@ -140,7 +140,7 @@ int main(int argc, char *argv[], char *env[])
vtun.persist = 1; vtun.persist = 1;
break; break;
case 't': case 't':
vtun.timeout = atoi(optarg); vtun.timeout = atoi(optarg);
break; break;
case 'q': case 'q':
vtun.quiet = 1; vtun.quiet = 1;
@ -149,7 +149,7 @@ int main(int argc, char *argv[], char *env[])
usage(); usage();
exit(1); exit(1);
} }
} }
reread_config(0); reread_config(0);
if (vtun.syslog != LOG_DAEMON) { if (vtun.syslog != LOG_DAEMON) {
@ -167,18 +167,18 @@ int main(int argc, char *argv[], char *env[])
} }
hst = argv[optind++]; hst = argv[optind++];
if( !(host = find_host(hst)) ){ if( !(host = find_host(hst)) ){
vtun_syslog(LOG_ERR,"Host %s not found in %s", hst, vtun.cfg_file); vtun_syslog(LOG_ERR,"Host %s not found in %s", hst, vtun.cfg_file);
exit(1); exit(1);
} }
vtun.svr_name = strdup(argv[optind]); vtun.svr_name = strdup(argv[optind]);
} }
/* /*
* Now fill uninitialized fields of the options structure * Now fill uninitialized fields of the options structure
* with default values. * with default values.
*/ */
if(vtun.bind_addr.port == -1) if(vtun.bind_addr.port == -1)
vtun.bind_addr.port = VTUN_PORT; vtun.bind_addr.port = VTUN_PORT;
if(vtun.persist == -1) if(vtun.persist == -1)
@ -193,11 +193,11 @@ int main(int argc, char *argv[], char *env[])
case VTUN_INETD: case VTUN_INETD:
sock = dup(0); sock = dup(0);
#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
dofork = 0; dofork = 0;
#endif #endif
break; break;
} }
#ifdef HAVE_SODIUM #ifdef HAVE_SODIUM
if (sodium_init() != 0) { if (sodium_init() != 0) {
abort(); abort();
@ -226,7 +226,7 @@ int main(int argc, char *argv[], char *env[])
} }
if(svr){ if(svr){
memset(&sa,0,sizeof(sa)); memset(&sa,0,sizeof(sa));
sa.sa_handler=reread_config; sa.sa_handler=reread_config;
sigaction(SIGHUP,&sa,NULL); sigaction(SIGHUP,&sa,NULL);
@ -240,28 +240,28 @@ int main(int argc, char *argv[], char *env[])
exit(1); exit(1);
#endif #endif
} }
server(sock); server(sock);
} else { } else {
init_title(argc,argv,env,"vtund[c]: "); init_title(argc,argv,env,"vtund[c]: ");
client(host); client(host);
} }
closelog(); closelog();
return 0; return 0;
} }
/* /*
* Very simple PID file creation function. Used by server. * Very simple PID file creation function. Used by server.
* Overrides existing file. * Overrides existing file.
*/ */
static void write_pid(void) static void write_pid(void)
{ {
FILE *f; FILE *f;
if( !(f=fopen(VTUN_PID_FILE,"w")) ){ if( !(f=fopen(VTUN_PID_FILE,"w")) ){
vtun_syslog(LOG_ERR,"Can't write PID file"); vtun_syslog(LOG_ERR,"Can't write PID file %s", VTUN_PID_FILE);
return; return;
} }

View File

@ -1,9 +1,9 @@
/* /*
VTun - Virtual Tunnel over TCP/IP network. VTun - Virtual Tunnel over TCP/IP network.
Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com> Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com>
VTun has been derived from VPPP package by Maxim Krasnyansky. VTun has been derived from VPPP package by Maxim Krasnyansky.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
/* /*
* $Id: server.c,v 1.9.2.4 2013/07/07 19:55:14 mtbishop Exp $ * $Id: server.c,v 1.9.2.4 2013/07/07 19:55:14 mtbishop Exp $
*/ */
#include "config.h" #include "config.h"
@ -74,22 +74,22 @@ static void connection(int sock)
opt = sizeof(struct sockaddr_in); opt = sizeof(struct sockaddr_in);
if( getsockname(sock, (struct sockaddr *) &my_addr, &opt) < 0 ){ if( getsockname(sock, (struct sockaddr *) &my_addr, &opt) < 0 ){
vtun_syslog(LOG_ERR, "Can't get local socket address"); vtun_syslog(LOG_ERR, "Can't get local socket address");
exit(1); exit(1);
} }
ip = strdup(inet_ntoa(cl_addr.sin_addr)); ip = strdup(inet_ntoa(cl_addr.sin_addr));
io_init(); io_init();
if( (host=auth_server(sock)) ){ if( (host=auth_server(sock)) ){
sa.sa_handler=SIG_IGN; sa.sa_handler=SIG_IGN;
sa.sa_flags=SA_NOCLDWAIT;; sa.sa_flags=SA_NOCLDWAIT;;
sigaction(SIGHUP,&sa,NULL); sigaction(SIGHUP,&sa,NULL);
vtun_syslog(LOG_INFO,"Session %s[%s:%d] opened", host->host, ip, vtun_syslog(LOG_INFO,"Session %s[%s:%d] opened", host->host, ip,
ntohs(cl_addr.sin_port) ); ntohs(cl_addr.sin_port) );
host->rmt_fd = sock; host->rmt_fd = sock;
host->sopt.laddr = strdup(inet_ntoa(my_addr.sin_addr)); host->sopt.laddr = strdup(inet_ntoa(my_addr.sin_addr));
host->sopt.lport = vtun.bind_addr.port; host->sopt.lport = vtun.bind_addr.port;
host->sopt.raddr = strdup(ip); host->sopt.raddr = strdup(ip);
@ -100,7 +100,7 @@ static void connection(int sock)
vtun_syslog(LOG_INFO,"Session %s closed", host->host); vtun_syslog(LOG_INFO,"Session %s closed", host->host);
/* Unlock host. (locked in auth_server) */ /* Unlock host. (locked in auth_server) */
unlock_host(host); unlock_host(host);
} else { } else {
vtun_syslog(LOG_INFO,"Denied connection from %s:%d", ip, vtun_syslog(LOG_INFO,"Denied connection from %s:%d", ip,
@ -127,18 +127,17 @@ static void listener(void)
vtun_syslog(LOG_ERR, "Can't fill in listen socket"); vtun_syslog(LOG_ERR, "Can't fill in listen socket");
exit(1); exit(1);
} }
if( (s=socket(AF_INET,SOCK_STREAM,0))== -1 ){ if( (s=socket(AF_INET,SOCK_STREAM,0))== -1 ){
vtun_syslog(LOG_ERR,"Can't create socket"); vtun_syslog(LOG_ERR,"Can't create socket");
exit(1); exit(1);
} }
opt=1; opt=1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){ if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){
vtun_syslog(LOG_ERR,"Can't bind to the socket"); vtun_syslog(LOG_ERR,"Can't bind to the socket %s", inet_ntoa(my_addr.sin_addr));
exit(1); exit(1);
} }
if( listen(s, 10) ){ if( listen(s, 10) ){
@ -158,7 +157,7 @@ static void listener(void)
while( (!server_term) || (server_term == VTUN_SIG_HUP) ){ while( (!server_term) || (server_term == VTUN_SIG_HUP) ){
opt=sizeof(cl_addr); opt=sizeof(cl_addr);
if( (s1=accept(s,(struct sockaddr *)&cl_addr,&opt)) < 0 ) if( (s1=accept(s,(struct sockaddr *)&cl_addr,&opt)) < 0 )
continue; continue;
switch( fork() ){ switch( fork() ){
case 0: case 0:
@ -171,8 +170,8 @@ static void listener(void)
close(s1); close(s1);
break; break;
} }
} }
} }
#endif #endif
void server(int sock) void server(int sock)
@ -201,5 +200,5 @@ void server(int sock)
case VTUN_INETD: case VTUN_INETD:
connection(sock); connection(sock);
break; break;
} }
} }