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.
This commit is contained in:
Vladimir Dubrovin 2026-04-21 21:49:52 +03:00
parent bfbbf1f446
commit 4f0f3c81e1
5 changed files with 28 additions and 11 deletions

View File

@ -843,7 +843,7 @@ int doauth(struct clientparam * param){
ac.sinsl_family = *SAFAMILY(&param->sinsl);
memcpy(ac.sinsl_addr, SAADDR(&param->sinsl), SAADDRLEN(&param->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, ""}
};

View File

@ -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;
}

View File

@ -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(&param->sincr), SAADDRLEN(&param->sincr));
if((conf.authcachetype & 16))blake2b_update(&S, &param->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(&param->sincr), SAADDRLEN(&param->sincr));
if((type & 16))blake2b_update(&S, &param->srv->acl, sizeof(param->srv->acl));
if((type & 64))blake2b_update(&S, SAADDR(&param->req), SAADDRLEN(&param->req));
if((type & 128))blake2b_update(&S, SAPORT(&param->req), 2);
if((type & 256) && param->hostname)blake2b_update(&S, param->hostname, strlen((const char *)param->hostname) + 1);
if((type & 512))blake2b_update(&S, &param->operation, sizeof(param->operation));
if((type & 1024))blake2b_update(&S, SAADDR(&param->srv->intsa), SAADDRLEN(&param->srv->intsa));
if((type & 2048))blake2b_update(&S, SAPORT(&param->srv->intsa), 2);
blake2b_final(&S, hash, ht->hash_size);
}

View File

@ -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){

View File

@ -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;