Environment: I use Sun Java JDK 1.8.0_60 on 64-bit Windows 7 using Spring Integration 4.1.6 (which is supposed to use Apache Commons Net 3.3 to access FTPS).
I am trying to integrate automatic downloading from our FTPS client server with our application. I successfully managed SFTP servers using Spring Integration without any problems for other clients without problems, but this is the first time the client has demanded that we use FTPS and connecting to it was very puzzling. Although in my real application I configure Spring Integration using XML beans to try to understand what is not working, I use the following test code (although I will anonymize the actual host / username / password here):
final DefaultFtpsSessionFactory sessionFactory = new DefaultFtpsSessionFactory(); sessionFactory.setHost("XXXXXXXXX"); sessionFactory.setPort(990); sessionFactory.setUsername("XXXXXXX"); sessionFactory.setPassword("XXXXXXX"); sessionFactory.setClientMode(2); sessionFactory.setFileType(2); sessionFactory.setUseClientMode(true); sessionFactory.setImplicit(true); sessionFactory.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager()); sessionFactory.setProt("P"); sessionFactory.setProtocol("TLSv1.2"); sessionFactory.setProtocols(new String[]{"TLSv1.2"}); sessionFactory.setSessionCreation(true); sessionFactory.setCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}); final FtpSession session = sessionFactory.getSession(); //try { final FTPFile[] ftpFiles = session.list("/"); logger.debug("FtpFiles: {}", (Object[]) ftpFiles); //} catch (Exception ignored ) {} session.close();
I run this code with -Djavax.net.debug=all to print all the TLS debugging information.
The main “control” connection to the FTPS server works fine, but when it tries to open a data connection (or any other data connection I tried), I get javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake , java.io.EOFException: SSL peer shut down incorrectly by java.io.EOFException: SSL peer shut down incorrectly . If I uncomment the catch-exceptions block around the session.list command, then I can see (although the output is javax.net.debug) that the server sent the following message after rejecting the SSL connection to connect to the data:
main, READ: TLSv1.2 Application Data, length = 129 Padded plaintext after DECRYPTION: len = 105 0000: 34 35 30 20 54 4C 53 20 73 65 73 73 69 6F 6E 20 450 TLS session 0010: 6F 66 20 64 61 74 61 20 63 6F 6E 6E 65 63 74 69 of data connecti 0020: 6F 6E 20 68 61 73 20 6E 6F 74 20 72 65 73 75 6D on has not resum 0030: 65 64 20 6F 72 20 74 68 65 20 73 65 73 73 69 6F ed or the sessio 0040: 6E 20 64 6F 65 73 20 6E 6F 74 20 6D 61 74 63 68 n does not match 0050: 20 74 68 65 20 63 6F 6E 74 72 6F 6C 20 63 6F 6E the control con 0060: 6E 65 63 74 69 6F 6E 0D 0A nection..
Something is happening (and this is my first experience with FTPS, although I used to deal with simple FTP) that the way the server provides authentication and encryption via control and data transmission channels, this is what is normal after "A TLS connection to establish a control connection and authentication occurs there, each data connection requires that the client connect to the same TLS session. It makes sense to me how it should work, but the implementation of Apache Commons Net FTPS does not seem to do this. It seems to be trying to establish a new TLS session, and therefore the server rejects the attempt.
Based on this question about resuming SSL sessions in JSSE , it looks like Java assumes or requires a different session for each combination of hosts and messages. My hypothesis is that since the FTPS data connection is on a different port than the control connection, it does not find an existing session and tries to establish a new one, so the connection fails.
I see three main possibilities:
- The server does not follow the FTPS standard, requiring the same TLS session on the data port as on the management port. I can connect to the server perfectly (using the same host / user / password that I am trying to use in my code) using FileZilla 3.13.1. The server identifies itself as “FileZilla Server 0.9.53 beta” at login, so maybe this is some kind of proprietary way of FileZilla to do something, and there is something strange I need to do to convince Java to use one the same TLS session.
- The Apache Commons Net client does not actually comply with the FTPS standard and only allows some subsets that do not allow a data connection. This would seem strange, as this is the standard way to connect to FTPS from Java.
- I completely missed something and misunderstood it.
I would appreciate any direction you can provide on how to connect to this FTPS server. Thanks.
java ftp filezilla ftps apache-commons-net
Peter Cooper Jr.
source share