Comments inline. ----- Original Message ----- > From: "Michael Simacek" <msima...@redhat.com> > To: freeipa-devel@redhat.com > Sent: Tuesday, July 21, 2015 8:02:26 AM > Subject: [Freeipa-devel] [PATCH] Port from python-kerberos library to > python-gssapi > > 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). > > -- > Michael Simacek > > > >From bca55a6bd9cdb9cdea9d81b55cfdbc2c1279f031 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 | 42 +++++++++++++++++++++--------------------- > ipalib/util.py | 14 +++++++------- > ipapython/ipautil.py | 17 ----------------- > 5 files changed, 30 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..bbedcc9 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,27 @@ 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 - (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 +551,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
Please do not use the raw api unless you have no other option. Use the high level api, also do not refernce a member while instantiating a class. Instantiate, then reference please, we want readable code. > + except gssapi.exceptions.GSSError as e: > self._handle_exception(e, service=service) > > for (h, v) in extra_headers: > @@ -564,7 +562,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 +630,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 Same as above. Create a credential and inquire it with the high level api > 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 > -- Simo Sorce * Red Hat, Inc. * New York -- 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