mirror of
https://github.com/3proxy/3proxy.git
synced 2026-09-03 13:25:48 +08:00
pop3p, imapp and smtpp are built with MAILPROXY=true, and ftppr and the ftp:// scheme of the HTTP proxy with FTP=true; with CMake the switches are 3PROXY_USE_MAILPROXY and 3PROXY_USE_FTP. Neither is in a default build, and the standalone binaries follow what was built. A configuration naming one of them is still read either way. The three mail protocols amount to a STARTTLS negotiation now that mail is carried over TLS, so without a proxy of their own those names are tlspr speaking the protocol: the file holds a stand-in which sets the protocol for the connection and returns tlspr for the caller to run, which serves the service name and a parent chain alike and leaves conf.c and the redirect table untouched. FTP has no such fallback, so the service is known, answers nothing and logs the refusal. The Linux workflow builds both, so all of it is still compiled and run.
105 lines
3.7 KiB
C
105 lines
3.7 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, conf.timeouts[STRING_S])!=11) {RETURN (611);}
|
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.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,conf.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, conf.timeouts[STRING_S]);
|
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.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, conf.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, conf.timeouts[STRING_S]);
|
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.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', conf.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, conf.timeouts[STRING_S])!= 5 ||
|
|
socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 ||
|
|
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.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&¶m->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,conf.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
|