示例#1
0
    def _login_krbv(self):
        """Login using kerberos credentials (uses python-krbV)."""

        # 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")
        proxyuser = self._conf.get("KRB_PROXYUSER")

        import krbV
        ctx = krbV.default_context()

        if ccache is not None:
            ccache = krbV.CCache(name='FILE:' + ccache, context=ctx)
        else:
            ccache = ctx.default_ccache()

        if principal is not None:
            if keytab is not None:
                cprinc = krbV.Principal(name=principal, context=ctx)
                keytab = krbV.Keytab(name=keytab, context=ctx)
                ccache.init(cprinc)
                ccache.init_creds_keytab(principal=cprinc, keytab=keytab)
            else:
                raise ImproperlyConfigured(
                    "Cannot specify a principal without a keytab")
        else:
            # connect using existing credentials
            cprinc = ccache.principal()

        sprinc = krbV.Principal(name=self.get_server_principal(service=service,
                                                               realm=realm),
                                context=ctx)

        ac = krbV.AuthContext(context=ctx)
        ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
        ac.rcache = ctx.default_rcache()

        # create and encode the authentication request
        try:
            ac, req = ctx.mk_req(server=sprinc,
                                 client=cprinc,
                                 auth_context=ac,
                                 ccache=ccache,
                                 options=krbV.AP_OPTS_MUTUAL_REQUIRED)
        except krbV.Krb5Error as ex:
            if getattr(ex, "err_code", None) == -1765328377:
                ex.message += ". Make sure you correctly set KRB_REALM (current value: %s)." % realm
                ex.args = (ex.err_code, ex.message)
            raise ex
        encode_func = base64.encodebytes if hasattr(
            base64, "encodebytes") else base64.encodestring
        req_enc = encode_func(req)

        self._hub.auth.login_krbv(req_enc)
示例#2
0
    def testCCacheFileBadFormat(self):
        os.system('echo > %s' % config.user_ccache_file)
        context = krbV.default_context()
        ccache = krbV.CCache(config.user_ccache_file, context=context)
        principal = krbV.Principal(config.service_principal, context=context)
        result = is_initialize_ccache_necessary(context, ccache, principal)
        self.assert_(result)

        if config.run_under_user_principal:
            context = krbV.default_context()
            ccache = krbV.CCache(config.user_ccache_file, context=context)
            principal = krbV.Principal(config.user_principal, context=context)
            result = is_initialize_ccache_necessary(context, ccache, principal)
            self.assert_(result)
示例#3
0
    def testCCacheFileNotFound(self):
        os.system('kdestroy -c %s 2>/dev/null' % config.user_ccache_file)
        context = krbV.default_context()
        ccache = krbV.CCache(config.user_ccache_file, context=context)
        principal = krbV.Principal(config.service_principal, context=context)
        result = is_initialize_ccache_necessary(context, ccache, principal)
        self.assert_(result)

        if config.run_under_user_principal:
            context = krbV.default_context()
            ccache = krbV.CCache(config.user_ccache_file, context=context)
            principal = krbV.Principal(config.user_principal, context=context)
            result = is_initialize_ccache_necessary(context, ccache, principal)
            self.assert_(result)
示例#4
0
def clean_kwargs(context, kwargs):
    ''' Clean argument to related object

    In the case of using Key table, principal is required. keytab_file is
    optional, and default key table file /etc/krb5.keytab is used if
    keytab_file is not provided.

    In the case of initing as a regular user, principal is optional, and
    current user's effective name is used if principal is not provided.

    By default, initialize credentials cache for regular user.
    '''
    cleaned_kwargs = {}

    using_keytab = kwargs.get('using_keytab', False)
    if using_keytab:
        # Principal is required when using key table to initialize
        # credential cache.
        principal_name = kwargs.get('principal', None)
        if principal_name is None:
            raise NameError('Principal is required when using key table.')
        else:
            principal = krbV.Principal(principal_name, context=context)
            cleaned_kwargs['principal'] = principal
        kt_name = kwargs.get('keytab_file', None)
        if kt_name is None:
            keytab = context.default_keytab()
        else:
            keytab = krbV.Keytab(kt_name, context=context)
        cleaned_kwargs['keytab'] = keytab
    else:
        # When initialize credentials cache with a regular user, clean
        # principal has different rule. It will return a valid Principal object
        # always.
        principal_name = kwargs.get('principal', None)
        if principal_name is None:
            principal_name = get_login()
        principal = krbV.Principal(principal_name, context=context)
        cleaned_kwargs['principal'] = principal
    cleaned_kwargs['using_keytab'] = using_keytab

    ccache_file = kwargs.get('ccache_file', None)
    if ccache_file is None:
        ccache = get_default_ccache(context)
    else:
        ccache = krbV.CCache(ccache_file, context=context)
    cleaned_kwargs['ccache'] = ccache

    return cleaned_kwargs
示例#5
0
    def testInitCCacheIsUnnecessary(self):
        if config.run_under_user_principal:
            init_user_ccache()
            context = krbV.default_context()
            ccache = krbV.CCache(config.user_ccache_file, context=context)
            principal = krbV.Principal(config.user_principal, context=context)
            result = is_initialize_ccache_necessary(context, ccache, principal)
            self.assertFalse(result)

        init_ccache_using_keytab()
        context = krbV.default_context()
        ccache = krbV.CCache(config.user_ccache_file, context=context)
        principal = krbV.Principal(config.service_principal, context=context)
        result = is_initialize_ccache_necessary(context, ccache, principal)
        self.assertFalse(result)
示例#6
0
def login_krbv(request, krb_request, proxy_user=None):
    """login_krbv(krb_request, proxy_user=None): session_key"""
    import krbV

    context = krbV.default_context()
    server_principal = krbV.Principal(name=settings.KRB_AUTH_PRINCIPAL, context=context)
    server_keytab = krbV.Keytab(name=settings.KRB_AUTH_KEYTAB, context=context)

    auth_context = krbV.AuthContext(context=context)
    auth_context.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
    auth_context.addrs = (socket.gethostbyname(request.META["HTTP_HOST"]), 0, request.META["REMOTE_ADDR"], 0)

    # decode and read the authentication request
    decoded_request = base64.decodestring(krb_request)
    auth_context, opts, server_principal, cache_credentials = context.rd_req(decoded_request, server=server_principal, keytab=server_keytab, auth_context=auth_context, options=krbV.AP_OPTS_MUTUAL_REQUIRED)
    cprinc = cache_credentials[2]

    # remove @REALM
    username = cprinc.name.split("@")[0]
    backend = Krb5RemoteUserBackend()
    user = backend.authenticate(username)
    if user is None:
        raise PermissionDenied()
    user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
    django.contrib.auth.login(request, user)
    return request.session.session_key
def tcp_client(opts, conn):
    ctx = krbV.default_context()
    if opts.ccache:
        ccache = krbV.CCache(name='FILE:' + opts.ccache, context=ctx)
    else:
        ccache = ctx.default_ccache()
    cprinc = ccache.principal()
    sprinc = krbV.Principal(name=opts.principal, context=ctx)
    ac = ctx.sendauth(conn,
                      '1.0',
                      options=krbV.AP_OPTS_MUTUAL_REQUIRED,
                      server=sprinc,
                      client=cprinc,
                      ccache=ccache,
                      data='authtest')
    print 'Successfully authenticated via tcp to service: %s' % sprinc.name
    ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
    ac.rcache = ctx.default_rcache()
    ac.genaddrs(
        conn, krbV.KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR
        | krbV.KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)
    enc_msg = ac.mk_priv(opts.message)
    conn.send(enc_msg)
    enc_resp = conn.recv(4096)
    resp = ac.rd_priv(enc_resp)
    if resp == opts.message:
        print '  Exchanging encrypted messages succeeded'
    conn.close()
示例#8
0
def get_sender():
    global config, session, target
    if session and target:
        try:
            return session.sender(target)
        except:
            logging.getLogger('koji.plugin.messagebus').warning('Error getting session, will retry', exc_info=True)
            session = None
            target = None

    config = ConfigParser.SafeConfigParser()
    config.read(CONFIG_FILE)
    if not config.has_option('broker', 'timeout'):
        config.set('broker', 'timeout', '60')
    if not config.has_option('broker', 'heartbeat'):
        config.set('broker', 'heartbeat', '60')

    if config.getboolean('broker', 'ssl'):
        url = 'amqps://'
    else:
        url = 'amqp://'
    auth = config.get('broker', 'auth')
    if auth == 'PLAIN':
        url += config.get('broker', 'username') + '/'
        url += config.get('broker', 'password') + '@'
    elif auth == 'GSSAPI':
        ccname = 'MEMORY:messagebus'
        os.environ['KRB5CCNAME'] = ccname
        ctx = krbV.default_context()
        ccache = krbV.CCache(name=ccname, context=ctx)
        cprinc = krbV.Principal(name=config.get('broker', 'principal'), context=ctx)
        ccache.init(principal=cprinc)
        keytab = krbV.Keytab(name='FILE:' + config.get('broker', 'keytab'), context=ctx)
        ccache.init_creds_keytab(principal=cprinc, keytab=keytab)
    else:
        raise PluginError('unsupported auth type: %s' % auth)

    url += config.get('broker', 'host') + ':'
    url += config.get('broker', 'port')

    conn = Connection.establish(url,
                                sasl_mechanisms=config.get('broker', 'auth'),
                                transport='tls+timeout',
                                timeout=config.getfloat('broker', 'timeout'),
                                heartbeat=config.getint('broker', 'heartbeat'))
    sess = conn.session()
    tgt = """%s;
             { create: sender,
               assert: always,
               node: { type: topic,
                       durable: %s,
                       x-declare: { exchange: "%s",
                                    type: %s } } }""" % \
    (config.get('exchange', 'name'), config.getboolean('exchange', 'durable'),
     config.get('exchange', 'name'), config.get('exchange', 'type'))
    sender = sess.sender(tgt)
    session = sess
    target = tgt

    return sender
示例#9
0
    def test_krb_login(self):
        if not krbV:
            raise SkipTest('krbV module not found')
        server_princ_name = turbogears.config.get(
            'identity.krb_auth_principal', None)
        if not server_princ_name:  # XXX FIXME dead test
            raise SkipTest('server not configured for krbV')

        # build krb request
        ctx = krbV.default_context()
        try:
            ccache = ctx.default_ccache()
            client_princ = ccache.principal()
        except krbV.Krb5Error:
            raise SkipTest('client ticket not found, run kinit first')
        server_princ = krbV.Principal(name=server_princ_name, context=ctx)
        ac = krbV.AuthContext(context=ctx)
        ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
        ac.rcache = ctx.default_rcache()
        ac, req = ctx.mk_req(server=sprinc,
                             client=cprinc,
                             auth_context=ac,
                             ccache=ccache,
                             options=krbV.AP_OPTS_MUTUAL_REQUIRED)
        encoded_req = base64.encodestring(req)

        # attempt to log in
        server = self.get_server()
        server.auth.login_krbv(encoded_req)
示例#10
0
def udp_client(opts, sock, addr):
    ctx = krbV.default_context()
    if opts.ccache:
        ccache = krbV.CCache(name='FILE:' + opts.ccache, context=ctx)
    else:
        ccache = ctx.default_ccache()
    cprinc = ccache.principal()
    sprinc = krbV.Principal(name=opts.principal, context=ctx)
    ac = krbV.AuthContext(context=ctx)
    ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
    ac.rcache = ctx.default_rcache()
    ac, req = ctx.mk_req(server=sprinc,
                         client=cprinc,
                         auth_context=ac,
                         ccache=ccache,
                         options=krbV.AP_OPTS_MUTUAL_REQUIRED)
    sock.sendto(req, addr)
    rep, saddr = sock.recvfrom(4096)
    rep_tup = ctx.rd_rep(rep, auth_context=ac)
    print 'Successfully authenticated via udp to service: %s' % sprinc.name
    try:
        addrinfo = socket.getaddrinfo(socket.gethostname(),
                                      sock.getsockname()[1], opts.addr_family)
        localaddr = addrinfo[0][4]
    except socket.gaierror, e:
        gai_error(opts, 'local', socket.gethostname(), e)
示例#11
0
    def krbLogin(self, krb_req, proxyuser=None):
        """Authenticate the user using the base64-encoded
        AP_REQ message in krb_req.  If proxyuser is not None,
        log in that user instead of the user associated with the
        Kerberos principal.  The principal must be an authorized
        "proxy_principal" in the server config."""
        if self.logged_in:
            raise koji.AuthError("Already logged in")

        if not (context.opts.get('AuthPrincipal') and context.opts.get('AuthKeytab')):
            raise koji.AuthError('not configured for Kerberos authentication')

        ctx = krbV.default_context()
        srvprinc = krbV.Principal(name=context.opts.get('AuthPrincipal'), context=ctx)
        srvkt = krbV.Keytab(name=context.opts.get('AuthKeytab'), context=ctx)

        ac = krbV.AuthContext(context=ctx)
        ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE|krbV.KRB5_AUTH_CONTEXT_DO_TIME
        conninfo = self.getConnInfo()
        ac.addrs = conninfo

        # decode and read the authentication request
        req = base64.decodestring(krb_req)
        ac, opts, sprinc, ccreds = ctx.rd_req(req, server=srvprinc, keytab=srvkt,
                                              auth_context=ac,
                                              options=krbV.AP_OPTS_MUTUAL_REQUIRED)
        cprinc = ccreds[2]

        # Successfully authenticated via Kerberos, now log in
        if proxyuser:
            proxyprincs = [princ.strip() for princ in context.opts.get('ProxyPrincipals', '').split(',')]
            if cprinc.name in proxyprincs:
                login_principal = proxyuser
            else:
                raise koji.AuthError(
                      'Kerberos principal %s is not authorized to log in other users' % cprinc.name)
        else:
            login_principal = cprinc.name
        user_id = self.getUserIdFromKerberos(login_principal)
        if not user_id:
            if context.opts.get('LoginCreatesUser'):
                user_id = self.createUserFromKerberos(login_principal)
            else:
                raise koji.AuthError('Unknown Kerberos principal: %s' % login_principal)

        self.checkLoginAllowed(user_id)

        hostip = self.get_remote_ip()

        sinfo = self.createSession(user_id, hostip, koji.AUTHTYPE_KERB)

        # encode the reply
        rep = ctx.mk_rep(auth_context=ac)
        rep_enc = base64.encodestring(rep)

        # encrypt and encode the login info
        sinfo_priv = ac.mk_priv('%(session-id)s %(session-key)s' % sinfo)
        sinfo_enc = base64.encodestring(sinfo_priv)

        return (rep_enc, sinfo_enc, conninfo)
示例#12
0
def handle_udp(opts, sock):
    data, addr = sock.recvfrom(4096)
    ctx = krbV.default_context()
    sprinc = krbV.Principal(name=opts.principal, context=ctx)
    keytab = krbV.Keytab(name=opts.keytab, context=ctx)
    ac = krbV.AuthContext(context=ctx)
    ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
    ac, options, sprinc, ccreds = ctx.rd_req(
        data,
        server=sprinc,
        keytab=keytab,
        auth_context=ac,
        options=krbV.AP_OPTS_MUTUAL_REQUIRED)
    cprinc = ccreds[2]
    print 'Successfully authenticated via udp: %s' % cprinc.name
    rep = ctx.mk_rep(auth_context=ac)
    sock.sendto(rep, addr)
    msg_enc, addr = sock.recvfrom(4096)
    print 'Using addresses: %s' % str(
        (opts.serveraddr[0], opts.serveraddr[1], addr[0], addr[1]))
    ac.addrs = (opts.serveraddr[0], opts.serveraddr[1], addr[0], addr[1])
    msg = ac.rd_priv(msg_enc)
    print '  Received: %s' % msg
    resp_enc = ac.mk_priv(msg)
    sock.sendto(resp_enc, addr)
示例#13
0
    def get_credentials(self, principal):
        '''
        Given a Kerberos principal return the krbV credentials
        tuple describing the credential. If the principal does
        not exist in the ccache a KeyError is raised.

        :parameters:
          principal
            The Kerberos principal whose ticket is being retrieved.
            The principal may be either a string formatted as a
            Kerberos V5 principal or it may be a `krbV.Principal`
            object.
        :returns:
          A krbV credentials tuple. If the principal is not in the
          ccache a KeyError is raised.

        '''

        if isinstance(principal, krbV.Principal):
            krbV_principal = principal
        else:
            try:
                krbV_principal = krbV.Principal(str(principal), self.context)
            except Exception, e:
                self.error('could not create krbV principal from "%s", %s',
                           principal, e)
                raise e
示例#14
0
def refresh_HTTP_credential_cache():
    '''
    Put service ticket into credential cache from service's keytab file.

    Return the credential cache file name.
    '''

    import krbV, os

    keytab_file = st.SERVICE_KEYTAB
    principal_name = st.SERVICE_PRINCIPAL
    # This is the credential cache file, according to the Kerberbos V5 standard
    ccache_file = '/tmp/krb5cc_%d_%d' % (os.getuid(), os.getpid())

    ctx = krbV.default_context()
    princ = krbV.Principal(name=principal_name, context=ctx)
    if keytab_file:
        keytab = krbV.Keytab(name=keytab_file, context=ctx)
    else:
        # According the documentation of MIT Kerberos V5,
        # default keytab file is /etc/krb5.keytab. It might be changed
        # by modifying default_keytab_name in krb5.conf
        keytab = ctx.default_keytab()
    ccache = krbV.CCache(name=ccache_file, context=ctx)

    ccache.init(princ)
    ccache.init_creds_keytab(principal=princ, keytab=keytab)

    return ccache_file
 def finish_state(self):
     if self.state == self.STATE_SETUP:
         need_retry = 10
         authmgr = self.cnx.coord.app.auth
         while need_retry:
             need_retry -= 1
             try:
                 princ = authmgr.primary_principal
                 creds = (princ,
                          krbV.Principal(
                              'krbtgt/%s@%s' % (princ.realm, princ.realm),
                              context=authmgr.context), (0, None),
                          (0, 0, 0, 0), None, None, None, None, None, None)
                 ocreds = authmgr.ccache.get_credentials(creds)
                 need_retry = 0
             except krbV.Krb5Error, e:
                 if not need_retry: raise
                 if e.err_code != krbV.KRB5KRB_AP_ERR_TKT_EXPIRED:
                     return self.fail()
                 authmgr.reinit()
         self.write_vals = {
             'localname': self.cnx.coord.app.localname,
             'cnxid': self.cnx.cnxid,
             'localprinc': princ.name,
             'reqdata': ocreds[7],
             'useruserkey': ocreds[2]
         }
         self.state = self.STATE_WRITING
示例#16
0
def kinit_keytab(principal, keytab, ccache_name, attempts=1):
    """
    Given a ccache_path, keytab file and a principal kinit as that user.

    The optional parameter 'attempts' specifies how many times the credential
    initialization should be attempted in case of non-responsive KDC.
    """
    errors_to_retry = {krbV.KRB5KDC_ERR_SVC_UNAVAILABLE, krbV.KRB5_KDC_UNREACH}
    root_logger.debug("Initializing principal %s using keytab %s" %
                      (principal, keytab))
    root_logger.debug("using ccache %s" % ccache_name)
    for attempt in range(1, attempts + 1):
        try:
            krbcontext = krbV.default_context()
            ktab = krbV.Keytab(name=keytab, context=krbcontext)
            princ = krbV.Principal(name=principal, context=krbcontext)
            ccache = krbV.CCache(name=ccache_name,
                                 context=krbcontext,
                                 primary_principal=princ)
            ccache.init(princ)
            ccache.init_creds_keytab(keytab=ktab, principal=princ)
            root_logger.debug("Attempt %d/%d: success" % (attempt, attempts))
            return
        except krbV.Krb5Error as e:
            if e.args[0] not in errors_to_retry:
                raise
            root_logger.debug("Attempt %d/%d: failed: %s" %
                              (attempt, attempts, e))
            if attempt == attempts:
                root_logger.debug("Maximum number of attempts (%d) reached" %
                                  attempts)
                raise
            root_logger.debug("Waiting 5 seconds before next retry")
            time.sleep(5)
示例#17
0
 def setUp(self):
     self.context = krbV.default_context()
     self.principal = krbV.Principal(config.service_principal,
                                     context=self.context)
     self.keytab = krbV.Keytab(config.user_keytab_file,
                               context=self.context)
     self.ccache = krbV.CCache(config.user_ccache_file,
                               context=self.context)
示例#18
0
    def login_krbV(self, krb_request, proxy_user=None):
        """
        Authenticates the current session using Kerberos.
        The caller may act as a proxy on behalf of another user by passing the
        *proxy_user* argument. This requires that the caller has 'proxy_auth'
        permission.
        :param krb_request: KRB_AP_REQ message containing client credentials,
        as produced by :c:func:`krb5_mk_req`
        :type krb_request: base64-encoded string
        :param proxy_user: username on whose behalf the caller is proxying
        :type proxy_user: string or None
        This method is also available under the alias :meth:`auth.login_krbv`,
        for compatibility with `Kobo`_.
        """
        import krbV
        import base64

        context = krbV.default_context()
        server_principal = krbV.Principal(name=KRB_AUTH_PRINCIPAL,
                                          context=context)
        server_keytab = krbV.Keytab(name=KRB_AUTH_KEYTAB, context=context)

        auth_context = krbV.AuthContext(context=context)
        auth_context.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
        auth_context.addrs = (socket.gethostbyname(
            cherrypy.request.remote_host), 0, cherrypy.request.remote_addr, 0)

        # decode and read the authentication request
        decoded_request = base64.decodestring(krb_request)
        auth_context, opts, server_principal, cache_credentials = context.rd_req(
            decoded_request,
            server=server_principal,
            keytab=server_keytab,
            auth_context=auth_context,
            options=krbV.AP_OPTS_MUTUAL_REQUIRED)
        cprinc = cache_credentials[2]

        # remove @REALM
        username = cprinc.name.split("@")[0]
        user = User.by_user_name(username)
        if user is None:
            raise LoginException(_(u'Invalid username'))
        if not user.can_log_in():
            raise LoginException(_(u'Invalid username'))
        if proxy_user:
            if not user.has_permission(u'proxy_auth'):
                raise LoginException(
                    _(u'%s does not have proxy_auth permission') %
                    user.user_name)
            proxied_user = User.by_user_name(proxy_user)
            if proxied_user is None:
                raise LoginException(
                    _(u'Proxy user %s does not exist') % proxy_user)
            identity.set_authentication(proxied_user, proxied_by=user)
        else:
            identity.set_authentication(user)
        return username
示例#19
0
def login_krbv():
    """
    Authenticates the current session using Kerberos.
    The caller may act as a proxy on behalf of another user by passing the
    *proxy_user* key. This requires that the caller has 'proxy_auth'
    permission. The request body must be a JSON object containing krb_request.
    Proxy_user is optional.

    :jsonparam base64-encoded-string krb_request: KRB_AP_REQ message containing
        client credentials, as produced by :c:func:`krb5_mk_req`
    :jsonparam string proxy_user: Username on whose behalf the caller is proxying
    """
    import krbV
    import base64

    payload = read_json_request(request)
    krb_request = payload.get('krb_request')
    proxy_user = payload.get('proxy_user')

    context = krbV.default_context()
    server_principal = krbV.Principal(name=KRB_AUTH_PRINCIPAL, context=context)
    server_keytab = krbV.Keytab(name=KRB_AUTH_KEYTAB, context=context)

    auth_context = krbV.AuthContext(context=context)
    auth_context.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
    auth_context.addrs = (socket.gethostbyaddr(request.remote_addr), 0,
                          request.remote_addr, 0)

    # decode and read the authentication request
    decoded_request = base64.decodestring(krb_request)
    auth_context, opts, server_principal, cache_credentials = context.rd_req(
        decoded_request,
        server=server_principal,
        keytab=server_keytab,
        auth_context=auth_context,
        options=krbV.AP_OPTS_MUTUAL_REQUIRED)
    cprinc = cache_credentials[2]

    # remove @REALM
    username = cprinc.name.split("@")[0]
    user = User.by_user_name(username)
    if user is None:
        raise Unauthorised401(u'Invalid username')
    if not user.can_log_in():
        raise Unauthorised401(u'Invalid username')
    if proxy_user:
        if not user.has_permission(u'proxy_auth'):
            raise Unauthorised401(u'%s does not have proxy_auth permission' %
                                  user.user_name)
        proxied_user = User.by_user_name(proxy_user)
        if proxied_user is None:
            raise Unauthorised401(u'Proxy user %s does not exist' % proxy_user)
        identity.set_authentication(proxied_user, proxied_by=user)
    else:
        identity.set_authentication(user)
    return jsonify({'username': user.user_name})
示例#20
0
    def testInitCCacheIsNecessary(self):
        ''' Sleep several seconds after initializing credentials cache so that
            it expires.
        '''
        if config.run_under_user_principal:
            init_user_ccache(lifetime='3s')
            time.sleep(5)
            context = krbV.default_context()
            ccache = krbV.CCache(config.user_ccache_file, context=context)
            principal = krbV.Principal(config.user_principal, context=context)
            result = is_initialize_ccache_necessary(context, ccache, principal)
            self.assert_(result)

        init_ccache_using_keytab(lifetime='3s')
        time.sleep(5)
        context = krbV.default_context()
        ccache = krbV.CCache(config.user_ccache_file, context=context)
        principal = krbV.Principal(config.service_principal, context=context)
        result = is_initialize_ccache_necessary(context, ccache, principal)
        self.assert_(result)
示例#21
0
 def __init__(self,principal,keytab,ccache_file=None):
     self.context = krbV.default_context()
     self.principal = krbV.Principal(name=principal, context=self.context)
     self.keytab = krbV.Keytab(name=keytab, context=self.context)
     self.ccache_file = ccache_file
     if ccache_file:
         self.ccache_file = ccache_file
         self.ccache = krbV.CCache(name="FILE:" + self.ccache_file, context=self.context, primary_principal=self.principal)
     else:
         self.ccache = self.context.default_ccache(primary_principal=self.principal)
     self.ccache.init(self.principal)
     self.ccache.init_creds_keytab(keytab=self.keytab,principal=self.principal)
示例#22
0
def get_tgt_time(context, ccache, principal):
    ''' Get specified TGT's credential time.

    Arguments:
    - context, current context object.
    - ccache, the CCache object that is associated with context.
    - principal, the principal that is being used for getting ticket.
    '''
    tgt_princ = krbV.Principal(build_tgt_ticket(principal), context=context)
    creds = (principal, tgt_princ, (0, None), (0, 0, 0, 0), None, None, None,
             None, None, None)
    result = ccache.get_credentials(creds, krbV.KRB5_GC_CACHED, 0)
    time_conv = datetime.fromtimestamp
    return CredentialTime._make([time_conv(t) for t in result[3]])
示例#23
0
    def get_encoded_request(self, full_principal):
        sprinc = krbV.Principal(name=full_principal, context=self.context)
        ac = krbV.AuthContext(context=self.context)
        ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
        ac.rcache = self.context.default_rcache()

        # create and encode the authentication request
        try:
            req = self._create_request(sprinc, ac)
        except krbV.Krb5Error, e:
            if 'Ticket expired' in str(e):
                self.reinit()
                req = self._create_request(sprinc, ac)
            else:
                raise
示例#24
0
def handle_tcp(opts, sock):
    conn, addr = sock.accept()
    ctx = krbV.default_context()
    sprinc = krbV.Principal(name=opts.principal, context=ctx)
    keytab = krbV.Keytab(name=opts.keytab, context=ctx)
    ac, cprinc = ctx.recvauth(conn,
                              '1.0',
                              options=krbV.AP_OPTS_MUTUAL_REQUIRED,
                              server=sprinc,
                              keytab=keytab)
    print 'Successfully authenticated via tcp: %s' % cprinc.name
    ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
    ac.genaddrs(
        conn, krbV.KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR
        | krbV.KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)
    msg_enc = conn.recv(4096)
    msg = ac.rd_priv(msg_enc)
    print '  Received: %s' % msg
    resp_enc = ac.mk_priv(msg)
    conn.send(resp_enc)
    conn.close()
示例#25
0
    def get_credential_times(self, principal):
        '''
        Given a Kerberos principal return the ticket timestamps if the
        principal's ticket in the ccache is valid.  If the principal
        does not exist in the ccache a KeyError is raised.

        The return credential time values are Unix timestamps in
        localtime.

        The returned timestamps are:

        authtime
          The time when the ticket was issued.
        starttime
          The time when the ticket becomes valid.
        endtime
          The time when the ticket expires.
        renew_till
          The time when the ticket becomes no longer renewable (if renewable).

        :parameters:
          principal
            The Kerberos principal whose ticket is being validated.
            The principal may be either a string formatted as a
            Kerberos V5 principal or it may be a `krbV.Principal`
            object.
        :returns:
            return authtime, starttime, endtime, renew_till
        '''

        if isinstance(principal, krbV.Principal):
            krbV_principal = principal
        else:
            try:
                krbV_principal = krbV.Principal(str(principal), self.context)
            except Exception, e:
                self.error('could not create krbV principal from "%s", %s',
                           principal, e)
                raise e
 def __init__(self,
              app,
              cache_file=None,
              primary_principal=None,
              keytab=None):
     self.context = krbV.default_context()
     self.primary_principal = primary_principal
     self.keytab = keytab
     if not keytab:
         self.keytab = app.config.get('auth.keytab')
     if self.keytab and not isinstance(self.keytab, krbV.Keytab):
         self.keytab = krbV.Keytab(name=self.keytab, context=self.context)
     if not self.primary_principal:
         self.primary_principal = app.config.get('auth.principal')
     if not self.primary_principal:
         self.primary_principal = None
     if self.primary_principal and not isinstance(self.primary_principal,
                                                  krbV.Principal):
         self.primary_principal = krbV.Principal(
             name=self.primary_principal, context=self.context)
     if self.primary_principal:
         if cache_file:
             self.ccache = krbV.CCache(
                 name="FILE:" + cache_file,
                 context=self.context,
                 primary_principal=self.primary_principal)
         else:
             self.ccache = self.context.default_ccache(
                 primary_principal=self.primary_principal)
     else:
         if cache_file:
             self.ccache = krbV.CCache(name="FILE:" + cache_file,
                                       context=self.context)
         else:
             self.ccache = self.context.default_ccache()
         self.primary_principal = self.ccache.principal()
     if self.keytab: self.reinit()
     self.local_rsa_info = None
     self.rsa_info = {}
示例#27
0
 def __init__(self, cache_file=None, primary_principal=None, keytab=None):
     self.context = krbV.default_context()
     self.primary_principal = primary_principal
     self.keytab = keytab
     if self.keytab and not isinstance(self.keytab, krbV.Keytab):
         self.keytab = krbV.Keytab(name=self.keytab, context=self.context)
     if not self.primary_principal and not cache_file:
         raise ValueError('No cache file nor primary principal')
     if self.primary_principal and not isinstance(self.primary_principal, krbV.Principal):
         self.primary_principal = krbV.Principal(name=self.primary_principal, context=self.context)
     if self.primary_principal:
         if cache_file:
             self.ccache = krbV.CCache(name="FILE:"+cache_file, context=self.context,
                                       primary_principal=self.primary_principal)
         else:
             self.ccache = self.context.default_ccache(primary_principal=self.primary_principal)
     else:
         if cache_file:
             self.ccache = krbV.CCache(name="FILE:"+cache_file, context=self.context)
         else:
             self.ccache = self.context.default_ccache()
         self.primary_principal = self.ccache.principal()
     if self.keytab: self.reinit()
示例#28
0
def use_keytab(principal, keytab):
    try:
        tmpdir = tempfile.mkdtemp(prefix="tmp-")
        ccache_file = 'FILE:%s/ccache' % tmpdir
        krbcontext = krbV.default_context()
        principal = str(principal)
        keytab = krbV.Keytab(name=keytab, context=krbcontext)
        principal = krbV.Principal(name=principal, context=krbcontext)
        os.environ['KRB5CCNAME'] = ccache_file
        ccache = krbV.CCache(name=ccache_file,
                             context=krbcontext,
                             primary_principal=principal)
        ccache.init(principal)
        ccache.init_creds_keytab(keytab=keytab, principal=principal)
        conn = ldap2(shared_instance=False,
                     ldap_uri=api.env.ldap_uri,
                     base_dn=api.env.basedn)
        conn.connect(ccache=ccache)
        conn.disconnect()
    except krbV.Krb5Error, e:
        raise StandardError(
            'Unable to bind to LDAP. Error initializing principal %s in %s: %s'
            % (principal.name, keytab, str(e)))
示例#29
0
def kinit_hostprincipal(keytab, ccachedir, principal):
    """
    Given a ccache directory and a principal kinit as that user.

    This blindly overwrites the current CCNAME so if you need to save
    it do so before calling this function.

    Thus far this is used to kinit as the local host.
    """
    try:
        ccache_file = 'FILE:%s/ccache' % ccachedir
        krbcontext = krbV.default_context()
        ktab = krbV.Keytab(name=keytab, context=krbcontext)
        princ = krbV.Principal(name=principal, context=krbcontext)
        os.environ['KRB5CCNAME'] = ccache_file
        ccache = krbV.CCache(name=ccache_file,
                             context=krbcontext,
                             primary_principal=princ)
        ccache.init(princ)
        ccache.init_creds_keytab(keytab=ktab, principal=princ)
        return ccache_file
    except krbV.Krb5Error, e:
        raise StandardError('Error initializing principal %s in %s: %s' %
                            (principal, keytab, str(e)))
示例#30
0
文件: hub.py 项目: joyxu/beaker
    def _login_krbv(self):
        """Login using kerberos credentials (uses python-krbV)."""
        def get_server_principal(service=None, realm=None):
            """Convert hub url to kerberos principal."""
            hostname = urlparse.urlparse(self._hub_url)[1]
            # remove port from hostname
            hostname = hostname.split(":")[0]

            if realm is None:
                # guess realm: last two parts from hostname
                realm = ".".join(hostname.split(".")[-2:]).upper()
            if service is None:
                service = "HTTP"
            return '%s/%s@%s' % (service, hostname, realm)

        # 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")
        proxyuser = self._conf.get("PROXY_USER")

        import krbV
        ctx = krbV.default_context()

        if ccache is not None:
            ccache = krbV.CCache(name='FILE:' + ccache, context=ctx)
        elif keytab is not None:
            # If we will be init'ing the ccache using a keytab, we need to
            # always avoid using the default shared ccache, as a workaround for
            # a race condition in krb5_cc_initialize() between unlink() and open()
            # (see RHBZ#1313580).
            ccache_tmpfile = tempfile.NamedTemporaryFile(prefix='krb5cc_bkr_')
            ccache = krbV.CCache(name='FILE:' + ccache_tmpfile.name,
                                 context=ctx)
        else:
            ccache = ctx.default_ccache()

        if principal is not None:
            if keytab is not None:
                cprinc = krbV.Principal(name=principal, context=ctx)
                keytab = krbV.Keytab(name=keytab, context=ctx)
                ccache.init(cprinc)
                ccache.init_creds_keytab(principal=cprinc, keytab=keytab)
            else:
                raise ImproperlyConfigured(
                    "Cannot specify a principal without a keytab")
        else:
            # connect using existing credentials
            cprinc = ccache.principal()

        sprinc = krbV.Principal(name=get_server_principal(service=service,
                                                          realm=realm),
                                context=ctx)

        ac = krbV.AuthContext(context=ctx)
        ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME
        ac.rcache = ctx.default_rcache()

        # create and encode the authentication request
        try:
            ac, req = ctx.mk_req(server=sprinc,
                                 client=cprinc,
                                 auth_context=ac,
                                 ccache=ccache,
                                 options=krbV.AP_OPTS_MUTUAL_REQUIRED)
        except krbV.Krb5Error, ex:
            if getattr(ex, "err_code", None) == -1765328377:
                ex.message += ". Make sure you correctly set KRB_REALM (current value: %s)." % realm
                ex.args = (ex.err_code, ex.message)
            raise ex