[Freeipa-devel] [PATCH] Port from python-kerberos library to python-gssapi
Michael Simacek
msimacek at redhat.com
Tue Jul 21 12:02:26 UTC 2015
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 <msimacek at 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
+ 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
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
More information about the Freeipa-devel
mailing list