diff options
author | Rob Crittenden <rcritten@redhat.com> | 2009-04-13 18:01:58 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2009-04-20 13:44:08 -0400 |
commit | a9387b48e66ca93cc8323869de25fe3f777567b6 (patch) | |
tree | 0b706b867766924bea0a5cda92060d5378eef58e | |
parent | e6171404bf0dce7cf08ef3044003190e18c851c9 (diff) | |
download | freeipa-a9387b48e66ca93cc8323869de25fe3f777567b6.tar.gz freeipa-a9387b48e66ca93cc8323869de25fe3f777567b6.tar.xz freeipa-a9387b48e66ca93cc8323869de25fe3f777567b6.zip |
Handle GSSAPI exceptions more gracefully
-rw-r--r-- | ipalib/errors2.py | 79 | ||||
-rw-r--r-- | ipalib/rpc.py | 34 | ||||
-rw-r--r-- | ipapython/ipautil.py | 16 |
3 files changed, 116 insertions, 13 deletions
diff --git a/ipalib/errors2.py b/ipalib/errors2.py index 33db5ccf1..7e752d824 100644 --- a/ipalib/errors2.py +++ b/ipalib/errors2.py @@ -458,6 +458,85 @@ class ServiceError(KerberosError): format = _('Service %(service)r not found in Kerberos database') +class NoCCacheError(KerberosError): + """ + **1103** Raised when a client attempts to use Kerberos without a ccache. + + For example: + + >>> raise NoCCacheError() + Traceback (most recent call last): + ... + NoCCacheError: No credentials cache found + """ + + errno = 1103 + format = _('No credentials cache found') + + +class TicketExpired(KerberosError): + """ + **1104** Raised when a client attempts to use an expired ticket + + For example: + + >>> raise TicketExpired() + Traceback (most recent call last): + ... + TicketExpired: Ticket expired + """ + + errno = 1104 + format = _('Ticket expired') + + +class BadCCachePerms(KerberosError): + """ + **1105** Raised when a client has bad permissions on their ccache + + For example: + + >>> raise BadCCachePerms() + Traceback (most recent call last): + ... + BadCCachePerms: Credentials cache permissions incorrect + """ + + errno = 1105 + format = _('Credentials cache permissions incorrect') + + +class BadCCacheFormat(KerberosError): + """ + **1106** Raised when a client has a misformated ccache + + For example: + + >>> raise BadCCacheFormat() + Traceback (most recent call last): + ... + BadCCacheFormat: Bad format in credentials cache + """ + + errno = 1106 + format = _('Bad format in credentials cache') + + +class CannotResolveKDC(KerberosError): + """ + **1107** Raised when the KDC can't be resolved + + For example: + + >>> raise CannotResolveKDC() + Traceback (most recent call last): + ... + CannotResolveKDC: Cannot resolve KDC for requested realm + """ + + errno = 1107 + format = _('Cannot resolve KDC for requested realm') + ############################################################################## # 2000 - 2999: Authorization errors diff --git a/ipalib/rpc.py b/ipalib/rpc.py index 5c336ca1d..b0b55ce59 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -34,15 +34,24 @@ from types import NoneType import threading import socket import os +import errno from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy, Transport import kerberos from ipalib.backend import Connectible from ipalib.errors2 import public_errors, PublicError, UnknownError, NetworkError from ipalib import errors2 from ipalib.request import context +from ipapython import ipautil from OpenSSL import SSL import httplib +# Some Kerberos error definitions from krb5.h +KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN = (-1765328377L) +KRB5KRB_AP_ERR_TKT_EXPIRED = (-1765328352L) +KRB5_FCC_PERM = (-1765328190L) +KRB5_FCC_NOFILE = (-1765328189L) +KRB5_CC_FORMAT = (-1765328185L) +KRB5_REALM_CANT_RESOLVE = (-1765328164L) def xml_wrap(value): """ @@ -304,6 +313,23 @@ class KerbTransport(SSLTransport): Handles Kerberos Negotiation authentication to an XML-RPC server. """ + def _handle_exception(self, e, service=None): + (major, minor) = ipautil.get_gsserror(e) + if minor[1] == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: + raise errors2.ServiceError(service=service) + elif minor[1] == KRB5_FCC_NOFILE: + raise errors2.NoCCacheError() + elif minor[1] == KRB5KRB_AP_ERR_TKT_EXPIRED: + raise errors2.TicketExpired() + elif minor[1] == KRB5_FCC_PERM: + raise errors2.BadCCachePerms() + elif minor[1] == KRB5_CC_FORMAT: + raise errors2.BadCCacheFormat() + elif minor[1] == KRB5_REALM_CANT_RESOLVE: + raise errors2.CannotResolveKDC() + else: + raise errors2.KerberosError(major=major, minor=minor) + def get_host_info(self, host): (host, extra_headers, x509) = SSLTransport.get_host_info(self, host) @@ -316,16 +342,12 @@ class KerbTransport(SSLTransport): kerberos.GSS_C_MUTUAL_FLAG | kerberos.GSS_C_SEQUENCE_FLAG) except kerberos.GSSError, e: - raise e # FIXME: raise a PublicError + self._handle_exception(e) try: kerberos.authGSSClientStep(vc, "") except kerberos.GSSError, e: - (major, minor) = e.args - if minor[1] == -1765328377: - raise errors2.ServiceError(service=service) - else: - raise e + self._handle_exception(e, service=service) extra_headers = [ ('Authorization', 'negotiate %s' % kerberos.authGSSClientResponse(vc)) diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index 57f5dcd9b..df721a518 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -956,14 +956,16 @@ class ItemCompleter: return items def get_gsserror(e): - """A GSSError exception looks differently in python 2.4 than it does - in python 2.5, deal with it.""" + """ + A GSSError exception looks differently in python 2.4 than it does + in python 2.5. Deal with it. + """ try: - primary = e[0] - secondary = e[1] + major = e[0] + minor = e[1] except: - primary = e[0][0] - secondary = e[0][1] + major = e[0][0] + minor = e[0][1] - return (primary[0], secondary[0]) + return (major, minor) |