Ejemplo n.º 1
0
    def _acquire_creds(self, username, password):
        # 3 use cases with Kerberos Auth
        #   1. Both the user and pass is supplied so we want to create a new
        #      ticket with the pass
        #   2. Only the user is supplied so we will attempt to get the cred
        #      from the existing store
        #   3. The user is not supplied so we will attempt to get the default
        #      cred from the existing store
        log.info("GSSAPI: Acquiring credentials handle")
        if username and password:
            log.debug("GSSAPI: Acquiring credentials handle for user %s with "
                      "password" % username)
            user = gssapi.Name(base=username,
                               name_type=gssapi.NameType.user)
            bpass = password.encode('utf-8')
            try:
                creds = gssapi.raw.acquire_cred_with_password(user, bpass,
                                                              usage='initiate')
            except AttributeError:
                raise SMBAuthenticationError("Cannot get GSSAPI credential "
                                             "with password as the necessary "
                                             "GSSAPI extensions are not "
                                             "available")
            except gssapi.exceptions.GSSError as er:
                raise SMBAuthenticationError("Failed to acquire GSSAPI "
                                             "credential with password: %s"
                                             % str(er))
            # acquire_cred_with_password returns a wrapper, we want the creds
            # object inside this wrapper
            creds = creds.creds
        elif username:
            log.debug("GSSAPI: Acquiring credentials handle for user %s from "
                      "existing cache" % username)
            user = gssapi.Name(base=username,
                               name_type=gssapi.NameType.user)

            try:
                creds = gssapi.Credentials(name=user, usage='initiate')
            except gssapi.exceptions.MissingCredentialsError as er:
                raise SMBAuthenticationError("Failed to acquire GSSAPI "
                                             "credential for user %s from the "
                                             "exisiting cache: %s"
                                             % (str(user), str(er)))
        else:
            log.debug("GSSAPI: Acquiring credentials handle for default user "
                      "in cache")
            try:
                creds = gssapi.Credentials(name=None, usage='initiate')
            except gssapi.exceptions.GSSError as er:
                raise SMBAuthenticationError("Failed to acquire default "
                                             "GSSAPI credential from the "
                                             "existing cache: %s" % str(er))
            user = creds.name

        log.info("GSSAPI: Acquired credentials for user %s" % str(user))
        return creds
Ejemplo n.º 2
0
Archivo: gss.py Proyecto: tiran/fasjson
    def _gssapi_check(self):
        environ = request.environ
        if environ["wsgi.multithread"]:
            abort(
                400,
                "GSSAPI is not compatible with multi-threaded WSGI servers.",
            )

        ccache = environ.get("KRB5CCNAME")
        if not ccache:
            abort(400, "KRB5CCNAME missing.")
            raise ValueError("KRB5CCNAME missing")

        principal = environ.get("GSS_NAME")
        if not principal:
            abort(400, "GSS_NAME missing.")

        gss_name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
        try:
            creds = gssapi.Credentials(usage="initiate",
                                       name=gss_name,
                                       store={"ccache": ccache})
        except gssapi.exceptions.GSSError as e:
            abort(403, f"Invalid credentials {e}")
        else:
            if creds.lifetime <= 0:
                abort(401, "Credential lifetime has expired.")
Ejemplo n.º 3
0
    def get_auth_info(self, use_cookie=True):
        """
        Two things can happen here. If we have a session we will add
        a cookie for that. If not we will set an Authorization header.
        """
        if not isinstance(self._extra_headers, list):
            self._extra_headers = []

        # Remove any existing Cookie first
        self._remove_extra_header('Cookie')
        if use_cookie:
            session_cookie = getattr(context, 'session_cookie', None)
            if session_cookie:
                self._extra_headers.append(('Cookie', session_cookie))
                return

        # Set the remote host principal
        host = self._get_host()
        service = self.service + "@" + host.split(':')[0]

        try:
            creds = None
            if self.ccache:
                creds = gssapi.Credentials(usage='initiate',
                                           store={'ccache': self.ccache})
            name = gssapi.Name(service, gssapi.NameType.hostbased_service)
            self._sec_context = gssapi.SecurityContext(creds=creds,
                                                       name=name,
                                                       flags=self.flags)
            response = self._sec_context.step()
        except gssapi.exceptions.GSSError as e:
            self._handle_exception(e, service=service)

        self._set_auth_header(response)
Ejemplo n.º 4
0
    def start(self):
        response = self.strategy.html('Authorization Required')
        response.status_code = 401
        response['WWW-Authenticate'] = 'Negotiate'

        # browser didn't send negotiation token
        if 'HTTP_AUTHORIZATION' not in self.strategy.request.META:
            # this will keep a reference to the current user b/c
            # kerberos auth is a stateful protocol while HTTP is stateless.
            context_id = "%d@%d" % (hash(repr(
                self.strategy.request.META)), id(self.strategy.request))
            self.strategy.request.session['_krb5'] = context_id
            self._krb5[context_id] = None
            return response

        token = self.strategy.request.META['HTTP_AUTHORIZATION']
        token = token.split('Negotiate')[-1].strip()
        token = base64.b64decode(token)

        context_id = self.strategy.request.session.get('_krb5', None)
        if self._krb5[context_id] is None:
            keytab_path = self.strategy.setting('SOCIAL_AUTH_KRB5_KEYTAB')
            creds = gssapi.Credentials(usage='accept',
                                       store={'keytab': keytab_path})
            self._krb5[context_id] = gssapi.SecurityContext(creds=creds)

        server_token = self._krb5[context_id].step(token)
        response = self.strategy.redirect(self.redirect_uri)

        if server_token is not None:
            server_token_hex = base64.b64encode(server_token).decode()
            response['WWW-Authenticate'] = 'Negotiate %s' % server_token_hex

        return response
Ejemplo n.º 5
0
 def init_creds(self):
     name = gssapi.Name(self.client_service,
                        gssapi.NameType.hostbased_service)
     store = {'client_keytab': self.keytab,
              'ccache': 'MEMORY:Custodia_%s' % b64encode(
                  os.urandom(8)).decode('ascii')}
     return gssapi.Credentials(name=name, store=store, usage='initiate')
Ejemplo n.º 6
0
def negotiate(request, name=None, store=None):
    '''Try to authenticate the user using SPNEGO and Kerberos'''

    if name:
        logger.debug(u'GSSAPI negotiate using name %s', name)

    try:
        server_creds = gssapi.Credentials(usage='accept', name=name, store=store)
    except gssapi.exceptions.GSSError as e:
        logging.debug('GSSAPI credentials failure: %s', e)
        return None, None

    if not request.META.get('HTTP_AUTHORIZATION', '').startswith('Negotiate '):
        return None, None

    authstr = request.META['HTTP_AUTHORIZATION'][10:]
    try:
        in_token = base64.b64decode(authstr)
    except (TypeError, ValueError):
        return None, None

    server_ctx = gssapi.SecurityContext(creds=server_creds, usage='accept')
    try:
        out_token = server_ctx.step(in_token)
    except gssapi.exceptions.GSSError as e:
        logging.debug('GSSAPI security context failure: %s', e)
        return None, None

    if not server_ctx.complete:
        raise NegotiateContinue(out_token)

    return server_ctx.initiator_name, out_token
Ejemplo n.º 7
0
    def generate_request_header(self, response, host, is_preemptive=False):
        # This method needs to be shimmed because `host` isn't exposed to
        # __init__() and we need to derive things from it.  Also, __init__()
        # can't fail, in the strictest compatability sense.
        try:
            if self.principal is not None:
                gss_stage = "acquiring credentials"
                name = gssapi.Name(self.principal,
                                   gssapi.NameType.hostbased_service)
                self.creds = gssapi.Credentials(name=name, usage="initiate")

            # contexts still need to be stored by host, but hostname_override
            # allows use of an arbitrary hostname for the GSSAPI exchange (eg,
            # in cases of aliased hosts, internal vs external, CNAMEs w/
            # name-based HTTP hosting)
            if self.service is not None:
                gss_stage = "initiating context"
                kerb_host = host
                if self.hostname_override:
                    kerb_host = self.hostname_override

                kerb_spn = "{0}@{1}".format(self.service, kerb_host)
                self.target_name = gssapi.Name(
                    kerb_spn, gssapi.NameType.hostbased_service)

            return HTTPSPNEGOAuth.generate_request_header(
                self, response, host, is_preemptive)
        except gssapi.exceptions.GSSError as error:
            msg = error.gen_message()
            log.exception(
                "generate_request_header(): {0} failed:".format(gss_stage))
            log.exception(msg)
            raise SPNEGOExchangeError("%s failed: %s" % (gss_stage, msg))
Ejemplo n.º 8
0
    def authenticate(self, request):
        if request.method == 'OPTIONS':
            return
        authorization = request.META.get('HTTP_AUTHORIZATION', '')
        if authorization.startswith('Negotiate '):
            host = socket.gethostbyaddr(request.META['SERVER_ADDR'])[0]
            service_name = 'HTTP/{}'.format(host)
            service_name = gssapi.Name(service_name)

            # The browser is authenticating using GSSAPI, trim off 'Negotiate ' and decode:
            in_token = base64.b64decode(authorization[10:])

            server_creds = gssapi.Credentials(name=service_name,
                                              usage='accept')
            ctx = gssapi.SecurityContext(creds=server_creds)

            # Feed the input token to the context, and get an output token in return
            out_token = ctx.step(in_token)
            if out_token:
                request.negotiate_token = base64.b64encode(out_token).decode()
            if ctx.complete:
                name = str(ctx.initiator_name)
                User = get_user_model()
                user = User.objects.get(**{self.principal_name_field: name})
                return user, None
            else:
                raise HTTPUnauthorized
Ejemplo n.º 9
0
 def __init__(self, app, ccname):
     self.app = app
     self.ccname = ccname
     self.creds = gssapi.Credentials(
         usage='initiate',
         store={'ccache': ccname}
     )
Ejemplo n.º 10
0
def test_explicit_creds(patched_creds, patched_ctx):
    response = null_response(headers=neg_token)
    creds = gssapi.Credentials()
    auth = httpx_gssapi.HTTPSPNEGOAuth(creds=creds)
    auth.generate_request_header(response.url.host, response)
    check_init(creds=b"fake creds")
    fake_resp.assert_called_with(b"token")
Ejemplo n.º 11
0
def get_credentials(name=None, ccache_name=None):
    '''
    Obtains GSSAPI credentials with given principal name from ccache. When no
    principal name specified, it retrieves the default one for given
    credentials cache.

    :parameters:
      name
        gssapi.Name object specifying principal or None for the default
      ccache_name
        string specifying Kerberos credentials cache name or None for the
        default
    :returns:
      gssapi.Credentials object
    '''
    store = None
    if ccache_name:
        store = {'ccache': ccache_name}
    try:
        return gssapi.Credentials(usage='initiate', name=name, store=store)
    except gssapi.exceptions.GSSError as e:
        if e.min_code in (  # pylint: disable=no-member
                KRB5_FCC_NOFILE,
                GSSPROXY_KRB5_FCC_NOFILE,
                KRB5_CC_NOTFOUND,
        ):
            raise ValueError('"%s", ccache="%s"' % (e, ccache_name))
        raise
Ejemplo n.º 12
0
def use_api_as_principal(principal, keytab):
    with ipautil.private_ccache() as ccache_file:
        try:
            old_principal = getattr(context, "principal", None)
            name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
            store = {"ccache": ccache_file, "client_keytab": keytab}
            gssapi.Credentials(name=name, usage="initiate", store=store)
            # Finalize API when TGT obtained using host keytab exists
            if not api.isdone("finalize"):
                api.finalize()

            # Now we have a TGT, connect to IPA
            try:
                if api.Backend.rpcclient.isconnected():
                    api.Backend.rpcclient.disconnect()
                api.Backend.rpcclient.connect()

                yield
            except gssapi.exceptions.GSSError as e:
                raise Exception(
                    "Unable to bind to IPA server. Error initializing "
                    "principal %s in %s: %s" % (principal, keytab, str(e)))
        finally:
            if api.Backend.rpcclient.isconnected():
                api.Backend.rpcclient.disconnect()
            setattr(context, "principal", old_principal)
Ejemplo n.º 13
0
    def _get_security_context(name_type,
                              mech,
                              spn,
                              username,
                              password,
                              delegate,
                              wrap_required,
                              channel_bindings=None):
        if username is not None:
            username = gssapi.Name(base=username, name_type=name_type)

        server_name = gssapi.Name(spn,
                                  name_type=gssapi.NameType.hostbased_service)

        # first try and get the cred from the existing cache, if that fails
        # then get a new ticket with the password (if specified). The cache
        # can only be used for Kerberos, NTLM/SPNEGO must have acquire the
        # cred with a pass
        cred = None
        kerb_oid = GSSAPIContext._AUTH_PROVIDERS['kerberos']
        kerb_mech = gssapi.OID.from_int_seq(kerb_oid)
        if mech == kerb_mech:
            try:
                cred = gssapi.Credentials(name=username,
                                          usage='initiate',
                                          mechs=[mech])
            except gssapi.exceptions.GSSError as err:
                # we can't acquire the cred if no password was supplied
                if password is None:
                    raise err
                pass
        elif username is None or password is None:
            raise ValueError("Can only use implicit credentials with kerberos "
                             "authentication")

        if cred is None:
            # error when trying to access the existing cache, get our own
            # credentials with the password specified
            b_password = to_bytes(password)
            cred = gssapi.raw.acquire_cred_with_password(username,
                                                         b_password,
                                                         usage='initiate',
                                                         mechs=[mech])
            cred = cred.creds

        flags = gssapi.RequirementFlag.mutual_authentication | \
            gssapi.RequirementFlag.out_of_sequence_detection
        if delegate:
            flags |= gssapi.RequirementFlag.delegate_to_peer
        if wrap_required:
            flags |= gssapi.RequirementFlag.confidentiality

        context = gssapi.SecurityContext(name=server_name,
                                         creds=cred,
                                         usage='initiate',
                                         mech=mech,
                                         flags=flags,
                                         channel_bindings=channel_bindings)

        return context
Ejemplo n.º 14
0
 def initiate_security_context(self):
     log.debug('Initialize security context for %s', self.canonical_name)
     credentials = gssapi.Credentials(name=self.name,
                                      usage='initiate',
                                      store=self.store)
     return gssapi.SecurityContext(name=self.name,
                                   usage='initiate',
                                   creds=credentials)
Ejemplo n.º 15
0
    def _login_gssapi(self):
        """Login using kerberos credentials (uses gssapi)."""

        login_url = urlparse.urljoin(self._hub_url, "auth/krb5login/")

        # read default values from settings
        principal = self._conf.get("KRB_PRINCIPAL")
        keytab = self._conf.get("KRB_KEYTAB")
        service = self._conf.get("KRB_SERVICE")
        realm = self._conf.get("KRB_REALM")
        ccache = self._conf.get("KRB_CCACHE")

        import requests
        import gssapi
        import requests_gssapi

        request_args = {}

        # NOTE behavior difference from hub proxy overall:
        # HubProxy by default DOES NOT verify https connections :(
        # See the constructor. It could be repeated here by defaulting verify to False,
        # but let's not do that, instead you must have an unbroken SSL setup to
        # use this auth method.
        if self._conf.get("CA_CERT"):
            request_args["verify"] = self._conf["CA_CERT"]

        server_name = self.get_server_principal(service=service, realm=realm)
        server_name = gssapi.Name(server_name,
                                  gssapi.NameType.kerberos_principal)

        auth_args = {
            "target_name": server_name,
        }
        if principal is not None:
            if keytab is None:
                raise ImproperlyConfigured(
                    "Cannot specify a principal without a keytab")
            name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
            store = {"client_keytab": keytab}
            if ccache is not None:
                store["ccache"] = "FILE:" + ccache

            auth_args["creds"] = gssapi.Credentials(name=name,
                                                    store=store,
                                                    usage="initiate")

        # We only do one request, but a Session is used to allow requests to write
        # the new session ID into the cookiejar.
        with requests.Session() as s:
            s.cookies = self._transport.cookiejar
            response = s.get(login_url,
                             auth=requests_gssapi.HTTPSPNEGOAuth(**auth_args),
                             allow_redirects=False,
                             **request_args)

        self._logger and self._logger.debug("Login response: %s %s", response,
                                            response.headers)
        response.raise_for_status()
Ejemplo n.º 16
0
def _get_kerberos_principal():
    """
    Use gssapi to get the current kerberos principal.
    This will be used as the requester for some tools when creating tickets.
    :return: The kerberos principal.
    """
    try:
        return str(gssapi.Credentials(usage='initiate').name).lower()
    except gssapi.raw.misc.GSSError:
        return None
Ejemplo n.º 17
0
 def get_user_from_credentials():
     """Get user from credentials without realm."""
     try:
         creds = gssapi.Credentials(usage="initiate")
         user = str(creds.name)
         if user.find("@") != -1:
             user, _ = user.split("@", 1)
         return user
     except gssapi.raw.misc.GSSError as err:
         return getpass.getuser()
Ejemplo n.º 18
0
    def generate_request_header(self, response, host, is_preemptive=False):
        """
        Generates the GSSAPI authentication token with kerberos.

        If any GSSAPI step fails, raise KerberosExchangeError
        with failure detail.

        """

        gssflags = [
            gssapi.RequirementFlag.mutual_authentication,
            gssapi.RequirementFlag.out_of_sequence_detection
        ]
        if self.delegate:
            gssflags.append(gssapi.RequirementFlag.delegate_to_peer)

        try:
            # contexts still need to be stored by host, but hostname_override
            # allows use of an arbitrary hostname for the GSSAPI exchange
            # (eg, in cases of aliased hosts, internal vs external, CNAMEs
            # w/ name-based HTTP hosting)
            kerb_host = host
            if self.hostname_override:
                kerb_host = self.hostname_override

            kerb_spn = "{0}@{1}".format(self.service, kerb_host)

            creds = None
            if self.principal:
                gss_stage = "acquiring credentials"
                creds = gssapi.Credentials(name=gssapi.Name(self.principal),
                                           usage="initiate")

            gss_stage = "initiating context"
            self.context[host] = gssapi.SecurityContext(
                usage="initiate",
                flags=gssflags,
                name=gssapi.Name(kerb_spn),
                creds=creds)

            gss_stage = "stepping context"
            if is_preemptive:
                gss_response = self.context[host].step()
            else:
                gss_response = self.context[host].step(
                    _negotiate_value(response))

            return "Negotiate {0}".format(gss_response)

        except gssapi.exceptions.GSSError as error:
            msg = error.gen_message()
            log.exception(
                "generate_request_header(): {0} failed:".format(gss_stage))
            log.exception(msg)
            raise KerberosExchangeError("%s failed: %s" % (gss_stage, msg))
Ejemplo n.º 19
0
 def get_context(self, host):
     service_name = gssapi.Name(self.service_name or '{0}@{1}'.format(self.service, host),
                                gssapi.NameType.hostbased_service)
     logging.debug("get_context(): service name={0}".format(service_name))
     if self.negotiate_client_name:
         creds = gssapi.Credentials(name=gssapi.Name(self.negotiate_client_name),
                                    usage='initiate')
     else:
         creds = None
     return gssapi.SecurityContext(name=service_name,
                                   creds=creds)
Ejemplo n.º 20
0
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 1-element tuple with the requested target_name or the True
    value to request the target_name from DNS
    """
    if connection.sasl_credentials and 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 = gssapi.Name('ldap@' + hostname, gssapi.NameType.hostbased_service)
        else:
            target_name = gssapi.Name('ldap@' + connection.sasl_credentials[0], gssapi.NameType.hostbased_service)
    else:
        target_name = gssapi.Name('ldap@' + connection.server.host, gssapi.NameType.hostbased_service)
    creds = gssapi.Credentials(name=gssapi.Name(connection.user), usage='initiate') if connection.user else None
    ctx = gssapi.SecurityContext(name=target_name, mech=gssapi.MechType.kerberos, creds=creds)
    in_token = None
    try:
        while True:
            out_token = ctx.step(in_token)
            if out_token is None:
                out_token = ''
            result = send_sasl_negotiation(connection, controls, out_token)
            in_token = result['saslCreds']
            try:
                # This raised an exception in gssapi<1.1.2 if the context was
                # incomplete, but was fixed in
                # https://github.com/pythongssapi/python-gssapi/pull/70
                if ctx.complete:
                    break
            except gssapi.exceptions.MissingContextError:
                pass

        unwrapped_token = ctx.unwrap(in_token)
        if len(unwrapped_token.message) != 4:
            raise LDAPCommunicationError("Incorrect response from server")

        server_security_layers = unwrapped_token.message[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])
        out_token = ctx.wrap(bytes(client_security_layers), False)
        return send_sasl_negotiation(connection, controls, out_token.message)
    except (gssapi.exceptions.GSSError, LDAPCommunicationError):
        abort_sasl_negotiation(connection, controls)
        raise
Ejemplo n.º 21
0
    def initial_step(self, request, response=None):
        if self.context is None:
            store = {'ccache': self.ccache_name}
            creds = gssapi.Credentials(usage='initiate', store=store)
            name = gssapi.Name('HTTP@{0}'.format(self.target_host),
                               name_type=gssapi.NameType.hostbased_service)
            self.context = gssapi.SecurityContext(creds=creds, name=name,
                                                  usage='initiate')

        in_token = self._get_negotiate_token(response)
        out_token = self.context.step(in_token)
        self._set_authz_header(request, out_token)
Ejemplo n.º 22
0
 def _get_creds(self):
     if self.principal is None:
         return None
     name = gssapi.Name(self.principal, gssapi.NameType.kerberos_principal)
     try:
         creds = gssapi.Credentials(name=name, usage="initiate")
     except gssapi.exceptions.GSSError as e:
         raise ClientError("Authentication failed",
                           errno.EPROTO,
                           data={"exc": e})
     if creds.lifetime <= 0:
         raise ClientError("Authentication expired", errno.EPROTO)
     return creds
Ejemplo n.º 23
0
def _common_determine_authz_id_and_creds(connection):
    """ Given our connection, figure out the authorization id (i.e. the kerberos principal) and kerberos credentials
    being used for our SASL bind.
    On posix systems, we can actively negotiate with raw credentials and receive a kerberos client ticket during our
    SASL bind. So credentials can be specified.
    However, on windows systems, winkerberos expects to use the credentials cached by the system because windows
    machines are generally domain-joined. So no initiation is supported, as the TGT must already be valid prior
    to beginning the SASL bind, and the windows system credentials will be used as needed with that.
    """
    authz_id = b""
    creds = None
    # the default value for credentials is only something we should instantiate on systems using the
    # posix GSSAPI, as windows kerberos expects that a tgt already exists (i.e. the machine is domain-joined)
    # and does not support initiation from raw credentials
    if not posix_gssapi_unavailable:
        creds = gssapi.Credentials(
            name=gssapi.Name(connection.user),
            usage='initiate',
            store=connection.cred_store) if connection.user else None
    if connection.sasl_credentials:
        if len(connection.sasl_credentials
               ) >= 2 and connection.sasl_credentials[1]:
            authz_id = connection.sasl_credentials[1].encode("utf-8")
        if len(connection.sasl_credentials
               ) >= 3 and connection.sasl_credentials[2]:
            if posix_gssapi_unavailable:
                raise LDAPPackageUnavailableError(
                    'The winkerberos package does not support specifying raw  credentials'
                    'to initiate GSSAPI Kerberos communication. A ticket granting ticket '
                    'must have already been obtained for the user before beginning a '
                    'SASL bind.')
            raw_creds = connection.sasl_credentials[2]
            creds = gssapi.Credentials(base=raw_creds,
                                       usage='initiate',
                                       store=connection.cred_store)
    return authz_id, creds
 def test_explicit_creds(self):
     with patch.multiple("gssapi.Credentials", __new__=fake_creds), \
          patch.multiple("gssapi.SecurityContext", __init__=fake_init,
                         step=fake_resp):
         response = requests.Response()
         response.url = "http://www.example.org/"
         response.headers = {'www-authenticate': b64_negotiate_token}
         host = urlparse(response.url).hostname
         creds = gssapi.Credentials()
         auth = requests_gssapi.HTTPSPNEGOAuth(creds=creds)
         auth.generate_request_header(response, host)
         fake_init.assert_called_with(
             name=gssapi_name("*****@*****.**"),
             usage="initiate", flags=gssflags, creds=b"fake creds")
         fake_resp.assert_called_with(b"token")
Ejemplo n.º 25
0
def kerberos_validate_ticket():
    """
    Return the kerberos ticket lifetime left after getting the
    ticket from the credential cache
    """
    import gssapi

    try:
        del_creds = gssapi.Credentials(store={'ccache': session['KRB5CCNAME']})
        creds = del_creds.acquire(store={'ccache': session['KRB5CCNAME']})
    except Exception as e:
        current_app.logger.exception(e)
        return internal_server_error(errormsg=str(e))

    return make_json_response(data={'ticket_lifetime': creds.lifetime},
                              status=200)
Ejemplo n.º 26
0
    def init_app(self, app):
        """
        Initialises the Negotiate extension for the given application.
        """
        if not hasattr(app, 'extensions'):
            app.extensions = {}

        service_name = app.config.get('GSSAPI_SERVICE_NAME', 'HTTP')
        name = app.config.get('GSSAPI_HOSTNAME', socket.getfqdn())
        if name is not None:
            principal = '{}@{}'.format(service_name, name)
            name = gssapi.Name(principal, gssapi.NameType.hostbased_service)

        app.extensions['gssapi'] = {
            'creds': gssapi.Credentials(name=name, usage='accept'),
        }
Ejemplo n.º 27
0
 def start(self, connection):
     try:
         if self.client_name:
             creds = gssapi.Credentials(
                 name=gssapi.Name(self.client_name))
         else:
             creds = None
         hostname = self.get_hostname(connection)
         name = gssapi.Name(b'@'.join([self.service, hostname]),
                            gssapi.NameType.hostbased_service)
         context = gssapi.SecurityContext(name=name, creds=creds)
         return context.step(None)
     except gssapi.raw.misc.GSSError:
         if self.fail_soft:
             return NotImplemented
         else:
             raise
def kinit_keytab(principal, keytab, ccache_name, config):
    """
    Perform kinit using principal/keytab, with the specified config file
    and store the TGT in ccache_name.
    """
    old_config = os.environ.get('KRB5_CONFIG')
    os.environ['KRB5_CONFIG'] = config
    try:
        name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
        store = {'ccache': ccache_name, 'client_keytab': keytab}
        cred = gssapi.Credentials(name=name, store=store, usage='initiate')
        return cred
    finally:
        if old_config is not None:
            os.environ['KRB5_CONFIG'] = old_config
        else:
            os.environ.pop('KRB5_CONFIG', None)
Ejemplo n.º 29
0
def use_keytab(principal, keytab):
    try:
        tmpdir = tempfile.mkdtemp(prefix = "tmp-")
        ccache_file = 'FILE:%s/ccache' % tmpdir
        name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
        store = {'ccache': ccache_file,
                 'client_keytab': keytab}
        os.environ['KRB5CCNAME'] = ccache_file
        gssapi.Credentials(name=name, usage='initiate', store=store)
        conn = ldap2(api)
        conn.connect(autobind=ipaldap.AUTOBIND_DISABLED)
        conn.disconnect()
    except gssapi.exceptions.GSSError as e:
        raise Exception('Unable to bind to LDAP. Error initializing principal %s in %s: %s' % (principal, keytab, str(e)))
    finally:
        os.environ.pop('KRB5CCNAME', None)
        if tmpdir:
            shutil.rmtree(tmpdir)
Ejemplo n.º 30
0
def use_keytab(principal, keytab):
    with private_ccache() as ccache_file:
        try:
            old_principal = getattr(context, 'principal', None)
            name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
            store = {'ccache': ccache_file, 'client_keytab': keytab}
            gssapi.Credentials(name=name, usage='initiate', store=store)
            conn = ldap2(api)
            conn.connect(ccache=ccache_file,
                         autobind=ipaldap.AUTOBIND_DISABLED)
            yield conn
            conn.disconnect()
        except gssapi.exceptions.GSSError as e:
            raise Exception('Unable to bind to LDAP. Error initializing '
                            'principal %s in %s: %s' %
                            (principal, keytab, str(e)))
        finally:
            setattr(context, 'principal', old_principal)