When using lftp through an HTTP proxy (ftp:proxy) combined with ftp:ignore-pasv-address true, the PASV data connection is attempted toward the proxy's IP address instead of the original server's IP address.
Environment
- lftp 4.9.2
- HTTP proxy (Squid) with CONNECT tunneling
- FTPS explicit (AUTH TLS)
How to reproduce
- Configure an HTTP proxy:
set ftp:proxy http://proxy:3128
- Enable ignore-pasv-address:
set ftp:ignore-pasv-address true
- Connect to an FTP server behind NAT that advertises a non-routable IP in PASV response
- Attempt a directory listing or file transfer
Expected behavior
The data connection CONNECT request should be directed to the original server IP.
Actual behavior
lftp sends CONNECT proxy_ip:data_port instead of CONNECT server_ip:data_port because peer_sa (used as fallback when ignoring PASV address) is overwritten with the proxy's IP during TCP connection setup.
Root cause
In ftpclass.cc, Handle_PASV() replaces the PASV-advertised address with conn->peer_sa. However, when the connection goes through an HTTP proxy, peer_sa holds the proxy's address rather than the server's. The same issue affects Handle_EPSV() and Handle_EPSV_CEPR().
Suggested fix
Track the original server address separately (e.g. a server_sa field in the Connection struct), populated by resolving hostname directly via getaddrinfo at connection time when proxy_is_http is true. Use server_sa instead of peer_sa in the ignore-pasv-address code path.
Happy to provide a patch if useful.
When using lftp through an HTTP proxy (
ftp:proxy) combined withftp:ignore-pasv-address true, the PASV data connection is attempted toward the proxy's IP address instead of the original server's IP address.Environment
How to reproduce
set ftp:proxy http://proxy:3128set ftp:ignore-pasv-address trueExpected behavior
The data connection CONNECT request should be directed to the original server IP.
Actual behavior
lftp sends
CONNECT proxy_ip:data_portinstead ofCONNECT server_ip:data_portbecausepeer_sa(used as fallback when ignoring PASV address) is overwritten with the proxy's IP during TCP connection setup.Root cause
In
ftpclass.cc,Handle_PASV()replaces the PASV-advertised address withconn->peer_sa. However, when the connection goes through an HTTP proxy,peer_saholds the proxy's address rather than the server's. The same issue affectsHandle_EPSV()andHandle_EPSV_CEPR().Suggested fix
Track the original server address separately (e.g. a
server_safield in theConnectionstruct), populated by resolvinghostnamedirectly viagetaddrinfoat connection time whenproxy_is_httpis true. Useserver_sainstead ofpeer_sain the ignore-pasv-address code path.Happy to provide a patch if useful.