From 17b41eda2dc5e73c345bb428d675df11e0d831d2 Mon Sep 17 00:00:00 2001 From: Tim Boeckstaens Date: Tue, 17 Mar 2026 17:44:07 +0100 Subject: [PATCH] Use hostname for FTPS EPSV data connection This allows FTPS to reuse the TLS session of the FSTP command connection for the data connection. --- .../java/org/apache/commons/net/ftp/FTPClient.java | 12 +++++++++++- .../java/org/apache/commons/net/ftp/FTPSClient.java | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/net/ftp/FTPClient.java b/src/main/java/org/apache/commons/net/ftp/FTPClient.java index 81239237c..da9016baa 100644 --- a/src/main/java/org/apache/commons/net/ftp/FTPClient.java +++ b/src/main/java/org/apache/commons/net/ftp/FTPClient.java @@ -828,10 +828,20 @@ protected void _parseExtendedPassiveModeReply(String reply) throws MalformedServ throw new MalformedServerReplyException("Could not parse extended passive host information.\nServer Reply: " + reply); } // in EPSV mode, the passive host address is implicit - passiveHost = getRemoteAddress().getHostAddress(); + passiveHost = resolveExtendedPassiveModeHost(); passivePort = port; } + /** + * Resolve the host for extended passive mode. + * + * @since 3.14.0 + * @return the passive host + */ + protected String resolveExtendedPassiveModeHost() { + return getRemoteAddress().getHostAddress(); + } + /** * Parses a reply. * diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSClient.java b/src/main/java/org/apache/commons/net/ftp/FTPSClient.java index bd49af4e8..a582ed3c2 100644 --- a/src/main/java/org/apache/commons/net/ftp/FTPSClient.java +++ b/src/main/java/org/apache/commons/net/ftp/FTPSClient.java @@ -1119,5 +1119,14 @@ protected void sslNegotiation() throws IOException { throw new SSLHandshakeException("Hostname doesn't match certificate"); } } + + @Override + protected String resolveExtendedPassiveModeHost() { + if (_socket_ instanceof SSLSocket) { + return ((SSLSocket) _socket_).getSession().getPeerHost(); + } else { + return super.resolveExtendedPassiveModeHost(); + } + } }