You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ftpserver-users@mina.apache.org by Sai Pullabhotla <sa...@jmethods.com> on 2011/04/05 23:27:55 UTC

Performing Certificate-only authentication with FTP/S server

Dear Developers,

I'm trying to make the FTPS authentication work without requiring a
password from the FTP clients. I was hoping to get the authentication
done with just user name and a client certificate. I thought may be I
could intercept the "before USER" command in an Ftplet, check the user
name, and the certificate, and if the certificate belongs to the user
(based on our internal database), update the FtpSession to set "login
completed".

So, I tried to use
FtpSession.setAttribute("org.apache.ftpserver.user", "MyUser").

The above call fails with IllegalArgumentException from
DefaultFtpSession.setAttribute(String, Object) method. It basically
does not allow manipulating the internal session attributes.

So, is there another way to accomplish what I need. In essence, the
FTP clients would connect (with a client certificate), and send the
USER command. They will never send the PASS command. As soon as I
receive the USER command, I should be able to determine if the user
should be considered logged in based on their user name and
certificate.

I appreciate any help you could provide on this.

Regards,
Sai Pullabhotla

Re: Performing Certificate-only authentication with FTP/S server

Posted by Sai Pullabhotla <sa...@jmethods.com>.
I forgot about not sending attachments to the list. Sorry about that.
I just opened a JIRA case and attached the preliminary patch to the
case. Please review the case
https://issues.apache.org/jira/browse/FTPSERVER-410.

Sai Pullabhotla



On Fri, Apr 15, 2011 at 12:35 PM, Sai Pullabhotla
<sa...@jmethods.com> wrote:
> I finally got some time to spend on this and here are my thoughts/a
> patch for review (not quite finished, but works):
>
> The requirements/assumptions:
>
> 1. Client uses a secure connection (either implicit or explicit SSL).
> 2. Client submits a trusted certificate during SSL handshake
> 3. Client submits a user name
> 4. If the server is configured to authenticate users without requiring
> passwords, it should let the user IN with the supplied user name and
> certificate.
> 5. Server might have been setup to authenticate users in the following ways -
>    a) Old fashioned way (user and password)
>    b) User name and certificate
>    c) Dual authentication (user name, certificate and password)
> 5. Individual users may have been configured with any of the
> authentication options described above (a, b or c). For example USER1
> is setup to use the option a. USER2 is setup to use option b. USER3 is
> setup to use option c.
>
> What does this patch do:
>
> 1. USER command invokes authenticate method on the registered
> UserManager. This might break backward compatibility. If it does and
> if we cannot afford it, we should be able to overcome this by creating
> UserManager2 extending UserManager. The USER command would then invoke
> the authenticate method if and only if the registered user manager is
> an instance of UserManager2. Otherwise, it would just do what it
> always did. Whether or not we create the new interface is up to us.
>
> 2. Created a subclass of AuthenticationFailedException. This exception
> is called PasswordRequiredException. If the UserManager cannot
> authenticate the user without a password(because of the server/user
> settings), it should throw this new exception.
>
> 3. If during the USER command execution, if it catches a
> PasswordRequiredException, it simply falls back to the old way, by
> sending a positive intermediate reply asking for the password. If it
> catches the AuthenticationFailedException, then we could either fall
> back to the old way, or send a negative completion reply indicating
> that the login failed. If the UserManager returns a valid User from
> the authenticate method, send a positive completion reply, and do what
> ever we normally do in the PASS command (such as setting up file
> system for the user etc).
>
> 5. A new implementation of Authentication, called
> UsernameAuthentication is used by the USER command performing the
> authentication. This is essentially same as the current
> UsernamePasswordAuthentication, minus the password. If a user manager
> does not care about this type of authentication, it can immediately
> throw a PasswordRequiredException. Other implementations would check
> the user authentication preferences for the user name, and act
> accordingly.
>
> In a nutshell, that is about it. I created an AbstractAuthentication
> to hold the user metadata, and concrete Authentication classes extend
> this abstract class. I also had to add a new flag to the UserMetadata
> to indicate if the session is secured or not. Eventually, we might
> just use the FtpSession in the UserMetadata so the authenticator can
> access any additional information from the session. Lastly, I don't
> think we want to affect the anonymous logins in anyway with this
> change, so I left it alone.
>
> Your feedback is appreciated.
>
> Thanks.
>
> Sai Pullabhotla
>
>
>
> On Wed, Apr 6, 2011 at 4:14 PM, Niklas Gustavsson <ni...@protocol7.com> wrote:
>> On Wed, Apr 6, 2011 at 6:22 PM, Sai Pullabhotla
>> <sa...@jmethods.com> wrote:
>>> Thanks, Niklas. Unfortunately we cannot control the clients. We were
>>> told that the client's are built to never send PASS command and expect
>>> either a 2XX reply on the USER command or 5XX reply. In other words,
>>> the server should perform the authentication soon after it receives
>>> the USER command (if the client was authenticated with digital
>>> certificates), and send a "230 logged in". If the client was not
>>> authenticated with digital certificate, then we need to fall back to
>>> the regular mode, and send a "331 password required" reply.
>>
>> Given FTP always requires the PASS command, even for anon users, I
>> find this client behavior a bit weird.
>>
>>> I guess, I will see if I can poke holes into the code and see if I can
>>> get it to work. Would you be willing to consider this as an
>>> enhancement and like to have the code submitted?
>>
>> Let's have a look at it when you're done :-)
>>
>> /niklas
>>
>

Re: Performing Certificate-only authentication with FTP/S server

Posted by Sai Pullabhotla <sa...@jmethods.com>.
I finally got some time to spend on this and here are my thoughts/a
patch for review (not quite finished, but works):

The requirements/assumptions:

1. Client uses a secure connection (either implicit or explicit SSL).
2. Client submits a trusted certificate during SSL handshake
3. Client submits a user name
4. If the server is configured to authenticate users without requiring
passwords, it should let the user IN with the supplied user name and
certificate.
5. Server might have been setup to authenticate users in the following ways -
    a) Old fashioned way (user and password)
    b) User name and certificate
    c) Dual authentication (user name, certificate and password)
5. Individual users may have been configured with any of the
authentication options described above (a, b or c). For example USER1
is setup to use the option a. USER2 is setup to use option b. USER3 is
setup to use option c.

What does this patch do:

1. USER command invokes authenticate method on the registered
UserManager. This might break backward compatibility. If it does and
if we cannot afford it, we should be able to overcome this by creating
UserManager2 extending UserManager. The USER command would then invoke
the authenticate method if and only if the registered user manager is
an instance of UserManager2. Otherwise, it would just do what it
always did. Whether or not we create the new interface is up to us.

2. Created a subclass of AuthenticationFailedException. This exception
is called PasswordRequiredException. If the UserManager cannot
authenticate the user without a password(because of the server/user
settings), it should throw this new exception.

3. If during the USER command execution, if it catches a
PasswordRequiredException, it simply falls back to the old way, by
sending a positive intermediate reply asking for the password. If it
catches the AuthenticationFailedException, then we could either fall
back to the old way, or send a negative completion reply indicating
that the login failed. If the UserManager returns a valid User from
the authenticate method, send a positive completion reply, and do what
ever we normally do in the PASS command (such as setting up file
system for the user etc).

5. A new implementation of Authentication, called
UsernameAuthentication is used by the USER command performing the
authentication. This is essentially same as the current
UsernamePasswordAuthentication, minus the password. If a user manager
does not care about this type of authentication, it can immediately
throw a PasswordRequiredException. Other implementations would check
the user authentication preferences for the user name, and act
accordingly.

In a nutshell, that is about it. I created an AbstractAuthentication
to hold the user metadata, and concrete Authentication classes extend
this abstract class. I also had to add a new flag to the UserMetadata
to indicate if the session is secured or not. Eventually, we might
just use the FtpSession in the UserMetadata so the authenticator can
access any additional information from the session. Lastly, I don't
think we want to affect the anonymous logins in anyway with this
change, so I left it alone.

Your feedback is appreciated.

Thanks.

Sai Pullabhotla



On Wed, Apr 6, 2011 at 4:14 PM, Niklas Gustavsson <ni...@protocol7.com> wrote:
> On Wed, Apr 6, 2011 at 6:22 PM, Sai Pullabhotla
> <sa...@jmethods.com> wrote:
>> Thanks, Niklas. Unfortunately we cannot control the clients. We were
>> told that the client's are built to never send PASS command and expect
>> either a 2XX reply on the USER command or 5XX reply. In other words,
>> the server should perform the authentication soon after it receives
>> the USER command (if the client was authenticated with digital
>> certificates), and send a "230 logged in". If the client was not
>> authenticated with digital certificate, then we need to fall back to
>> the regular mode, and send a "331 password required" reply.
>
> Given FTP always requires the PASS command, even for anon users, I
> find this client behavior a bit weird.
>
>> I guess, I will see if I can poke holes into the code and see if I can
>> get it to work. Would you be willing to consider this as an
>> enhancement and like to have the code submitted?
>
> Let's have a look at it when you're done :-)
>
> /niklas
>

Re: Performing Certificate-only authentication with FTP/S server

Posted by Niklas Gustavsson <ni...@protocol7.com>.
On Wed, Apr 20, 2011 at 1:55 PM, Sai Pullabhotla
<sa...@jmethods.com> wrote:
> I personally think adding the new interface is much cleaner,
> guarantees backward compatibility.

I think I agree. But, using a more descriptive name than sticking a
digit on the end :-)

/niklas

Re: Performing Certificate-only authentication with FTP/S server

Posted by Sai Pullabhotla <sa...@jmethods.com>.
I personally think adding the new interface is much cleaner,
guarantees backward compatibility.

Sai Pullabhotla



On Tue, Apr 19, 2011 at 4:48 PM, Niklas Gustavsson <ni...@protocol7.com> wrote:
> On Tue, Apr 19, 2011 at 6:27 PM, Sai Pullabhotla
> <sa...@jmethods.com> wrote:
>> Just wanted to address the comment made by Niklas that a password
>> should always be required:
>>
>> Just reading back the RFC 4217, and found this:
>>
>> Note 2: The PASS command might not be required at all (if the USER
>>   parameter and any client identity presented provide sufficient
>>   authentication).  The server would indicate this by issuing a '232'
>>   reply to the USER command instead of the '331', which requests a PASS
>>   from the client (see below).
>>
>> So, it looks like we now do have a standard.
>
> Good find! I still haven't gotten around to reviewing the patch, but
> having this spec makes me think we can include this in 1.1.x. For
> 1.1.x we need to maintain backwards compatibility. Perhaps if on
> calling authenticate on USER, if it throws FtpException (and not
> AuthenticationFailedException) or a RuntimeException, we treat that as
> authentication not supported and requires PASS. Or, we need a new
> interfaces.
>
> /niklas
>

Re: Performing Certificate-only authentication with FTP/S server

Posted by Niklas Gustavsson <ni...@protocol7.com>.
On Tue, Apr 19, 2011 at 6:27 PM, Sai Pullabhotla
<sa...@jmethods.com> wrote:
> Just wanted to address the comment made by Niklas that a password
> should always be required:
>
> Just reading back the RFC 4217, and found this:
>
> Note 2: The PASS command might not be required at all (if the USER
>   parameter and any client identity presented provide sufficient
>   authentication).  The server would indicate this by issuing a '232'
>   reply to the USER command instead of the '331', which requests a PASS
>   from the client (see below).
>
> So, it looks like we now do have a standard.

Good find! I still haven't gotten around to reviewing the patch, but
having this spec makes me think we can include this in 1.1.x. For
1.1.x we need to maintain backwards compatibility. Perhaps if on
calling authenticate on USER, if it throws FtpException (and not
AuthenticationFailedException) or a RuntimeException, we treat that as
authentication not supported and requires PASS. Or, we need a new
interfaces.

/niklas

Re: Performing Certificate-only authentication with FTP/S server

Posted by Sai Pullabhotla <sa...@jmethods.com>.
Just wanted to address the comment made by Niklas that a password
should always be required:

Just reading back the RFC 4217, and found this:

Note 2: The PASS command might not be required at all (if the USER
   parameter and any client identity presented provide sufficient
   authentication).  The server would indicate this by issuing a '232'
   reply to the USER command instead of the '331', which requests a PASS
   from the client (see below).

So, it looks like we now do have a standard.

Sai Pullabhotla



On Wed, Apr 6, 2011 at 4:14 PM, Niklas Gustavsson <ni...@protocol7.com> wrote:
> On Wed, Apr 6, 2011 at 6:22 PM, Sai Pullabhotla
> <sa...@jmethods.com> wrote:
>> Thanks, Niklas. Unfortunately we cannot control the clients. We were
>> told that the client's are built to never send PASS command and expect
>> either a 2XX reply on the USER command or 5XX reply. In other words,
>> the server should perform the authentication soon after it receives
>> the USER command (if the client was authenticated with digital
>> certificates), and send a "230 logged in". If the client was not
>> authenticated with digital certificate, then we need to fall back to
>> the regular mode, and send a "331 password required" reply.
>
> Given FTP always requires the PASS command, even for anon users, I
> find this client behavior a bit weird.
>
>> I guess, I will see if I can poke holes into the code and see if I can
>> get it to work. Would you be willing to consider this as an
>> enhancement and like to have the code submitted?
>
> Let's have a look at it when you're done :-)
>
> /niklas
>

Re: Performing Certificate-only authentication with FTP/S server

Posted by Niklas Gustavsson <ni...@protocol7.com>.
On Wed, Apr 6, 2011 at 6:22 PM, Sai Pullabhotla
<sa...@jmethods.com> wrote:
> Thanks, Niklas. Unfortunately we cannot control the clients. We were
> told that the client's are built to never send PASS command and expect
> either a 2XX reply on the USER command or 5XX reply. In other words,
> the server should perform the authentication soon after it receives
> the USER command (if the client was authenticated with digital
> certificates), and send a "230 logged in". If the client was not
> authenticated with digital certificate, then we need to fall back to
> the regular mode, and send a "331 password required" reply.

Given FTP always requires the PASS command, even for anon users, I
find this client behavior a bit weird.

> I guess, I will see if I can poke holes into the code and see if I can
> get it to work. Would you be willing to consider this as an
> enhancement and like to have the code submitted?

Let's have a look at it when you're done :-)

/niklas

Re: Performing Certificate-only authentication with FTP/S server

Posted by Sai Pullabhotla <sa...@jmethods.com>.
Thanks, Niklas. Unfortunately we cannot control the clients. We were
told that the client's are built to never send PASS command and expect
either a 2XX reply on the USER command or 5XX reply. In other words,
the server should perform the authentication soon after it receives
the USER command (if the client was authenticated with digital
certificates), and send a "230 logged in". If the client was not
authenticated with digital certificate, then we need to fall back to
the regular mode, and send a "331 password required" reply.

I guess, I will see if I can poke holes into the code and see if I can
get it to work. Would you be willing to consider this as an
enhancement and like to have the code submitted?

On Wed, Apr 6, 2011 at 10:52 AM, Niklas Gustavsson <ni...@protocol7.com> wrote:
> Hi
>
> My suggestion would be to let the client execute the PASS command with
> any password (blank, fixed, random). Then, implement UserManager and
> perform the certificate check in the authenticate() method. The
> certificate chain is included in the UsernamePasswordAuthentication
> object.
>
> We actually supported this out of the box with FtpServer at one time,
> but decided to remove it due to lack of a spec.
>
> /niklas
>
> On Tue, Apr 5, 2011 at 11:27 PM, Sai Pullabhotla
> <sa...@jmethods.com> wrote:
>> Dear Developers,
>>
>> I'm trying to make the FTPS authentication work without requiring a
>> password from the FTP clients. I was hoping to get the authentication
>> done with just user name and a client certificate. I thought may be I
>> could intercept the "before USER" command in an Ftplet, check the user
>> name, and the certificate, and if the certificate belongs to the user
>> (based on our internal database), update the FtpSession to set "login
>> completed".
>>
>> So, I tried to use
>> FtpSession.setAttribute("org.apache.ftpserver.user", "MyUser").
>>
>> The above call fails with IllegalArgumentException from
>> DefaultFtpSession.setAttribute(String, Object) method. It basically
>> does not allow manipulating the internal session attributes.
>>
>> So, is there another way to accomplish what I need. In essence, the
>> FTP clients would connect (with a client certificate), and send the
>> USER command. They will never send the PASS command. As soon as I
>> receive the USER command, I should be able to determine if the user
>> should be considered logged in based on their user name and
>> certificate.
>>
>> I appreciate any help you could provide on this.
>>
>> Regards,
>> Sai Pullabhotla
>>
>

Re: Performing Certificate-only authentication with FTP/S server

Posted by Niklas Gustavsson <ni...@protocol7.com>.
Hi

My suggestion would be to let the client execute the PASS command with
any password (blank, fixed, random). Then, implement UserManager and
perform the certificate check in the authenticate() method. The
certificate chain is included in the UsernamePasswordAuthentication
object.

We actually supported this out of the box with FtpServer at one time,
but decided to remove it due to lack of a spec.

/niklas

On Tue, Apr 5, 2011 at 11:27 PM, Sai Pullabhotla
<sa...@jmethods.com> wrote:
> Dear Developers,
>
> I'm trying to make the FTPS authentication work without requiring a
> password from the FTP clients. I was hoping to get the authentication
> done with just user name and a client certificate. I thought may be I
> could intercept the "before USER" command in an Ftplet, check the user
> name, and the certificate, and if the certificate belongs to the user
> (based on our internal database), update the FtpSession to set "login
> completed".
>
> So, I tried to use
> FtpSession.setAttribute("org.apache.ftpserver.user", "MyUser").
>
> The above call fails with IllegalArgumentException from
> DefaultFtpSession.setAttribute(String, Object) method. It basically
> does not allow manipulating the internal session attributes.
>
> So, is there another way to accomplish what I need. In essence, the
> FTP clients would connect (with a client certificate), and send the
> USER command. They will never send the PASS command. As soon as I
> receive the USER command, I should be able to determine if the user
> should be considered logged in based on their user name and
> certificate.
>
> I appreciate any help you could provide on this.
>
> Regards,
> Sai Pullabhotla
>