[Twisted-Python] (conch) credentials.signature always None?

Hi all, I'm experiencing something weird while writing a simple SSH server, and I wonder if anyone did run into this before: On every snippet I see around regarding public key authentication, the signature is checked as follows: # if not credentials.signature: # return failure.Failure(ValidPublicKey()) # try: # public_key = keys.Key.fromString(data=credentials.blob) # except (keys.BadKeyError, keys.EncryptedKeyError): # return failure.Failure(ConchError("Public key error")) However, I'm always getting None there and thus the authentication cannot proceed. I printed its value in the sshsimpleserver.py from the examples directory and same seems to be happening, so I guess it's not only my script :-S Any clue? Thanks in advance! -- /Saúl http://saghul.net | http://sipdoc.net

On Wed, Jan 19, 2011 at 6:55 PM, Saúl Ibarra Corretgé <saghul@gmail.com> wrote:
Hi all,
I'm experiencing something weird while writing a simple SSH server, and I wonder if anyone did run into this before:
On every snippet I see around regarding public key authentication, the signature is checked as follows:
# if not credentials.signature: # return failure.Failure(ValidPublicKey()) # try: # public_key = keys.Key.fromString(data=credentials.blob) # except (keys.BadKeyError, keys.EncryptedKeyError): # return failure.Failure(ConchError("Public key error"))
If it's not continuing, that's a problem with the other side. What happens with the SSH protocol is: C: sends a message asking 'if this public key okay?' without sending any signed data S: says either "no it's not valid for this account" or "yes it is valid, please prove you have the private key" C: if yes, sign some data and send the signature; otherwise try a different key or different authentication mechanism The 'if not credentials.signature: return failure.Failure(ValidPublicKey())' code is how the server tells the client it's a valid key, but needs to prove it also has the public key. -p -- Paul Swartz paulswartz at gmail dot com http://paulswartz.net/ AIM: z3penguin

Hi Paul, Thanks for that quick response! On Thu, Jan 20, 2011 at 1:06 AM, Paul Swartz <paulswartz@gmail.com> wrote:
On Wed, Jan 19, 2011 at 6:55 PM, Saúl Ibarra Corretgé <saghul@gmail.com> wrote:
Hi all,
I'm experiencing something weird while writing a simple SSH server, and I wonder if anyone did run into this before:
On every snippet I see around regarding public key authentication, the signature is checked as follows:
# if not credentials.signature: # return failure.Failure(ValidPublicKey()) # try: # public_key = keys.Key.fromString(data=credentials.blob) # except (keys.BadKeyError, keys.EncryptedKeyError): # return failure.Failure(ConchError("Public key error"))
If it's not continuing, that's a problem with the other side. What happens with the SSH protocol is:
C: sends a message asking 'if this public key okay?' without sending any signed data S: says either "no it's not valid for this account" or "yes it is valid, please prove you have the private key" C: if yes, sign some data and send the signature; otherwise try a different key or different authentication mechanism
The 'if not credentials.signature: return failure.Failure(ValidPublicKey())' code is how the server tells the client it's a valid key, but needs to prove it also has the public key.
My test was done wrong, my bad :-S I tested again and finally found the issue: I'm searching for the user's key in a DB and errors are handled in a errback. So ValidPublicKey was also handled there, incorrectly. I fixed it by doing the following: def _got_keys_error(self, error, credentials): if not error.check(ValidPublicKey): return failure.Failure(ConchError(error.getErrorMessage())) So now it does work :-) Thanks and regards, -- /Saúl http://saghul.net | http://sipdoc.net

On Jan 19, 2011, at 8:10 PM, Saúl Ibarra Corretgé wrote:
I fixed it by doing the following:
def _got_keys_error(self, error, credentials): if not error.check(ValidPublicKey): return failure.Failure(ConchError(error.getErrorMessage()))
Are you sure that's what you want? If you just say "I don't want to handle anything except FooError", i.e. the asynchronous equivalent to "except FooError", it's like this: def myErrback(self, f): f.trap(FooError) # ... handle it ...

On Thu, Jan 20, 2011 at 6:18 AM, Glyph Lefkowitz <glyph@twistedmatrix.com> wrote:
On Jan 19, 2011, at 8:10 PM, Saúl Ibarra Corretgé wrote:
I fixed it by doing the following:
def _got_keys_error(self, error, credentials): if not error.check(ValidPublicKey): return failure.Failure(ConchError(error.getErrorMessage()))
Are you sure that's what you want? If you just say "I don't want to handle anything except FooError", i.e. the asynchronous equivalent to "except FooError", it's like this: def myErrback(self, f): f.trap(FooError) # ... handle it ...
In this case I could get here (the errback) for several reasons, depending on the DB backend, for example. I guess I could trap and all the cases but ValidPrivateKey, but in this case I know for sure I want ValidPrivateKey to be ignored, that's why I reversed the order. Or am I missing something here? Thanks! -- /Saúl http://saghul.net | http://sipdoc.net

On Jan 20, 2011, at 1:56 AM, Saúl Ibarra Corretgé wrote:
In this case I could get here (the errback) for several reasons, depending on the DB backend, for example. I guess I could trap and all the cases but ValidPrivateKey, but in this case I know for sure I want ValidPrivateKey to be ignored, that's why I reversed the order. Or am I missing something here?
Nope, it sounds like you know what you're doing. The example just looked slightly fishy (there wasn't quite enough there for me to really know what you were doing) and I wanted to make sure you were familiar with the usual idiom. Sorry for the false alarm!
participants (3)
-
Glyph Lefkowitz
-
Paul Swartz
-
Saúl Ibarra Corretgé