def _auth_complete(self, response): if self._sec_context: header = response.getheader('www-authenticate', '') token = None for field in header.split(','): k, _dummy, v = field.strip().partition(' ') if k.lower() == 'negotiate': try: token = base64.b64decode(v.encode('ascii')) break # b64decode raises TypeError on invalid input except (TypeError, UnicodeError): pass if not token: raise errors.KerberosError( message=u"No valid Negotiate header in server response") token = self._sec_context.step(token=token) if self._sec_context.complete: self._sec_context = None return True self._set_auth_header(token) return False elif response.status == 401: self.get_auth_info(use_cookie=False) return False return True
def create_connection(self, ccache=None, verbose=False, fallback=True, delegate=False): try: xmlrpc_uri = self.env.xmlrpc_uri principal = get_current_principal() setattr(context, 'principal', principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: xmlrpc_uri = self.apply_session_cookie(xmlrpc_uri) except ValueError: # No session key, do full Kerberos auth pass urls = self.get_url_list(xmlrpc_uri) serverproxy = None for url in urls: kw = dict(allow_none=True, encoding='UTF-8') kw['verbose'] = verbose if url.startswith('https://'): if delegate: kw['transport'] = DelegatedKerbTransport() else: kw['transport'] = KerbTransport() else: kw['transport'] = LanguageAwareTransport() self.log.info('trying %s' % url) setattr(context, 'request_url', url) serverproxy = ServerProxy(url, **kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, 'ping') try: response = command() except Fault, e: e = decode_fault(e) if e.faultCode in self.__errors: error = self.__errors[e.faultCode] raise error(message=e.faultString) else: raise UnknownError( code=e.faultCode, error=e.faultString, server=url, ) # We don't care about the response, just that we got one break except KerberosError, krberr: # kerberos error on one server is likely on all raise errors.KerberosError(major=str(krberr), minor='')
def _handle_exception(self, e, service=None): (major, minor) = ipautil.get_gsserror(e) if minor[1] == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: raise errors.ServiceError(service=service) elif minor[1] == KRB5_FCC_NOFILE: raise errors.NoCCacheError() elif minor[1] == KRB5KRB_AP_ERR_TKT_EXPIRED: raise errors.TicketExpired() elif minor[1] == KRB5_FCC_PERM: raise errors.BadCCachePerms() elif minor[1] == KRB5_CC_FORMAT: raise errors.BadCCacheFormat() elif minor[1] == KRB5_REALM_CANT_RESOLVE: raise errors.CannotResolveKDC() else: raise errors.KerberosError(major=major, minor=minor)
def _handle_exception(self, e, service=None): minor = e.min_code if minor == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: raise errors.ServiceError(service=service) elif minor == KRB5_FCC_NOFILE: raise errors.NoCCacheError() elif minor == KRB5KRB_AP_ERR_TKT_EXPIRED: raise errors.TicketExpired() elif minor == KRB5_FCC_PERM: raise errors.BadCCachePerms() elif minor == KRB5_CC_FORMAT: raise errors.BadCCacheFormat() elif minor == KRB5_REALM_CANT_RESOLVE: raise errors.CannotResolveKDC() elif minor == KRB5_CC_NOTFOUND: raise errors.CCacheError() else: raise errors.KerberosError(message=unicode(e))
def create_connection(self, ccache=None, verbose=None, fallback=None, delegate=None, ca_certfile=None): if verbose is None: verbose = self.api.env.verbose if fallback is None: fallback = self.api.env.fallback if delegate is None: delegate = self.api.env.delegate if ca_certfile is None: ca_certfile = self.api.env.tls_ca_cert try: rpc_uri = self.env[self.env_rpc_uri_key] principal = get_principal(ccache_name=ccache) stored_principal = getattr(context, 'principal', None) if principal != stored_principal: try: delattr(context, 'session_cookie') except AttributeError: pass setattr(context, 'principal', principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: rpc_uri = self.apply_session_cookie(rpc_uri) except (errors.CCacheError, ValueError): # No session key, do full Kerberos auth pass context.ca_certfile = ca_certfile urls = self.get_url_list(rpc_uri) serverproxy = None for url in urls: kw = dict(allow_none=True, encoding='UTF-8') kw['verbose'] = verbose if url.startswith('https://'): if delegate: transport_class = DelegatedKerbTransport else: transport_class = KerbTransport else: transport_class = LanguageAwareTransport kw['transport'] = transport_class(protocol=self.protocol, service='HTTP', ccache=ccache) self.log.info('trying %s' % url) setattr(context, 'request_url', url) serverproxy = self.server_proxy_class(url, **kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, 'ping') try: command([], {}) except Fault as e: e = decode_fault(e) if e.faultCode in errors_by_code: error = errors_by_code[e.faultCode] raise error(message=e.faultString) else: raise UnknownError( code=e.faultCode, error=e.faultString, server=url, ) # We don't care about the response, just that we got one break except KerberosError as krberr: # kerberos error on one server is likely on all raise errors.KerberosError(message=unicode(krberr)) except ProtocolError as e: if hasattr(context, 'session_cookie') and e.errcode == 401: # Unauthorized. Remove the session and try again. delattr(context, 'session_cookie') try: delete_persistent_client_session_data(principal) except Exception as e: # This shouldn't happen if we have a session but it isn't fatal. pass return self.create_connection(ccache, verbose, fallback, delegate) if not fallback: raise serverproxy = None except Exception as e: if not fallback: raise else: self.log.info('Connection to %s failed with %s', url, e) serverproxy = None if serverproxy is None: raise NetworkError(uri=_('any of the configured servers'), error=', '.join(urls)) return serverproxy