def test_authenticate(self): res, ctx = kerberos.authGSSClientInit(_SPN, None, kerberos.GSS_C_MUTUAL_FLAG, _USER, _DOMAIN, _PASSWORD) self.assertEqual(res, kerberos.AUTH_GSS_COMPLETE) res = kerberos.authGSSClientStep(ctx, "") self.assertEqual(res, kerberos.AUTH_GSS_CONTINUE) payload = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(payload, str) response = self.db.command('saslStart', mechanism='GSSAPI', payload=payload) while res == kerberos.AUTH_GSS_CONTINUE: res = kerberos.authGSSClientStep(ctx, response['payload']) payload = kerberos.authGSSClientResponse(ctx) or '' response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=payload) res = kerberos.authGSSClientUnwrap(ctx, response['payload']) self.assertEqual(res, 1) unwrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(unwrapped, str) self.assertIsInstance(kerberos.authGSSClientResponseConf(ctx), int) # RFC-4752 challenge_bytes = base64.standard_b64decode(unwrapped) self.assertEqual(4, len(challenge_bytes)) # Manually create an authorization message and encrypt it. This # is the "no security layer" message as detailed in RFC-4752, # section 3.1, final paragraph. This is also the message created # by calling authGSSClientWrap with the "user" option. msg = base64.standard_b64encode(b"\x01\x00\x00\x00" + _UPN.encode("utf8")).decode("utf8") res = kerberos.authGSSClientWrap(ctx, msg) self.assertEqual(res, 1) custom = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(custom, str) # Wrap using unwrapped and user principal. res = kerberos.authGSSClientWrap(ctx, unwrapped, _UPN) self.assertEqual(res, 1) wrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(wrapped, str) # Actually complete authentication, using our custom message. response = self.db.command('saslContinue', conversationId=response['conversationId'], payload=custom) self.assertTrue(response['done']) self.assertIsInstance(kerberos.authGSSClientUsername(ctx), str)
def retry_http_krb_sspi_auth(self, host, req): url = req.full_url scheme, _, host, path = url.split('/', 3) h = HTTPConnection(host) if scheme == 'http:' else HTTPSConnection( host) headers = dict(req.unredirected_hdrs) headers.update( dict((k, v) for k, v in req.headers.items() if k not in headers)) try: __, krb_context = kerberos.authGSSClientInit("HTTP@" + host) kerberos.authGSSClientStep(krb_context, "") negotiate_details = kerberos.authGSSClientResponse(krb_context) headers["Connection"] = "Keep-Alive" headers["Authorization"] = "Negotiate " + negotiate_details h.request(req.get_method(), req.selector, req.data, headers) response = h.getresponse() return addinfourl(response, response.msg, req.get_full_url(), response.status) except: # e = sys.exc_info()[0] # _log.warning(str(e)) # _log.warning('Failed Kerberos authentication') return None
def authenticate(self, service=_SPN, principal=None, flags=kerberos.GSS_C_MUTUAL_FLAG, user=_USER, domain=_DOMAIN, password=_PASSWORD, mech_oid=kerberos.GSS_MECH_OID_KRB5, upn=_UPN, protect=0): res, ctx = kerberos.authGSSClientInit( service, principal, flags, user, domain, password, mech_oid) res = kerberos.authGSSClientStep(ctx, "") payload = kerberos.authGSSClientResponse(ctx) response = self.db.command( 'saslStart', mechanism='GSSAPI', payload=payload) while res == kerberos.AUTH_GSS_CONTINUE: res = kerberos.authGSSClientStep(ctx, response['payload']) payload = kerberos.authGSSClientResponse(ctx) or '' response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=payload) kerberos.authGSSClientUnwrap(ctx, response['payload']) kerberos.authGSSClientWrap(ctx, kerberos.authGSSClientResponse(ctx), upn, protect) response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=kerberos.authGSSClientResponse(ctx)) self.assertTrue(response['done'])
def authenticate(self, service=_SPN, principal=None, flags=kerberos.GSS_C_MUTUAL_FLAG, user=_USER, domain=_DOMAIN, password=_PASSWORD, mech_oid=kerberos.GSS_MECH_OID_KRB5, upn=_UPN, protect=0): res, ctx = kerberos.authGSSClientInit(service, principal, flags, user, domain, password, mech_oid) res = kerberos.authGSSClientStep(ctx, "") payload = kerberos.authGSSClientResponse(ctx) response = self.db.command('saslStart', mechanism='GSSAPI', payload=payload) while res == kerberos.AUTH_GSS_CONTINUE: res = kerberos.authGSSClientStep(ctx, response['payload']) payload = kerberos.authGSSClientResponse(ctx) or '' response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=payload) kerberos.authGSSClientUnwrap(ctx, response['payload']) kerberos.authGSSClientWrap(ctx, kerberos.authGSSClientResponse(ctx), upn, protect) response = self.db.command('saslContinue', conversationId=response['conversationId'], payload=kerberos.authGSSClientResponse(ctx)) self.assertTrue(response['done'])
def process_challenge_kerberos(self, packet): digest = packet[3] if not digest.startswith(b"kerberos:"): authlog("%s is not a kerberos challenge", digest) #not a kerberos challenge return False try: if WIN32: import winkerberos as kerberos else: import kerberos except ImportError as e: authlog("import (win)kerberos", exc_info=True) if first_time("no-kerberos"): authlog.warn( "Warning: kerberos challenge handler is not supported:") authlog.warn(" %s", e) return False service = bytestostr(digest.split(b":", 1)[1]) if service not in KERBEROS_SERVICES and "*" not in KERBEROS_SERVICES: authlog.warn("Warning: invalid kerberos request for service '%s'", service) authlog.warn(" services supported: %s", csv(KERBEROS_SERVICES)) return False authlog("kerberos service=%s", service) def log_kerberos_exception(e): try: for x in e.args: if isinstance(x, (list, tuple)): try: log.error(" %s", csv(x)) continue except: pass authlog.error(" %s", x) except Exception: authlog.error(" %s", e) try: r, ctx = kerberos.authGSSClientInit(service) assert r == 1, "return code %s" % r except Exception as e: authlog("kerberos.authGSSClientInit(%s)", service, exc_info=True) authlog.error("Error: cannot initialize kerberos client:") log_kerberos_exception(e) return False try: kerberos.authGSSClientStep(ctx, "") except Exception as e: authlog("kerberos.authGSSClientStep", exc_info=True) authlog.error("Error: kerberos client authentication failure:") log_kerberos_exception(e) return False token = kerberos.authGSSClientResponse(ctx) authlog("kerberos token=%s", token) self.send_challenge_reply(packet, token) return True
def get_response_wkb(self, challenge=""): dprint("winkerberos SSPI") try: winkerberos.authGSSClientStep(self.ctx, challenge) auth_req = winkerberos.authGSSClientResponse(self.ctx) except winkerberos.GSSError: traceback.print_exc(file=sys.stdout) return None return auth_req
def test_authenticate(self): res, ctx = kerberos.authGSSClientInit( _SPN, _PRINCIPAL, kerberos.GSS_C_MUTUAL_FLAG, _USER, _DOMAIN, _PASSWORD) self.assertEqual(res, kerberos.AUTH_GSS_COMPLETE) res = kerberos.authGSSClientStep(ctx, "") self.assertEqual(res, kerberos.AUTH_GSS_CONTINUE) payload = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(payload, str) response = self.db.command( 'saslStart', mechanism='GSSAPI', payload=payload) while res == kerberos.AUTH_GSS_CONTINUE: res = kerberos.authGSSClientStep(ctx, response['payload']) payload = kerberos.authGSSClientResponse(ctx) or '' response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=payload) res = kerberos.authGSSClientUnwrap(ctx, response['payload']) self.assertEqual(res, 1) unwrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(unwrapped, str) # Try just rewrapping (no user) res = kerberos.authGSSClientWrap(ctx, unwrapped) self.assertEqual(res, 1) wrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(wrapped, str) # Actually complete authentication res = kerberos.authGSSClientWrap(ctx, unwrapped, _UPN) self.assertEqual(res, 1) wrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(wrapped, str) response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=wrapped) self.assertTrue(response['done']) self.assertIsInstance(kerberos.authGSSClientUsername(ctx), str)
def test_authenticate(self): res, ctx = kerberos.authGSSClientInit(_SPN, _PRINCIPAL, kerberos.GSS_C_MUTUAL_FLAG, _USER, _DOMAIN, _PASSWORD) self.assertEqual(res, kerberos.AUTH_GSS_COMPLETE) res = kerberos.authGSSClientStep(ctx, "") self.assertEqual(res, kerberos.AUTH_GSS_CONTINUE) payload = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(payload, str) response = self.db.command('saslStart', mechanism='GSSAPI', payload=payload) while res == kerberos.AUTH_GSS_CONTINUE: res = kerberos.authGSSClientStep(ctx, response['payload']) payload = kerberos.authGSSClientResponse(ctx) or '' response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=payload) res = kerberos.authGSSClientUnwrap(ctx, response['payload']) self.assertEqual(res, 1) unwrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(unwrapped, str) # Try just rewrapping (no user) res = kerberos.authGSSClientWrap(ctx, unwrapped) self.assertEqual(res, 1) wrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(wrapped, str) # Actually complete authentication res = kerberos.authGSSClientWrap(ctx, unwrapped, _UPN) self.assertEqual(res, 1) wrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(wrapped, str) response = self.db.command('saslContinue', conversationId=response['conversationId'], payload=wrapped) self.assertTrue(response['done']) self.assertIsInstance(kerberos.authGSSClientUsername(ctx), str)
def netcat(host, port, proxy_host, proxy_port): request = [('CONNECT %s:%d HTTP/1.1' % (host, port)).encode('ascii')] request.append(('Host: %s:%d' % (host, port)).encode('ascii')) request.append(('Proxy-Connection: Keep-Alive').encode('ascii')) request.append(('\r\n').encode('ascii')) dst = create_connection((proxy_host, proxy_port)) dst.sendall(b'\r\n'.join(request)) data = b'' while True: data += dst.recv(1024) if b'\r\n\r\n' in data: break if b'200 Connection established' not in data and b'407' in data: if sys.platform == "win32": status, ctx = winkerberos.authGSSClientInit('HTTP/%s' % proxy_host, gssflags=0, mech_oid=winkerberos.GSS_MECH_OID_KRB5) status = winkerberos.authGSSClientStep(ctx, "") b64token = winkerberos.authGSSClientResponse(ctx) else: service = gssapi.Name('HTTP@%s' % proxy_host, gssapi.NameType.hostbased_service) ctx = gssapi.SecurityContext(name=service, usage='initiate') token = ctx.step() b64token = base64.b64encode(token).encode('ascii') request[-1] = ('Proxy-Authorization: Negotiate %s' % b64token).encode('ascii') request.append(('\r\n').encode('ascii')) try: dst.sendall(b'\r\n'.join(request)) except: # if proxy does not support Keep-Alive dst.close() dst = create_connection((proxy_host, proxy_port)) dst.sendall(b'\r\n'.join(request)) data = b'' while True: data += dst.recv(1024) if b'\r\n\r\n' in data: break if b'200 Connection established' in data: sys.stderr.write('Proxy connection established\n') data = data.split(b'\r\n\r\n', 1)[1] if data: dst.sendall(data) forwarders = (gevent.spawn(forward_stdin, dst), gevent.spawn(forward_stdout, dst)) gevent.joinall(forwarders) elif b'407' in data: sys.stderr.write('Proxy authentication failed\n') else: version, status_code, status_message = data.split(b'\r\n', 1)[0].split(b' ', 2) sys.stderr.write('Proxy returned %s %s\n' % (status_code, status_message))
def handle(self, packet): digest = bytestostr(packet[3]) if not digest.startswith("kerberos:"): log("%s is not a kerberos challenge", digest) #not a kerberos challenge return False try: if WIN32: import winkerberos as kerberos else: import kerberos #@UnresolvedImport except ImportError as e: log.warn("Warning: cannot use kerberos authentication handler") log.warn(" %s", e) return False service = digest.split(":", 1)[1] if service not in self.services and "*" not in self.services: log.warn("Warning: invalid kerberos request for service '%s'", service) log.warn(" services supported: %s", csv(self.services)) return False log("kerberos service=%s", service) try: r, ctx = kerberos.authGSSClientInit(service) assert r == 1, "return code %s" % r except Exception as e: log("kerberos.authGSSClientInit(%s)", service, exc_info=True) log.error("Error: cannot initialize kerberos client:") log_kerberos_exception(e) return False try: kerberos.authGSSClientStep(ctx, "") except Exception as e: log("kerberos.authGSSClientStep", exc_info=True) log.error("Error: kerberos client authentication failure:") log_kerberos_exception(e) return False token = kerberos.authGSSClientResponse(ctx) log("kerberos token=%s", token) self.client.send_challenge_reply(packet, token) return True
def _windows_sasl_gssapi(connection, controls): """ Performs a bind using the Kerberos v5 ("GSSAPI") SASL mechanism from RFC 4752 using the winkerberos package that works natively on most windows operating systems. """ target_name = _common_determine_target_name(connection) # initiation happens before beginning the SASL bind when using windows kerberos authz_id, _ = _common_determine_authz_id_and_creds(connection) gssflags = (winkerberos.GSS_C_MUTUAL_FLAG | winkerberos.GSS_C_SEQUENCE_FLAG | winkerberos.GSS_C_INTEG_FLAG | winkerberos.GSS_C_CONF_FLAG) _, ctx = winkerberos.authGSSClientInit(target_name, gssflags=gssflags) in_token = b'' try: negotiation_complete = False while not negotiation_complete: # GSSAPI is a "client goes first" SASL mechanism. Send the first "response" to the server and # recieve its first challenge. # Despite this, we can get channel binding, which includes CBTs for windows environments computed from # the peer certificate, before starting. status = winkerberos.authGSSClientStep( ctx, base64.b64encode(in_token).decode('utf-8'), channel_bindings=get_channel_bindings(connection.socket)) # figure out if we're done with our sasl negotiation negotiation_complete = (status == winkerberos.AUTH_GSS_COMPLETE) out_token = winkerberos.authGSSClientResponse(ctx) or '' out_token_bytes = base64.b64decode(out_token) result = send_sasl_negotiation(connection, controls, out_token_bytes) in_token = result['saslCreds'] or b'' winkerberos.authGSSClientUnwrap( ctx, base64.b64encode(in_token).decode('utf-8')) negotiated_token = '' if winkerberos.authGSSClientResponse(ctx): negotiated_token = base64.standard_b64decode( winkerberos.authGSSClientResponse(ctx)) client_security_layers = _common_process_end_token_get_security_layers( negotiated_token) # manually construct a message indicating use of authorization-only layer # see winkerberos example: https://github.com/mongodb/winkerberos/blob/master/test/test_winkerberos.py authz_only_msg = base64.b64encode( bytes(client_security_layers) + authz_id).decode('utf-8') winkerberos.authGSSClientWrap(ctx, authz_only_msg) out_token = winkerberos.authGSSClientResponse(ctx) or '' return send_sasl_negotiation(connection, controls, base64.b64decode(out_token)) except (winkerberos.GSSError, LDAPCommunicationError): abort_sasl_negotiation(connection, controls) raise
def step(self, in_token): if not self._ctx: self.init() in_token = b64encode(in_token) if in_token else '' result = krb.authGSSClientStep(self._ctx, in_token) if result < 0: raise GSSAPIAdapterException(result) self.complete = result == krb.AUTH_GSS_COMPLETE out_token = krb.authGSSClientResponse(self._ctx) return b64decode(out_token) if out_token else None
def handle(self, src, addr): data = b'' while True: data += src.recv(1024) if b'\r\n\r\n' in data: break if sys.platform == "win32": status, ctx = winkerberos.authGSSClientInit('HTTP/%s' % self.upstream[0], gssflags=0, mech_oid=winkerberos.GSS_MECH_OID_KRB5) status = winkerberos.authGSSClientStep(ctx, "") b64token = winkerberos.authGSSClientResponse(ctx) else: service = gssapi.Name('HTTP@%s' % self.upstream[0], gssapi.NameType.hostbased_service) ctx = gssapi.SecurityContext(name=service, usage='initiate') token = ctx.step() b64token = base64.b64encode(token).encode('ascii') headers, data = data.split(b'\r\n\r\n', 1) headers = headers.split('\r\n') replaced = False for i, header in enumerate(headers): if header.startswith('Proxy-Authorization:'): headers[i] = b'Proxy-Authorization: Negotiate %s' % b64token replaced = True break if not replaced: headers.append(b'Proxy-Authorization: Negotiate %s' % b64token) dst = create_connection(self.upstream) dst.sendall(b'\r\n'.join(headers) + b'\r\n\r\n' + data) forwarders = (gevent.spawn(forward, src, dst), gevent.spawn(forward, dst, src)) gevent.joinall(forwarders)
def _authenticate_gssapi(credentials, sock_info): """Authenticate using GSSAPI. """ if not HAVE_KERBEROS: raise ConfigurationError('The "kerberos" module must be ' 'installed to use GSSAPI authentication.') try: username = credentials.username password = credentials.password props = credentials.mechanism_properties # Starting here and continuing through the while loop below - establish # the security context. See RFC 4752, Section 3.1, first paragraph. host = sock_info.address[0] if props.canonicalize_host_name: host = socket.getfqdn(host) service = props.service_name + '@' + host if props.service_realm is not None: service = service + '@' + props.service_realm if password is not None: if _USE_PRINCIPAL: # Note that, though we use unquote_plus for unquoting URI # options, we use quote here. Microsoft's UrlUnescape (used # by WinKerberos) doesn't support +. principal = ":".join((quote(username), quote(password))) result, ctx = kerberos.authGSSClientInit( service, principal, gssflags=kerberos.GSS_C_MUTUAL_FLAG) else: if '@' in username: user, domain = username.split('@', 1) else: user, domain = username, None result, ctx = kerberos.authGSSClientInit( service, gssflags=kerberos.GSS_C_MUTUAL_FLAG, user=user, domain=domain, password=password) else: result, ctx = kerberos.authGSSClientInit( service, gssflags=kerberos.GSS_C_MUTUAL_FLAG) if result != kerberos.AUTH_GSS_COMPLETE: raise OperationFailure('Kerberos context failed to initialize.') try: # pykerberos uses a weird mix of exceptions and return values # to indicate errors. # 0 == continue, 1 == complete, -1 == error # Only authGSSClientStep can return 0. if kerberos.authGSSClientStep(ctx, '') != 0: raise OperationFailure('Unknown kerberos ' 'failure in step function.') # Start a SASL conversation with mongod/s # Note: pykerberos deals with base64 encoded byte strings. # Since mongo accepts base64 strings as the payload we don't # have to use bson.binary.Binary. payload = kerberos.authGSSClientResponse(ctx) cmd = SON([('saslStart', 1), ('mechanism', 'GSSAPI'), ('payload', payload), ('autoAuthorize', 1)]) response = sock_info.command('$external', cmd) # Limit how many times we loop to catch protocol / library issues for _ in range(10): result = kerberos.authGSSClientStep(ctx, str(response['payload'])) if result == -1: raise OperationFailure('Unknown kerberos ' 'failure in step function.') payload = kerberos.authGSSClientResponse(ctx) or '' cmd = SON([('saslContinue', 1), ('conversationId', response['conversationId']), ('payload', payload)]) response = sock_info.command('$external', cmd) if result == kerberos.AUTH_GSS_COMPLETE: break else: raise OperationFailure('Kerberos ' 'authentication failed to complete.') # Once the security context is established actually authenticate. # See RFC 4752, Section 3.1, last two paragraphs. if kerberos.authGSSClientUnwrap(ctx, str(response['payload'])) != 1: raise OperationFailure('Unknown kerberos ' 'failure during GSS_Unwrap step.') if kerberos.authGSSClientWrap(ctx, kerberos.authGSSClientResponse(ctx), username) != 1: raise OperationFailure('Unknown kerberos ' 'failure during GSS_Wrap step.') payload = kerberos.authGSSClientResponse(ctx) cmd = SON([('saslContinue', 1), ('conversationId', response['conversationId']), ('payload', payload)]) sock_info.command('$external', cmd) finally: kerberos.authGSSClientClean(ctx) except kerberos.KrbError as exc: raise OperationFailure(str(exc))
def create_challenge_response(self, challenge): status = kerberos.authGSSClientStep(self.ctx, challenge) auth_req = kerberos.authGSSClientResponse(self.ctx) return auth_req
def sasl_gssapi(connection, controls): """ Performs a bind using the Kerberos v5 ("GSSAPI") SASL mechanism from RFC 4752. Does not support any security layers, only authentication! sasl_credentials can be empty or a tuple with one or two elements. The first element determines which service principal to request a ticket for and can be one of the following: - None or False, to use the hostname from the Server object - True to perform a reverse DNS lookup to retrieve the canonical hostname for the hosts IP address - A string containing the hostname The optional second element is what authorization ID to request. - If omitted or None, the authentication ID is used as the authorization ID - If a string, the authorization ID to use. Should start with "dn:" or "user:"******""" # pylint: disable=too-many-branches target_name = None authz_id = b'' if connection.sasl_credentials: if (len(connection.sasl_credentials) >= 1 and connection.sasl_credentials[0]): if connection.sasl_credentials[0] is True: hostname = \ socket.gethostbyaddr(connection.socket.getpeername()[0])[0] target_name = 'ldap@' + hostname else: target_name = 'ldap@' + connection.sasl_credentials[0] if (len(connection.sasl_credentials) >= 2 and connection.sasl_credentials[1]): authz_id = connection.sasl_credentials[1].encode("utf-8") if target_name is None: target_name = 'ldap@' + connection.server.host gssflags = (kerberos.GSS_C_MUTUAL_FLAG | kerberos.GSS_C_SEQUENCE_FLAG | kerberos.GSS_C_INTEG_FLAG | kerberos.GSS_C_CONF_FLAG) channel_bindings = get_channel_bindings(connection.socket) _, ctx = kerberos.authGSSClientInit(target_name, gssflags=gssflags) in_token = b'' try: while True: if channel_bindings: status = kerberos.authGSSClientStep( ctx, base64.b64encode(in_token).decode('ascii'), channel_bindings=channel_bindings) else: status = kerberos.authGSSClientStep( ctx, base64.b64encode(in_token).decode('ascii')) out_token = kerberos.authGSSClientResponse(ctx) or '' result = send_sasl_negotiation(connection, controls, base64.b64decode(out_token)) in_token = result['saslCreds'] or b'' if status == kerberos.AUTH_GSS_COMPLETE: break kerberos.authGSSClientUnwrap( ctx, base64.b64encode(in_token).decode('ascii')) unwrapped_token = base64.b64decode( kerberos.authGSSClientResponse(ctx) or '') if len(unwrapped_token) != 4: raise LDAPCommunicationError('Incorrect response from server') server_security_layers = unwrapped_token[0] if not isinstance(server_security_layers, int): server_security_layers = ord(server_security_layers) if server_security_layers in (0, NO_SECURITY_LAYER): if unwrapped_token.message[1:] != '\x00\x00\x00': raise LDAPCommunicationError( 'Server max buffer size must be 0 if no security layer') if not server_security_layers & NO_SECURITY_LAYER: raise LDAPCommunicationError( 'Server requires a security layer, but this is not implemented' ) client_security_layers = bytearray([NO_SECURITY_LAYER, 0, 0, 0]) kerberos.authGSSClientWrap( ctx, base64.b64encode(bytes(client_security_layers) + authz_id).decode('ascii')) out_token = kerberos.authGSSClientResponse(ctx) or '' return send_sasl_negotiation(connection, controls, base64.b64decode(out_token)) except (kerberos.GSSError, LDAPCommunicationError): abort_sasl_negotiation(connection, controls) raise
def test_authenticate(self): res, ctx = kerberos.authGSSClientInit( _SPN, None, kerberos.GSS_C_MUTUAL_FLAG, _USER, _DOMAIN, _PASSWORD) self.assertEqual(res, kerberos.AUTH_GSS_COMPLETE) res = kerberos.authGSSClientStep(ctx, "") self.assertEqual(res, kerberos.AUTH_GSS_CONTINUE) payload = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(payload, str) response = self.db.command( 'saslStart', mechanism='GSSAPI', payload=payload) while res == kerberos.AUTH_GSS_CONTINUE: res = kerberos.authGSSClientStep(ctx, response['payload']) payload = kerberos.authGSSClientResponse(ctx) or '' response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=payload) res = kerberos.authGSSClientUnwrap(ctx, response['payload']) self.assertEqual(res, 1) unwrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(unwrapped, str) self.assertIsInstance(kerberos.authGSSClientResponseConf(ctx), int) # RFC-4752 challenge_bytes = base64.standard_b64decode(unwrapped) self.assertEqual(4, len(challenge_bytes)) # Manually create an authorization message and encrypt it. This # is the "no security layer" message as detailed in RFC-4752, # section 3.1, final paragraph. This is also the message created # by calling authGSSClientWrap with the "user" option. msg = base64.standard_b64encode( b"\x01\x00\x00\x00" + _UPN.encode("utf8")).decode("utf8") res = kerberos.authGSSClientWrap(ctx, msg) self.assertEqual(res, 1) custom = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(custom, str) # Wrap using unwrapped and user principal. res = kerberos.authGSSClientWrap(ctx, unwrapped, _UPN) self.assertEqual(res, 1) wrapped = kerberos.authGSSClientResponse(ctx) self.assertIsInstance(wrapped, str) # Actually complete authentication, using our custom message. response = self.db.command( 'saslContinue', conversationId=response['conversationId'], payload=custom) self.assertTrue(response['done']) self.assertIsInstance(kerberos.authGSSClientUserName(ctx), str)
def get_response_wkb(self, challenge=""): status = winkerberos.authGSSClientStep(self.ctx, challenge) auth_req = winkerberos.authGSSClientResponse(self.ctx) return auth_req