From 8cdf341d0e7f03a6c7b520962d935cdd75ab9c1d Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Sat, 14 May 2016 00:09:51 +0300 Subject: [PATCH] workaround for broken getsockname() in FTP proxy --- src/common.c | 2 +- src/ftp.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index 8c0ba6c..9e3cb25 100644 --- a/src/common.c +++ b/src/common.c @@ -694,8 +694,8 @@ int doconnect(struct clientparam * param){ #else fcntl(param->remsock,F_SETFL,O_NONBLOCK); #endif - size = sizeof(param->sinsl); } + size = sizeof(param->sinsl); if(so._getsockname(param->remsock, (struct sockaddr *)¶m->sinsl, &size)==-1) {return (15);} } return 0; diff --git a/src/ftp.c b/src/ftp.c index 3007ade..2480aa9 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -174,6 +174,7 @@ SOCKET ftpdata(struct clientparam *param){ SOCKET s = INVALID_SOCKET, rem; unsigned long b1, b2, b3, b4; unsigned short b5, b6; + SASIZETYPE sasize; if(socksend(param->remsock, (unsigned char *)"PASV\r\n", 6, conf.timeouts[STRING_S]) != 6){ return INVALID_SOCKET; @@ -187,15 +188,27 @@ SOCKET ftpdata(struct clientparam *param){ buf[i-2] = 0; if(!(sb = strchr(buf+4, '(')) || !(se= strchr(sb, ')'))) return INVALID_SOCKET; if(sscanf(sb+1, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) return INVALID_SOCKET; + sasize = sizeof(param->sinsl); + if(so._getsockname(param->remsock, (struct sockaddr *)¶m->sinsl, &sasize)){return INVALID_SOCKET;} + sasize = sizeof(param->sinsr); + if(so._getpeername(param->remsock, (struct sockaddr *)¶m->sinsr, &sasize)){return INVALID_SOCKET;} rem = param->remsock; param->remsock = INVALID_SOCKET; param->req = param->sinsr; *SAPORT(¶m->req) = *SAPORT(¶m->sinsr) = htons((unsigned short)((b5<<8)^b6)); + *SAPORT(¶m->sinsl) = 0; i = param->operation; param->operation = FTP_DATA; if((param->res = (*param->srv->authfunc)(param))) { - param->remsock = rem; - return INVALID_SOCKET; + if(param->remsock != INVALID_SOCKET) { + so._closesocket(param->remsock); + param->remsock = INVALID_SOCKET; + } + memset(¶m->sinsl, 0, sizeof(param->sinsl)); + if((param->res = (*param->srv->authfunc)(param))) { + param->remsock = rem; + return INVALID_SOCKET; + } } param->operation = i; s = param->remsock;