[ 
https://issues.apache.org/jira/browse/FTPSERVER-277?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13039274#comment-13039274
 ] 

Bob Ziuchkovski commented on FTPSERVER-277:
-------------------------------------------

I would like to request support for this as well, but as Niklas mentioned, in a 
more integrated fashion.  Ideally it would be nice to have the following 
properties:

<nio-listener force-ssl="true">
<data-connection force-ssl="true">

If either of these has 'implicit-ssl="true"' set, then the force-ssl option 
essentially becomes a no-op.  Otherwise, SSL is forced before sensitive data 
can be sent.  When force-ssl is enabled on a control channel, respond something 
like '530 Access denied.' or '534 Insufficient data protection.' to all 
commands except for 'STARTTLS' (and perhaps FEAT?) from the client until the 
TLS connection is established.  'CCC' command would be rejected.  If force-ssl 
is enabled for the data channel, the client must send 'PROT P' prior to sending 
commands that would open a data channel connection.  If the 
client sends such commands before a 'PROT P', send back '534 Data protection 
required', and if the client sends a 'PROT C', respond '534 Insufficient data 
protection.'

I'll admit that I'm not 100% confident on the above responses. They are based 
only on my reading of the relevant RFCs.  However, something akin to this 
mechanism would wonderful.  My experience has been that explicit mode SSL 
appears to be supported on a wider variety of FTP clients than implicit mode.  
I would like to deploy our FTP services in explicit mode, but don't wish to 
give people the ability to shoot themselves in the foot by sending sensitive 
data in cleartext.

> Ftplet which forces TLS/SSL for control and data channels when using explicit 
> FTPS
> ----------------------------------------------------------------------------------
>
>                 Key: FTPSERVER-277
>                 URL: https://issues.apache.org/jira/browse/FTPSERVER-277
>             Project: FtpServer
>          Issue Type: New Feature
>          Components: Ftplets
>            Reporter: Niklas Therning
>            Assignee: Niklas Gustavsson
>            Priority: Minor
>             Fix For: 1.1.0
>
>
> I've developed a simple Ftplet which forces the client to use secure control 
> and data channels when the server has been configured for explicit FTPS. The 
> code has been pasted below. Let me know what you think about it. I've tried 
> it with curl and it seems to work as expected both for passive and active 
> data channels. Feel free to include it in Ftpserver if you find it useful.
> import java.io.IOException;
> import java.util.HashSet;
> import java.util.Set;
> import org.apache.ftpserver.ftplet.DefaultFtpReply;
> import org.apache.ftpserver.ftplet.FtpException;
> import org.apache.ftpserver.ftplet.FtpReply;
> import org.apache.ftpserver.ftplet.FtpRequest;
> import org.apache.ftpserver.ftplet.FtpSession;
> import org.apache.ftpserver.ftplet.Ftplet;
> import org.apache.ftpserver.ftplet.FtpletContext;
> import org.apache.ftpserver.ftplet.FtpletResult;
> /**
>  * {@link Ftplet} which forces the client to use secure control and data 
>  * channels when connecting in explicit FTPS mode. In implicit FTPS the 
> control 
>  * channel is always secure, however, the data channel can be plain text. This
>  * {@link Ftplet} will not allow clients to open insecure data channels in
>  * implicit FTPS mode.
>  *
>  * @version $Id$
>  */
> public class ExplicitSslForcingFtplet implements Ftplet {
>     private static final String SECURE = 
> ExplicitSslForcingFtplet.class.getName() + ".secure";
>     private static final Set<String> DATA_CHANNEL_COMMANDS;
>     
>     static {
>         DATA_CHANNEL_COMMANDS = new HashSet<String>();
>         DATA_CHANNEL_COMMANDS.add("APPE");
>         DATA_CHANNEL_COMMANDS.add("LIST");
>         DATA_CHANNEL_COMMANDS.add("MLSD");
>         DATA_CHANNEL_COMMANDS.add("NLST");
>         DATA_CHANNEL_COMMANDS.add("RETR");
>         DATA_CHANNEL_COMMANDS.add("STOR");
>         DATA_CHANNEL_COMMANDS.add("STOU");
>     }
>     public FtpletResult afterCommand(FtpSession session, FtpRequest request,
>             FtpReply reply) throws FtpException, IOException {
>         String cmd = request.getCommand().toUpperCase();
>         int code = reply.getCode();
>         if ("AUTH".equals(cmd) && code >= 200 && code < 300) {
>             session.setAttribute(SECURE, true);
>         }
>         
>         return FtpletResult.DEFAULT;
>     }
>     public FtpletResult beforeCommand(FtpSession session, FtpRequest request)
>             throws FtpException, IOException {
>         String cmd = request.getCommand().toUpperCase();
>         boolean secure = (Boolean) session.getAttribute(SECURE);
>         if ("USER".equals(cmd)) {
>             if (!secure) {
>                 session.write(new DefaultFtpReply(500, "Control channel not 
> secure. Issue AUTH command first."));
>                 return FtpletResult.SKIP;
>             }
>         } else if (DATA_CHANNEL_COMMANDS.contains(cmd)) {
>             if (!session.getDataConnection().isSecure()) {
>                 session.write(new DefaultFtpReply(500, "Data channel not 
> secure. Issue PROT command first."));
>                 return FtpletResult.SKIP;
>             }
>         }
>         return FtpletResult.DEFAULT;
>     }
>     public void destroy() {
>     }
>     public void init(FtpletContext ftpletContext) throws FtpException {
>     }
>     public FtpletResult onConnect(FtpSession session) throws FtpException,
>             IOException {
>         session.setAttribute(SECURE, session.isSecure());
>         return FtpletResult.DEFAULT;
>     }
>     public FtpletResult onDisconnect(FtpSession session) throws FtpException,
>             IOException {
>         
>         return FtpletResult.DEFAULT;
>     }
> }

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to