diff --git a/src/auth.c b/src/auth.c index 85ea0e4..653ea06 100644 --- a/src/auth.c +++ b/src/auth.c @@ -7,6 +7,7 @@ */ #include "proxy.h" +#include "blake2_compat.h" void initbandlims(struct clientparam *param); @@ -217,23 +218,43 @@ int dnsauth(struct clientparam * param){ int strongauth(struct clientparam * param){ static char dummy; unsigned char buf[256]; - char cryptpw[65] = {0}; + char pass[256] = {0}; if (!param->username) return 4; if (!param->pwtype && param->password) { - if (pw_table.ihashtable && hashresolv(&pw_table, param, &dummy, NULL)) - return 0; + if (pwl_table.ihashtable && hashresolv(&pwl_table, param->username, pass, NULL)) { + switch(pass[0]){ + case CL: { + int pwlen = strlen((char *)param->password); + if(pwlen > 255) pwlen = 255; + if((unsigned)pwlen < pwl_table.recsize) { + if(!strncmp(pass + 1, (char *)param->password, pwl_table.recsize - 1)) return 0; + } else { + blake2b_state S; + unsigned hashsz; + hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64; + memset(buf, 0, pwl_table.recsize - 1); + blake2b_init(&S, hashsz); + blake2b_update(&S, param->password, pwlen + 1); + blake2b_final(&S, buf, hashsz); + if(!memcmp(pass + 1, buf, pwl_table.recsize - 1)) return 0; + } + return 6; + } + case CR: + if (!strcmp(pass + 1, (char *)mycrypt(param->password, (unsigned char *)pass, buf))) + return 0; + else return 7; #ifdef WITH_SSL - if (pwnt_table.ihashtable && hashresolv(&pwnt_table, param, &dummy, NULL)) - return 0; + case NT: + ntpwdhash(buf, param->password, 1); + if(!strcmp(pass + 1, (char *)buf)) return 0; + else return 8; #endif -#ifndef NOCRYPT - if (pwcr_table.ihashtable && hashresolv(&pwcr_table, param, cryptpw, NULL)) { - if (!strcmp(cryptpw, (char *)mycrypt(param->password, (unsigned char *)cryptpw, buf))) - return 0; - return 7; + default: + break; + } } -#endif } return 5; } diff --git a/src/conf.c b/src/conf.c index 5455b46..31dff2f 100644 --- a/src/conf.c +++ b/src/conf.c @@ -7,6 +7,7 @@ */ #include "proxy.h" +#include "blake2_compat.h" #ifdef WITH_SSL void ssl_install(void); #endif @@ -522,6 +523,8 @@ static int h_users(int argc, unsigned char **argv){ int j; unsigned char *arg; char *pw[2]; + char pass[256]; + int l; for (j = 1; j < argc; j++) { arg = (unsigned char *)strchr((char *)argv[j], ':'); @@ -529,34 +532,44 @@ static int h_users(int argc, unsigned char **argv){ *arg = 0; pw[0] = (char *)argv[j]; + if (!pwl_table.ihashtable && inithashtable(&pwl_table, 16, 32, 1048576)) + return 3; + memset(pass, 0, sizeof(pass)); if (arg[1] && arg[2] && arg[3] == ':') { pw[1] = (char *)(arg + 4); if (arg[1] == 'N' && arg[2] == 'T') { #ifdef WITH_SSL - if (!pwnt_table.ihashtable && inithashtable(&pwnt_table, 16, 32, 1048576)) - return 3; - hashadd(&pwnt_table, pw, &dummy, MAX_COUNTER_TIME); + *pass = NT; +#else + continue; #endif - continue; } - if (arg[1] == 'C' && arg[2] == 'R') { - if (!pwcr_table.ihashtable && inithashtable(&pwcr_table, 16, 32, 1048576)) - return 3; - hashadd(&pwcr_table, pw[0], pw[1], MAX_COUNTER_TIME); - continue; + else if (arg[1] == 'C' && arg[2] == 'R') { + *pass = CR; } - if (arg[1] == 'C' && arg[2] == 'L') { - /* fall through to CL handling below */ + else if (arg[1] == 'C' && arg[2] == 'L') { + *pass = CL; } else { continue; } } else { + *pass = CL; pw[1] = (char *)(arg + 1); } - - if (!pw_table.ihashtable && inithashtable(&pw_table, 16, 32, 1048576)) - return 3; - hashadd(&pw_table, pw, &dummy, MAX_COUNTER_TIME); + l = strlen(pw[1]); + if(l > 255) l = 255; + if((unsigned)l >= pwl_table.recsize) { + if(*pass != CL) continue; + blake2b_state S; + unsigned hashsz; + hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64; + blake2b_init(&S, hashsz); + blake2b_update(&S, pw[1], l + 1); + blake2b_final(&S, (uint8_t *)(pass + 1), hashsz); + } else { + memcpy(pass + 1, pw[1], l); + } + hashadd(&pwl_table, pw[0], pass, MAX_COUNTER_TIME); } return 0; } @@ -1892,11 +1905,7 @@ void freeconf(struct extparam *confp){ confp->connlimiter = NULL; _3proxy_mutex_unlock(&connlim_mutex); - destroyhashtable(&pw_table); -#ifdef WITH_SSL - destroyhashtable(&pwnt_table); -#endif - destroyhashtable(&pwcr_table); + destroyhashtable(&pwl_table); confp->logfunc = lognone; logformat = confp->logformat; diff --git a/src/hashtables.c b/src/hashtables.c index 71d13eb..533716e 100644 --- a/src/hashtables.c +++ b/src/hashtables.c @@ -71,15 +71,6 @@ void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){ memcpy(hash, param->hash, ht->hash_size); } -static void user2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){ - struct clientparam *param = (struct clientparam *)index; - blake2b_state S; - - blake2b_init(&S, ht->hash_size); - blake2b_update(&S, param->username, strlen((const char *)param->username) + 1); - blake2b_final(&S, hash, ht->hash_size); -} - static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){ struct clientparam *param = (struct clientparam *)index; blake2b_state S; @@ -91,54 +82,7 @@ static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash blake2b_final(&S, hash, ht->hash_size); } -static void pw2hash_add(const struct hashtable *ht, void *index, uint8_t *hash){ - char ** pw = (char **)index; - blake2b_state S; - - blake2b_init(&S, ht->hash_size); - if(pw[0])blake2b_update(&S, pw[0], strlen(pw[0]) + 1); - if(pw[1])blake2b_update(&S, pw[1], strlen(pw[1]) + 1); - blake2b_final(&S, hash, ht->hash_size); -} - - -static void pw2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){ - struct clientparam *param = (struct clientparam *)index; - - char *pw[2] = {(char *)param->username, (char *)param->password}; - - pw2hash_add(ht, pw, hash); -} - -static void pwnt2hash_add(const struct hashtable *ht, void *index, uint8_t *hash){ - char ** pw = (char **)index; - blake2b_state S; - - blake2b_init(&S, ht->hash_size); - if(pw[0])blake2b_update(&S, pw[0], strlen(pw[0]) + 1); - if(pw[1])blake2b_update(&S, pw[1], strlen(pw[1]) + 1); - blake2b_final(&S, hash, ht->hash_size); -} - - -#ifdef WITH_SSL -static void pwnt2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){ - struct clientparam *param = (struct clientparam *)index; - unsigned char pass[40]; - char *pw[2] = {(char *)param->username, (char *)pass}; - - ntpwdhash(pass, param->password, 1); - pwnt2hash_add(ht, pw, hash); -} -#endif - - - struct hashtable dns_table = {char_index2hash, char_index2hash, 4, 32}; struct hashtable dns6_table = {char_index2hash, char_index2hash, 16, 32}; struct hashtable auth_table = {param2hash_add, param2hash_search, sizeof(struct authcache), 64}; -struct hashtable pw_table = {pw2hash_add, pw2hash_search, 0, 12}; -#ifdef WITH_SSL -struct hashtable pwnt_table = {pwnt2hash_add, pwnt2hash_search, 0, 12}; -#endif -struct hashtable pwcr_table = {char_index2hash, user2hash_search, 64, 12}; +struct hashtable pwl_table = {char_index2hash, char_index2hash, 64, 64}; diff --git a/src/structures.h b/src/structures.h index d043937..6f23302 100644 --- a/src/structures.h +++ b/src/structures.h @@ -781,11 +781,7 @@ struct child { extern struct hashtable dns_table; extern struct hashtable dns6_table; extern struct hashtable auth_table; -extern struct hashtable pw_table; -#ifdef WITH_SSL -extern struct hashtable pwnt_table; -#endif -extern struct hashtable pwcr_table; +extern struct hashtable pwl_table; extern struct hashtable udp_table; struct authcache {