Handle GSSAPI exceptions more gracefully

This commit is contained in:
Rob Crittenden 2009-04-13 18:01:58 -04:00
parent e6171404bf
commit a9387b48e6
3 changed files with 116 additions and 13 deletions

View File

@ -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

View File

@ -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))

View File

@ -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)