Hello,


I have the FTPServer class listed below.



This worked fine under the following environment:



- Java 11

- ftplet-api 1.1.0

- ftpserver-core 1.1.0

- mina-core 2.1.4



After I upgraded my application to the following environment:



- Java 17

- ftplet-api 1.2.0

- ftpserver-core 1.2.0

- mina-core 2.2.3



I got the following "Unsupported protocolTLS" error when trying to make an FTP 
connection:



o.a.m.u.DefaultExceptionMonitor: S:- {"message":"Unexpected 
exception.","exception":"java.lang.IllegalArgumentException: Unsupported 
protocolTLS\n\tat 
java.base/sun.security.ssl.ProtocolVersion.namesOf(ProtocolVersion.java:292)\n\tat
 
java.base/sun.security.ssl.SSLEngineImpl.setEnabledProtocols(SSLEngineImpl.java:896)\n\tat
 org.apache.mina.filter.ssl.SslFilter.createEngine(SslFilter.java:334)\n\tat 
org.apache.mina.filter.ssl.SslFilter.onConnected(SslFilter.java:278)\n\tat 
org.apache.mina.filter.ssl.SslFilter.onPostAdd(SslFilter.java:250)\n\tat 
org.apache.mina.core.filterchain.DefaultIoFilterChain.register(DefaultIoFilterChain.java:473)\n\t...
 9 common frames omitted\nWrapped by: 
org.apache.mina.core.filterchain.IoFilterLifeCycleException: onPostAdd(): 
sslFilter:SslFilter in (0x0000000A: nio socket, server, 
192.168.76.1/192.168.76.1:20461 => /192.168.76.79:2121)\n\tat 
org.apache.mina.core.filterchain.DefaultIoFilterChain.register(DefaultIoFilterChain.java:476)\n\tat
 
org.apache.mina.core.filterchain.DefaultIoFilterChain.addLast(DefaultIoFilterChain.java:234)\n\tat
 
org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder.buildFilterChain(DefaultIoFilterChainBuilder.java:553)\n\tat
 
org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.addNow(AbstractPollingIoProcessor.java:832)\n\tat
 
org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.handleNewSessions(AbstractPollingIoProcessor.java:752)\n\tat
 
org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:652)\n\tat
 
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)\n\tat
 
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)\n\tat
 
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)\n\tat
 java.base/java.lang.Thread.run(Thread.java:840)\n"}



The release notes for ftpserver and mina do mention some changes around TLS, 
but I am not sure if/how those would affect my application below:



https://mina.apache.org/ftpserver-project/download_1_2.html
https://mina.apache.org/mina-project/2.2-vs-2.1.html



Any help is much appreciated!



Mant thanks





import org.apache.ftpserver.DataConnectionConfigurationFactory;

import org.apache.ftpserver.FtpServer;

import org.apache.ftpserver.FtpServerFactory;

import org.apache.ftpserver.command.CommandFactory;

import org.apache.ftpserver.command.CommandFactoryFactory;

import org.apache.ftpserver.listener.ListenerFactory;

import org.apache.ftpserver.ssl.SslConfiguration;

import org.apache.ftpserver.ssl.SslConfigurationFactory;

import org.glassfish.jersey.client.JerseyClientBuilder;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;



import jakarta.ws.rs.client.Client;

import java.io.File;

import java.nio.file.FileSystems;

import java.util.LinkedList;

import java.util.List;



public class FTPServer {



    public static FTPConfiguration ftpConfiguration = null;

    private static Logger logger = LoggerFactory.getLogger(FTPServer.class);

    private static String[] safeDefaultCipherSuitesList = 
{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",

            
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",

            "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"};

    private FtpServer server = null;

    private FtpLetImpl ftpLet = null;



    public FTPServer(final FTPConfiguration ftpConfiguration) {

        this.ftpConfiguration = ftpConfiguration;

    }



    public boolean isServerRunning() {

        boolean bResult = false;

        if ((!server.isStopped()) && ((ftpLet == null) || 
(!ftpLet.ShutdownServer()))) {

            bResult = true;

        }

        return bResult;

    }



    public boolean stopServer() {

        if (ftpLet.ShutdownServer()) {

            try {

                logger.info("Finished FTPlet task.  Stopping server.");

                ftpLet.closeIDMAdminSession();

                server.stop();

                return true;

            } catch (Exception e) {

                logger.error("Failed to STOP FTP server.  Exception: ", e);

            }

        }

        return false;

    }



    public boolean launchFtpServer() {

        boolean bResult;

        try {

            DataConnectionConfigurationFactory configurationFactory = new 
DataConnectionConfigurationFactory();

            setActiveMode(configurationFactory);

            
configurationFactory.setImplicitSsl(ftpConfiguration.getSslConfig().isImplicitSslEnabled());

            
configurationFactory.setPassiveExternalAddress(ftpConfiguration.getPassiveExternalAddress());

            
configurationFactory.setPassivePorts(ftpConfiguration.getPassivePortRange());



            ListenerFactory listenerFactory = new ListenerFactory();

            if (ftpConfiguration.getSslConfig().isImplicitSslEnabled()) {

                SslConfiguration sslConfiguration = getSslConfiguration();

                if (null != sslConfiguration) {

                    listenerFactory.setSslConfiguration(sslConfiguration);

                    listenerFactory.setImplicitSsl(true);

                }

            }

            listenerFactory.setPort(ftpConfiguration.getFtpPort());

            listenerFactory.setIdleTimeout(ftpConfiguration.getTimeout());

            
listenerFactory.setDataConnectionConfiguration(configurationFactory.createDataConnectionConfiguration());



            FtpServerFactory serverFactory = new FtpServerFactory();

            serverFactory.addListener("default", 
listenerFactory.createListener());



            FTPFileSystemFactory ftpFS = new FTPFileSystemFactory(true);

            ftpLet = new FtpLetImpl();

            serverFactory.getFtplets().put(FtpLetImpl.class.getName(), ftpLet);

            serverFactory.setCommandFactory(getCommandFactory());



            serverFactory.setConnectionConfig(new FTPConnectionConfig(false, 
500, 10, 10, 3, 0));



            AuditChannel auditChannel = null;



            if (ftpConfiguration.isAuditingEnabled()) {

                auditChannel = new 
FtpAuditEventConfiguration().createAuditChannel();

            }



            FTPUserManagerFactory ftpUserMgrFactory = new 
FTPUserManagerFactory(auditChannel);

            serverFactory.setUserManager(ftpUserMgrFactory);

            ftpLet.setUserManagerFactory(ftpUserMgrFactory);

            serverFactory.setFileSystem(ftpFS);



            server = serverFactory.createServer();

            logger.debug("FTP server starting...");

            server.start();

            bResult = true;



        } catch (Exception e) {

            bResult = false;

            String msg = e.getMessage();

            logger.error("Exception while starting the FTP server: {}", msg);

        }

        return bResult;

    }



    private void setActiveMode(DataConnectionConfigurationFactory connfactory) {

        if (ftpConfiguration.getActivePort() == 0) {

            connfactory.setActiveEnabled(false);

            logger.debug("Active connections have been disabled.");

        } else {

            connfactory.setActiveEnabled(true);

            connfactory.setActiveLocalPort(ftpConfiguration.getActivePort());

            logger.debug("Active connections are enabled.");

        }

    }



    private CommandFactory getCommandFactory() {

        try {

            CommandFactoryFactory allCommandsFactory = new 
CommandFactoryFactory();

            allCommandsFactory.setUseDefaultCommands(true);

            allCommandsFactory.addCommand("PASS", new PASS());

            allCommandsFactory.addCommand("DELE", new NotSupportedCommand());

            allCommandsFactory.addCommand("RMD", new NotSupportedCommand());

            allCommandsFactory.addCommand("RNFR", new NotSupportedCommand());

            allCommandsFactory.addCommand("RNTO", new NotSupportedCommand());

            allCommandsFactory.addCommand("SITE", new NotSupportedCommand());

            return allCommandsFactory.createCommandFactory();

        } catch (Exception ex) {

            logger.error("Command factory could not be created.");

            throw ex;

        }

    }



    private SslConfiguration getSslConfiguration() {

        SslConfiguration sslConfiguration = null;

        SslConfigurationFactory sslConfigFactory = new 
SslConfigurationFactory();

        sslConfigFactory.setSslProtocol("TLS");



        SslConfig config = ftpConfiguration.getSslConfig();

        File sslFile = new File(config.getKeystorePath()

                + FileSystems.getDefault().getSeparator() + 
config.getKeystoreFileName());



        sslConfigFactory.setKeystoreFile(sslFile);

        sslConfigFactory.setKeystorePassword(config.getKeystorePassword());

        sslConfigFactory.setKeyAlias(config.getCertAlias());

        if (config.getEnabledCipherSuites() != null) {

            String[] cipherSuites = config.getEnabledCipherSuites().split(",");

            sslConfigFactory.setEnabledCipherSuites(cipherSuites);

            logger.info("Cipher Suites list defined in environment variable is 
used:{}", config.getEnabledCipherSuites());

        }else{

            
sslConfigFactory.setEnabledCipherSuites(safeDefaultCipherSuitesList);

            logger.info("Default Cipher Suites list is used:{}", String.join(", 
", safeDefaultCipherSuitesList));

        }

        sslConfiguration = sslConfigFactory.createSslConfiguration();



        return sslConfiguration;

    }

}

Reply via email to