This is an automated email from the ASF dual-hosted git repository. elecharny pushed a commit to branch 1.2.X in repository https://gitbox.apache.org/repos/asf/mina-ftpserver.git
The following commit(s) were added to refs/heads/1.2.X by this push: new 37ef5fd3 o Applied Arturo Bernal PRs o Code formatting 37ef5fd3 is described below commit 37ef5fd3dcd2afb38b8a21e07f815424e41d290d Author: emmanuel lecharny <elecha...@apache.org> AuthorDate: Tue Apr 5 07:15:46 2022 +0200 o Applied Arturo Bernal PRs o Code formatting --- .../ftpserver/command/CommandFactoryFactory.java | 4 +- .../org/apache/ftpserver/command/impl/MD5.java | 17 +- .../apache/ftpserver/command/impl/OPTS_MLST.java | 21 +- .../ftpserver/impl/IODataConnectionFactory.java | 236 ++++++++++----------- .../org/apache/ftpserver/util/EncryptUtils.java | 4 +- distribution/src/main/assemblies/src.xml | 1 + 6 files changed, 146 insertions(+), 137 deletions(-) diff --git a/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java b/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java index 0ac2d247..d2149110 100644 --- a/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java +++ b/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java @@ -99,9 +99,9 @@ public class CommandFactoryFactory { DEFAULT_COMMAND_MAP.put("HELP", new HELP()); DEFAULT_COMMAND_MAP.put("LANG", new LANG()); DEFAULT_COMMAND_MAP.put("LIST", new LIST()); - DEFAULT_COMMAND_MAP.put("MD5", new MD5()); + DEFAULT_COMMAND_MAP.put(MD5.MD5, new MD5()); DEFAULT_COMMAND_MAP.put("MFMT", new MFMT()); - DEFAULT_COMMAND_MAP.put("MMD5", new MD5()); + DEFAULT_COMMAND_MAP.put(MD5.MMD5, new MD5()); DEFAULT_COMMAND_MAP.put("MDTM", new MDTM()); DEFAULT_COMMAND_MAP.put("MLST", new MLST()); DEFAULT_COMMAND_MAP.put("MKD", new MKD()); diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java b/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java index 881951a8..170f9697 100644 --- a/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java +++ b/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java @@ -48,6 +48,11 @@ import org.slf4j.LoggerFactory; * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public class MD5 extends AbstractCommand { + /** The MD5 String constant */ + public static final String MD5 = "MD5"; + + /** The MMD5 String constant */ + public static final String MMD5 = "MMD5"; private final Logger LOG = LoggerFactory.getLogger(MD5.class); @@ -61,11 +66,7 @@ public class MD5 extends AbstractCommand { // reset state variables session.resetState(); - boolean isMMD5 = false; - - if ("MMD5".equals(request.getCommand())) { - isMMD5 = true; - } + boolean isMMD5 = MMD5.equals(request.getCommand()); // print file information String argument = request.getArgument(); @@ -157,10 +158,10 @@ public class MD5 extends AbstractCommand { } if (isMMD5) { session.write(LocalizedFtpReply.translate(session, request, context, - 252, "MMD5", sb.toString())); + 252, MMD5, sb.toString())); } else { session.write(LocalizedFtpReply.translate(session, request, context, - 251, "MD5", sb.toString())); + 251, MD5, sb.toString())); } } @@ -173,7 +174,7 @@ public class MD5 extends AbstractCommand { */ private String md5(InputStream is) throws IOException, NoSuchAlgorithmException { - MessageDigest digest = MessageDigest.getInstance("MD5"); + MessageDigest digest = MessageDigest.getInstance(MD5); DigestInputStream dis = new DigestInputStream(is, digest); byte[] buffer = new byte[1024]; diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java index 196d619a..967b81ac 100644 --- a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java +++ b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java @@ -61,6 +61,7 @@ public class OPTS_MLST extends AbstractCommand { String listTypes; String types[]; int spIndex = argument.indexOf(' '); + if (spIndex == -1) { types = new String[0]; listTypes = ""; @@ -70,24 +71,27 @@ public class OPTS_MLST extends AbstractCommand { // parse all the type tokens StringTokenizer st = new StringTokenizer(listTypes, ";"); types = new String[st.countTokens()]; + for (int i = 0; i < types.length; ++i) { types[i] = st.nextToken(); } } + // set the list types String[] validatedTypes = validateSelectedTypes(types); - if (validatedTypes != null) { + + //if (validatedTypes.length != 0) { session.setAttribute("MLST.types", validatedTypes); session.write(LocalizedFtpReply.translate(session, request, context, FtpReply.REPLY_200_COMMAND_OKAY, "OPTS.MLST", listTypes)); - } else { + /*} else { session.write(LocalizedFtpReply.translate(session, request, context, FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "OPTS.MLST", listTypes)); - } + }*/ } - private String[] validateSelectedTypes(final String types[]) { + private String[] validateSelectedTypes(String... types) { // ignore null types if (types == null) { @@ -95,11 +99,12 @@ public class OPTS_MLST extends AbstractCommand { } List<String> selectedTypes = new ArrayList<String>(); + // check all the types - for (int i = 0; i < types.length; ++i) { - for (int j = 0; j < AVAILABLE_TYPES.length; ++j) { - if (AVAILABLE_TYPES[j].equalsIgnoreCase(types[i])) { - selectedTypes.add(AVAILABLE_TYPES[j]); + for (String type:types) { + for (String availableType: AVAILABLE_TYPES) { + if (availableType.equalsIgnoreCase( type )) { + selectedTypes.add(availableType); break; } } diff --git a/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java b/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java index 180800ff..1b274442 100644 --- a/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java +++ b/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java @@ -74,6 +74,7 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { public IODataConnectionFactory(final FtpServerContext serverContext, final FtpIoSession session) { this.session = session; this.serverContext = serverContext; + if ((session != null) && (session.getListener() != null) && session.getListener().getDataConnectionConfiguration().isImplicitSsl()) { secure = true; } @@ -83,37 +84,38 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { * Close data socket. This method must be idempotent as we might call it multiple times during disconnect. */ public synchronized void closeDataConnection() { - - // close client socket if any - if (dataSoc != null) { - try { - dataSoc.close(); - } catch (Exception ex) { - LOG.warn("FtpDataConnection.closeDataSocket()", ex); - } - dataSoc = null; - } - - // close server socket if any - if (servSoc != null) { - try { - servSoc.close(); - } catch (Exception ex) { - LOG.warn("FtpDataConnection.closeDataSocket()", ex); + // close client socket if any + if (dataSoc != null) { + try { + dataSoc.close(); + } catch (Exception ex) { + LOG.warn("FtpDataConnection.closeDataSocket()", ex); + } + + dataSoc = null; } + + // close server socket if any + if (servSoc != null) { + try { + servSoc.close(); + } catch (Exception ex) { + LOG.warn("FtpDataConnection.closeDataSocket()", ex); + } + + if (session != null) { + DataConnectionConfiguration dcc = session.getListener().getDataConnectionConfiguration(); - if (session != null) { - DataConnectionConfiguration dcc = session.getListener().getDataConnectionConfiguration(); - if (dcc != null) { - dcc.releasePassivePort(port); - } + if (dcc != null) { + dcc.releasePassivePort(port); + } + } + + servSoc = null; } - - servSoc = null; - } - - // reset request time - requestTime = 0L; + + // reset request time + requestTime = 0L; } /** @@ -128,9 +130,9 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { this.address = address.getAddress(); port = address.getPort(); requestTime = System.currentTimeMillis(); - } + } - private SslConfiguration getSslConfiguration() { + private SslConfiguration getSslConfiguration() { DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration(); SslConfiguration configuration = dataCfg.getSslConfiguration(); @@ -153,6 +155,7 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { // get the passive port int passivePort = session.getListener().getDataConnectionConfiguration().requestPassivePort(); + if (passivePort == -1) { servSoc = null; throw new DataConnectionException("Cannot find an available passive port."); @@ -238,6 +241,7 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { // get socket depending on the selection dataSoc = null; DataConnectionConfiguration dataConfig = session.getListener().getDataConnectionConfiguration(); + try { if (!passive) { if (secure) { @@ -286,71 +290,72 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { dataSoc.connect(new InetSocketAddress(address, port)); } else { - - if (secure) { - LOG.debug("Opening secure passive data connection"); - // this is where we wrap the unsecured socket as a SSLSocket. This is - // due to the JVM bug described in FTPSERVER-241. - - // get server socket factory - SslConfiguration ssl = getSslConfiguration(); - - // we've already checked this, but let's do it again - if (ssl == null) { - throw new FtpException("Data connection SSL not configured"); - } - - SSLSocketFactory ssocketFactory = ssl.getSocketFactory(); - - Socket serverSocket = servSoc.accept(); - - SSLSocket sslSocket = (SSLSocket) ssocketFactory.createSocket(serverSocket, serverSocket.getInetAddress().getHostAddress(), serverSocket.getPort(), true); - sslSocket.setUseClientMode(false); - - // initialize server socket - if (ssl.getClientAuth() == ClientAuth.NEED) { - sslSocket.setNeedClientAuth(true); - } else if (ssl.getClientAuth() == ClientAuth.WANT) { - sslSocket.setWantClientAuth(true); - } - - if (ssl.getEnabledCipherSuites() != null) { - sslSocket.setEnabledCipherSuites(ssl.getEnabledCipherSuites()); - } - - if (ssl.getEnabledProtocols() != null) { - sslSocket.setEnabledProtocols(ssl.getEnabledProtocols()); + if (secure) { + LOG.debug("Opening secure passive data connection"); + // this is where we wrap the unsecured socket as a SSLSocket. This is + // due to the JVM bug described in FTPSERVER-241. + + // get server socket factory + SslConfiguration ssl = getSslConfiguration(); + + // we've already checked this, but let's do it again + if (ssl == null) { + throw new FtpException("Data connection SSL not configured"); + } + + SSLSocketFactory ssocketFactory = ssl.getSocketFactory(); + + Socket serverSocket = servSoc.accept(); + + SSLSocket sslSocket = (SSLSocket) ssocketFactory.createSocket(serverSocket, serverSocket.getInetAddress().getHostAddress(), serverSocket.getPort(), true); + sslSocket.setUseClientMode(false); + + // initialize server socket + if (ssl.getClientAuth() == ClientAuth.NEED) { + sslSocket.setNeedClientAuth(true); + } else if (ssl.getClientAuth() == ClientAuth.WANT) { + sslSocket.setWantClientAuth(true); + } + + if (ssl.getEnabledCipherSuites() != null) { + sslSocket.setEnabledCipherSuites(ssl.getEnabledCipherSuites()); + } + + if (ssl.getEnabledProtocols() != null) { + sslSocket.setEnabledProtocols(ssl.getEnabledProtocols()); + } + + dataSoc = sslSocket; + } else { + LOG.debug("Opening passive data connection"); + + dataSoc = servSoc.accept(); } - - dataSoc = sslSocket; - } else { - LOG.debug("Opening passive data connection"); - - dataSoc = servSoc.accept(); - } - - if (dataConfig.isPassiveIpCheck()) { - // Let's make sure we got the connection from the same - // client that we are expecting - InetAddress remoteAddress = ((InetSocketAddress) session.getRemoteAddress()).getAddress(); - InetAddress dataSocketAddress = dataSoc.getInetAddress(); - if (!dataSocketAddress.equals(remoteAddress)) { - LOG.warn("Passive IP Check failed. Closing data connection from " + dataSocketAddress + " as it does not match the expected address " + remoteAddress); - closeDataConnection(); - return null; + + if (dataConfig.isPassiveIpCheck()) { + // Let's make sure we got the connection from the same + // client that we are expecting + InetAddress remoteAddress = ((InetSocketAddress) session.getRemoteAddress()).getAddress(); + InetAddress dataSocketAddress = dataSoc.getInetAddress(); + + if (!dataSocketAddress.equals(remoteAddress)) { + LOG.warn("Passive IP Check failed. Closing data connection from " + dataSocketAddress + " as it does not match the expected address " + remoteAddress); + closeDataConnection(); + return null; + } } - } - - DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration(); - - dataSoc.setSoTimeout(dataCfg.getIdleTime() * 1000); - LOG.debug("Passive data connection opened"); + + DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration(); + + dataSoc.setSoTimeout(dataCfg.getIdleTime() * 1000); + LOG.debug("Passive data connection opened"); } } catch (Exception ex) { closeDataConnection(); LOG.warn("FtpDataConnection.getDataSocket()", ex); throw ex; } + dataSoc.setSoTimeout(dataConfig.getIdleTime() * 1000); // Make sure we initiate the SSL handshake, or we'll @@ -371,9 +376,9 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { return null; } else { try { - return InetAddress.getByName(host); + return InetAddress.getByName(host); } catch (UnknownHostException ex) { - throw new DataConnectionException("Failed to resolve address", ex); + throw new DataConnectionException("Failed to resolve address", ex); } } } @@ -384,14 +389,14 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { * @see org.apache.ftpserver.DataConnectionFactory#isSecure() */ public boolean isSecure() { - return secure; + return secure; } /** * Set the security protocol. */ public void setSecure(final boolean secure) { - this.secure = secure; + this.secure = secure; } /* @@ -400,56 +405,51 @@ public class IODataConnectionFactory implements ServerDataConnectionFactory { * @see org.apache.ftpserver.DataConnectionFactory#isZipMode() */ public boolean isZipMode() { - return isZip; + return isZip; } /** * Set zip mode. */ public void setZipMode(final boolean zip) { - isZip = zip; + isZip = zip; } /** * Check the data connection idle status. */ public synchronized boolean isTimeout(final long currTime) { - - // data connection not requested - not a timeout - if (requestTime == 0L) { - return false; - } - - // data connection active - not a timeout - if (dataSoc != null) { - return false; - } - - // no idle time limit - not a timeout - int maxIdleTime = session.getListener().getDataConnectionConfiguration().getIdleTime() * 1000; - if (maxIdleTime == 0) { - return false; - } - - // idle time is within limit - not a timeout - if ((currTime - requestTime) < maxIdleTime) { - return false; - } - - return true; + // data connection not requested - not a timeout + if (requestTime == 0L) { + return false; + } + + // data connection active - not a timeout + if (dataSoc != null) { + return false; + } + + // no idle time limit - not a timeout + int maxIdleTime = session.getListener().getDataConnectionConfiguration().getIdleTime() * 1000; + if (maxIdleTime == 0) { + return false; + } + + // idle time is within limit - not a timeout + return ((currTime - requestTime) >= maxIdleTime); } /** * Dispose data connection - close all the sockets. */ public void dispose() { - closeDataConnection(); + closeDataConnection(); } /** * Sets the server's control address. */ public void setServerControlAddress(final InetAddress serverControlAddress) { - this.serverControlAddress = serverControlAddress; + this.serverControlAddress = serverControlAddress; } } diff --git a/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java b/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java index 77077262..04be9fe5 100644 --- a/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java +++ b/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java @@ -22,6 +22,8 @@ package org.apache.ftpserver.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import org.apache.ftpserver.command.impl.MD5; + /** * <strong>Internal class, do not use directly.</strong> * @@ -61,7 +63,7 @@ public class EncryptUtils { String result = ""; try { - result = encrypt(source, "MD5"); + result = encrypt(source, MD5.MD5); } catch (NoSuchAlgorithmException ex) { // this should never happen throw new RuntimeException(ex); diff --git a/distribution/src/main/assemblies/src.xml b/distribution/src/main/assemblies/src.xml index e552b532..1dd9aace 100644 --- a/distribution/src/main/assemblies/src.xml +++ b/distribution/src/main/assemblies/src.xml @@ -49,6 +49,7 @@ <exclude>core/res/**/*</exclude> <exclude>**/target</exclude> + <exclude>**/ftpserver.properties</exclude> <exclude>**/target/**/*</exclude> <exclude>**/.settings</exclude> <exclude>**/.settings/**/*</exclude>