mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 18:45:40 +08:00
Preauthorization added
ACL which can be checked prior to request parsing and authentication (first entries with only IP and time, if any) are automatically marked as preauthentication and checked immediately after connection is accepted, prior to any resources are allocated. Connection is silently dropped if preauthentication fails.
This commit is contained in:
parent
b1a3755a94
commit
da215a152e
79
src/auth.c
79
src/auth.c
@ -676,27 +676,30 @@ int alwaysauth(struct clientparam * param){
|
||||
return res;
|
||||
}
|
||||
|
||||
int checkACL(struct clientparam * param){
|
||||
int checkACL2(struct clientparam * param, int pre){
|
||||
struct ace* acentry;
|
||||
|
||||
if(!param->srv->acl) {
|
||||
acentry = pre?param->srv->preacl:param->srv->acl;
|
||||
if(!acentry) {
|
||||
return 0;
|
||||
}
|
||||
for(acentry = param->srv->acl; acentry; acentry = acentry->next) {
|
||||
for(; acentry; acentry = acentry->next) {
|
||||
if(ACLmatches(acentry, param)) {
|
||||
param->nolog = acentry->nolog;
|
||||
param->weight = acentry->weight;
|
||||
if(acentry->action == 2) {
|
||||
struct ace dup;
|
||||
if(!pre){
|
||||
param->nolog = acentry->nolog;
|
||||
param->weight = acentry->weight;
|
||||
if(acentry->action == 2) {
|
||||
struct ace dup;
|
||||
|
||||
if(param->operation < 256 && !(param->operation & CONNECT)){
|
||||
continue;
|
||||
if(param->operation < 256 && !(param->operation & CONNECT)){
|
||||
continue;
|
||||
}
|
||||
if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
|
||||
continue;
|
||||
}
|
||||
dup = *acentry;
|
||||
return handleredirect(param, &dup);
|
||||
}
|
||||
if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
|
||||
continue;
|
||||
}
|
||||
dup = *acentry;
|
||||
return handleredirect(param, &dup);
|
||||
}
|
||||
return acentry->action;
|
||||
}
|
||||
@ -704,6 +707,19 @@ int checkACL(struct clientparam * param){
|
||||
return 3;
|
||||
}
|
||||
|
||||
int checkACL(struct clientparam * param){
|
||||
int res;
|
||||
res = checkACL2(param, 1);
|
||||
if(res < 2) return res;
|
||||
return checkACL2(param, 0);
|
||||
}
|
||||
|
||||
|
||||
int checkpreACL(struct clientparam * param){
|
||||
return checkACL2(param, 1);
|
||||
}
|
||||
|
||||
|
||||
struct authcache {
|
||||
char * username;
|
||||
char * password;
|
||||
@ -771,6 +787,16 @@ int cacheauth(struct clientparam * param){
|
||||
return 4;
|
||||
}
|
||||
|
||||
int dopreauth(struct clientparam * param){
|
||||
int res = 0;
|
||||
|
||||
if(param->srv && param->srv->authfuncs && param->srv->authfuncs->preauthorize){
|
||||
res = param->srv->authfuncs->preauthorize(param);
|
||||
param->preauthorized = !res;
|
||||
if(res != 1) res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int doauth(struct clientparam * param){
|
||||
int res = 0;
|
||||
struct auth *authfuncs;
|
||||
@ -781,7 +807,8 @@ int doauth(struct clientparam * param){
|
||||
for(authfuncs=param->srv->authfuncs; authfuncs; authfuncs=authfuncs->next){
|
||||
res = authfuncs->authenticate?(*authfuncs->authenticate)(param):0;
|
||||
if(!res) {
|
||||
if(authfuncs->authorize &&
|
||||
|
||||
if(!param->preauthorized && authfuncs->authorize &&
|
||||
(res = (*authfuncs->authorize)(param)))
|
||||
return res;
|
||||
if(conf.authcachetype && authfuncs->authenticate && authfuncs->authenticate != cacheauth && param->username && (!(conf.authcachetype&4) || (!param->pwtype && param->password))){
|
||||
@ -847,9 +874,11 @@ int doauth(struct clientparam * param){
|
||||
int ipauth(struct clientparam * param){
|
||||
int res;
|
||||
unsigned char *username;
|
||||
|
||||
if(param->preauthorized) return (0);
|
||||
username = param->username;
|
||||
param->username = NULL;
|
||||
res = checkACL(param);
|
||||
res = checkACL2(param,0);
|
||||
param->username = username;
|
||||
return res;
|
||||
}
|
||||
@ -960,20 +989,20 @@ int strongauth(struct clientparam * param){
|
||||
int radauth(struct clientparam * param);
|
||||
|
||||
struct auth authfuncs[] = {
|
||||
{authfuncs+1, NULL, NULL, ""},
|
||||
{authfuncs+2, ipauth, NULL, "iponly"},
|
||||
{authfuncs+3, userauth, checkACL, "useronly"},
|
||||
{authfuncs+4, dnsauth, checkACL, "dnsname"},
|
||||
{authfuncs+5, strongauth, checkACL, "strong"},
|
||||
{authfuncs+6, cacheauth, checkACL, "cache"},
|
||||
{authfuncs+1, NULL,NULL, NULL, ""},
|
||||
{authfuncs+2, checkpreACL, ipauth, NULL, "iponly"},
|
||||
{authfuncs+3, checkpreACL, userauth, checkACL, "useronly"},
|
||||
{authfuncs+4, checkpreACL, dnsauth, checkACL, "dnsname"},
|
||||
{authfuncs+5, checkpreACL, strongauth, checkACL, "strong"},
|
||||
{authfuncs+6, checkpreACL, cacheauth, checkACL, "cache"},
|
||||
#ifndef NORADIUS
|
||||
#define AUTHOFFSET 1
|
||||
{authfuncs+7, radauth, checkACL, "radius"},
|
||||
{authfuncs+7, checkpreACL, radauth, checkACL, "radius"},
|
||||
#else
|
||||
#define AUTHOFFSET 0
|
||||
#endif
|
||||
{authfuncs+7+AUTHOFFSET, NULL, NULL, "none"},
|
||||
{NULL, NULL, NULL, ""}
|
||||
{authfuncs+7+AUTHOFFSET, NULL, NULL, NULL, "none"},
|
||||
{NULL, NULL, NULL, NULL, ""}
|
||||
};
|
||||
|
||||
|
||||
|
@ -481,6 +481,7 @@ static int h_auth(int argc, unsigned char **argv){
|
||||
newau->next = conf.authfuncs;
|
||||
conf.authfuncs = newau;
|
||||
conf.authfuncs->desc = au->desc;
|
||||
conf.authfuncs->preauthorize = au->preauthorize;
|
||||
conf.authfuncs->authenticate = au->authenticate;
|
||||
conf.authfuncs->authorize = au->authorize;
|
||||
break;
|
||||
|
@ -74,6 +74,7 @@ struct symbol symbols[] = {
|
||||
{symbols+47, "parsestr", (void *) parsestr},
|
||||
{symbols+48, "make_ace", (void *) make_ace},
|
||||
{symbols+49, "freeacl", (void *) freeacl},
|
||||
{symbols+50, "checkpreACL", (void *) checkpreACL},
|
||||
{NULL, "", NULL}
|
||||
};
|
||||
|
||||
@ -108,6 +109,7 @@ struct pluginlink pluginlink = {
|
||||
ACLmatches,
|
||||
alwaysauth,
|
||||
checkACL,
|
||||
checkpreACL,
|
||||
nametohash,
|
||||
hashindex,
|
||||
en64,
|
||||
|
@ -488,6 +488,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
|
||||
|
||||
|
||||
|
||||
myalwaysauth.preauthorize = pluginlink->checkpreACL;
|
||||
myalwaysauth.authenticate = ldapfunc;
|
||||
myalwaysauth.authorize = pluginlink->checkACL;
|
||||
myalwaysauth.desc = "ldap";
|
||||
|
@ -139,6 +139,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, unsigne
|
||||
already_loaded = 1;
|
||||
|
||||
pthread_mutex_init(&pam_mutex, NULL);
|
||||
pamauth.preauthorize = pluginlink->checkpreACL;
|
||||
pamauth.authenticate = pamfunc;
|
||||
pamauth.authorize = pluginlink->checkACL;
|
||||
pamauth.desc = "pam";
|
||||
|
@ -78,6 +78,7 @@ PLUGINAPI int PLUGINCALL WindowsAuthentication(struct pluginlink * pluginlink, i
|
||||
(LPTSTR) tmpbuf, &dlen, &snu)) return 100000 + (int)GetLastError();
|
||||
if(snu != SidTypeGroup && snu != SidTypeAlias && snu != SidTypeWellKnownGroup) return 12;
|
||||
if(!loaded){
|
||||
alwaysauth.preauthorize = pluginlink->checkpreACL;
|
||||
alwaysauth.authenticate = windowsfunc;
|
||||
alwaysauth.authorize = pluginlink->checkACL;
|
||||
alwaysauth.desc = "windows";
|
||||
|
@ -184,6 +184,7 @@ void close_sql();
|
||||
int doconnect(struct clientparam * param);
|
||||
int alwaysauth(struct clientparam * param);
|
||||
int ipauth(struct clientparam * param);
|
||||
int dopreauth(struct clientparam * param);
|
||||
int doauth(struct clientparam * param);
|
||||
int strongauth(struct clientparam * param);
|
||||
void trafcountfunc(struct clientparam *param);
|
||||
@ -248,10 +249,11 @@ int parseusername(char *username, struct clientparam *param, int extpasswd);
|
||||
int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port);
|
||||
int ACLmatches(struct ace* acentry, struct clientparam * param);
|
||||
int checkACL(struct clientparam * param);
|
||||
int checkpreACL(struct clientparam * param);
|
||||
extern int havelog;
|
||||
unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth);
|
||||
|
||||
struct ace * copyacl (struct ace *ac);
|
||||
void copyacl (struct ace *ac, struct srvparam *srv);
|
||||
struct auth * copyauth (struct auth *);
|
||||
void * itfree(void *data, void * retval);
|
||||
void freeacl(struct ace *ac);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2017 by Vladimir Dubrovin <3proxy@3proxy.ru>
|
||||
|
||||
@ -34,7 +34,7 @@ void * threadfunc (void *p) {
|
||||
}
|
||||
#ifndef WITHMAIN
|
||||
param->req = param->sinsr;
|
||||
if(param->srv->acl) param->res = checkACL(param);
|
||||
if(param->srv->preacl) param->res = checkpreACL(param);
|
||||
if(param->res){
|
||||
dolog(param, (unsigned char *)"Connect back ACL failed");
|
||||
so._closesocket(param->remsock);
|
||||
@ -277,7 +277,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
srv.service = defparam.service = childdef.service;
|
||||
|
||||
#ifndef STDMAIN
|
||||
srv.acl = copyacl(conf.acl);
|
||||
copyacl(conf.acl, &srv);
|
||||
srv.authfuncs = copyauth(conf.authfuncs);
|
||||
if(!conf.services){
|
||||
conf.services = &srv;
|
||||
@ -774,6 +774,13 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
else {
|
||||
srv.fds.events = 0;
|
||||
}
|
||||
|
||||
#ifndef STDMAIN
|
||||
if((dopreauth(&defparam)) != 0){
|
||||
if(!isudp) so._closesocket(new_sock);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if(! (newparam = myalloc (sizeof(defparam)))){
|
||||
if(!isudp) so._closesocket(new_sock);
|
||||
defparam.res = 21;
|
||||
@ -784,6 +791,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
*newparam = defparam;
|
||||
if(defparam.hostname)newparam->hostname=(unsigned char *)mystrdup((char *)defparam.hostname);
|
||||
clearstat(newparam);
|
||||
|
||||
if(!isudp) newparam->clisock = new_sock;
|
||||
#ifndef STDMAIN
|
||||
if(makefilters(&srv, newparam) > CONTINUE){
|
||||
@ -946,6 +954,7 @@ void srvfree(struct srvparam * srv){
|
||||
}
|
||||
|
||||
if(srv->acl)freeacl(srv->acl);
|
||||
if(srv->preacl)freeacl(srv->preacl);
|
||||
if(srv->authfuncs)freeauth(srv->authfuncs);
|
||||
#endif
|
||||
pthread_mutex_destroy(&srv->counter_mutex);
|
||||
@ -1036,16 +1045,17 @@ struct auth * copyauth (struct auth * authfuncs){
|
||||
return newauth;
|
||||
}
|
||||
|
||||
struct ace * copyacl (struct ace *ac){
|
||||
struct ace * ret = NULL;
|
||||
void copyacl (struct ace *ac, struct srvparam *srv){
|
||||
struct iplist *ipl;
|
||||
struct portlist *pl;
|
||||
struct userlist *ul;
|
||||
struct chain *ch;
|
||||
struct period *pel;
|
||||
struct hostname *hst;
|
||||
int preacl = 1;
|
||||
struct ace *acc;
|
||||
|
||||
ret = ac = itcopy(ac, sizeof(struct ace));
|
||||
ac = itcopy(ac, sizeof(struct ace));
|
||||
for( ; ac; ac = ac->next = itcopy(ac->next, sizeof(struct ace))){
|
||||
ac->src = itcopy(ac->src, sizeof(struct iplist));
|
||||
for(ipl = ac->src; ipl; ipl = ipl->next = itcopy(ipl->next, sizeof(struct iplist)));
|
||||
@ -1069,8 +1079,21 @@ struct ace * copyacl (struct ace *ac){
|
||||
if(ch->extpass)ch->extpass = (unsigned char*)mystrdup((char *)ch->extpass);
|
||||
if(ch->exthost)ch->exthost = (unsigned char*)mystrdup((char *)ch->exthost);
|
||||
}
|
||||
if(preacl){
|
||||
if(ac->dst || ac->ports || ac->users || ac->dstnames || ac->chains|| ac->action>1){
|
||||
preacl = 0;
|
||||
for(acc = srv->preacl; acc; acc=acc->next)if(acc->next == ac) {
|
||||
acc->next = NULL;
|
||||
break;
|
||||
}
|
||||
srv->acl = ac;
|
||||
}
|
||||
else {
|
||||
if(!srv->preacl) srv->preacl = ac;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,6 +216,7 @@ typedef int (*PLUGINFUNC)(struct pluginlink *pluginlink, int argc, char** argv);
|
||||
|
||||
struct auth {
|
||||
struct auth *next;
|
||||
AUTHFUNC preauthorize;
|
||||
AUTHFUNC authenticate;
|
||||
AUTHFUNC authorize;
|
||||
char * desc;
|
||||
@ -461,7 +462,7 @@ struct srvparam {
|
||||
#endif
|
||||
struct auth *authenticate;
|
||||
struct pollfd * srvfds;
|
||||
struct ace *acl;
|
||||
struct ace *preacl, *acl;
|
||||
struct auth *authfuncs;
|
||||
struct filter *filter;
|
||||
unsigned char * logformat;
|
||||
@ -503,6 +504,7 @@ struct clientparam {
|
||||
operation,
|
||||
nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv,
|
||||
unsafefilter,
|
||||
preauthorized,
|
||||
bandlimver;
|
||||
|
||||
int res,
|
||||
@ -744,6 +746,7 @@ struct pluginlink {
|
||||
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
|
||||
int (*alwaysauth)(struct clientparam * param);
|
||||
int (*checkACL)(struct clientparam * param);
|
||||
int (*checkpreACL)(struct clientparam * param);
|
||||
void (*nametohash)(const unsigned char * name, unsigned char *hash);
|
||||
unsigned (*hashindex)(const unsigned char* hash);
|
||||
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);
|
||||
|
Loading…
Reference in New Issue
Block a user