How should support for alternate credential types in twisted.pb be implemented?
My project has been trying to implement a credential checker using scrypt. We've tried implementing our own credentials and checker objects, but we've had a lot of trouble getting pb to use them.
Pb seems hard-coded to use MD5 hashes over the wire, which absolutely won't work in our implementation; we don't have a way to get the correct password in plaintext on the serve开发者_如何学Cr side, since we're using scrypt, so we need a way to transmit the password to be verified in plaintext instead. We've tried using twisted.cred.credentials.UsernamePassword with our credential checker, but it doesn't seem to make it to the server. (we still get _PortalAuthChallenger instead)
The ticket at http://twistedmatrix.com/trac/ticket/4398 seems to indicate that a PBServerFactory subclass is needed in order to support custom credential checkers in pb, but so far I have been completely unable to figure out what to override in order to make it use a different ICredentials implementation. Are there any examples (or even just documentation) of how to get pb to use a different credentials class?
PB isn't exactly hard-coded to use MD5 hashes over the wire; that's just the authentication protocol as it's currently implemented. You can do pretty much whatever you want by implementing your own authentication protocol - which, in PB, just means an object that you get to call some authentication methods on.
Make your own object that implements IPBRoot
, and pass it to PBServerFactory
. This just means you need to implement a method called rootObject
which returns the root object for a particular connection (and then declare that implementation with Zope Interface, of course).
Your IPBRoot
implementation should wrap a Portal
, similar to similar to _PortalRoot
in Twisted's implementation.
Then, make a remote method on the object returned from rootObject
suitable to your application; maybe something like remote_loginPlaintext
. In this method you can authenticate users however you want, then call login
on your particular Portal
with whatever credentials are derived from that interaction and make sense for your requirements (and whatever interface, although for hopefully obvious reasons, IPerspective
is what I'd recommend).
The fact that the somewhat inflexible _PortalRoot
(which only supports 2 credential types; IAnonymous
and IUsernamePassword
) is registered as the adapter for Portal
, making it seem a bit more official than it really is. Don't think of it is as the "official" PB/Cred integration mechanism, just the "default" one.
It would be great if you could contribute a more flexible authentication mechanism (perhaps a full SASL implementation?) for PB so that we could support other authentication types. I hope that you'll consider doing that when your application's particular needs are met.
Here's a link to the preliminary fix we came up with: http://paste.skewedaspect.com/show/20/
Note that this requires the custom credential to be Copyable, and allows the default MD5 key exchange behavior to be controlled by the keyword arg useMD5Challenge.
Note: in our implementation we're leaving the checking entirely to the Checker and having our Credential object contain nothing but username and password, so no actual code is being serialized.
精彩评论