Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Locale;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import org.apache.commons.net.ftp.FTPSClient;
import com.google.common.base.Throwables;
public class SSLSessionReuseFTPSClient extends FTPSClient {
// adapted from: https://trac.cyberduck.io/changeset/10760
@Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if(socket instanceof SSLSocket) {
final SSLSession session = ((SSLSocket) _socket_).getSession();
final SSLSessionContext context = session.getSessionContext();
try {
final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method putMethod = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
putMethod.setAccessible(true);
final Method getHostMethod = socket.getClass().getDeclaredMethod("getHost");
getHostMethod.setAccessible(true);
Object host = getHostMethod.invoke(socket);
final String key = String.format("%s:%s", host, String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT);
putMethod.invoke(cache, key, session);
} catch(Exception e) {
throw Throwables.propagate(e);
}
}
}
}
@51M0Ng
Copy link

51M0Ng commented Mar 14, 2018

I have the same problem too, for retrieving the Field "sessionHostPortCache", basically I view the source code for class "SSLSessionConnecion" there is no "sessionHostPortCache" Fiels, that Field is exist in class call "SSLSessionConnecionImp" from package "sun. security. ssl", but this package is removed from android default SDK, (because some of the function for original SDK package Android doesn't support), also I cannot find that class from jsse.jar library (inside jre1.8u151 folder) , then I tried to build my own from OpenJDK 1.8 source code directly, but it got problem that android studio cannot identify class from the custom-made library. I also tried lgrousset advice, but got no hope, anyone have a ideas?

@farizaghayev
Copy link

farizaghayev commented Jul 4, 2018

Respect :)

@joc7188
Copy link

joc7188 commented May 13, 2020

I implemented the mentioned solution and still getting same error. My java version is 1.8.0_221. This part of code is executed (I saw debugging) and I also added System.setProperty("jdk.tls.useExtendedMasterSecret", "false");

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:994)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at org.apache.commons.net.ftp.FTPSClient.openDataConnection(FTPSClient.java:646)
at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:1899)
at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1885)
at com.motoresocasion.core.utils.ftp.FtpClient.downloadFile(FtpClient.java:72)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
... 26 common frames omitted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment