/* Authentication (Client side) */ int auth_client(int fd, struct vtun_host *host, int * reason) { char buf[VTUN_MESG_SIZE], chal[VTUN_CHAL_SIZE]; int stage, success=0 ; stage = ST_INIT; *reason = D_NOREAD; while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){ *reason = D_OTHER; buf[sizeof(buf)-1]='\0'; switch( stage ){ case ST_INIT: if (!strncmp(buf, "VTRUNKD", 7)) { stage = ST_HOST; print_p(fd,"HOST: %s\n",host->host); continue; } *reason = D_GREET; 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; } *reason = D_CHAL; break; case ST_CHAL: if( !strncmp(buf,"OK",2) && cf2bf(buf,host) ) success = 1; else *reason = D_PWD; break; } break; } return success; }
/* 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; }