mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 22:05:48 +08:00
105 lines
3.8 KiB
C
105 lines
3.8 KiB
C
/*
|
|
3APA3A simplest proxy server
|
|
(c) 2002-2026 by Vladimir Dubrovin <vlad@3proxy.org>
|
|
|
|
please read License Agreement
|
|
|
|
*/
|
|
|
|
#include "proxy.h"
|
|
|
|
#ifdef WITH_POP3P
|
|
|
|
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
|
|
|
#ifdef WITHMAIN
|
|
#define NOSTARTTLS 1
|
|
#else
|
|
#define NOSTARTTLS param->srv->nostarttls
|
|
#endif
|
|
|
|
void * pop3pchild(struct clientparam* param) {
|
|
int i=0, res;
|
|
unsigned char buf[320];
|
|
unsigned char *se;
|
|
|
|
if(socksend(param, param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, param->srv->timeouts[STRING_S])!=11) {RETURN (611);}
|
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]);
|
|
while(i > 4 && strncasecmp((char *)buf, "USER", 4)){
|
|
if(!strncasecmp((char *)buf, "QUIT", 4)){
|
|
socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5,param->srv->timeouts[STRING_S]);
|
|
RETURN(0);
|
|
}
|
|
if(!strncasecmp((char *)buf, "CAPA", 4) && !NOSTARTTLS){
|
|
socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, param->srv->timeouts[STRING_S]);
|
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]);
|
|
continue;
|
|
}
|
|
#ifndef WITHMAIN
|
|
if(!strncasecmp((char *)buf, "STLS", 4) && !param->srv->nostarttls){
|
|
if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, param->srv->timeouts[STRING_S])!=27) {RETURN(623);}
|
|
param->clientstarttls = S_POP3P;
|
|
if(!param->srv->targetport) param->srv->targetport = htons(110);
|
|
return (void *)tlsprchild;
|
|
}
|
|
#endif
|
|
socksend(param, param->clisock, (unsigned char *)"-ERR need USER first\r\n", 22, param->srv->timeouts[STRING_S]);
|
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]);
|
|
}
|
|
if(i<6) {RETURN(612);}
|
|
|
|
buf[i] = 0;
|
|
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
|
if (strncasecmp((char *)buf, "USER ", 5)){RETURN (614);}
|
|
if(parseconnusername((char *)buf +5, param, 0, 110)){RETURN(615);}
|
|
param->operation = CONNECT;
|
|
res = (*param->srv->authfunc)(param);
|
|
if(res) {RETURN(res);}
|
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]);
|
|
if( i < 3 ) {RETURN(621);}
|
|
buf[i] = 0;
|
|
if(strncasecmp((char *)buf, "+OK", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(622);}
|
|
if( socksend(param, param->remsock, (unsigned char *)"USER ", 5, param->srv->timeouts[STRING_S])!= 5 ||
|
|
socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), param->srv->timeouts[STRING_S]) <= 0 ||
|
|
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S])!=2)
|
|
{RETURN(623);}
|
|
param->statscli64 += (uint64_t)(strlen((char *)param->extusername) + 7);
|
|
param->nwrites++;
|
|
RETURN (mapsocket(param, 180));
|
|
CLEANRET:
|
|
|
|
if(*param->hostname&&*param->extusername) {
|
|
sprintf((char *)buf, "%.128s@%.128s%c%hu", param->extusername, param->hostname, (*SAPORT(¶m->sinsr)==110)?0:':', ntohs(*SAPORT(¶m->sinsr)));
|
|
dolog(param, buf);
|
|
}
|
|
else dolog(param, NULL);
|
|
if(param->clisock != INVALID_SOCKET) {
|
|
if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"-ERR\r\n", 6,param->srv->timeouts[STRING_S]);
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
#ifdef WITHMAIN
|
|
struct proxydef childdef = {
|
|
pop3pchild,
|
|
110,
|
|
0,
|
|
S_POP3P,
|
|
" -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n"
|
|
|
|
};
|
|
#include "proxymain.c"
|
|
#endif
|
|
#else
|
|
|
|
/* Built without this proxy of its own. The command and the redirect
|
|
naming it are the STARTTLS proxy speaking that protocol, which
|
|
negotiates the same way and passes the session on: what "tlspr -Xpop3"
|
|
does, under the name a configuration already uses. */
|
|
void * pop3pchild(struct clientparam * param){
|
|
param->starttls = S_POP3P;
|
|
return (void *)tlsprchild;
|
|
}
|
|
|
|
#endif
|