crossbario / autobahn-python

WebSocket and WAMP in Python for Twisted and asyncio
https://crossbar.io/autobahn
MIT License
2.48k stars 766 forks source link

activation_code missing in wamp.auth.AuthCryptoSign #1304

Open om26er opened 4 years ago

om26er commented 4 years ago

For implementing custom authenticators, one may want to pass "extra information" while connecting. It seems AuthCryptoSign class does not allow that https://github.com/crossbario/autobahn-python/blob/108408cb1c274570e7e06f31427058a7b04c72fc/autobahn/wamp/auth.py#L160

I have a custom authenticator which saves the provided public key to "authorized keys" in my local db if the authextra dictionary contains a valid OTP pin, allowing to use a single wamp connection for pairing and connecting (i.e. no reconnects required)

Does the WAMP spec enforce that or any other reason we do that ? If not, then I'd like to remove that check.

meejah commented 4 years ago

I think the intention of authextra is that it is information for the authenticators themselves (and so cryptosign is checking because that's the only authextra keyword it understands).

I guess I'm kind of confused by the last part: if it's a custom authenticator, are you subclassing (or otherwise using) cryptosign somehow? Or, how does cryptosign come into this?

oberstet commented 4 years ago

Does the WAMP spec enforce that or any other reason we do that ?

in general, yes, the contents of authextra is completely defined by the authentication method.

that being said, in the specific case of WAMP-cryptosign: not yet completed in the spec text :( https://github.com/wamp-proto/wamp-proto/issues/230

I have a custom authenticator which saves the provided public key to "authorized keys" in my local db if the authextra dictionary contains a valid OTP pin, allowing to use a single wamp connection for pairing and connecting (i.e. no reconnects required)

you might use activation_code like cfx does https://github.com/crossbario/crossbarfx/blob/5f71235c0b497aa3c4e6b263d9234c3ea8e40609/crossbarfx/master/node/authenticator.py#L331

but regardless of above: seems like we're missing activation_code in https://github.com/crossbario/autobahn-python/blob/108408cb1c274570e7e06f31427058a7b04c72fc/autobahn/wamp/auth.py#L151 .. not sure why it actually works given that;)

meejah commented 4 years ago

I think activation_code etc work in cbfx because it implements its own onChallenge etc (i.e. instead of using the stuff referenced in this method, which basically grew out of and is used by Component)

meejah commented 4 years ago

....so maybe the real bug here is to spec-out what the "activation_code" and "request_new_activation_code" stuff in CBFX does and implement it in Autobahn? Still, though, this seems somewhat application-specific. Is there a way to make it more generic?

I haven't looked at this for a while, but the request_new_activation_code doesn't feel like it should be in authextra at all? It almost eems like it's command-line options leaking into the protocol: if a user wants a new activation code, there could be a (public) method that the client (CLI, JS) could call instead.

For the OTP thing, it seems almost like that should be a separate authentication method: you submit a valid OTP (with a public-key in authextra?), and that causes two things to happen: your session will be authorized and the public-key is put in local authorized-keys (so that a subsequent cryptosign auth succeeds). Can we write down the actual use-case for this? (Is it just a 2FA type thing like FreeOTP?)

Similarly for the activation-code: could that be its own custom authentication method, where you submit a (valid) activation-code (with a public-key in authextra?) and a similar thing happens (public-key goes in some kind of authorized keys, and session is authorized).

Perhaps it would be worth trying to spec-out this general need: that is, some kind of dance mediated through a human such that a public-key for an account is given to a crossbar-side authentication database. One way is using the "activation_code via email" method as CBFX does right now. Another might be magic-wormhole. I'm sure there are other, similar, ways?

oberstet commented 4 years ago

^ ah, right, it is actually 3 attributes in atuhextra that is processed by cryptosign:


I haven't looked at this for a while, but the request_new_activation_code doesn't feel like it should be in authextra at all?

not sure .. we could provide that via a WAMP proc, but then we need more logic to actually kick out idle anonymous sessions that simply do not call into that WAMP proc to request a new activation code.

whereas now, there are no actual anonymous sessions, since all clients always connect trying WAMP-cryptosign, and there are exactly 4 outcomes (leaving out invalid activation codes and such):

  1. pubkey is known => cryptosign succeeds and client session is fully identified and authenticated
  2. pubkey is not know and there no activation_code or request_new_activation_code at all given by the client =>client is denied, but an activation_code is sent
  3. pubkey is not known and a valid activation_code is given => the client pubkey is now verified and persisted in the CFX node DB. the client is fully identified and authenticated, and the session continues
  4. pubkey is not known. there is an outstanding activation code already, but request_new_activation_code is set => client is denied, but a new code is sent

Perhaps it would be worth trying to spec-out this general need: that is, some kind of dance mediated through a human such that a public-key for an account is given to a crossbar-side authentication database.

yes, exactly! that's what we need in general. would be best to have that of course then decscribed in the spec as well. *

One way is using the "activation_code via email" method as CBFX does right now. Another might be magic-wormhole. I'm sure there are other, similar, ways?

yep, agreed, there could be an even better way .. I haven't looked deep enough into magic-wormhole, but it could be exactly "the best" method to address ^ * ..

meejah commented 4 years ago

yep, agreed, there could be an even better way .. I haven't looked deep enough into magic-wormhole, but it could be exactly "the best" method to address ^ * ..

Honestly, I think it needs some more "user interface research" first. Basically, magic-wormhole comes from the core of the original Firefox Sync design .. their problem with that was that people didn't understand it and thus didn't use it properly. The design was great (IMO): pair different browsers and share bookmarks (etc) without any "accounts". However, ultimately this got shut down because users were confused (at least, as far as I know). So, definitely a method to keep an eye on, but I think we should keep the "activation code via email" for now because 1) it already works (!!) and 2) users are used to that dance (create account, get some link/code via email, ...) even if it's not as secure as it could be.

One way to "keep an eye on it" might be: maybe some student / grant etc would sponsor UX researchers to implement it into crossbar and see how users respond. But, I don't think we should implement magic-wormhole for production use right now.

A method we could implement now that's more secure than email would be "activation code via Signal" -- there is a command-line client, so it would be mostly "a simple matter of DevOps" to make this go and it's so similar to the email flow I don't think users would be confused.