mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 18:45:40 +08:00
Merge remote-tracking branch 'refs/remotes/origin/devel' into devel-logthread
# Conflicts: # src/plugins.c # src/proxymain.c # src/sockmap.c
This commit is contained in:
commit
fa4322afee
10
3proxy.rc
10
3proxy.rc
@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,9,0,0
|
||||
PRODUCTVERSION 0,9,0,0
|
||||
FILEVERSION 10,0,0,0
|
||||
PRODUCTVERSION 10,0,0,0
|
||||
FILETYPE 1
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
@ -14,12 +14,12 @@ BEGIN
|
||||
VALUE "Comments", "3proxy - tiny proxy server, http://3proxy.org/\0"
|
||||
VALUE "CompanyName", "Vladimir Dubrovin\0"
|
||||
VALUE "FileDescription", "3proxy - tiny proxy server\0"
|
||||
VALUE "FileVersion", "0.9-devel-" BUILDDATE "\0"
|
||||
VALUE "FileVersion", "10-devel-" BUILDDATE "\0"
|
||||
VALUE "InternalName", "3proxy\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2002-2019 Vladimir Dubrovin\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2002-2020 Vladimir Dubrovin\0"
|
||||
VALUE "OriginalFilename", "3proxy.exe\0"
|
||||
VALUE "ProductName", "3proxy\0"
|
||||
VALUE "ProductVersion", "0.9-devel-" BUILDDATE "\0"
|
||||
VALUE "ProductVersion", "10-devel-" BUILDDATE "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
20
README
20
README
@ -1,5 +1,11 @@
|
||||
# 3APA3A 3proxy tiny proxy server
|
||||
(c) 2002-2019 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
|
||||
(c) 2002-2020 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
|
||||
|
||||
|
||||
Branches:
|
||||
Master (stable) branch - 3proxy 0.9
|
||||
Devel branch - 3proxy 10
|
||||
|
||||
|
||||
Download:
|
||||
https://github.com/z3APA3A/3proxy/releases
|
||||
@ -58,7 +64,7 @@ Please read doc/html/index.html and man pages.
|
||||
+ Threaded application (no child process).
|
||||
+ Web administration and statistics
|
||||
+ Plugins for functionality extension
|
||||
+ Native 64 bit application
|
||||
+ Native 32/64 bit application
|
||||
2. Proxy chaining and network connections
|
||||
+ Can be used as a bridge between client and different proxy type
|
||||
(e.g. convert incoming HTTP proxy request from client to SOCKSv5
|
||||
@ -78,9 +84,8 @@ Please read doc/html/index.html and man pages.
|
||||
+ syslog logging (Unix)
|
||||
+ ODBC logging
|
||||
+ RADIUS accounting
|
||||
+ log file rotation (hourly, daily, weekly, monthly)
|
||||
+ automatic log file comperssion with external archiver (for files)
|
||||
+ automatic removal of older log files
|
||||
+ log file rotation
|
||||
+ automatic log file processing with external archiver (for files)
|
||||
+ Character filtering for log files
|
||||
+ different log files for different servces are supported
|
||||
4. Access control
|
||||
@ -89,12 +94,13 @@ Please read doc/html/index.html and man pages.
|
||||
(POST, PUT, GET, etc), weekday and daytime.
|
||||
+ ACL-driven (user/source/destination/protocol/weekday/daytime or
|
||||
combined) bandwith limitation for incoming and (!)outgoing trafic.
|
||||
+ ACL-driven (user/source/destination/protocol/weekday/daytime or
|
||||
combined) traffic limitation per day, week or month for incoming and
|
||||
+ ACL-driven traffic limitation per day, week or month for incoming and
|
||||
outgoing traffic
|
||||
+ Connection limitation and ratelimting
|
||||
+ User authentication by username / password
|
||||
+ RADIUS Authentication and Authorization
|
||||
+ User authentication by DNS hostname
|
||||
+ Authentication cache with possibility to limit user to single IP address
|
||||
+ Access control by username/password for SOCKSv5 and HTTP/HTTPS/FTP
|
||||
+ Cleartext or encrypted (crypt/MD5 or NT) passwords.
|
||||
+ Connection redirection
|
||||
|
@ -873,12 +873,12 @@ You can control 3proxy service via "Services" administration ot via "net" comman
|
||||
<li>since 0.9
|
||||
<li>90 - unexpected system error (should not happen)
|
||||
<li>91 - unexpected poll error (should not happen)
|
||||
<li>92 - connection terminated by timeout
|
||||
<li>93 - dirty connection termination by server or client (or network issue) with unsent data
|
||||
<li>94 - clear connection termination by server or client with unsent data
|
||||
<li>95 - dirty connection termination by client (or network issue)
|
||||
<li>96 - dirty connection termination by server (or network issue)
|
||||
<li>97 - dirty connection termination by both client and server (probably network issue)
|
||||
<li>92 - connection terminated by timeout (see timeouts)
|
||||
<li>93 - connection terminated by ratelimit-related timeout or due to errors limit
|
||||
<li>94 - connection termination by server or client with unsent data
|
||||
<li>95 - dirty connection termination by client (or networking issue)
|
||||
<li>96 - dirty connection termination by server (or networking issue)
|
||||
<li>97 - dirty connection termination by both client and server (probably networking issue)
|
||||
<li>prior to 0.9:
|
||||
<li>90 - socket error or connection broken
|
||||
<li>91 - TCP/IP common failure
|
||||
|
@ -1049,9 +1049,9 @@
|
||||
<li>с версии 0.9
|
||||
<li>90 - неожиданная системная ошибка (не должно происходить)
|
||||
<li>91 - ошибка poll (не должно происходить)
|
||||
<li>92 - соединение прервано по таймауту
|
||||
<li>93 - клиент или сервер "грязно" закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
|
||||
<li>94 - клиент или сервер "чисто" закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
|
||||
<li>92 - соединение прервано по таймауту на сетевую операцию (см. timeouts)
|
||||
<li>93 - соединение прервано по таймауту связанному с рейтлимитом или из-за превышения числа ошибок
|
||||
<li>94 - клиент или сервер закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
|
||||
<li>95 - клиент "грязно" закрыл соединение или сетевая ошибка
|
||||
<li>96 - сервер "грязно" закрыл соединение или сетевая ошибка
|
||||
<li>97 - клиент и сервер "грязно" закрыли соединение или сетевая ошибка
|
||||
|
@ -240,6 +240,8 @@ alternate config file. Think twice before using it.
|
||||
@ (for Unix) use syslog, filename is used as ident name
|
||||
.br
|
||||
& use ODBC, filename consists of comma-delimited datasource,username,password (username and password are optional)
|
||||
.br
|
||||
radius - use RADIUS for logging
|
||||
.br
|
||||
LOGTYPE is one of:
|
||||
.br
|
||||
@ -388,6 +390,28 @@ can use %A as produced archive name and %F as filename.
|
||||
.br
|
||||
default timeouts 1 5 30 60 180 1800 15 60 15 5
|
||||
|
||||
.br
|
||||
.B radius
|
||||
<NAS_SECRET> <radius_server_1[:port][/local_address_1]> <radius_server_2[:port][/local_address_2]>
|
||||
.br
|
||||
Configures RADIUS servers to be used for logging and authentication (log and auth types
|
||||
must be set to radius). port and local address to use with given server may be specified.
|
||||
.br
|
||||
Attributes within request: User-Name, Password: (username and password if presented by client),
|
||||
Service Type: Authenticate-Only,
|
||||
NAS-Port-Type: NAS-Port-Virtual,
|
||||
NAS-Port-ID: (proxy service port, e.g. 1080),
|
||||
NAS-IPv6-Address / NAS-IP-Address: (proxy interface accessed by client),
|
||||
NAS-Identifier: (text identifing proxy, e.g. PROXY or SOCKSv5),
|
||||
Framed-IPv6-Address / Framed-IP-Address: (IP address of the client),
|
||||
Called-Station-ID: (requested Hostname, if presents),
|
||||
Login-Service: (type of request, e.g. 1001 - SOCKS CONNECT, 1010 - HTTP GET, 1013 - HTTP CONNECT),
|
||||
Login-TCP-Port: (requested port),
|
||||
Login-IPv6-Host / Login-IP-Host: (requested IP).
|
||||
.br
|
||||
Supported reply attributes for authentication:
|
||||
Framed-IP-Address / Framed-IPv6-Address (IP to assign to user), Reply-Message.
|
||||
Use authcache to speedup authentication. RADIUS feature is currently experimental.
|
||||
|
||||
.br
|
||||
.B nserver
|
||||
@ -503,6 +527,8 @@ NB: there is no any password check, name may be spoofed.
|
||||
SOCKSv5, FTP, POP3 and HTTP proxy.
|
||||
.br
|
||||
cache - cached authentication, may be used with \'authcache\'.
|
||||
.br
|
||||
radius - authentication with RADIUS.
|
||||
.br
|
||||
Plugins may add additional authentication types.
|
||||
|
||||
|
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, ""}
|
||||
};
|
||||
|
||||
|
||||
|
@ -578,6 +578,7 @@ int radsend(const char *buf, int total_length, int auth){
|
||||
}
|
||||
else remsock = radiuslist[loop].logsock;
|
||||
*/
|
||||
so._bind(param->remsock,(struct sockaddr *)&radiuslist[loop].localaddr,SASIZE(&radiuslist[loop].localaddr));
|
||||
len = so._sendto(remsock, (char *)&packet, total_length, 0,
|
||||
(struct sockaddr *)&saremote, sizeof(saremote));
|
||||
if(len != ntohs(packet.length)){
|
||||
|
@ -292,7 +292,10 @@ int parsehostname(char *hostname, struct clientparam *param, unsigned short port
|
||||
|
||||
if(!hostname || !*hostname)return 2;
|
||||
if(*hostname == '[') se=strchr(hostname, ']');
|
||||
if ( (sp = strchr(se?se:hostname, ':')) && !strchr(sp+1, ':')) *sp = 0;
|
||||
if (sp = strchr(se?se:hostname, ':')) {
|
||||
if(strchr(sp+1, ':'))sp = NULL;
|
||||
else *sp = 0;
|
||||
}
|
||||
if(se){
|
||||
*se = 0;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -1329,13 +1330,19 @@ static int h_radius(int argc, unsigned char **argv){
|
||||
if(strlen(argv[1]) > 63) argv[1][63] = 0;
|
||||
strcpy(radiussecret, argv[1]);
|
||||
for( nradservers=0; nradservers < MAXRADIUS && nradservers < argc -2; nradservers++){
|
||||
char *s = 0;
|
||||
if(strchr(argv[nradservers + 2], '/')){
|
||||
*s = 0;
|
||||
s++;
|
||||
}
|
||||
if( !getip46(46, argv[nradservers + 2], (struct sockaddr *)&radiuslist[nradservers].authaddr)) return 1;
|
||||
if( s && !getip46(46, s, (struct sockaddr *)&radiuslist[nradservers].localaddr)) return 2;
|
||||
if(!*SAPORT(&radiuslist[nradservers].authaddr))*SAPORT(&radiuslist[nradservers].authaddr) = htons(1812);
|
||||
port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr));
|
||||
radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr;
|
||||
*SAPORT(&radiuslist[nradservers].logaddr) = htons(port+1);
|
||||
/*
|
||||
bindaddr = conf.intsa;
|
||||
bindaddr = radiuslist[nradservers].localaddr;
|
||||
if ((radiuslist[nradservers].logsock = so._socket(SASOCK(&radiuslist[nradservers].logaddr), SOCK_DGRAM, 0)) < 0) return 2;
|
||||
if (so._bind(radiuslist[nradservers].logsock, (struct sockaddr *)&bindaddr, SASIZE(&bindaddr))) return 3;
|
||||
*/
|
||||
|
@ -74,9 +74,10 @@ struct symbol symbols[] = {
|
||||
{symbols+47, "parsestr", (void *) parsestr},
|
||||
{symbols+48, "make_ace", (void *) make_ace},
|
||||
{symbols+49, "freeacl", (void *) freeacl}
|
||||
{symbols+50, "dolog", (void *) dolog},
|
||||
{symbols+50, "logfuncs", (void *) logfuncs},
|
||||
{symbols+50, "prelog", (void *) prelog},
|
||||
{symbols+50, "checkpreACL", (void *) checkpreACL},
|
||||
{symbols+51, "dolog", (void *) dolog},
|
||||
{symbols+52, "logfuncs", (void *) logfuncs},
|
||||
{symbols+53, "prelog", (void *) prelog},
|
||||
{NULL, "", NULL}
|
||||
};
|
||||
|
||||
@ -111,6 +112,7 @@ struct pluginlink pluginlink = {
|
||||
ACLmatches,
|
||||
alwaysauth,
|
||||
checkACL,
|
||||
checkpreACL,
|
||||
nametohash,
|
||||
hashindex,
|
||||
en64,
|
||||
|
@ -494,6 +494,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";
|
||||
|
@ -173,6 +173,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
|
||||
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);
|
||||
@ -236,10 +237,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);
|
||||
@ -308,9 +310,9 @@ extern struct commands commandhandlers[];
|
||||
|
||||
extern struct radserver {
|
||||
#ifdef NOIPV6
|
||||
struct sockaddr_in authaddr, logaddr;
|
||||
struct sockaddr_in authaddr, logaddr, localaddr;
|
||||
#else
|
||||
struct sockaddr_in6 authaddr, logaddr;
|
||||
struct sockaddr_in6 authaddr, logaddr, localaddr;
|
||||
#endif
|
||||
/*
|
||||
SOCKET logsock;
|
||||
|
@ -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);
|
||||
@ -61,7 +61,7 @@ void * threadfunc (void *p) {
|
||||
#ifndef _WIN32
|
||||
sigset_t mask;
|
||||
sigfillset(&mask);
|
||||
pthread_sigmask(SIG_SETMASK, &mask, NULL);
|
||||
if(param->srv->service != S_UDPPM)pthread_sigmask(SIG_SETMASK, &mask, NULL);
|
||||
#endif
|
||||
|
||||
((struct clientparam *) p)->srv->pf((struct clientparam *)p);
|
||||
@ -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;
|
||||
@ -286,11 +286,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
srv.next = conf.services;
|
||||
conf.services = conf.services->prev = &srv;
|
||||
}
|
||||
#else
|
||||
srv.needuser = 0;
|
||||
initlog();
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
{
|
||||
sigset_t mask;
|
||||
@ -298,6 +293,10 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
pthread_sigmask(SIG_SETMASK, &mask, NULL);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
srv.needuser = 0;
|
||||
initlog();
|
||||
#endif
|
||||
|
||||
for (i=1; i<argc; i++) {
|
||||
if(*argv[i]=='-') {
|
||||
@ -774,6 +773,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 +790,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 +953,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 +1044,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 +1078,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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
#define MAXFAILATTEMPT 10
|
||||
|
||||
#ifdef WITHLOG
|
||||
#if WITHLOG > 1
|
||||
char logbuf[1024];
|
||||
@ -57,6 +59,7 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
|
||||
FILTER_ACTION action;
|
||||
int res;
|
||||
SASIZETYPE sasize;
|
||||
int needaction = 0;
|
||||
|
||||
#ifdef WITHSPLICE
|
||||
uint64_t inclientpipe = 0, inserverpipe = 0;
|
||||
@ -120,17 +123,17 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
|
||||
if(action != PASS) RETURN(19);
|
||||
|
||||
while(
|
||||
((!CLIENTTERM) && (inserverbuf
|
||||
((!CLIENTTERM) && fromserver && (inserverbuf
|
||||
#ifdef WITHSPLICE
|
||||
|| inserverpipe
|
||||
#endif
|
||||
|| (!SERVERTERM && fromserver)))
|
||||
|| (!SERVERTERM )))
|
||||
||
|
||||
((!SERVERTERM) && (inclientbuf
|
||||
((!SERVERTERM) && fromclient && (inclientbuf
|
||||
#ifdef WITHSPLICE
|
||||
|| inclientpipe
|
||||
#endif
|
||||
|| (!CLIENTTERM && fromclient)))
|
||||
|| (!CLIENTTERM )))
|
||||
){
|
||||
|
||||
|
||||
@ -155,8 +158,12 @@ sprintf(logbuf, "int FROMCLIENT = %d, TOCLIENTBUF = %d, FROMCLIENTBUF = %d, TOSE
|
||||
log(logbuf);
|
||||
#endif
|
||||
|
||||
if(needaction > 2 && !sleeptime){
|
||||
if(needaction > (MAXFAILATTEMPT+1)){RETURN (93);}
|
||||
sleeptime = (1<<(needaction-2));
|
||||
}
|
||||
if(sleeptime > 0) {
|
||||
if(sleeptime > (timeo * 1000)){RETURN (92);}
|
||||
if(sleeptime > (timeo * 1000)){RETURN (93);}
|
||||
memset(fds, 0, sizeof(fds));
|
||||
fds[0].fd = param->clisock;
|
||||
fds[1].fd = param->remsock;
|
||||
@ -216,6 +223,7 @@ log("done send to server from buf");
|
||||
sl1 = (*param->bandlimfunc)(param, 0, res);
|
||||
if(sl1 > sleeptime) sleeptime = sl1;
|
||||
}
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -247,6 +255,7 @@ log("done send to client from buf");
|
||||
param->srvoffset += res;
|
||||
if(param->srvoffset == param->srvinbuf)param->srvoffset = param->srvinbuf =0;
|
||||
if(param->srvinbuf < param->srvbufsize) TOSERVERBUF = 1;
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -270,6 +279,7 @@ log("done send to server from pipe");
|
||||
sl1 = (*param->bandlimfunc)(param, 0, res);
|
||||
if(sl1 > sleeptime) sleeptime = sl1;
|
||||
}
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
@ -288,6 +298,7 @@ log("done send to client from pipe");
|
||||
inserverpipe -= res;
|
||||
fromserver -= res;
|
||||
if(fromserver)TOSERVERPIPE = 1;
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
@ -306,6 +317,10 @@ log("read from client to pipe");
|
||||
log("read failed");
|
||||
#endif
|
||||
FROMCLIENT = TOCLIENTPIPE = 0;
|
||||
if(res == 0) {
|
||||
CLIENTTERM = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITHLOG
|
||||
@ -313,6 +328,7 @@ log("done read from client to pipe");
|
||||
#endif
|
||||
inclientpipe += res;
|
||||
if(inclientpipe >= MAXSPLICE) TOCLIENTPIPE = 0;
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -328,6 +344,10 @@ log("splice finished\n");
|
||||
#endif
|
||||
if(res <= 0) {
|
||||
FROMSERVER = TOSERVERPIPE = 0;
|
||||
if(res == 0 || !errno) {
|
||||
SERVERTERM = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITHLOG
|
||||
@ -346,8 +366,9 @@ log("done read from server to pipe\n");
|
||||
fromserver = inserverpipe;
|
||||
FROMSERVER = 0;
|
||||
}
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -360,8 +381,11 @@ log("read from client to buf");
|
||||
sasize = sizeof(param->sincr);
|
||||
res = so._recvfrom(param->clisock, (char *)param->clibuf + param->cliinbuf, (int)MIN((uint64_t)param->clibufsize - param->cliinbuf, fromclient-inclientbuf), 0, (struct sockaddr *)¶m->sincr, &sasize);
|
||||
if(res <= 0) {
|
||||
if(!errno)CLIENTTERM = 1;
|
||||
FROMCLIENT = 0;
|
||||
if(res == 0){
|
||||
CLIENTTERM = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITHLOG
|
||||
@ -370,6 +394,7 @@ log("done read from client to buf");
|
||||
inclientbuf += res;
|
||||
param->cliinbuf += res;
|
||||
if(param->clibufsize == param->cliinbuf) TOCLIENTBUF = 0;
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -381,8 +406,11 @@ log("read from server to buf");
|
||||
sasize = sizeof(param->sinsr);
|
||||
res = so._recvfrom(param->remsock, (char *)param->srvbuf + param->srvinbuf, (int)MIN((uint64_t)param->srvbufsize - param->srvinbuf, fromserver-inserverbuf), 0, (struct sockaddr *)¶m->sinsr, &sasize);
|
||||
if(res <= 0) {
|
||||
if(!errno) SERVERTERM = 1;
|
||||
FROMSERVER = 0;
|
||||
if(res == 0) {
|
||||
SERVERTERM = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITHLOG
|
||||
@ -402,6 +430,7 @@ log("done read from server to buf");
|
||||
fromserver = inserverbuf;
|
||||
FROMSERVER = 0;
|
||||
}
|
||||
needaction = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -639,7 +668,7 @@ log("leaving poll");
|
||||
#ifdef WITHLOG
|
||||
log("poll error");
|
||||
#endif
|
||||
if(errno != EAGAIN && errno != EINTR) RETURN(91);
|
||||
if(errno != EINTR) RETURN(91);
|
||||
break;
|
||||
}
|
||||
if(res < 1){
|
||||
@ -650,14 +679,15 @@ log("timeout");
|
||||
}
|
||||
}
|
||||
}
|
||||
needaction++;
|
||||
|
||||
}
|
||||
res = 0;
|
||||
if(!fromserver && param->waitserver64) res = 98;
|
||||
else if(!fromclient && param->waitclient64) res = 99;
|
||||
else if((inclientbuf || inserverbuf)) res = HASERROR?93:94;
|
||||
else if((inclientbuf || inserverbuf)) res = 94;
|
||||
#ifdef WITHSPLICE
|
||||
else if(inclientpipe || inserverpipe) res = HASERROR?93:94;
|
||||
else if(inclientpipe || inserverpipe) res = 94;
|
||||
#endif
|
||||
else if(HASERROR) res = 94+HASERROR;
|
||||
|
||||
|
@ -215,6 +215,7 @@ typedef int (*PLUGINFUNC)(struct pluginlink *pluginlink, int argc, char** argv);
|
||||
|
||||
struct auth {
|
||||
struct auth *next;
|
||||
AUTHFUNC preauthorize;
|
||||
AUTHFUNC authenticate;
|
||||
AUTHFUNC authorize;
|
||||
char * desc;
|
||||
@ -477,7 +478,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;
|
||||
@ -519,6 +520,7 @@ struct clientparam {
|
||||
operation,
|
||||
nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv,
|
||||
unsafefilter,
|
||||
preauthorized,
|
||||
bandlimver;
|
||||
|
||||
int res,
|
||||
@ -759,6 +761,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);
|
||||
|
@ -16,7 +16,7 @@
|
||||
void * tcppmchild(struct clientparam* param) {
|
||||
int res;
|
||||
|
||||
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
|
||||
if(!param->hostname && parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) RETURN(100);
|
||||
param->operation = CONNECT;
|
||||
res = (*param->srv->authfunc)(param);
|
||||
if(res) {RETURN(res);}
|
||||
|
@ -38,7 +38,7 @@ void * udppmchild(struct clientparam* param) {
|
||||
struct pollfd fds[256];
|
||||
|
||||
|
||||
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
|
||||
if(!param->hostname && parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) RETURN(100);
|
||||
if (SAISNULL(¶m->req)) {
|
||||
param->srv->fds.events = POLLIN;
|
||||
RETURN (100);
|
||||
|
Loading…
Reference in New Issue
Block a user