def test_process_with_authorization_id_or_identity(self): challenge = u"\U0001F44D" identity = 'user2' # Test that we can pass an identity sasl_kwargs = self.sasl_kwargs.copy() sasl_kwargs.update({'identity': identity}) sasl = SASLClient('localhost', mechanism=self.mechanism_class.name, **sasl_kwargs) response = sasl.process(challenge) self.assertEqual( response, six.b('{0}\x00{1}\x00{2}'.format(identity, self.username, self.password))) self.assertIsInstance(response, six.binary_type) # Test that the sasl authorization_id has priority over identity auth_id = 'user3' sasl_kwargs.update({'authorization_id': auth_id}) sasl = SASLClient('localhost', mechanism=self.mechanism_class.name, **sasl_kwargs) response = sasl.process(challenge) self.assertEqual( response, six.b('{0}\x00{1}\x00{2}'.format(auth_id, self.username, self.password))) self.assertIsInstance(response, six.binary_type)
def test_init(self): # defaults SASLClient('localhost') # with mechanism sasl_client = SASLClient('localhost', mechanism=AnonymousMechanism.name) self.assertIsInstance(sasl_client._chosen_mech, AnonymousMechanism) self.assertIs(sasl_client._chosen_mech.sasl, sasl_client) # invalid mech self.assertRaises(SASLError, SASLClient, 'localhost', mechanism='WRONG')
def authenticate_xmpp(self): """Authenticate the user to the XMPP server via the BOSH connection.""" self.request_sid() self.log.debug('Prepare the XMPP authentication') # Instantiate a sasl object sasl = SASLClient(host=self.to, service='xmpp', username=self.jid, password=self.password) # Choose an auth mechanism sasl.choose_mechanism(self.server_auth, allow_anonymous=False) # Request challenge challenge = self.get_challenge(sasl.mechanism) # Process challenge and generate response response = sasl.process(base64.b64decode(challenge)) # Send response success = self.send_challenge_response(response) if not success: return False self.request_restart() self.bind_resource() return True
def __init__(self, transport, host, service, mechanism=six.u('GSSAPI'), generate_tickets=False, using_keytab=False, principal=None, keytab_file=None, ccache_file=None, password=None, **sasl_kwargs): """ transport: an underlying transport to use, typically just a TSocket host: the name of the server, from a SASL perspective service: the name of the server's service, from a SASL perspective mechanism: the name of the preferred mechanism to use All other kwargs will be passed to the puresasl.client.SASLClient constructor. """ self.transport = transport if six.PY3: self._patch_pure_sasl() self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) self.__wbuf = BytesIO() self.__rbuf = BytesIO() self.generate_tickets = generate_tickets if self.generate_tickets: self.krb_context = krbContext(using_keytab, principal, keytab_file, ccache_file, password) self.krb_context.init_with_keytab()
def __init__(self, host, service, qops, properties): properties = properties or {} self.sasl = SASLClient(host, service, 'GSSAPI', qops=qops, **properties)
def test_choose_mechanism(self): client = SASLClient('localhost', service='something') choices = ['invalid'] self.assertRaises(SASLError, client.choose_mechanism, choices) choices = [m for m in mechanisms.values() if m is not DigestMD5Mechanism] mech_names = set(m.name for m in choices) client.choose_mechanism(mech_names) self.assertIsInstance(client._chosen_mech, max(choices, key=lambda m: m.score)) anon_names = set(m.name for m in choices if m.allows_anonymous) client.choose_mechanism(anon_names) self.assertIn(client.mechanism, anon_names) self.assertRaises(SASLError, client.choose_mechanism, anon_names, allow_anonymous=False) plain_names = set(m.name for m in choices if m.uses_plaintext) client.choose_mechanism(plain_names) self.assertIn(client.mechanism, plain_names) self.assertRaises(SASLError, client.choose_mechanism, plain_names, allow_plaintext=False) not_active_names = set(m.name for m in choices if not m.active_safe) client.choose_mechanism(not_active_names) self.assertIn(client.mechanism, not_active_names) self.assertRaises(SASLError, client.choose_mechanism, not_active_names, allow_active=False) not_dict_names = set(m.name for m in choices if not m.dictionary_safe) client.choose_mechanism(not_dict_names) self.assertIn(client.mechanism, not_dict_names) self.assertRaises(SASLError, client.choose_mechanism, not_dict_names, allow_dictionary=False)
def test_init_basic(self, *args): sasl = SASLClient('localhost', mechanism=self.mechanism_class.name, **self.sasl_kwargs) mech = sasl._chosen_mech self.assertIs(mech.sasl, sasl) self.assertIsInstance(mech, self.mechanism_class)
def __init__(self, transport, host, service, mechanism='GSSAPI', **sasl_kwargs): from puresasl.client import SASLClient self.transport = transport self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) self.__wbuf = BufferIO() self.__rbuf = BufferIO(b'')
def authenticate_xmpp(self): """Authenticate the user to the XMPP server via the BOSH connection.""" self.request_sid() self.log.debug('Prepare the XMPP authentication') # Instantiate a sasl object sasl = SASLClient(host=self.to, service='xmpp', username=self.jid, password=self.password) # Choose an auth mechanism sasl.choose_mechanism(self.server_auth, allow_anonymous=False) # Request challenge challenge = self.get_challenge(sasl.mechanism) # Process challenge and generate response challengeString = base64.b64decode(challenge) if not 'realm=' in challengeString: challengeString += ',realm="random"' response = sasl.process(challengeString) # Send response resp_root = self.send_challenge_response(response) success = self.check_authenticate_success(resp_root) if success is None and\ resp_root.find('{{{0}}}challenge'.format(XMPP_SASL_NS)) is not None: resp_root = self.send_challenge_response('') return self.check_authenticate_success(resp_root) return success
def test_chosen_mechanism(self): client = SASLClient('localhost', mechanism=PlainMechanism.name, username='******', password='******') self.assertTrue(client.process()) self.assertTrue(client.complete) msg = 'msg' self.assertEqual(client.wrap(msg), msg) self.assertEqual(client.unwrap(msg), msg) client.dispose()
def test_unchosen_mechanism(self): client = SASLClient('localhost') self.assertRaises(SASLError, client.process) self.assertRaises(SASLError, client.wrap, 'msg') self.assertRaises(SASLError, client.unwrap, 'msg') with self.assertRaises(SASLError): client.complete self.assertRaises(SASLError, client.dispose)
def connect(self): # use service name component from principal service = re.split('[\/@]', str(self.hdfs_namenode_principal))[0] if not self.sasl: self.sasl = SASLClient(self._trans.host, service) negotiate = RpcSaslProto() negotiate.state = 1 self._send_sasl_message(negotiate) # do while true while True: res = self._recv_sasl_message() # TODO: check mechanisms if res.state == 1: mechs = [] for auth in res.auths: mechs.append(auth.mechanism) log.debug("Available mechs: %s" % (",".join(mechs))) self.sasl.choose_mechanism(mechs, allow_anonymous=False) log.debug("Chosen mech: %s" % self.sasl.mechanism) initiate = RpcSaslProto() initiate.state = 2 initiate.token = self.sasl.process() for auth in res.auths: if auth.mechanism == self.sasl.mechanism: auth_method = initiate.auths.add() auth_method.mechanism = self.sasl.mechanism auth_method.method = auth.method auth_method.protocol = auth.protocol auth_method.serverId = self._trans.host self._send_sasl_message(initiate) continue if res.state == 3: res_token = self._evaluate_token(res) response = RpcSaslProto() response.token = res_token response.state = 4 self._send_sasl_message(response) continue if res.state == 0: return True
def test_process_server_answer(self): sasl_kwargs = {'username': "******", 'password': "******"} sasl = SASLClient('elwood.innosoft.com', service="imap", mechanism=self.mechanism_class.name, mutual_auth=True, **sasl_kwargs) testChallenge = ( b'utf-8,username="******",realm="elwood.innosoft.com",' b'nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",' b'digest-uri="imap/elwood.innosoft.com",' b'response=d388dad90d4bbd760a152321f2143af7,qop=auth') sasl.process(testChallenge) # cnonce is generated randomly so we have to set it so # we assert the expected value sasl._chosen_mech.cnonce = b"OA6MHXh6VqTrRk" serverResponse = (b'rspauth=ea40f60335c427b5527b84dbabcdfffd') sasl.process(serverResponse)
def __init__(self, transport, host, service, mechanism=six.u('GSSAPI'), **sasl_kwargs): """ transport: an underlying transport to use, typically just a TSocket host: the name of the server, from a SASL perspective service: the name of the server's service, from a SASL perspective mechanism: the name of the preferred mechanism to use All other kwargs will be passed to the puresasl.client.SASLClient constructor. """ self.transport = transport if six.PY3: self._patch_pure_sasl() self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) self.__wbuf = BytesIO() self.__rbuf = BytesIO()
def __init__(self, transport, host, service, mechanism='GSSAPI', **sasl_kwargs): """ transport: an underlying transport to use, typically just a TSocket host: the name of the server, from a SASL perspective service: the name of the server's service, from a SASL perspective mechanism: the name of the preferred mechanism to use All other kwargs will be passed to the puresasl.client.SASLClient constructor. """ from puresasl.client import SASLClient self.transport = transport self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) self.__wbuf = BufferIO() self.__rbuf = BufferIO(b'')
def start(self, chosen): self.sasl = SASLClient(self.attributes['host'], mechanism=chosen, callback=self.getAttr) # ret, (bytes)chosen_mech, (bytes)initial_response = self.sasl.start(self.mechanism) return True, chosen.encode(), self.sasl.process()
def createSASLClient(self, host, service, mechanism, **kwargs): self.sasl = SASLClient(host, service, mechanism, **kwargs)
def setUp(self): self.sasl = SASLClient('localhost', mechanism=self.mechanism_class.name, **self.sasl_kwargs) self.mechanism = self.sasl._chosen_mech
def __init__(self, host, service, mechanism='GSSAPI', **sasl_kwargs): if SASLClient is None: raise ImportError('The puresasl library has not been installed') self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs)
def _connect(self, host, port): client = self.client self.logger.info('Connecting to %s:%s, use_ssl: %r', host, port, self.client.use_ssl) self.logger.log(BLATHER, ' Using session_id: %r session_passwd: %s', client._session_id, hexlify(client._session_passwd)) with self._socket_error_handling(): self._socket = self.handler.create_connection( address=(host, port), timeout=client._session_timeout / 1000.0, use_ssl=self.client.use_ssl, keyfile=self.client.keyfile, certfile=self.client.certfile, ca=self.client.ca, keyfile_password=self.client.keyfile_password, verify_certs=self.client.verify_certs, ) self._socket.setblocking(0) connect = Connect(0, client.last_zxid, client._session_timeout, client._session_id or 0, client._session_passwd, client.read_only) connect_result, zxid = self._invoke(client._session_timeout / 1000.0, connect) if connect_result.time_out <= 0: raise SessionExpiredError("Session has expired") if zxid: client.last_zxid = zxid # Load return values client._session_id = connect_result.session_id client._protocol_version = connect_result.protocol_version negotiated_session_timeout = connect_result.time_out connect_timeout = negotiated_session_timeout / len(client.hosts) read_timeout = negotiated_session_timeout * 2.0 / 3.0 client._session_passwd = connect_result.passwd self.logger.log( BLATHER, 'Session created, session_id: %r session_passwd: %s\n' ' negotiated session timeout: %s\n' ' connect timeout: %s\n' ' read timeout: %s', client._session_id, hexlify(client._session_passwd), negotiated_session_timeout, connect_timeout, read_timeout) if connect_result.read_only: client._session_callback(KeeperState.CONNECTED_RO) self._ro_mode = iter(self._server_pinger()) else: self._ro_mode = None # Get a copy of the auth data before iterating, in case it is # changed. client_auth_data_copy = copy.copy(client.auth_data) if client.use_sasl and self.sasl_cli is None: if PURESASL_AVAILABLE: for scheme, auth in client_auth_data_copy: if scheme == 'sasl': username, password = auth.split(":") self.sasl_cli = SASLClient( host=client.sasl_server_principal, service='zookeeper', mechanism='DIGEST-MD5', username=username, password=password) break # As described in rfc # https://tools.ietf.org/html/rfc2831#section-2.1 # sending empty challenge self._send_sasl_request(challenge=b'', timeout=connect_timeout) else: self.logger.warn('Pure-sasl library is missing while sasl' ' authentification is configured. Please' ' install pure-sasl library to connect ' 'using sasl. Now falling back ' 'connecting WITHOUT any ' 'authentification.') client.use_sasl = False client._session_callback(KeeperState.CONNECTED) else: client._session_callback(KeeperState.CONNECTED) for scheme, auth in client_auth_data_copy: if scheme == "digest": ap = Auth(0, scheme, auth) zxid = self._invoke(connect_timeout / 1000.0, ap, xid=AUTH_XID) if zxid: client.last_zxid = zxid return read_timeout, connect_timeout
def sasl_init(self, mechs, **props): """Initialize a :class:`.puresasl.client.SASLClient`""" self._sasl_client = SASLClient(self.host, 'ldap', **props) self._sasl_client.choose_mechanism(mechs)