title: How to connect to FTPS server with data connection using same TLS session?
body: <p>Environment: I'm using Sun Java JDK 1.8.0_60 on 64-bit Windows 7, using Spring Integration 4.1.6 (which internally appears to use Apache Commons Net 3.3 for FTPS access).</p>
  
  <p>I'm attempting to integrate with our application an automatic download from our client's FTPS server. I've done so successfully with SFTP servers using Spring Integration without any trouble for other clients without issues, but this is the first time a client has required us to use FTPS, and getting it to connect has been very puzzling. While in my real application I'm configuring Spring Integration using XML beans, to try to understand what's not working I'm using the following test code (though I'm anonymizing the actual host/username/password here):</p>
  
  <pre><code>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();
  </code></pre>
  
  <p>I'm running this code with <code>-Djavax.net.debug=all</code> to get all the TLS debugging information printed.</p>
  
  <p>The main "control" connection to the FTPS server works fine, but when it tries to open the data connection for the list (or any other data connection I've tried), I get a <code>javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake</code>, caused by <code>java.io.EOFException: SSL peer shut down incorrectly</code>. If I uncomment the swallowing-exceptions catch block around the <code>session.list</code> command, then I can see (though the javax.net.debug output) that the server sent the following message after rejecting the data connection SSL handshake: </p>
  
  <pre class="lang-none prettyprint-override"><code>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..
  </code></pre>
  
  <p>What appears to be happening (and this is my first time dealing with FTPS, though I've dealt with plain FTP before) is that the way the server ensures authentication and encryption over both the control and data connections is that after a "normal" TLS connection to establish the control connection and authentication happens there, each data connection requires the client to connect with the same TLS session. This makes sense to me as how it's supposed to be work, but the Apache Commons Net FTPS implementation doesn't seem to be doing that. It seems to be trying to establish a new TLS session, and so the server is rejecting the attempt.</p>
  
  <p>Based on <a href="https://stackoverflow.com/q/10605062/65839">this question about resuming SSL sessions in JSSE</a>, it appears that Java assumes or requires a different session for each host/post combination. My hypothesis is that since the FTPS data connection is on a different port than the control connection, it's not finding the existing session and is trying to establish a new one, so the connection fails.</p>
  
  <p>I see three main possibilities:</p>
  
  <ol>
  <li>The server is not following the FTPS standard in requiring the same TLS session on the data port as on the control port. I can connect to the server fine (using the same host/user/password as I'm trying to use in my code) using FileZilla 3.13.1. The server identifies itself as "FileZilla Server 0.9.53 beta" upon login, so perhaps this is some sort of proprietary FileZilla way of doing things, and there's something odd I need to do to convince Java to use the same TLS session.</li>
  <li>The Apache Commons Net client doesn't actually follow the FTPS standard, and only allows some subset that doesn't allow for securing the data connections. This would seem odd, as it appears to be the standard way of connecting to FTPS from within Java.</li>
  <li>I'm completely missing something and misdiagnosing this.</li>
  </ol>
  
  <p>I'd appreciate any direction you can provide as to how to connect to this kind of FTPS server. Thank you.</p>