[Twisted-Python] Questions about the Perspective Broker login mechanism

Hi readers,
I'm looking for the person who implements the actual version of the login mechanism in the Perspective Broker. More precisely, I wonder what are the reasons to have chosen a challenge/response strategy to do login.
I use the Perspective Broker in a project and before modifying anything, I want to be sure of what I do.
Thank you for your attention, Julien.

Julien Peeters jj.peeters@gmail.com writes:
I'm looking for the person who implements the actual version of the login mechanism in the Perspective Broker. More precisely, I wonder what are the reasons to have chosen a challenge/response strategy to do login.
I'm only a user of Twisted and not a core developer, but I suspect for all the same reasons you'd choose such a system in general (which aren't PB, nor Twisted, specific). Avoiding the transmission of raw authentication information in favor of generated information such as challenge/response data helps prevent a slew of possible attacks (injection, playback, man-in-the-middle, etc...) when such information is available on the wire.
Note however that if you're implying that PB authentication must be challenge/response, that's not entirely accurate. While it's true the default Portal and ClientFactory implementations make use of a challenge/response approach, you could just as easily change that to be whatever you would like including simple clear text transmission of authentication information in one step. And that exchange is distinct from the credential checker itself so can be replaced without changing anything else.
Why you'd bother (when challenge/response is implemented for free) is another question, but it's certainly possible. I suppose if you're using an SSL link for the PB connection with appropriate certificates you could consider the challenge/response an extra round trip, but it's got to be pretty insignificant compared to the overall session.
-- David

Why you'd bother (when challenge/response is implemented for free) is another question, but it's certainly possible. I suppose if you're using an SSL link for the PB connection with appropriate certificates you could consider the challenge/response an extra round trip, but it's got to be pretty insignificant compared to the overall session.
-- David
I don't especially use/want a SSL link. But I would like to use different hash methods than md5 based ones. For instance, I'll possibly need SHA or MD5CRYPT (I don't know if it's compatible with md5) hash methods. Or why not any other one...
Then, I would like to use different credentials and to the other side, different login method to be compatible with credentials I use. The actual implementation force to use md5 hash method. It's what I'm looking for to change if I find a good way to do what I habe in mind.
Julien.

Julien Peeters jj.peeters@gmail.com writes:
Why you'd bother (when challenge/response is implemented for free) is another question, but it's certainly possible. I suppose if you're using an SSL link for the PB connection with appropriate certificates you could consider the challenge/response an extra round trip, but it's got to be pretty insignificant compared to the overall session.
-- David
I don't especially use/want a SSL link. But I would like to use different hash methods than md5 based ones. For instance, I'll possibly need SHA or MD5CRYPT (I don't know if it's compatible with md5) hash methods. Or why not any other one...
Of course you're certainly allowed to prefer something else, although you might want to consider if the effort is worth it. MD5CRYPT is just an MD5 version of the classic Unix crypt() approach, including salt, so isn't compatible with a direct MD5 hash. But the PB approach already has the random challenge as a salt, so MD5CRYPT shouldn't be any more robust than the current approach - probably slightly less so since it doesn't have the double hash of the password. But it would be compatible with Unix systems using MD5CRYPT for their passwd entries if you were trying to compare directly to local entries.
If you're avoiding MD5 simply because it's been shown to no longer be cryptographically secure (collisions can be generated for a given hash), it's still worth considering what impact that really has on this mechanism's use of MD5.
While I'm not a cryptology expert (and I suspect analyzing such vulnerabilities is often distinctly non-intuitive), with respect to passwords, I believe the biggest exposure with MD5 is those systems that store a direct MD5 hash of a password that an intruder can obtain and then attempt attacks on by trying to produce alternate passwords that will hash to the same value (and in some approaches, backtrack to the true original password). I'm not sure that sort of attack would practically be launched against PB. In particular, salts help defend against that sort of attack.
For a PB session, the most common attack would be an attacker attempting to impersonating a client, in which case all they'll have access to is the random challenge. Without seeing an actual response, they've no hash to try to duplicate, and I'm not sure that the MD5 vulnerability comes into play at all.
If you're concerned about attackers with physical access to your network and/or packet flow, things get messier. If the attacker is using a man-in-the-middle attack, I'm not sure they'd even bother with attacking the password - just let the challenge and response flow through, and then observe the traffic, or hijack the session once established without ever figuring out the password.
If they didn't want control of the session, but just wanted the password for other purposes, they could sniff traffic, and obtain the challenge and response (and obviously have access to the source code available to see how they're combined), but would have to deal with the response having a hash of a hash for the password component. I know it makes use of the MD5 vulnerability more difficult, but may not prevent its use entirely.
To be honest though, if I were really concerned with the latter two cases - traffic interception/sniffing - I'd go right for link level security (SSL with certificate verification on both ends), since even with any other hash why give an attacker access to any of the hash information if not necessary. And no authentication system will protect against a man-in-the-middle attack hijacking a session once established.
Then, I would like to use different credentials and to the other side, different login method to be compatible with credentials I use. The actual implementation force to use md5 hash method. It's what I'm looking for to change if I find a good way to do what I habe in mind.
I'm not sure you need to change the login method signature, since it's just passing an arbitrary credentials object which can be as complex as you want. But sure, you can make up your own checker interface to match your particular credential information. Similar to how PB implements the IUsernameMD5Password checker to incorporate the MD5 operation.
So, feel free to have at it. There are probably a few ways you could take control, but I were doing it, I'd probably take my Portal subclass and make it directly implement IPBRoot (thus avoiding the registered adapter _PortalRoot). Then use the existing classes (_PortalWrapper, _PortalAuthChallenger) as a model and/or subclass them, and build your own process from the IPBRoot rootObject() call. You'd be in complete control and can do anything you'd like.
If you haven't already, you might just start out with using the existing implementation since it'll be easy enough to replace out later and you might find that there are other aspects of the system that deserve attention before delving too deeply into the very initial authentication.
-- David

On Sun, 19 Aug 2007 16:37:01 -0400, David Bolen db3l.net@gmail.com wrote:
[snip]
So, feel free to have at it. There are probably a few ways you could take control, but I were doing it, I'd probably take my Portal subclass and make it directly implement IPBRoot (thus avoiding the registered adapter _PortalRoot). Then use the existing classes (_PortalWrapper, _PortalAuthChallenger) as a model and/or subclass them, and build your own process from the IPBRoot rootObject() call. You'd be in complete control and can do anything you'd like.
I generally agree with the comments you've made here, except for this paragraph. Don't subclass Portal (ever, preferably ;). Just make an entirely new class which implements IPBRoot. If appropriate (as it likely will be), let that class wrap a Portal instance. eg,
portal = Portal(...) ... factory = PBServerFactory(YourRoot(portal))
Jean-Paul

Jean-Paul Calderone exarkun@divmod.com writes:
On Sun, 19 Aug 2007 16:37:01 -0400, David Bolen db3l.net@gmail.com wrote:
[snip]
So, feel free to have at it. There are probably a few ways you could take control, but I were doing it, I'd probably take my Portal subclass and make it directly implement IPBRoot (thus avoiding the registered adapter _PortalRoot). (...)
I generally agree with the comments you've made here, except for this paragraph. Don't subclass Portal (ever, preferably ;). (...)
Hmm, not that I've actually ever needed to yet myself, but is there something specifically about Portal that prefers composition to subclassing, or is it just a general design preference?
-- David

David Bolen db3l.net@gmail.com writes:
Hmm, not that I've actually ever needed to yet myself, but is there something specifically about Portal that prefers composition to subclassing, or is it just a general design preference?
Just to respond to my own post - finally noticed the comment in the Portal class about not being designed for subclassing, so certainly based on the expressed intent that's enough of a reason not too. Although I'm probably still curious as to why.
-- David

On 09:16 pm, db3l.net@gmail.com wrote:
David Bolen db3l.net@gmail.com writes:
Hmm, not that I've actually ever needed to yet myself, but is there something specifically about Portal that prefers composition to subclassing, or is it just a general design preference?
Just to respond to my own post - finally noticed the comment in the Portal class about not being designed for subclassing, so certainly based on the expressed intent that's enough of a reason not too. Although I'm probably still curious as to why.
The portal is simply a utility class for composing an IRealm provider with some ICredentialsChecker providers. The behavior in Portal itself is designed to be static, and decidable (in an ideal situation) by the administrator.
In other words, realms and credentials checkers should be arbitrarily "remixable"; you should not implement one to depend on the other.
If you start messing with the behavior of Portal, just about the only thing you *can* do is introduce an unnecessary dependency that makes either your checker or your realm unusable by someone else in their own application.

glyph@divmod.com writes:
(...)
In other words, realms and credentials checkers should be arbitrarily "remixable"; you should not implement one to depend on the other.
If you start messing with the behavior of Portal, just about the only thing you *can* do is introduce an unnecessary dependency that makes either your checker or your realm unusable by someone else in their own application.
Fair enough ... and in the end, my original suggested use of a subclass wasn't really intended to augment the Portal interface behavior, but rather produce a single object satisfying both the Portal and IPBRoot interfaces. Given the application (and that those interfaces aren't really related aspects of anything), that desire seems to fit more cleanly with composition than inheritance anyway.
-- David

On Sun, 2007-08-19 at 16:37 -0400, David Bolen wrote:
I'm not sure you need to change the login method signature, since it's just passing an arbitrary credentials object which can be as complex as you want. But sure, you can make up your own checker interface to match your particular credential information. Similar to how PB implements the IUsernameMD5Password checker to incorporate the MD5 operation.
So, feel free to have at it. There are probably a few ways you could take control, but I were doing it, I'd probably take my Portal subclass and make it directly implement IPBRoot (thus avoiding the registered adapter _PortalRoot). Then use the existing classes (_PortalWrapper, _PortalAuthChallenger) as a model and/or subclass them, and build your own process from the IPBRoot rootObject() call. You'd be in complete control and can do anything you'd like.
If you haven't already, you might just start out with using the existing implementation since it'll be easy enough to replace out later and you might find that there are other aspects of the system that deserve attention before delving too deeply into the very initial authentication.
-- David
For the moment, except I make a mistake, only credentials which implements IUsernamePassword are supported by the PBClientFactory.login method. Then if, for instance, passwords are stored with a SHA hash method, I can't use it as it is.
Another case in which the implementation present for the moment does not permit another credentials to be use: for instance, if the credentials are based, on an other strategy than the username/password one, I think it couldn't work too.
May be I misunderstood some important points. And at least a part of what I've talk just before is possible.
What I would be able to do is to arbitrary choice any credentials, and at the other side, that any checker which is able to check this credentials is possible to use (I think it's already O.K. for the checker part).
I thought at a solution, but I don't really know if it is a good one (both from a design and security point of view). And in the case I made a mistake in my comprehension, it would be useless.
May be it's possible to put a kind of "credential remote reference" at the server side which serve as a proxy for the real credential. Form a security point of view it's all right because remote reference does not transmit data but juste provide remote method calls. And then, instead of give the _PortalAuthChallenger to the portal as the credentials, that proxy would be given. The proxy have to implement the same ICredentials interface to be compatible with the checker. And it have also to implement a "zero-knowledge password proof" mechanism (response/challenge) to communicate with the real credentials to preserve security.
This solution is based on the existing one. And may be would be more flexible? Why not a starting point for an effective solution?
Julien.

Julien Peeters jj.peeters@gmail.com writes:
For the moment, except I make a mistake, only credentials which implements IUsernamePassword are supported by the PBClientFactory.login method. Then if, for instance, passwords are stored with a SHA hash method, I can't use it as it is.
Ah, I see - sorry I missed that. Yup, so I agree you may want to override that portion of PBClientFactory (and perhaps the matching remote_login in PBServerFactory) in your own mechanism as well.
It's possible the existing signature might still work even with a hashed password, since the password field from the supplied credentials are passed unchanged to the challenge response generation function, with nothing other than the client/server shared challenge/response implementation caring that it is clear text, but that does sort of "bend" the interface for IUsernamePassword so it's probably clearer to implement your own.
(...) May be it's possible to put a kind of "credential remote reference" at the server side which serve as a proxy for the real credential. Form a security point of view it's all right because remote reference does not transmit data but juste provide remote method calls.
Not sure this is a big win, since at some point in time you need to transfer over the actual credentials used for authentication anyway. So it's really a tradeoff between an established remote object method interface (to retrieve the credentials) or the type of credential object transmitted in general when sent as copyable data. Toss up, but you're free to try either approach.
And then, instead of give the _PortalAuthChallenger to the portal as the credentials, that proxy would be given. The proxy have to implement the same ICredentials interface to be compatible with the checker. And it have also to implement a "zero-knowledge password proof" mechanism (response/challenge) to communicate with the real credentials to preserve security.
This solution is based on the existing one. And may be would be more flexible? Why not a starting point for an effective solution?
Why not indeed? If I were you and I had convinced myself the authentication approach was worth replacing in my application (per my last response) at this point I'd just go ahead and do some implementation to see how it goes. You can certainly achieve everything you're talking about by just overriding some of the existing default behavior.
-- David

On Mon, 2007-08-20 at 12:47 -0400, David Bolen wrote:
Julien Peeters jj.peeters@gmail.com writes:
For the moment, except I make a mistake, only credentials which implements IUsernamePassword are supported by the PBClientFactory.login method. Then if, for instance, passwords are stored with a SHA hash method, I can't use it as it is.
Ah, I see - sorry I missed that. Yup, so I agree you may want to override that portion of PBClientFactory (and perhaps the matching remote_login in PBServerFactory) in your own mechanism as well.
It's possible the existing signature might still work even with a hashed password, since the password field from the supplied credentials are passed unchanged to the challenge response generation function, with nothing other than the client/server shared challenge/response implementation caring that it is clear text, but that does sort of "bend" the interface for IUsernamePassword so it's probably clearer to implement your own.
Yes, It's what I noticed. When you use a username/password strategy it's all right. With a precision that the password have to be hashed with the same method with which the stored password at the ckercker side is hashed.
In the case of other type of credentials, it's not so trivial.
(...) May be it's possible to put a kind of "credential remote reference" at the server side which serve as a proxy for the real credential. Form a security point of view it's all right because remote reference does not transmit data but juste provide remote method calls.
Not sure this is a big win, since at some point in time you need to transfer over the actual credentials used for authentication anyway. So it's really a tradeoff between an established remote object method interface (to retrieve the credentials) or the type of credential object transmitted in general when sent as copyable data. Toss up, but you're free to try either approach.
And so. I noticed that the solution I proposed does not correctly work because the "proxy" have to implements the interface the checker match for. And it's impossible to do cleanly.
And then, instead of give the _PortalAuthChallenger to the portal as the credentials, that proxy would be given. The proxy have to implement the same ICredentials interface to be compatible with the checker. And it have also to implement a "zero-knowledge password proof" mechanism (response/challenge) to communicate with the real credentials to preserve security.
This solution is based on the existing one. And may be would be more flexible? Why not a starting point for an effective solution?
Why not indeed? If I were you and I had convinced myself the authentication approach was worth replacing in my application (per my last response) at this point I'd just go ahead and do some implementation to see how it goes. You can certainly achieve everything you're talking about by just overriding some of the existing default behavior.
In theory all is possible. But it's an other challenge that to find a good and clean way to do it :-).
I interested in all propositions if someone have any ideas.
Julien.

Julien Peeters jj.peeters@gmail.com writes:
In theory all is possible. But it's an other challenge that to find a good and clean way to do it :-).
I interested in all propositions if someone have any ideas.
Maybe I missed it, but it sounded like "it" was just using an alternate hashing algorithm, for which an approach towards doing that is what I think we've covered, no?
Perhaps it might be clearer if you restated your needs and/or goal for an alternate method of authentication - that might prompt more helpful responses.
-- David

On Mon, 2007-08-20 at 15:02 -0400, David Bolen wrote:
Julien Peeters jj.peeters@gmail.com writes:
In theory all is possible. But it's an other challenge that to find a good and clean way to do it :-).
I interested in all propositions if someone have any ideas.
Maybe I missed it, but it sounded like "it" was just using an alternate hashing algorithm, for which an approach towards doing that is what I think we've covered, no?
I'm sorry, I done an English mistake may be (I'm not a native english speaker). When I talked about another "challenge", I talked about the support of any credentials (different from username/password).
I agree that the use of different hashing algorithm is trivial. However, that's important to notice that the credentials at the client side have to hash the password given by the user, if this last one is given as clear text.
Perhaps it might be clearer if you restated your needs and/or goal for an alternate method of authentication - that might prompt more helpful responses.
In the end, my main interest is to be able to use any credentials I want. By for the moment, use any hashing algorithm is already positive ;-) .
Julien.
participants (4)
-
David Bolen
-
glyph@divmod.com
-
Jean-Paul Calderone
-
Julien Peeters