You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Remy Maucherat <re...@exoffice.com> on 2000/05/13 02:33:58 UTC

[Catalina] Realm problem

I'm trying to implement HTTP digest authentication method, and I have
problems with the current design of the Realm interface.

Basically, the digest method involves generating a hash of a string (which
includes the user password), and comparing the result with a hash the client
has generated (using the same method). So the valve would have to know the
user's password, and therfore needs a way to retrieve it from the realm.
More specifically, the digest which has to be calculated is :
digest = MD5(MD5(username + ":" + realm + ":" + password) + ":" +
MD5(httpMethod + ":" + pathUri))
Then, this digest is compared to the one handed out by the client.

It could be implemented either :

- With a simple call to a new Realm.getPassword(String login)
- With a callback to a method of an interface the valve would implement.
Something like :
interface DigestGenerator {
    String digest(String password);
}
and adding a new authenticate function to the Realm :
boolean authenticate(String username, String digest, DigestGenerator
generator) {
 ....
}

Either way, the valve gets access to the user's password, which could raise
security issues, and neither of these two solutions look very clean to me
:-( I prefer the second one, though ...

Ideas anyone ?

Remy


Re: [Catalina] Realm problem

Posted by Remy Maucherat <re...@exoffice.com>.
> I've been looking at this also and ran into the same issue. I tried a
couple
> different things and found that extending Realm with a getPassword method
was
> the easiest. The next best thing was passing athenticate a MessageDigest
and
> having it do an update. I think that the original idea was that a parital
> digest (A1) would be stored instead of the password.

That adds a lot of overhead when doing basic (you have to calculate a hash
code with every request). And it might not work with other authentication
schemes ...
For those who don't want to read the RFC, I do a small translation : A1 =
username + ":" + realm + ":" + password, so the partial digest is MD5(A1).
Basically, without that, digest authentication is not possible.

> The only problem then is
> the user's password has to be stored for each realm they are in.

Definitely.

> I think
> storing the partial digest is the only "safe" way to go. I think sticking
> getPassword on Realm and doing the DIGEST so that people can store either
the
> plaintext password or the partial digest is good. This kind of throws
> everything to the person putting the app together. If they want tight
security
> they can spend the extra time/pain putting together a way to stick
pre-hashed
> passwords into their user store.

Ok, but then it's very hard / impossible to change the authentication
scheme.

Perhaps, instead of storing :
user/pass
we should store :
user/list of authentication tokens, with an authentication token being
name/value.
That way, if you want to do digest, you can look first for a token with
name="A1", then with name="plain" if no token with an "A1" name was found.

> Another small problem is that the DIGEST method needs a private key and a
> timeout. So the new way of auto-starting authentication methods doesn't
work
> well for it. No big deal since you can add it in by hand.

The private key could be :
- A param for the valve in the config file
- In a file on the HD
So I don't think it's a big deal ...

> The code I have works if you want it. I don't know how far along you are.
It
> is kind of messy and I've been short on time so I haven't been brave
enough to
> send it as a patch. :)

You added a Realm.getPassword function to make it work ?
Basically, that's all my implementation lacks (everything else is quite
straightforward).

Remy


Re: [Catalina] Realm problem

Posted by Carson McDonald <ca...@missiondata.com>.
I've been looking at this also and ran into the same issue. I tried a couple
different things and found that extending Realm with a getPassword method was
the easiest. The next best thing was passing athenticate a MessageDigest and
having it do an update. I think that the original idea was that a parital
digest (A1) would be stored instead of the password. The only problem then is 
the user's password has to be stored for each realm they are in. I think 
storing the partial digest is the only "safe" way to go. I think sticking 
getPassword on Realm and doing the DIGEST so that people can store either the 
plaintext password or the partial digest is good. This kind of throws 
everything to the person putting the app together. If they want tight security 
they can spend the extra time/pain putting together a way to stick pre-hashed 
passwords into their user store.

Another small problem is that the DIGEST method needs a private key and a
timeout. So the new way of auto-starting authentication methods doesn't work
well for it. No big deal since you can add it in by hand.

The code I have works if you want it. I don't know how far along you are. It
is kind of messy and I've been short on time so I haven't been brave enough to
send it as a patch. :) 


On Fri, May 12, 2000 at 05:33:58PM -0700, Remy Maucherat wrote:
> I'm trying to implement HTTP digest authentication method, and I have
> problems with the current design of the Realm interface.
> 
> Basically, the digest method involves generating a hash of a string (which
> includes the user password), and comparing the result with a hash the client
> has generated (using the same method). So the valve would have to know the
> user's password, and therfore needs a way to retrieve it from the realm.
> More specifically, the digest which has to be calculated is :
> digest = MD5(MD5(username + ":" + realm + ":" + password) + ":" +
> MD5(httpMethod + ":" + pathUri))
> Then, this digest is compared to the one handed out by the client.
> 
> It could be implemented either :
> 
> - With a simple call to a new Realm.getPassword(String login)
> - With a callback to a method of an interface the valve would implement.
> Something like :
> interface DigestGenerator {
>     String digest(String password);
> }
> and adding a new authenticate function to the Realm :
> boolean authenticate(String username, String digest, DigestGenerator
> generator) {
>  ....
> }
> 
> Either way, the valve gets access to the user's password, which could raise
> security issues, and neither of these two solutions look very clean to me
> :-( I prefer the second one, though ...
> 
> Ideas anyone ?
> 
> Remy
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
> 

Re: [Catalina] Realm problem

Posted by Remy Maucherat <re...@exoffice.com>.
> Remy Maucherat wrote:
>
> > I'm trying to implement HTTP digest authentication method, and I have
> > problems with the current design of the Realm interface.
> >
> > Basically, the digest method involves generating a hash of a string
(which
> > includes the user password), and comparing the result with a hash the
client
> > has generated (using the same method). So the valve would have to know
the
> > user's password, and therfore needs a way to retrieve it from the realm.
> > More specifically, the digest which has to be calculated is :
> > digest = MD5(MD5(username + ":" + realm + ":" + password) + ":" +
> > MD5(httpMethod + ":" + pathUri))

Small correction, I forgot the token, so it's actually :
digest = MD5(MD5(username + ":" + realm + ":" + password) + ":" + token +
":" + MD5(httpMethod + ":" + pathUri))

Of course, the real problem is that part MD5(username + ":" + realm + ":" +
password) since we can figure out everything but the password.

> In either case, what happens if the underlying security domain does not
store
> its passwords in cleartext (examples:  Unix password files, many LDAP
servers,
> password files generated by Apache'd "htpasswd" utility)?

Ouch, we really have a problem there ... And the client have no way of
knowing how he should encode / hash his password before generating the
hashed response.
As stated in the RFC (2069), the server MUST have access to either the clear
text password, or MD5(username + ":" + realm + ":" + password). So it seems
there will be realms on top of which there is no way to implement digest
:-((

I really wanted digest because it's quite a secure way to send your
password. It doesn't encrypt anything, on the other hand.

> We probably want to look at the issues related to SSL authentication as
well, to
> make sure we've got all of the required use cases covered;

You're right. I'll look into that (just like I did for digest).
Since AFAIK everything is encrypted in SSL, we'll have to intercept the
request, give out a fake request object, which would contain a fake input
stream (ie, each time a read is called, the fake input stream reads the data
on the real input stream and decrypts it) and a fake response which would do
the same for output. I don't think there's anything which would prevent the
valve from doing that (correct me if I'm wrong).
Additionally, Pier told me we shouldn't use JCA for implementing SSL,
because of export restrictions. Is it true ? That would be really bad,
because the work to do in such a case would have to be done outside of the
US, and involve reimplementing a big part of JCA ...

> but I agree that
> exposing the password should be prevented if its possible.

100% agreed. The best is of course never to manipulate clear text passwords.

Offtopic : I talked with Pier, and we'll be doing HTTP/1.1 together.

Remy


RE: [Catalina] Protocol Independence

Posted by Andy Riedel <an...@hearme.com>.
Great. This is definitely top priority. What is the team's current feeling
of difficulty of non-HTTP protocol development? Does the architecture feel
clean enough that it will fly?

Andy

-----Original Message-----
From: Remy Maucherat [mailto:remm@exoffice.com]
Sent: Friday, May 12, 2000 7:21 PM
To: tomcat-dev@jakarta.apache.org
Subject: Re: [Catalina] Protocol Independence


> Sorry I've been gone for a while. Looks like great progrss is being made
on
> Catalina. Anyone working on the development of protocols connectors, etc.
> for non-HTTP requests yet?

Not yet, right now, we're trying to have HTTP implemented the Right Way
(TM), with persistent connection support, and all the other HTTP/1.1
goodies.

Remy


---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: [Catalina] Protocol Independence

Posted by Remy Maucherat <re...@exoffice.com>.
> Sorry I've been gone for a while. Looks like great progrss is being made
on
> Catalina. Anyone working on the development of protocols connectors, etc.
> for non-HTTP requests yet?

Not yet, right now, we're trying to have HTTP implemented the Right Way
(TM), with persistent connection support, and all the other HTTP/1.1
goodies.

Remy


[Catalina] Protocol Independence

Posted by Andy Riedel <an...@hearme.com>.
Sorry I've been gone for a while. Looks like great progrss is being made on
Catalina. Anyone working on the development of protocols connectors, etc.
for non-HTTP requests yet?

Thanks,

Andy

-----Original Message-----
From: Craig R. McClanahan [mailto:Craig.McClanahan@eng.sun.com]
Sent: Friday, May 12, 2000 6:30 PM
To: tomcat-dev@jakarta.apache.org
Subject: Re: [Catalina] Realm problem


Remy Maucherat wrote:

> I'm trying to implement HTTP digest authentication method, and I have
> problems with the current design of the Realm interface.
>
> Basically, the digest method involves generating a hash of a string (which
> includes the user password), and comparing the result with a hash the
client
> has generated (using the same method). So the valve would have to know the
> user's password, and therfore needs a way to retrieve it from the realm.
> More specifically, the digest which has to be calculated is :
> digest = MD5(MD5(username + ":" + realm + ":" + password) + ":" +
> MD5(httpMethod + ":" + pathUri))
> Then, this digest is compared to the one handed out by the client.
>
> It could be implemented either :
>
> - With a simple call to a new Realm.getPassword(String login)
> - With a callback to a method of an interface the valve would implement.
> Something like :
> interface DigestGenerator {
>     String digest(String password);
> }
> and adding a new authenticate function to the Realm :
> boolean authenticate(String username, String digest, DigestGenerator
> generator) {
>  ....
> }
>
> Either way, the valve gets access to the user's password, which could
raise
> security issues, and neither of these two solutions look very clean to me
> :-( I prefer the second one, though ...

> Ideas anyone ?
>

In either case, what happens if the underlying security domain does not
store
its passwords in cleartext (examples:  Unix password files, many LDAP
servers,
password files generated by Apache'd "htpasswd" utility)?

We probably want to look at the issues related to SSL authentication as
well, to
make sure we've got all of the required use cases covered; but I agree that
exposing the password should be prevented if its possible.

>
> Remy
>

Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: [Catalina] Realm problem

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Remy Maucherat wrote:

> I'm trying to implement HTTP digest authentication method, and I have
> problems with the current design of the Realm interface.
>
> Basically, the digest method involves generating a hash of a string (which
> includes the user password), and comparing the result with a hash the client
> has generated (using the same method). So the valve would have to know the
> user's password, and therfore needs a way to retrieve it from the realm.
> More specifically, the digest which has to be calculated is :
> digest = MD5(MD5(username + ":" + realm + ":" + password) + ":" +
> MD5(httpMethod + ":" + pathUri))
> Then, this digest is compared to the one handed out by the client.
>
> It could be implemented either :
>
> - With a simple call to a new Realm.getPassword(String login)
> - With a callback to a method of an interface the valve would implement.
> Something like :
> interface DigestGenerator {
>     String digest(String password);
> }
> and adding a new authenticate function to the Realm :
> boolean authenticate(String username, String digest, DigestGenerator
> generator) {
>  ....
> }
>
> Either way, the valve gets access to the user's password, which could raise
> security issues, and neither of these two solutions look very clean to me
> :-( I prefer the second one, though ...

> Ideas anyone ?
>

In either case, what happens if the underlying security domain does not store
its passwords in cleartext (examples:  Unix password files, many LDAP servers,
password files generated by Apache'd "htpasswd" utility)?

We probably want to look at the issues related to SSL authentication as well, to
make sure we've got all of the required use cases covered; but I agree that
exposing the password should be prevented if its possible.

>
> Remy
>

Craig