Exemple #1
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)
Exemple #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)
Exemple #3
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)
Exemple #4
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)
    def run(self):
        api.bootstrap(in_server=True)
        api.finalize()

        conn = ldap2(api)
        try:
            ccache = krbV.default_context().default_ccache()
            conn.connect(ccache=ccache)
        except (krbV.Krb5Error, errors.ACIError):
            raise admintool.ScriptError("Unable to connect to LDAP! Did you kinit?")

        try:
            # Parse tokens
            for keypkg in self.doc.getKeyPackages():
                try:
                    api.Command.otptoken_add(keypkg.id, no_qrcode=True, **keypkg.options)
                except Exception as e:
                    self.log.warn("Error adding token: %s", e)
                else:
                    self.log.info("Added token: %s", keypkg.id)
                    keypkg.remove()
        finally:
            conn.disconnect()

        # Write out the XML file without the tokens that succeeded.
        self.doc.save(self.output)
Exemple #6
0
def get_realm():
    """
    Returns the default kerberos realm configured for this server.
    """
    krbctx = krbV.default_context()

    return unicode(krbctx.default_realm)
Exemple #7
0
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 = krbV.RCache(name=sprinc[0], context=ctx)
    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()
Exemple #8
0
    def __init__(self, ccache):
        """
        :parameters:
          ccache
            The name of a Kerberos ccache used to hold Kerberos tickets.
        :returns:
          `KRB5_CCache` object encapsulting the ccache.
        """
        log_mgr.get_logger(self, True)
        self.context = None
        self.scheme = None
        self.name = None
        self.ccache = None
        self.principal = None

        try:
            self.context = krbV.default_context()
            self.scheme, self.name = krb5_parse_ccache(ccache)
            self.ccache = krbV.CCache(name=str(ccache), context=self.context)
            self.principal = self.ccache.principal()
        except krbV.Krb5Error, e:
            error_code = e.args[0]
            message = e.args[1]
            if error_code == KRB5_FCC_NOFILE:
                raise ValueError('"%s", ccache="%s"' % (message, ccache))
            else:
                raise e
Exemple #9
0
    def url2dbinfos(url):
        url = urlparse.urlparse(url)
        userinfo = {}
        if "@" in url.netloc:
            username = url.netloc[: url.netloc.index("@")]
            if ":" in username:
                userinfo = dict(zip(["username", "password"], map(urllib.unquote, username.split(":", 1))))
            else:
                username = urllib.unquote(username)
                if username == "GSSAPI":
                    import krbV

                    userinfo = {
                        "username": (krbV.default_context().default_ccache().principal().name),
                        "mechanism": "GSSAPI",
                    }
                elif "@" in username:
                    userinfo = {"username": username, "mechanism": "GSSAPI"}
                else:
                    userinfo = {"username": username}
            hostname = url.netloc[url.netloc.index("@") + 1 :]
        else:
            hostname = url.netloc
        if not hostname:
            hostname = None
        dbname = url.path.lstrip("/")
        if not dbname:
            dbname = "ivre"
        params = dict(x.split("=", 1) if "=" in x else [x, None] for x in url.query.split("&") if x)
        params.update(userinfo)
        return (url.scheme, (hostname, dbname), params)
Exemple #10
0
    def __init__(self, ccache):
        '''
        :parameters:
          ccache
            The name of a Kerberos ccache used to hold Kerberos tickets.
        :returns:
          `KRB5_CCache` object encapsulting the ccache.
        '''
        log_mgr.get_logger(self, True)
        self.context = None
        self.scheme = None
        self.name = None
        self.ccache = None
        self.principal = None

        try:
            self.context = krbV.default_context()
            self.scheme, self.name = krb5_parse_ccache(ccache)
            self.ccache = krbV.CCache(name=str(ccache), context=self.context)
            self.principal = self.ccache.principal()
        except krbV.Krb5Error, e:
            error_code = e.args[0]
            message = e.args[1]
            if error_code == KRB5_FCC_NOFILE:
                raise ValueError('"%s", ccache="%s"' % (message, ccache))
            else:
                raise e
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)
Exemple #12
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)
Exemple #13
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
Exemple #14
0
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)
    tgt = krbV.Principal('krbtgt/%s@%s' % (sprinc.realm, sprinc.realm), context=ctx)
    try:
        creds = (cprinc, tgt, (0, None), (0,0,0,0), None, None, None, None, None, None)
        tcreds = ccache.get_credentials(creds, krbV.KRB5_GC_CACHED)
        creds = (cprinc, sprinc, (0, None), (0,0,0,0), None, None, None, None, tcreds[7], None)
        screds = ccache.get_credentials(creds, krbV.KRB5_GC_USER_USER)
	ac = krbV.AuthContext(context=ctx)
	ac, bc = ctx.mk_req(sprinc, 'None', krbV.AP_OPTS_MUTUAL_REQUIRED, cprinc, ccache, ac, screds)
	pdb.set_trace()
	_ignore, vc = kerberos.authGSSClientInit('*****@*****.**')
	kerberos.authGSSClientStep(vc, "")
	#_ignore = kerberos.authGSSClientStep(ctx, bc)
	#tgt = kerberos.authGSSClientResponse(ctx)
	headers = {'Authorization': 'Negotiate %s' % kerberos.authGSSClientResponse(vc) }
	servername, port = ('localhost', 80)
	h = httplib.HTTPConnection(servername, port)
	h.request('GET', "", "", headers)
	response = h.getresponse()
	print 'Successfully authenticated via tcp to service: %s' % sprinc.name
    except krbV.Krb5Error, e:
	return e
Exemple #15
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
Exemple #16
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
Exemple #17
0
def _mongodb_url2dbinfos(url):
    userinfo = {}
    if '@' in url.netloc:
        username = url.netloc[:url.netloc.index('@')]
        if ':' in username:
            userinfo = dict(
                zip(["username", "password"],
                    map(urllib.unquote, username.split(':', 1))))
        else:
            username = urllib.unquote(username)
            if username == 'GSSAPI':
                import krbV
                userinfo = {
                    'username':
                    (krbV.default_context().default_ccache().principal().name),
                    'mechanism':
                    'GSSAPI'
                }
            elif '@' in username:
                userinfo = {'username': username, 'mechanism': 'GSSAPI'}
            else:
                userinfo = {'username': username}
        hostname = url.netloc[url.netloc.index('@') + 1:]
    else:
        hostname = url.netloc
    if not hostname:
        hostname = None
    dbname = url.path.lstrip('/')
    if not dbname:
        dbname = 'ivre'
    params = dict(
        x.split('=', 1) if '=' in x else [x, None]
        for x in url.query.split('&') if x)
    params.update(userinfo)
    return (url.scheme, (hostname, dbname), params)
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)
Exemple #19
0
    def run(self):
        api.bootstrap(in_server=True)
        api.finalize()

        conn = ldap2()
        try:
            ccache = krbV.default_context().default_ccache()
            conn.connect(ccache=ccache)
        except (krbV.Krb5Error, errors.ACIError):
            raise admintool.ScriptError(
                "Unable to connect to LDAP! Did you kinit?")

        try:
            # Parse tokens
            for keypkg in self.doc.getKeyPackages():
                try:
                    api.Command.otptoken_add(keypkg.id,
                                             no_qrcode=True,
                                             **keypkg.options)
                except Exception as e:
                    self.log.warn("Error adding token: %s", e)
                else:
                    self.log.info("Added token: %s", keypkg.id)
                    keypkg.remove()
        finally:
            conn.disconnect()

        # Write out the XML file without the tokens that succeeded.
        self.doc.save(self.output)
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()
Exemple #21
0
 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 = {}
Exemple #22
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 koji.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
Exemple #23
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)
Exemple #24
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)
Exemple #25
0
def get_realm():
    """
    Returns the default kerberos realm configured for this server.
    """
    krbctx = krbV.default_context()

    return unicode(krbctx.default_realm)
Exemple #26
0
    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("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=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
Exemple #27
0
def get_principal():
    ctx = krbV.default_context()
    cc = ctx.default_ccache()
    try:
        princ = cc.principal()
        return princ.name
    except krbV.Krb5Error:
        return None
Exemple #28
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)
    def run(self):
        super(ServerUpgrade, self).run()

        api.bootstrap(in_server=True, context='updates')
        api.finalize()

        options = self.options

        if not options.skip_version_check:
            # check IPA version and data version
            try:
                installutils.check_version()
            except (installutils.UpgradePlatformError,
                    installutils.UpgradeDataNewerVersionError) as e:
                raise admintool.ScriptError(
                    'Unable to execute IPA upgrade: %s' % e, 1)
            except installutils.UpgradeMissingVersionError as e:
                self.log.info("Missing version: %s", e)
            except installutils.UpgradeVersionError:
                # Ignore other errors
                pass
        else:
            self.log.info("Skipping version check")
            self.log.warning("Upgrade without version check may break your "
                             "system")

        realm = krbV.default_context().default_realm
        schema_files = [os.path.join(ipautil.SHARE_DIR, f) for f
                        in dsinstance.ALL_SCHEMA_FILES]
        data_upgrade = IPAUpgrade(realm, schema_files=schema_files)

        try:
            data_upgrade.create_instance()
        except BadSyntax:
            raise admintool.ScriptError(
                'Bad syntax detected in upgrade file(s).', 1)
        except RuntimeError:
            raise admintool.ScriptError('IPA upgrade failed.', 1)
        else:
            if data_upgrade.modified:
                self.log.info('Update complete')
            else:
                self.log.info('Update complete, no data were modified')

        # store new data version after upgrade
        installutils.store_version()

        # FIXME: remove this when new installer will be ready
        # execute upgrade of configuration
        cmd = ['ipa-upgradeconfig', ]
        if options.verbose:
            cmd.append('--debug')
        if options.quiet:
            cmd.append('--quiet')

        self.log.info('Executing ipa-upgradeconfig, please wait')
        ipautil.run(cmd)
Exemple #30
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)
Exemple #31
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
Exemple #32
0
def __discover_config(discover_server = True):
    servers = []
    try:
        if not config.default_realm:
            try:
                # only import krbV when we need it
                import krbV
                krbctx = krbV.default_context()
                config.default_realm = krbctx.default_realm
            except ImportError:
                pass
            if not config.default_realm:
                return False

        if not config.default_domain:
            # try once with REALM -> domain
            domain = str(config.default_realm).lower()
            name = "_ldap._tcp." + domain

            try:
                servers = resolver.query(name, rdatatype.SRV)
            except DNSException:
                # try cycling on domain components of FQDN
                try:
                    domain = dns.name.from_text(socket.getfqdn())
                except DNSException:
                    return False

                while True:
                    domain = domain.parent()

                    if str(domain) == '.':
                        return False
                    name = "_ldap._tcp.%s" % domain
                    try:
                        servers = resolver.query(name, rdatatype.SRV)
                        break
                    except DNSException:
                        pass

            config.default_domain = str(domain).rstrip(".")

        if discover_server:
            if not servers:
                name = "_ldap._tcp.%s." % config.default_domain
                try:
                    servers = resolver.query(name, rdatatype.SRV)
                except DNSException:
                    pass

            for server in servers:
                hostname = str(server.target).rstrip(".")
                config.default_server.append(hostname)

    except:
        pass
Exemple #33
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})
Exemple #34
0
def __discover_config(discover_server=True):
    servers = []
    try:
        if not config.default_realm:
            try:
                # only import krbV when we need it
                import krbV
                krbctx = krbV.default_context()
                config.default_realm = krbctx.default_realm
            except ImportError:
                pass
            if not config.default_realm:
                return False

        if not config.default_domain:
            # try once with REALM -> domain
            domain = str(config.default_realm).lower()
            name = "_ldap._tcp." + domain

            try:
                servers = resolver.query(name, rdatatype.SRV)
            except DNSException:
                # try cycling on domain components of FQDN
                try:
                    domain = dns.name.from_text(socket.getfqdn())
                except DNSException:
                    return False

                while True:
                    domain = domain.parent()

                    if str(domain) == '.':
                        return False
                    name = "_ldap._tcp.%s" % domain
                    try:
                        servers = resolver.query(name, rdatatype.SRV)
                        break
                    except DNSException:
                        pass

            config.default_domain = str(domain).rstrip(".")

        if discover_server:
            if not servers:
                name = "_ldap._tcp.%s." % config.default_domain
                try:
                    servers = resolver.query(name, rdatatype.SRV)
                except DNSException:
                    pass

            for server in servers:
                hostname = str(server.target).rstrip(".")
                config.default_server.append(hostname)

    except:
        pass
Exemple #35
0
def get_current_principal():
    try:
        # krbV isn't necessarily available on client machines, fail gracefully
        import krbV
        return unicode(krbV.default_context().default_ccache().principal().name)
    except ImportError:
        raise RuntimeError('python-krbV is not available.')
    except krbV.Krb5Error:
        #TODO: do a kinit?
        raise errors.CCacheError()
Exemple #36
0
def has_krb_creds():
    if krbV is None:
        return False
    try:
        ctx = krbV.default_context()
        ccache = ctx.default_ccache()
        ccache.principal()
        return True
    except krbV.Krb5Error:
        return False
Exemple #37
0
def has_krb_creds():
    if krbV is None:
        return False
    try:
        ctx = krbV.default_context()
        ccache = ctx.default_ccache()
        ccache.principal()
        return True
    except krbV.Krb5Error:
        return False
    def run(self):
        super(ServerUpgrade, self).run()

        api.bootstrap(in_server=True, context='updates')
        api.finalize()

        options = self.options

        if not options.skip_version_check:
            # check IPA version and data version
            try:
                installutils.check_version()
            except (installutils.UpgradePlatformError,
                    installutils.UpgradeDataNewerVersionError) as e:
                raise admintool.ScriptError(
                    'Unable to execute IPA upgrade: %s' % e, 1)
            except installutils.UpgradeMissingVersionError as e:
                self.log.info("Missing version: %s", e)
            except installutils.UpgradeVersionError:
                # Ignore other errors
                pass
        else:
            self.log.info("Skipping version check")
            self.log.warning("Upgrade without version check may break your "
                             "system")

        realm = krbV.default_context().default_realm
        data_upgrade = IPAUpgrade(realm)
        data_upgrade.create_instance()

        if data_upgrade.badsyntax:
            raise admintool.ScriptError(
                'Bad syntax detected in upgrade file(s).', 1)
        elif data_upgrade.upgradefailed:
            raise admintool.ScriptError('IPA upgrade failed.', 1)
        elif data_upgrade.modified:
            self.log.info('Data update complete')
        else:
            self.log.info('Data update complete, no data were modified')

        # store new data version after upgrade
        installutils.store_version()

        # FIXME: remove this when new installer will be ready
        # execute upgrade of configuration
        cmd = [
            'ipa-upgradeconfig',
        ]
        if options.verbose:
            cmd.append('--debug')
        if options.quiet:
            cmd.append('--quiet')

        self.log.info('Executing ipa-upgradeconfig, please wait')
        ipautil.run(cmd)
Exemple #39
0
    def default_realm(self):
        """
        Return the realm from the default credential cache.

        This will return something like 'EXAMPLE.COM'.  If no credential cache
        exists for the invoking user, None is returned.

        This cannot return anything meaningful if used in the server as a
        request is processed.
        """
        return krbV.default_context().default_realm.decode(ENCODING)
Exemple #40
0
def get_current_principal():
    try:
        # krbV isn't necessarily available on client machines, fail gracefully
        import krbV
        return unicode(
            krbV.default_context().default_ccache().principal().name)
    except ImportError:
        raise RuntimeError('python-krbV is not available.')
    except krbV.Krb5Error:
        #TODO: do a kinit?
        raise errors.CCacheError()
Exemple #41
0
    def default_realm(self):
        """
        Return the realm from the default credential cache.

        This will return something like 'EXAMPLE.COM'.  If no credential cache
        exists for the invoking user, None is returned.

        This cannot return anything meaningful if used in the server as a
        request is processed.
        """
        return krbV.default_context().default_realm.decode(ENCODING)
Exemple #42
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)
 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)
Exemple #44
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)
Exemple #45
0
def has_ticket():
    '''
    Checks to see if the user has a valid ticket.
    '''
    ctx = krbV.default_context()
    cc = ctx.default_ccache()
    try:
        princ = cc.principal()
        retval = True
    except krbV.Krb5Error:
        retval = False

    return retval
Exemple #46
0
def __discover_config(discover_server=True):
    rl = 0
    try:
        if not config.default_realm:
            try:
                # only import krbV when we need it
                import krbV
                krbctx = krbV.default_context()
                config.default_realm = krbctx.default_realm
            except ImportError:
                pass
            if not config.default_realm:
                return False

        if not config.default_domain:
            #try once with REALM -> domain
            dom_name = str(config.default_realm).lower()
            name = "_ldap._tcp." + dom_name + "."
            rs = ipapython.dnsclient.query(name, ipapython.dnsclient.DNS_C_IN,
                                           ipapython.dnsclient.DNS_T_SRV)
            rl = len(rs)
            if rl == 0:
                #try cycling on domain components of FQDN
                dom_name = socket.getfqdn()
            while rl == 0:
                tok = dom_name.find(".")
                if tok == -1:
                    return False
                dom_name = dom_name[tok + 1:]
                name = "_ldap._tcp." + dom_name + "."
                rs = ipapython.dnsclient.query(name,
                                               ipapython.dnsclient.DNS_C_IN,
                                               ipapython.dnsclient.DNS_T_SRV)
                rl = len(rs)

            config.default_domain = dom_name

        if discover_server:
            if rl == 0:
                name = "_ldap._tcp." + config.default_domain + "."
                rs = ipapython.dnsclient.query(name,
                                               ipapython.dnsclient.DNS_C_IN,
                                               ipapython.dnsclient.DNS_T_SRV)

            for r in rs:
                if r.dns_type == ipapython.dnsclient.DNS_T_SRV:
                    rsrv = r.rdata.server.rstrip(".")
                    config.default_server.append(rsrv)

    except Exception:
        pass
Exemple #47
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=self.KRB_AUTH_PRINCIPAL, context=context)
        server_keytab = krbV.Keytab(name=self.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
Exemple #48
0
def verify_kerberos_environment():
    """
    Verify the user has a valid Kerberos token and associated environment.

    :return: the Kerberos principal name
    :raise AiToolsInitError: if the user has no valid Kerberos token
    """
    context = krbV.default_context()
    ccache = context.default_ccache()
    try:
        # If the TGT is expired the next call will raise krbV.Krb5Error
        get_tgt_time(ccache)
        return ccache.principal().name
    except krbV.Krb5Error:
        raise AiToolsInitError("Kerberos ticket not available or expired")
Exemple #49
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=self.KRB_AUTH_PRINCIPAL, context=context)
        server_keytab = krbV.Keytab(name=self.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]
        visit_key = turbogears.visit.current().key
        user = identity.current_provider.validate_identity(
                user_name=username, password=None,
                visit_key=visit_key, krb=True)
        if user is None:
            raise IdentityException()
        if proxy_user:
            proxied_identity = proxy_identity(user, proxy_user)
            if proxied_identity is None:
                raise IdentityException('Failed to authenticate on behalf of %s' % proxy_user)
        return identity.current.visit_key
Exemple #50
0
def __discover_config(discover_server = True):
    rl = 0
    try:
        if not config.default_realm:
            try:
                # only import krbV when we need it
                import krbV
                krbctx = krbV.default_context()
                config.default_realm = krbctx.default_realm
            except ImportError:
                pass
            if not config.default_realm:
                return False

        if not config.default_domain:
            #try once with REALM -> domain
            dom_name = str(config.default_realm).lower()
            name = "_ldap._tcp."+dom_name+"."
            rs = ipapython.dnsclient.query(name, ipapython.dnsclient.DNS_C_IN, ipapython.dnsclient.DNS_T_SRV)
            rl = len(rs)
            if rl == 0:
                #try cycling on domain components of FQDN
                dom_name = socket.getfqdn()
            while rl == 0:
                tok = dom_name.find(".")
                if tok == -1:
                    return False
                dom_name = dom_name[tok+1:]
                name = "_ldap._tcp." + dom_name + "."
                rs = ipapython.dnsclient.query(name, ipapython.dnsclient.DNS_C_IN, ipapython.dnsclient.DNS_T_SRV)
                rl = len(rs)

            config.default_domain = dom_name

        if discover_server:
            if rl == 0:
                name = "_ldap._tcp."+config.default_domain+"."
                rs = ipapython.dnsclient.query(name, ipapython.dnsclient.DNS_C_IN, ipapython.dnsclient.DNS_T_SRV)

            for r in rs:
                if r.dns_type == ipapython.dnsclient.DNS_T_SRV:
                    rsrv = r.rdata.server.rstrip(".")
                    config.default_server.append(rsrv)

    except Exception:
        pass
Exemple #51
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)))
Exemple #52
0
def kinit_keytab(principal, keytab, ccache_name, config=None, 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):
        old_config = os.environ.get('KRB5_CONFIG')
        if config is not None:
            os.environ['KRB5_CONFIG'] = config
        else:
            os.environ.pop('KRB5_CONFIG', None)
        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)
        finally:
            if old_config is not None:
                os.environ['KRB5_CONFIG'] = old_config
            else:
                os.environ.pop('KRB5_CONFIG', None)
Exemple #53
0
    def run(self):
        super(LDAPUpdater_Upgrade, self).run()
        options = self.options

        updates = None
        realm = krbV.default_context().default_realm
        upgrade = IPAUpgrade(realm, self.files, live_run=not options.test)
        upgrade.create_instance()
        upgradefailed = upgrade.upgradefailed

        if upgrade.badsyntax:
            raise admintool.ScriptError(
                'Bad syntax detected in upgrade file(s).', 1)
        elif upgrade.upgradefailed:
            raise admintool.ScriptError('IPA upgrade failed.', 1)
        elif upgrade.modified and options.test:
            self.info('Update complete, changes to be made, test mode')
            return 2