Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to plugin custom clients #356

Closed
lmlynik opened this issue Aug 7, 2023 · 2 comments
Closed

Ability to plugin custom clients #356

lmlynik opened this issue Aug 7, 2023 · 2 comments

Comments

@lmlynik
Copy link

lmlynik commented Aug 7, 2023

Using Implicit FTP over TLS sometimes requires various "hackery".
i.e. apache-commons-net doesn't manage ssl session reuse which might be needed.

I had to create

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetAddress;
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;

public class SSLSessionReuseFTPSClient extends FTPSClient {

    public SSLSessionReuseFTPSClient(String protocol, boolean isImplicit) {
        super(protocol, isImplicit);
    }

    @Override
    protected void _prepareDataSocket_(Socket socket) throws IOException {
        if (socket instanceof SSLSocket) {
            // Control socket is SSL
            final SSLSession session = ((SSLSocket)_socket_).getSession();
            if (session.isValid()) {
                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);
                    Method getHostMethod;
                    try {
                        getHostMethod = socket.getClass().getMethod("getPeerHost");
                    }
                    catch (NoSuchMethodException e) {
                        // Running in IKVM
                        getHostMethod = socket.getClass().getDeclaredMethod("getHost");
                    }
                    getHostMethod.setAccessible(true);
                    Object peerHost = getHostMethod.invoke(socket);
                    InetAddress iAddr = socket.getInetAddress();
                    int port = socket.getPort();
                    putMethod.invoke(cache, String.format("%s:%s", peerHost, port).toLowerCase(Locale.ROOT), session);
                    putMethod.invoke(cache, String.format("%s:%s", iAddr.getHostName(), port).toLowerCase(Locale.ROOT), session);
                    putMethod.invoke(cache, String.format("%s:%s", iAddr.getHostAddress(), port).toLowerCase(Locale.ROOT), session);
                }
                catch (Exception e) {
                    throw new IOException(e);
                }
            }
            else {
                throw new IOException("Invalid SSL Session");
            }
        }
    }
}

To "plugin" the socket reuse.
Currently zio-ftp doesn't allow custom clients, so library cannot be used in these situations.

Another issue, for my use-case I also had to

          System.setProperty("jdk.tls.client.enableSessionTicketExtension", "false")
          System.setProperty("jdk.tls.useExtendedMasterSecret", "false")

albeit not sure if this can be covered by library.

@regis-leray
Copy link
Member

regis-leray commented Aug 7, 2023

@lmlynik please tell me if it helps the new constructor ?

#357

@regis-leray
Copy link
Member

Now an unsafe method constructor is available.

UnsecureFTP.unsafe(c: Client)
SecureFTP.unsafe(c: Client)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants