コード例 #1
0
 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
コード例 #2
0
 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='')
コード例 #3
0
 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)
コード例 #4
0
 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))
コード例 #5
0
    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