You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jo...@apache.org on 2019/05/05 22:50:09 UTC

[mina-ftpserver] branch FTPSERVER-491 created (now 8ac3e47)

This is an automated email from the ASF dual-hosted git repository.

johnnyv pushed a change to branch FTPSERVER-491
in repository https://gitbox.apache.org/repos/asf/mina-ftpserver.git.


      at 8ac3e47  Initial fix for FTPSERVER-491

This branch includes the following new commits:

     new 8ac3e47  Initial fix for FTPSERVER-491

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[mina-ftpserver] 01/01: Initial fix for FTPSERVER-491

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

johnnyv pushed a commit to branch FTPSERVER-491
in repository https://gitbox.apache.org/repos/asf/mina-ftpserver.git

commit 8ac3e47267aea7f38475b1588a4f5540d2801a48
Author: johnnyv <jo...@apache.org>
AuthorDate: Sun May 5 18:49:16 2019 -0400

    Initial fix for FTPSERVER-491
---
 .../apache/ftpserver/listener/nio/NioListener.java | 262 ++++++++++-----------
 .../org/apache/ftpserver/ssl/SslConfiguration.java |  42 ++--
 .../ssl/impl/DefaultSslConfiguration.java          | 107 ++++-----
 3 files changed, 202 insertions(+), 209 deletions(-)

diff --git a/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java b/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
index 401b7d3..4cbf62a 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
@@ -74,148 +74,138 @@ public class NioListener extends AbstractListener {
     private FtpServerContext context;
 
     /**
-     * @deprecated Use the constructor with IpFilter instead. 
-     * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
+     * @deprecated Use the constructor with IpFilter instead. Constructor for internal use, do not use directly. Instead
+     *             use {@link ListenerFactory}
      */
     @Deprecated
-    public NioListener(String serverAddress, int port,
-            boolean implicitSsl,
-            SslConfiguration sslConfiguration,
-            DataConnectionConfiguration dataConnectionConfig, 
-            int idleTimeout, List<InetAddress> blockedAddresses, List<Subnet> blockedSubnets) {
-        super(serverAddress, port, implicitSsl, sslConfiguration, dataConnectionConfig, 
-                idleTimeout, blockedAddresses, blockedSubnets);   
+    public NioListener(String serverAddress, int port, boolean implicitSsl, SslConfiguration sslConfiguration, DataConnectionConfiguration dataConnectionConfig, int idleTimeout, List<InetAddress> blockedAddresses, List<Subnet> blockedSubnets) {
+	super(serverAddress, port, implicitSsl, sslConfiguration, dataConnectionConfig, idleTimeout, blockedAddresses, blockedSubnets);
     }
 
     /**
      * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
      */
-    public NioListener(String serverAddress, int port, boolean implicitSsl,
-            SslConfiguration sslConfiguration,
-            DataConnectionConfiguration dataConnectionConfig, int idleTimeout,
-            SessionFilter sessionFilter) {
-        super(serverAddress, port, implicitSsl, sslConfiguration,
-                dataConnectionConfig, idleTimeout, sessionFilter);
+    public NioListener(String serverAddress, int port, boolean implicitSsl, SslConfiguration sslConfiguration, DataConnectionConfiguration dataConnectionConfig, int idleTimeout, SessionFilter sessionFilter) {
+	super(serverAddress, port, implicitSsl, sslConfiguration, dataConnectionConfig, idleTimeout, sessionFilter);
     }
 
     /**
      * @see Listener#start(FtpServerContext)
      */
     public synchronized void start(FtpServerContext context) {
-        if(!isStopped()) {
-            // listener already started, don't allow
-            throw new IllegalStateException("Listener already started");
-        }
-        
-        try {
-            
-            this.context = context;
-    
-            acceptor = new NioSocketAcceptor(Runtime.getRuntime()
-                    .availableProcessors());
-    
-            if (getServerAddress() != null) {
-                address = new InetSocketAddress(getServerAddress(), getPort());
-            } else {
-                address = new InetSocketAddress(getPort());
-            }
-    
-            acceptor.setReuseAddress(true);
-            acceptor.getSessionConfig().setReadBufferSize(2048);
-            acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
-                    getIdleTimeout());
-            // Decrease the default receiver buffer size
-            acceptor.getSessionConfig().setReceiveBufferSize(512);
-    
-            MdcInjectionFilter mdcFilter = new MdcInjectionFilter();
-    
-            acceptor.getFilterChain().addLast("mdcFilter", mdcFilter);
-
-            SessionFilter sessionFilter = getSessionFilter();
-            if (sessionFilter != null) {
-                // add and IP filter to the filter chain.
-                acceptor.getFilterChain().addLast("sessionFilter",
-                        new MinaSessionFilter(sessionFilter));
-            }
-    
-            acceptor.getFilterChain().addLast("threadPool",
-                    new ExecutorFilter(context.getThreadPoolExecutor()));
-            acceptor.getFilterChain().addLast("codec",
-                    new ProtocolCodecFilter(new FtpServerProtocolCodecFactory()));
-            acceptor.getFilterChain().addLast("mdcFilter2", mdcFilter);
-            acceptor.getFilterChain().addLast("logger", new FtpLoggingFilter());
-    
-            if (isImplicitSsl()) {
-                SslConfiguration ssl = getSslConfiguration();
-                SslFilter sslFilter;
-                try {
-                    sslFilter = new SslFilter(ssl.getSSLContext());
-                } catch (GeneralSecurityException e) {
-                    throw new FtpServerConfigurationException("SSL could not be initialized, check configuration");
-                }
-    
-                if (ssl.getClientAuth() == ClientAuth.NEED) {
-                    sslFilter.setNeedClientAuth(true);
-                } else if (ssl.getClientAuth() == ClientAuth.WANT) {
-                    sslFilter.setWantClientAuth(true);
-                }
-    
-                if (ssl.getEnabledCipherSuites() != null) {
-                    sslFilter.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
-                }
-    
-                acceptor.getFilterChain().addFirst("sslFilter", sslFilter);
-            }
-    
-            handler.init(context, this);
-            acceptor.setHandler(new FtpHandlerAdapter(context, handler));
-    
-            try {
-                acceptor.bind(address);
-            } catch (IOException e) {
-                throw new FtpServerConfigurationException("Failed to bind to address " + address + ", check configuration", e);
-            }
-            
-            updatePort();
-    
-        } catch(RuntimeException e) {
-            // clean up if we fail to start
-            stop();
-            
-            throw e;
-        }
+	if (!isStopped()) {
+	    // listener already started, don't allow
+	    throw new IllegalStateException("Listener already started");
+	}
+
+	try {
+
+	    this.context = context;
+
+	    acceptor = new NioSocketAcceptor(Runtime.getRuntime().availableProcessors());
+
+	    if (getServerAddress() != null) {
+		address = new InetSocketAddress(getServerAddress(), getPort());
+	    } else {
+		address = new InetSocketAddress(getPort());
+	    }
+
+	    acceptor.setReuseAddress(true);
+	    acceptor.getSessionConfig().setReadBufferSize(2048);
+	    acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, getIdleTimeout());
+	    // Decrease the default receiver buffer size
+	    acceptor.getSessionConfig().setReceiveBufferSize(512);
+
+	    MdcInjectionFilter mdcFilter = new MdcInjectionFilter();
+
+	    acceptor.getFilterChain().addLast("mdcFilter", mdcFilter);
+
+	    SessionFilter sessionFilter = getSessionFilter();
+	    if (sessionFilter != null) {
+		// add and IP filter to the filter chain.
+		acceptor.getFilterChain().addLast("sessionFilter", new MinaSessionFilter(sessionFilter));
+	    }
+
+	    acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(context.getThreadPoolExecutor()));
+	    acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new FtpServerProtocolCodecFactory()));
+	    acceptor.getFilterChain().addLast("mdcFilter2", mdcFilter);
+	    acceptor.getFilterChain().addLast("logger", new FtpLoggingFilter());
+
+	    if (isImplicitSsl()) {
+		SslConfiguration ssl_conf = getSslConfiguration();
+		SslFilter ssl_filter;
+		try {
+		    ssl_filter = new SslFilter(ssl_conf.getSSLContext());
+		} catch (GeneralSecurityException e) {
+		    throw new FtpServerConfigurationException("SSL could not be initialized, check configuration");
+		}
+
+		if (ssl_conf.getClientAuth() == ClientAuth.NEED) {
+		    ssl_filter.setNeedClientAuth(true);
+		} else if (ssl_conf.getClientAuth() == ClientAuth.WANT) {
+		    ssl_filter.setWantClientAuth(true);
+		}
+
+		if (ssl_conf.getEnabledProtocol() != null) {
+		    ssl_filter.setEnabledProtocols(new String[] { ssl_conf.getEnabledProtocol() });
+		}
+
+		if (ssl_conf.getEnabledCipherSuites() != null) {
+		    ssl_filter.setEnabledCipherSuites(ssl_conf.getEnabledCipherSuites());
+		}
+
+		acceptor.getFilterChain().addFirst("sslFilter", ssl_filter);
+	    }
+
+	    handler.init(context, this);
+	    acceptor.setHandler(new FtpHandlerAdapter(context, handler));
+
+	    try {
+		acceptor.bind(address);
+	    } catch (IOException e) {
+		throw new FtpServerConfigurationException("Failed to bind to address " + address + ", check configuration", e);
+	    }
+
+	    updatePort();
+
+	} catch (RuntimeException e) {
+	    // clean up if we fail to start
+	    stop();
+
+	    throw e;
+	}
     }
-    
+
     private void updatePort() {
-        // update the port to the real port bound by the listener
-        setPort(acceptor.getLocalAddress().getPort());
+	// update the port to the real port bound by the listener
+	setPort(acceptor.getLocalAddress().getPort());
     }
 
     /**
      * @see Listener#stop()
      */
     public synchronized void stop() {
-        // close server socket
-        if (acceptor != null) {
-            acceptor.unbind();
-            acceptor.dispose();
-            acceptor = null;
-        }
-        context = null;
+	// close server socket
+	if (acceptor != null) {
+	    acceptor.unbind();
+	    acceptor.dispose();
+	    acceptor = null;
+	}
+	context = null;
     }
 
     /**
      * @see Listener#isStopped()
      */
     public boolean isStopped() {
-        return acceptor == null;
+	return acceptor == null;
     }
 
     /**
      * @see Listener#isSuspended()
      */
     public boolean isSuspended() {
-        return suspended;
+	return suspended;
 
     }
 
@@ -223,44 +213,44 @@ public class NioListener extends AbstractListener {
      * @see Listener#resume()
      */
     public synchronized void resume() {
-        if (acceptor != null && suspended) {
-            try {
-                LOG.debug("Resuming listener");
-                acceptor.bind(address);
-                LOG.debug("Listener resumed");
-                
-                updatePort();
-                
-                suspended = false;
-            } catch (IOException e) {
-                LOG.error("Failed to resume listener", e);
-            }
-        }
+	if (acceptor != null && suspended) {
+	    try {
+		LOG.debug("Resuming listener");
+		acceptor.bind(address);
+		LOG.debug("Listener resumed");
+
+		updatePort();
+
+		suspended = false;
+	    } catch (IOException e) {
+		LOG.error("Failed to resume listener", e);
+	    }
+	}
     }
 
     /**
      * @see Listener#suspend()
      */
     public synchronized void suspend() {
-        if (acceptor != null && !suspended) {
-            LOG.debug("Suspending listener");
-            acceptor.unbind();
-            
-            suspended = true;
-            LOG.debug("Listener suspended");
-        }
+	if (acceptor != null && !suspended) {
+	    LOG.debug("Suspending listener");
+	    acceptor.unbind();
+
+	    suspended = true;
+	    LOG.debug("Listener suspended");
+	}
     }
-    
+
     /**
      * @see Listener#getActiveSessions()
      */
     public synchronized Set<FtpIoSession> getActiveSessions() {
-        Map<Long, IoSession> sessions = acceptor.getManagedSessions();
+	Map<Long, IoSession> sessions = acceptor.getManagedSessions();
 
-        Set<FtpIoSession> ftpSessions = new HashSet<FtpIoSession>();
-        for (IoSession session : sessions.values()) {
-            ftpSessions.add(new FtpIoSession(session, context));
-        }
-        return ftpSessions;
+	Set<FtpIoSession> ftpSessions = new HashSet<FtpIoSession>();
+	for (IoSession session : sessions.values()) {
+	    ftpSessions.add(new FtpIoSession(session, context));
+	}
+	return ftpSessions;
     }
 }
diff --git a/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java b/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java
index 4b6213f..c4da591 100644
--- a/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java
+++ b/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java
@@ -30,17 +30,16 @@ import javax.net.ssl.SSLSocketFactory;
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public interface SslConfiguration {
-	
-	/**
-	 * Returns the socket factory that can be used to create sockets using 
-	 * 		   this <code>SslConfiguration</code>. 
-	 * @return the socket factory that can be used to create sockets using this 
-	 * 		   <code>SslConfiguration</code>.
-	 * @throws GeneralSecurityException if any error occurs while creating the 
-	 *         socket factory.  
-	 * 		    
-	 */
-	SSLSocketFactory getSocketFactory() throws GeneralSecurityException;
+
+    /**
+     * Returns the socket factory that can be used to create sockets using this <code>SslConfiguration</code>.
+     * 
+     * @return the socket factory that can be used to create sockets using this <code>SslConfiguration</code>.
+     * @throws GeneralSecurityException
+     *             if any error occurs while creating the socket factory.
+     * 
+     */
+    SSLSocketFactory getSocketFactory() throws GeneralSecurityException;
 
     /**
      * Return the SSL context for this configuration
@@ -51,8 +50,7 @@ public interface SslConfiguration {
     SSLContext getSSLContext() throws GeneralSecurityException;
 
     /**
-     * Return the SSL context for this configuration given the specified
-     * protocol
+     * Return the SSL context for this configuration given the specified protocol
      * 
      * @param protocol
      *            The protocol, SSL or TLS must be supported
@@ -62,21 +60,25 @@ public interface SslConfiguration {
     SSLContext getSSLContext(String protocol) throws GeneralSecurityException;
 
     /**
-     * Returns the cipher suites that should be enabled for this connection.
-     * Must return null if the default (as decided by the JVM) cipher suites
-     * should be used.
+     * Returns the cipher suites that should be enabled for this connection. Must return null if the default (as decided
+     * by the JVM) cipher suites should be used.
      * 
      * @return An array of cipher suites, or null.
      */
     String[] getEnabledCipherSuites();
 
     /**
+     * Returns the default ssl protocol
+     * 
+     * @return The name of the protocol as a String
+     */
+    String getEnabledProtocol();
+
+    /**
      * Return the required client authentication setting
      * 
-     * @return {@link ClientAuth#NEED} if client authentication is required,
-     *         {@link ClientAuth#WANT} is client authentication is wanted or
-     *         {@link ClientAuth#NONE} if no client authentication is the be
-     *         performed
+     * @return {@link ClientAuth#NEED} if client authentication is required, {@link ClientAuth#WANT} is client
+     *         authentication is wanted or {@link ClientAuth#NONE} if no client authentication is the be performed
      */
     ClientAuth getClientAuth();
 }
diff --git a/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java b/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java
index 04e4ab0..b7f71e5 100644
--- a/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java
+++ b/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java
@@ -36,8 +36,7 @@ import org.apache.ftpserver.util.ClassUtils;
 /**
  * <strong>Internal class, do not use directly.</strong>
  * 
- * Used to configure the SSL settings for the control channel or the data
- * channel.
+ * Used to configure the SSL settings for the control channel or the data channel.
  * 
  * <strong><strong>Internal class, do not use directly.</strong></strong>
  *
@@ -49,93 +48,95 @@ public class DefaultSslConfiguration implements SslConfiguration {
 
     private final TrustManagerFactory trustManagerFactory;
 
-    private String sslProtocol = "TLS";
+    private String enabledProtocol = "TLS";
 
     private final ClientAuth clientAuth;// = ClientAuth.NONE;
 
     private final String keyAlias;
 
     private final String[] enabledCipherSuites;
-    
+
     private final SSLContext sslContext;
-    
+
     private final SSLSocketFactory socketFactory;
-    
+
     /**
      * Internal constructor, do not use directly. Instead, use {@link SslConfigurationFactory}
-     * @throws GeneralSecurityException 
+     * 
+     * @throws GeneralSecurityException
      */
-    public DefaultSslConfiguration(KeyManagerFactory keyManagerFactory,
-            TrustManagerFactory trustManagerFactory, ClientAuth clientAuthReqd,
-            String sslProtocol, String[] enabledCipherSuites, String keyAlias) 
-    		throws GeneralSecurityException {
-        super();
-        this.clientAuth = clientAuthReqd;
-        this.enabledCipherSuites = enabledCipherSuites;
-        this.keyAlias = keyAlias;
-        this.keyManagerFactory = keyManagerFactory;
-        this.sslProtocol = sslProtocol;
-        this.trustManagerFactory = trustManagerFactory;
-        this.sslContext = initContext();
-        this.socketFactory = sslContext.getSocketFactory();
+    public DefaultSslConfiguration(KeyManagerFactory keyManagerFactory, TrustManagerFactory trustManagerFactory, ClientAuth clientAuthReqd, String sslProtocol, String[] enabledCipherSuites, String keyAlias) throws GeneralSecurityException {
+	super();
+	this.clientAuth = clientAuthReqd;
+	this.enabledCipherSuites = enabledCipherSuites;
+	this.keyAlias = keyAlias;
+	this.keyManagerFactory = keyManagerFactory;
+	this.enabledProtocol = sslProtocol;
+	this.trustManagerFactory = trustManagerFactory;
+	this.sslContext = initContext();
+	this.socketFactory = sslContext.getSocketFactory();
     }
-    
+
     public SSLSocketFactory getSocketFactory() throws GeneralSecurityException {
-    	return socketFactory;
+	return socketFactory;
     }
 
     /**
      * @see SslConfiguration#getSSLContext(String)
      */
-    public SSLContext getSSLContext(String protocol)
-            throws GeneralSecurityException {
-		return sslContext;
+    public SSLContext getSSLContext(String protocol) throws GeneralSecurityException {
+	return sslContext;
+    }
+
+    /**
+     * @see SslConfiguration#getEnabledProtocol()
+     */
+    public String getEnabledProtocol() {
+	return enabledProtocol;
     }
-    
+
     /**
      * @see SslConfiguration#getClientAuth()
      */
     public ClientAuth getClientAuth() {
-        return clientAuth;
+	return clientAuth;
     }
 
     /**
      * @see SslConfiguration#getSSLContext()
      */
     public SSLContext getSSLContext() throws GeneralSecurityException {
-        return getSSLContext(sslProtocol);
+	return getSSLContext(enabledProtocol);
     }
 
     /**
      * @see SslConfiguration#getEnabledCipherSuites()
      */
     public String[] getEnabledCipherSuites() {
-        if (enabledCipherSuites != null) {
-            return enabledCipherSuites.clone();
-        } else {
-            return null;
-        }
+	if (enabledCipherSuites != null) {
+	    return enabledCipherSuites.clone();
+	} else {
+	    return null;
+	}
     }
-    
+
     private SSLContext initContext() throws GeneralSecurityException {
-        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
-
-        // wrap key managers to allow us to control their behavior
-        // (FTPSERVER-93)
-        for (int i = 0; i < keyManagers.length; i++) {
-            if (ClassUtils.extendsClass(keyManagers[i].getClass(),
-                    "javax.net.ssl.X509ExtendedKeyManager")) {
-                keyManagers[i] = new ExtendedAliasKeyManager(keyManagers[i],
-                        keyAlias);
-            } else if (keyManagers[i] instanceof X509KeyManager) {
-                keyManagers[i] = new AliasKeyManager(keyManagers[i], keyAlias);
-            }
-        }
-
-        // create and initialize the SSLContext
-        SSLContext ctx = SSLContext.getInstance(sslProtocol);
-        ctx.init(keyManagers, trustManagerFactory.getTrustManagers(), null);
-        //Create the socket factory
-        return ctx;
+	KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
+
+	// wrap key managers to allow us to control their behavior
+	// (FTPSERVER-93)
+	for (int i = 0; i < keyManagers.length; i++) {
+	    if (ClassUtils.extendsClass(keyManagers[i].getClass(), "javax.net.ssl.X509ExtendedKeyManager")) {
+		keyManagers[i] = new ExtendedAliasKeyManager(keyManagers[i], keyAlias);
+	    } else if (keyManagers[i] instanceof X509KeyManager) {
+		keyManagers[i] = new AliasKeyManager(keyManagers[i], keyAlias);
+	    }
+	}
+
+	// create and initialize the SSLContext
+	SSLContext ctx = SSLContext.getInstance(sslProtocol);
+	ctx.init(keyManagers, trustManagerFactory.getTrustManagers(), null);
+	// Create the socket factory
+	return ctx;
     }
 }