----- Original Message ----- > From: "Christian Heimes" <chei...@redhat.com> > To: freeipa-devel@redhat.com, msima...@redhat.com > Sent: Tuesday, July 21, 2015 2:23:06 PM > Subject: Re: [Freeipa-devel] [PATCH] Port from python-kerberos library to > python-gssapi > > On 2015-07-21 14:02, Michael Simacek wrote: > > Hi, > > > > This is a first part of my effort to port FreeIPA from Python3-incompatible > > Kerberos libraries to python-gssapi. This patch should replace > > python-kerberos > > with python-gssapi (both use C GSSAPI behind the scenes). > > > def _handle_exception(self, e, service=None): > > - (major, minor) = ipautil.get_gsserror(e) > > - if minor[1] == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: > > + # kerberos library coerced error codes to signed, gssapi uses > > unsigned > > + minor = e.min_code - (1 << 32) > > + if minor == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: > > The unsigned to sign conversion is not correct. Although it doesn't make > a difference here, please use the technical correct way: > > minor = e.min_code > if minor & (1 << 31): > minor -= 1 << 32 > > or if you prefer hex: > > if minor & 0x80000000: > minor -= 0x100000000 >
Fixed, thank you. Hopefully, when FreeIPA will use python-gssapi everywhere, such coercions won't be needed. -- Michael Simacek >From c59cadae8d461aa0c771cb56a34d53c9533a4248 Mon Sep 17 00:00:00 2001 From: Michael Simacek <msima...@redhat.com> Date: Thu, 16 Jul 2015 18:22:00 +0200 Subject: [PATCH] Port from python-kerberos library to python-gssapi kerberos library doesn't support Python 3 and probably never will. python-gssapi library is Python 3 compatible. --- BUILD.txt | 2 +- freeipa.spec.in | 2 +- ipalib/rpc.py | 44 +++++++++++++++++++++++--------------------- ipalib/util.py | 14 +++++++------- ipapython/ipautil.py | 17 ----------------- 5 files changed, 32 insertions(+), 47 deletions(-) diff --git a/BUILD.txt b/BUILD.txt index 6a28beb..53012b1 100644 --- a/BUILD.txt +++ b/BUILD.txt @@ -20,7 +20,7 @@ systemd-units samba-devel samba-python libwbclient-devel libtalloc-devel \ libtevent-devel nspr-devel nss-devel openssl-devel openldap-devel krb5-devel \ krb5-workstation libuuid-devel libcurl-devel xmlrpc-c-devel popt-devel \ autoconf automake m4 libtool gettext python-devel python-ldap \ -python-setuptools python-krbV python-nss python-netaddr python-kerberos \ +python-setuptools python-krbV python-nss python-netaddr python-gssapi \ python-rhsm pyOpenSSL pylint python-polib libipa_hbac-python python-memcached \ sssd python-lxml python-pyasn1 python-qrcode-core python-dns m2crypto \ check libsss_idmap-devel libsss_nss_idmap-devel java-headless rhino \ diff --git a/freeipa.spec.in b/freeipa.spec.in index fef20e1..5e10022 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -72,7 +72,7 @@ BuildRequires: python-krbV BuildRequires: python-nss BuildRequires: python-cryptography BuildRequires: python-netaddr -BuildRequires: python-kerberos >= 1.1-14 +BuildRequires: python-gssapi >= 1.1.1 BuildRequires: python-rhsm BuildRequires: pyOpenSSL BuildRequires: pylint >= 1.0 diff --git a/ipalib/rpc.py b/ipalib/rpc.py index 466b49a..9e8c97d 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -44,7 +44,7 @@ from urllib2 import urlparse from xmlrpclib import (Binary, Fault, DateTime, dumps, loads, ServerProxy, Transport, ProtocolError, MININT, MAXINT) -import kerberos +import gssapi from dns import resolver, rdatatype from dns.exception import DNSException from nss.error import NSPRError @@ -510,24 +510,29 @@ class KerbTransport(SSLTransport): """ Handles Kerberos Negotiation authentication to an XML-RPC server. """ - flags = kerberos.GSS_C_MUTUAL_FLAG | kerberos.GSS_C_SEQUENCE_FLAG + flags = gssapi.IntEnumFlagSet(gssapi.RequirementFlag, + [gssapi.RequirementFlag.mutual_authentication, + gssapi.RequirementFlag.out_of_sequence_detection]) def _handle_exception(self, e, service=None): - (major, minor) = ipautil.get_gsserror(e) - if minor[1] == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: + # kerberos library coerced error codes to signed, gssapi uses unsigned + minor = e.min_code + if minor & (1 << 31): + minor -= 1 << 32 + if minor == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: raise errors.ServiceError(service=service) - elif minor[1] == KRB5_FCC_NOFILE: + elif minor == KRB5_FCC_NOFILE: raise errors.NoCCacheError() - elif minor[1] == KRB5KRB_AP_ERR_TKT_EXPIRED: + elif minor == KRB5KRB_AP_ERR_TKT_EXPIRED: raise errors.TicketExpired() - elif minor[1] == KRB5_FCC_PERM: + elif minor == KRB5_FCC_PERM: raise errors.BadCCachePerms() - elif minor[1] == KRB5_CC_FORMAT: + elif minor == KRB5_CC_FORMAT: raise errors.BadCCacheFormat() - elif minor[1] == KRB5_REALM_CANT_RESOLVE: + elif minor == KRB5_REALM_CANT_RESOLVE: raise errors.CannotResolveKDC() else: - raise errors.KerberosError(major=major, minor=minor) + raise errors.KerberosError(major=e.maj_code, minor=minor) def get_host_info(self, host): """ @@ -548,14 +553,9 @@ class KerbTransport(SSLTransport): service = "HTTP@" + host.split(':')[0] try: - (rc, vc) = kerberos.authGSSClientInit(service=service, - gssflags=self.flags) - except kerberos.GSSError, e: - self._handle_exception(e) - - try: - kerberos.authGSSClientStep(vc, "") - except kerberos.GSSError, e: + name = gssapi.Name(service, gssapi.NameType.hostbased_service) + response = gssapi.raw.init_sec_context(name, flags=self.flags).token + except gssapi.exceptions.GSSError as e: self._handle_exception(e, service=service) for (h, v) in extra_headers: @@ -564,7 +564,7 @@ class KerbTransport(SSLTransport): break extra_headers.append( - ('Authorization', 'negotiate %s' % kerberos.authGSSClientResponse(vc)) + ('Authorization', 'negotiate %s' % base64.b64encode(response)) ) return (host, extra_headers, x509) @@ -632,8 +632,10 @@ class DelegatedKerbTransport(KerbTransport): Handles Kerberos Negotiation authentication and TGT delegation to an XML-RPC server. """ - flags = kerberos.GSS_C_DELEG_FLAG | kerberos.GSS_C_MUTUAL_FLAG | \ - kerberos.GSS_C_SEQUENCE_FLAG + flags = gssapi.IntEnumFlagSet(gssapi.RequirementFlag, + [gssapi.RequirementFlag.delegate_to_peer, + gssapi.RequirementFlag.mutual_authentication, + gssapi.RequirementFlag.out_of_sequence_detection]) class RPCClient(Connectible): diff --git a/ipalib/util.py b/ipalib/util.py index 649a487..aea3ba9 100644 --- a/ipalib/util.py +++ b/ipalib/util.py @@ -63,15 +63,15 @@ def json_serialize(obj): def get_current_principal(): try: - import kerberos - rc, vc = kerberos.authGSSClientInit("notempty") - rc = kerberos.authGSSClientInquireCred(vc) - username = kerberos.authGSSClientUserName(vc) - kerberos.authGSSClientClean(vc) + import gssapi + cred = gssapi.raw.acquire_cred(usage='initiate').creds + name = gssapi.raw.inquire_cred(cred, lifetime=False, usage=False, + mechs=False).name + username = gssapi.raw.display_name(name, name_type=False).name return unicode(username) except ImportError: - raise RuntimeError('python-kerberos is not available.') - except kerberos.GSSError, e: + raise RuntimeError('python-gssapi is not available.') + except gssapi.exceptions.GSSError: #TODO: do a kinit? raise errors.CCacheError() diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index 88e8970..05a7eeb 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -783,23 +783,6 @@ def user_input(prompt, default = None, allow_empty = True): return ret -def get_gsserror(e): - """ - A GSSError exception looks differently in python 2.4 than it does - in python 2.5. Deal with it. - """ - - try: - major = e[0] - minor = e[1] - except: - major = e[0][0] - minor = e[0][1] - - return (major, minor) - - - def host_port_open(host, port, socket_type=socket.SOCK_STREAM, socket_timeout=None): for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket_type): af, socktype, proto, canonname, sa = res -- 2.1.0 -- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code