ftpgetput: add EPSV support (PASV-like thing for IPv6)

Based on a patch by Kev Kitchens.

function                                             old     new   delta
xconnect_ftpdata                                     149     223     +74

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-02-04 19:08:34 +01:00
parent daa643205f
commit 05b84d4e92

View File

@ -156,7 +156,7 @@ static int xconnect_ftpdata(void)
unsigned port_num; unsigned port_num;
/* /*
TODO: PASV command will not work for IPv6. RFC2428 describes PASV command will not work for IPv6. RFC2428 describes
IPv6-capable "extended PASV" - EPSV. IPv6-capable "extended PASV" - EPSV.
"EPSV [protocol]" asks server to bind to and listen on a data port "EPSV [protocol]" asks server to bind to and listen on a data port
@ -171,15 +171,16 @@ but we don't need that.
NB: PASV may still work for some servers even over IPv6. NB: PASV may still work for some servers even over IPv6.
For example, vsftp happily answers For example, vsftp happily answers
"227 Entering Passive Mode (0,0,0,0,n,n)" and proceeds as usual. "227 Entering Passive Mode (0,0,0,0,n,n)" and proceeds as usual.
TODO2: need to stop ignoring IP address in PASV response.
*/ */
//if (ftpcmd("EPSV", NULL) != 229) { if (!ENABLE_FEATURE_IPV6
|| ftpcmd("EPSV", NULL) != 229
) {
/* maybe also go straight to PAST if lsa->u.sa.sa_family == AF_INET? */
if (ftpcmd("PASV", NULL) != 227) { if (ftpcmd("PASV", NULL) != 227) {
ftp_die("PASV"); ftp_die("PASV");
} }
/* Response is "NNN garbageN1,N2,N3,N4,P1,P2[)garbage] /* Response is "NNN garbageN1,N2,N3,N4,P1,P2[)garbage]"
* Server's IP is N1.N2.N3.N4 (we ignore it) * Server's IP is N1.N2.N3.N4 (we ignore it)
* Server's port for data connection is P1*256+P2 */ * Server's port for data connection is P1*256+P2 */
buf_ptr = strrchr(buf, ')'); buf_ptr = strrchr(buf, ')');
@ -192,7 +193,16 @@ TODO2: need to stop ignoring IP address in PASV response.
buf_ptr = strrchr(buf, ','); buf_ptr = strrchr(buf, ',');
*buf_ptr = '\0'; *buf_ptr = '\0';
port_num += xatoul_range(buf_ptr + 1, 0, 255) * 256; port_num += xatoul_range(buf_ptr + 1, 0, 255) * 256;
//} } else {
/* Response is "NNN garbage(|||P1|)"
* Server's port for data connection is P1 */
buf_ptr = strrchr(buf, '|');
if (buf_ptr) *buf_ptr = '\0';
buf_ptr = strrchr(buf, '|');
*buf_ptr = '\0';
port_num = xatoul_range(buf_ptr + 1, 0, 65535);
}
set_nport(&lsa->u.sa, htons(port_num)); set_nport(&lsa->u.sa, htons(port_num));
return xconnect_stream(lsa); return xconnect_stream(lsa);