The attached patch file was designed with the following ideas in mind:
FTP commands accepted by the server should be implementable/filterable on a user-level basis. Certain private objects in classes such as NativeFileSystemView should be mode protected to allow greater customizations within user-created subclasses. At any point where a class can access a FTP connection, it should be able to query whether the connection has been secured or not. Matthew Schulze
diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/command/LIST.java new/trunk/core/src/java/org/apache/ftpserver/command/LIST.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/command/LIST.java 2007-08-22 14:15:31.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/command/LIST.java 2007-08-15 16:00:14.000000000 -0400 @@ -54,8 +54,8 @@ private final Logger LOG = LoggerFactory.getLogger(LIST.class); - private static final LISTFileFormater LIST_FILE_FORMATER = new LISTFileFormater(); - private DirectoryLister directoryLister = new DirectoryLister(); + protected static final LISTFileFormater LIST_FILE_FORMATER = new LISTFileFormater(); + protected DirectoryLister directoryLister = new DirectoryLister(); /** * Execute command. diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/DefaultCommandFactory.java new/trunk/core/src/java/org/apache/ftpserver/DefaultCommandFactory.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/DefaultCommandFactory.java 2007-08-22 14:15:32.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/DefaultCommandFactory.java 2007-08-15 15:52:09.000000000 -0400 @@ -25,6 +25,7 @@ import org.apache.ftpserver.ftplet.Component; import org.apache.ftpserver.ftplet.Configuration; import org.apache.ftpserver.ftplet.FtpException; +import org.apache.ftpserver.ftplet.FtpSession; import org.apache.ftpserver.interfaces.Command; import org.apache.ftpserver.interfaces.CommandFactory; import org.slf4j.Logger; @@ -126,7 +127,7 @@ /** * Get command. Returns null if not found. */ - public Command getCommand(String cmdName) { + public Command getCommand(String cmdName, FtpSession session) { if(cmdName == null || cmdName.equals("")) { return null; } diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/filesystem/NativeFileSystemView.java new/trunk/core/src/java/org/apache/ftpserver/filesystem/NativeFileSystemView.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/filesystem/NativeFileSystemView.java 2007-08-22 14:15:31.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/filesystem/NativeFileSystemView.java 2007-08-16 10:17:03.000000000 -0400 @@ -34,17 +34,17 @@ class NativeFileSystemView implements FileSystemView { // the root directory will always end with '/'. - private String rootDir; + protected String rootDir; // the first and the last character will always be '/' // It is always with respect to the root directory. - private String currDir; + protected String currDir; - private User user; + protected User user; //private boolean writePermission; - private boolean caseInsensitive = false; + protected boolean caseInsensitive = false; /** * Constructor - set the user object. diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/interfaces/CommandFactory.java new/trunk/core/src/java/org/apache/ftpserver/interfaces/CommandFactory.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/interfaces/CommandFactory.java 2007-08-22 14:15:27.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/interfaces/CommandFactory.java 2007-08-15 15:33:48.000000000 -0400 @@ -19,6 +19,8 @@ package org.apache.ftpserver.interfaces; +import org.apache.ftpserver.ftplet.FtpSession; + /** * Command factory interface. @@ -29,5 +31,5 @@ /** * Get the command instance. */ - Command getCommand(String commandName); + Command getCommand(String commandName, FtpSession session); } diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/Connection.java new/trunk/core/src/java/org/apache/ftpserver/listener/Connection.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/Connection.java 2007-08-22 14:15:28.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/listener/Connection.java 2007-08-15 16:21:10.000000000 -0400 @@ -58,5 +58,7 @@ void beforeSecureControlChannel(FtpServerSession session, String type) throws Exception; void afterSecureControlChannel(FtpServerSession session, String type) throws Exception; + + boolean isSecureControlChannel(); } diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/FtpProtocolHandler.java new/trunk/core/src/java/org/apache/ftpserver/listener/FtpProtocolHandler.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/FtpProtocolHandler.java 2007-08-22 14:15:28.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/listener/FtpProtocolHandler.java 2007-08-20 14:48:47.000000000 -0400 @@ -190,7 +191,7 @@ try { String commandName = request.getCommand(); CommandFactory commandFactory = serverContext.getCommandFactory(); - Command command = commandFactory.getCommand(commandName); + Command command = commandFactory.getCommand(commandName, session); if(command != null) { command.execute(connection, request, session, out); } diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/io/IOConnection.java new/trunk/core/src/java/org/apache/ftpserver/listener/io/IOConnection.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/io/IOConnection.java 2007-08-22 14:15:28.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/listener/io/IOConnection.java 2007-08-22 14:32:26.000000000 -0400 @@ -264,4 +264,8 @@ // do nothing } + + public boolean isSecureControlChannel() { + return controlSocket instanceof SSLSocket; + } } diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/mina/MinaConnection.java new/trunk/core/src/java/org/apache/ftpserver/listener/mina/MinaConnection.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/listener/mina/MinaConnection.java 2007-08-22 14:15:27.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/listener/mina/MinaConnection.java 2007-08-22 14:32:26.000000000 -0400 @@ -117,4 +117,8 @@ public void afterSecureControlChannel(FtpServerSession ftpSession, String type) throws Exception { // do nothing } + + public boolean isSecureControlChannel() { + return session.getFilterChain().contains("sslSessionFilter"); + } } diff -Naurw ftpserver/trunk/core/src/java/org/apache/ftpserver/listing/LISTFileFormater.java new/trunk/core/src/java/org/apache/ftpserver/listing/LISTFileFormater.java --- ftpserver/trunk/core/src/java/org/apache/ftpserver/listing/LISTFileFormater.java 2007-08-22 14:15:29.000000000 -0400 +++ new/trunk/core/src/java/org/apache/ftpserver/listing/LISTFileFormater.java 2007-08-10 17:05:12.000000000 -0400 @@ -28,8 +28,8 @@ */ public class LISTFileFormater implements FileFormater { - private final static char DELIM = ' '; - private final static char[] NEWLINE = {'\r', '\n'}; + protected final static char DELIM = ' '; + protected final static char[] NEWLINE = {'\r', '\n'}; /** * @see FileFormater#format(FileObject) @@ -59,7 +59,7 @@ /** * Get size */ - private String getLength(FileObject file) { + protected String getLength(FileObject file) { String initStr = " "; long sz = 0; if(file.isFile()) { @@ -75,14 +75,14 @@ /** * Get last modified date string. */ - private String getLastModified(FileObject file) { + protected String getLastModified(FileObject file) { return DateUtils.getUnixDate( file.getLastModified() ); } /** * Get permission string. */ - private char[] getPermission(FileObject file) { + protected char[] getPermission(FileObject file) { char permission[] = new char[10]; Arrays.fill(permission, '-');