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 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)
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
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)
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 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 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 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
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)
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})
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)
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
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()
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 = {}
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()
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)))
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)))
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 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 req_enc = base64.encodestring(req) self._hub.auth.login_krbv(req_enc)
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