From 4f0f3c81e12ef0d376caec66e1f38edf5e23c79f Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 21 Apr 2026 21:49:52 +0300 Subject: [PATCH] add 'cacheacl' auth type, dstaddr, dstport, dsthost, dstoper, srvaddr and srvport authcache types; allow to configure authcache by service 'auth cacheacl ...' is identical to 'auth cache ...' except ACL is not checked for cached authentication. dstaddr, dstport, dsthost and dstoper (operation) are intended to be used with cacheacl. For example authcache user,ip,password,dstaddr 600 auth cacheacl iponly strong allows user to access destination ip without ACL/password revalidation if he has cached attempt to the same ip from the same ip with the same username and password. srvaddr, srvport are useful to only match with cached attempts to the same `internal` address / service port. --- src/auth.c | 7 ++++--- src/conf.c | 12 +++++++++--- src/hash.c | 15 +++++++++++---- src/proxymain.c | 2 ++ src/structures.h | 3 ++- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/auth.c b/src/auth.c index ed120d5..9ded49d 100644 --- a/src/auth.c +++ b/src/auth.c @@ -843,7 +843,7 @@ int doauth(struct clientparam * param){ ac.sinsl_family = *SAFAMILY(¶m->sinsl); memcpy(ac.sinsl_addr, SAADDR(¶m->sinsl), SAADDRLEN(¶m->sinsl)); } - hashadd(&auth_table, param, &ac, conf.time + conf.authcachetime); + hashadd(&auth_table, param, &ac, conf.time + param->srv->authcachetime); } break; } @@ -971,13 +971,14 @@ struct auth authfuncs[] = { {authfuncs+4, dnsauth, checkACL, "dnsname"}, {authfuncs+5, strongauth, checkACL, "strong"}, {authfuncs+6, cacheauth, checkACL, "cache"}, + {authfuncs+7, cacheauth, NULL, "cacheacl"}, #ifndef NORADIUS #define AUTHOFFSET 1 - {authfuncs+7, radauth, checkACL, "radius"}, + {authfuncs+8, radauth, checkACL, "radius"}, #else #define AUTHOFFSET 0 #endif - {authfuncs+7+AUTHOFFSET, NULL, NULL, "none"}, + {authfuncs+8+AUTHOFFSET, NULL, NULL, "none"}, {NULL, NULL, NULL, ""} }; diff --git a/src/conf.c b/src/conf.c index 1d1c84b..dd6d082 100644 --- a/src/conf.c +++ b/src/conf.c @@ -662,7 +662,7 @@ static int h_nscache(int argc, unsigned char **argv){ fprintf(stderr, "Invalid NS cache size: %d\n", res); return 1; } - if(inithashtable(&dns_table, (res << 2), (res << 2), res)){ + if(dns_table.growlimit != res && inithashtable(&dns_table, (res << 2), (res << 2), res)){ fprintf(stderr, "Failed to initialize NS cache\n"); return 2; } @@ -685,7 +685,7 @@ static int h_nscache6(int argc, unsigned char **argv){ fprintf(stderr, "Invalid NS cache size: %d\n", res); return 1; } - if(inithashtable(&dns6_table, (res<<2), (res<<2), res)){ + if(dns6_table.growlimit != res &&inithashtable(&dns6_table, (res<<2), (res<<2), res)){ fprintf(stderr, "Failed to initialize NS cache\n"); return 2; } @@ -1438,12 +1438,18 @@ static int h_authcache(int argc, unsigned char **argv){ if(strstr((char *) *(argv + 1), "limit")) conf.authcachetype |= 8; if(strstr((char *) *(argv + 1), "acl")) conf.authcachetype |= 16; if(strstr((char *) *(argv + 1), "ext")) conf.authcachetype |= 32; + if(strstr((char *) *(argv + 1), "dstaddr")) conf.authcachetype |= 64; + if(strstr((char *) *(argv + 1), "dstport")) conf.authcachetype |= 128; + if(strstr((char *) *(argv + 1), "dsthost")) conf.authcachetype |= 256; + if(strstr((char *) *(argv + 1), "dstoper")) conf.authcachetype |= 512; + if(strstr((char *) *(argv + 1), "srvaddr")) conf.authcachetype |= 1024; + if(strstr((char *) *(argv + 1), "srvport")) conf.authcachetype |= 2048; if(argc > 2) conf.authcachetime = (unsigned) atoi((char *) *(argv + 2)); if(argc > 3) authcachesize = (unsigned) atoi((char *) *(argv + 3)); if(!conf.authcachetype) conf.authcachetype = 6; if(!conf.authcachetime) conf.authcachetime = 600; if(!authcachesize) authcachesize = 65536*4; - if(inithashtable(&auth_table, 1024, 1024, authcachesize)){ + if(auth_table.growlimit != authcachesize && inithashtable(&auth_table, 1024, 1024, authcachesize)){ fprintf(stderr, "Failed to initialize auth cache\n"); return 2; } diff --git a/src/hash.c b/src/hash.c index af65c7b..73a3054 100644 --- a/src/hash.c +++ b/src/hash.c @@ -230,12 +230,19 @@ void char_index2hash(const struct hashtable *ht, const void *index, uint8_t *has void param2hash(const struct hashtable *ht, const void *index, uint8_t *hash){ blake2b_state S; const struct clientparam *param = (struct clientparam *)index; + unsigned type = param->srv->authcachetype; blake2b_init(&S, ht->hash_size); - if((conf.authcachetype & 2) && param->username)blake2b_update(&S, param->username, strlen((const char *)param->username) + 1); - if((conf.authcachetype & 4) && param->password)blake2b_update(&S, param->password, strlen((const char *)param->password) + 1); - if((conf.authcachetype & 1) && !(conf.authcachetype & 8))blake2b_update(&S, SAADDR(¶m->sincr), SAADDRLEN(¶m->sincr)); - if((conf.authcachetype & 16))blake2b_update(&S, ¶m->srv->acl, sizeof(param->srv->acl)); + if((type & 2) && param->username)blake2b_update(&S, param->username, strlen((const char *)param->username) + 1); + if((type & 4) && param->password)blake2b_update(&S, param->password, strlen((const char *)param->password) + 1); + if((type & 1) && !(type & 8))blake2b_update(&S, SAADDR(¶m->sincr), SAADDRLEN(¶m->sincr)); + if((type & 16))blake2b_update(&S, ¶m->srv->acl, sizeof(param->srv->acl)); + if((type & 64))blake2b_update(&S, SAADDR(¶m->req), SAADDRLEN(¶m->req)); + if((type & 128))blake2b_update(&S, SAPORT(¶m->req), 2); + if((type & 256) && param->hostname)blake2b_update(&S, param->hostname, strlen((const char *)param->hostname) + 1); + if((type & 512))blake2b_update(&S, ¶m->operation, sizeof(param->operation)); + if((type & 1024))blake2b_update(&S, SAADDR(¶m->srv->intsa), SAADDRLEN(¶m->srv->intsa)); + if((type & 2048))blake2b_update(&S, SAPORT(¶m->srv->intsa), 2); blake2b_final(&S, hash, ht->hash_size); } diff --git a/src/proxymain.c b/src/proxymain.c index 3074e36..fef8b0c 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -1028,6 +1028,8 @@ void srvinit(struct srvparam * srv, struct clientparam *param){ srv->extsa6 = conf.extsa6; #endif srv->so = so; + srv->authcachetime = conf.authcachetime; + srv->authcachetype = conf.authcachetype; } void srvinit2(struct srvparam * srv, struct clientparam *param){ diff --git a/src/structures.h b/src/structures.h index e07d915..be28e7e 100644 --- a/src/structures.h +++ b/src/structures.h @@ -529,6 +529,7 @@ struct srvparam { int usesplice; #endif unsigned bufsize; + unsigned authcachetype, authcachetime; unsigned logdumpsrv, logdumpcli; PROXYSOCKADDRTYPE intsa, intNat, extNat; #ifndef NOIPV6 @@ -665,7 +666,7 @@ struct extparam { int stacksize, counterd, haveerror, rotate, paused, archiverc, demon, maxchild, backlog, needreload, timetoexit, version, noforce, bandlimver, parentretries; - int authcachetype, authcachetime; + unsigned authcachetype, authcachetime; int filtermaxsize; int gracetraf, gracenum, gracedelay; int maxseg;