def init(_error): if _error: return _error self._session_details[ 'authmethod'] = self._authmethod # from AUTHMETHOD, via base self._session_details['authextra'] = details.authextra return Challenge(self._authmethod)
def on_authenticate_ok(_principal): _error = self._assign_principal(_principal) if _error: return _error # now compute CHALLENGE.Extra and signature expected _extra, self._signature = self._compute_challenge(_principal) return Challenge(self._authmethod, _extra)
def test_challenge_mismatch(self): session = AsphaltSession('default', 'ticket', 'foo', 'bar', asyncio.Future()) challenge = Challenge('wampcra') exc = pytest.raises(WAMPError, session.onChallenge, challenge) assert str(exc.value) == ( 'expected authentication method "ticket" but received a ' '"wampcra" challenge instead')
def sign_challenge(self, challenge_method, challenge_extra, channel_id_raw, channel_id_type='tls-unique', details=None): challenge = Challenge(challenge_method, challenge_extra) data = format_challenge(challenge, channel_id_raw, channel_id_type) return sign_challenge(data, self._node._node_key.sign)
def test_wampcra_salted_challenge(self): session = AsphaltSession('default', 'wampcra', 'foo', 'bar', asyncio.Future()) challenge = Challenge( 'wampcra', { 'challenge': b'\xff\x00345jfsdf', 'salt': '5ihod', 'iterations': 5, 'keylen': 32 }) retval = session.onChallenge(challenge) assert isinstance(retval, bytes)
def on_authenticate_ok(principal): self._salt = binascii.a2b_hex( principal['salt']) # error if no salt per-user self._iterations = principal['iterations'] self._memory = principal['memory'] self._kdf = principal['kdf'] self._stored_key = binascii.a2b_hex(principal['stored-key']) # do we actually need the server-key? can we compute it ourselves? self._server_key = binascii.a2b_hex(principal['server-key']) error = self._assign_principal(principal) if error: return error # XXX TODO this needs to include (optional) channel-binding extra = self._compute_challenge() return Challenge(self._authmethod, extra)
def hello(self, realm: str, details: HelloDetails) -> Union[Accept, Deny, Challenge]: # remember the realm the client requested to join (if any) self._realm = realm # remember the authid the client wants to identify as (if any) self._authid = details.authid # define local helpers if self._config['type'] in ['dynamic', 'function']: def on_authenticate_ok(_principal): _error = self._assign_principal(_principal) if _error: return _error # now compute CHALLENGE.Extra and signature expected _extra, self._signature = self._compute_challenge(_principal) return Challenge(self._authmethod, _extra) def on_authenticate_error(err): return self._marshal_dynamic_authenticator_error(err) # use static principal database from configuration if self._config['type'] == 'static': self._authprovider = 'static' if self._authid in self._config.get('users', {}): principal = self._config['users'][self._authid] error = self._assign_principal(principal) if error: return error # now compute CHALLENGE.Extra and signature as # expected for WAMP-CRA extra, self._signature = self._compute_challenge(principal) return Challenge(self._authmethod, extra) else: return Deny(message='no principal with authid "{}" exists'. format(details.authid)) # use configured procedure to dynamically get a ticket for the principal elif self._config['type'] == 'dynamic': self._authprovider = 'dynamic' init_d = txaio.as_future(self._init_dynamic_authenticator) def init(result): if result: return result self._session_details[ 'authmethod'] = self._authmethod # from AUTHMETHOD, via base self._session_details['authid'] = details.authid self._session_details['authrole'] = details.authrole self._session_details['authextra'] = details.authextra d = self._authenticator_session.call(self._authenticator, realm, details.authid, self._session_details) d.addCallbacks(on_authenticate_ok, on_authenticate_error) return d init_d.addBoth(init) return init_d elif self._config['type'] == 'function': self._authprovider = 'function' init_d = txaio.as_future(self._init_function_authenticator) def init(result): if result: return result self._session_details[ 'authmethod'] = self._authmethod # from AUTHMETHOD, via base self._session_details['authid'] = details.authid self._session_details['authrole'] = details.authrole self._session_details['authextra'] = details.authextra auth_d = txaio.as_future(self._authenticator, realm, details.authid, self._session_details) auth_d.addCallbacks(on_authenticate_ok, on_authenticate_error) return auth_d init_d.addBoth(init) return init_d else: # should not arrive here, as config errors should be caught earlier return Deny( message= 'invalid authentication configuration (authentication type "{}" is unknown)' .format(self._config['type']))
def test_wampcra_challenge(self): session = AsphaltSession('default', 'wampcra', 'foo', 'bar', asyncio.Future()) challenge = Challenge('wampcra', {'challenge': b'\xff\x00345jfsdf'}) retval = session.onChallenge(challenge) assert isinstance(retval, bytes)
def test_ticket_challenge(self): session = AsphaltSession('default', 'ticket', 'foo', 'bar', asyncio.Future()) challenge = Challenge('ticket') assert session.onChallenge(challenge) == 'bar'
def hello(self, realm: str, details: HelloDetails) -> Union[Accept, Deny, Challenge]: # remember the realm the client requested to join (if any) self._realm = realm # remember the authid the client wants to identify as (if any) self._authid = details.authid # use static principal database from configuration if self._config['type'] == 'static': self._authprovider = 'static' if self._authid in self._config.get('principals', {}): principal = self._config['principals'][self._authid] principal['extra'] = details.authextra error = self._assign_principal(principal) if error: return error # now set signature as expected for WAMP-Ticket self._signature = principal['ticket'] return Challenge(self._authmethod) else: return Deny(message='no principal with authid "{}" exists'. format(self._authid)) # use configured procedure to dynamically get a ticket for the principal elif self._config['type'] == 'dynamic': self._authprovider = 'dynamic' init_d = as_future(self._init_dynamic_authenticator) def init(_error): if _error: return _error self._session_details[ 'authmethod'] = self._authmethod # from AUTHMETHOD, via base self._session_details['authextra'] = details.authextra return Challenge(self._authmethod) init_d.addBoth(init) return init_d elif self._config['type'] == 'function': self._authprovider = 'function' init_d = as_future(self._init_function_authenticator) def init(_error): if _error: return _error self._session_details[ 'authmethod'] = self._authmethod # from AUTHMETHOD, via base self._session_details['authextra'] = details.authextra return Challenge(self._authmethod) init_d.addBoth(init) return init_d else: # should not arrive here, as config errors should be caught earlier return Deny( message= 'invalid authentication configuration (authentication type "{}" is unknown)' .format(self._config['type']))