URL: https://github.com/freeipa/freeipa/pull/427 Author: MartinBasti Title: #427: [Py3] WSGI part 2 Action: opened
PR body: """ with this PR: * server can be installed with python3-mod_wsgi * any xmlrpc test can be executed to find a new py3 issues (still a lot of them there) """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/427/head:pr427 git checkout pr427
From 2f86d65d64bf3034d2fd91623f4b7c3bdfdc00be Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Tue, 24 Jan 2017 17:49:06 +0100 Subject: [PATCH 1/7] py3: base64 encoding/decoding returns always bytes don't mix it Using unicode(bytes) call causes undesired side effect that is inserting `b` character to result. This obviously causes issues with binary base64 data https://fedorahosted.org/freeipa/ticket/4985 --- ipaserver/plugins/baseldap.py | 4 ++-- ipaserver/plugins/ca.py | 2 +- ipaserver/plugins/cert.py | 2 +- ipaserver/secrets/client.py | 6 ++++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py index e7bf43c..2f7889b 100644 --- a/ipaserver/plugins/baseldap.py +++ b/ipaserver/plugins/baseldap.py @@ -1036,8 +1036,8 @@ def process_attr_options(self, entry_attrs, dn, keys, options): except ValueError: if isinstance(delval, bytes): # This is a Binary value, base64 encode it - delval = unicode(base64.b64encode(delval)) - raise errors.AttrValueNotFound(attr=attr, value=delval) + delval = base64.b64encode(delval).decode('ascii') + raise errors.AttrValueNotFound(attr=attr, value=delval) # normalize all values changedattrs = setattrs | addattrs | delattrs diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py index 4f24278..ac9f68e 100644 --- a/ipaserver/plugins/ca.py +++ b/ipaserver/plugins/ca.py @@ -176,7 +176,7 @@ def set_certificate_attrs(entry, options, want_cert=True): with api.Backend.ra_lightweight_ca as ca_api: if want_cert or full: der = ca_api.read_ca_cert(ca_id) - entry['certificate'] = six.text_type(base64.b64encode(der)) + entry['certificate'] = base64.b64encode(der).decode('ascii') if want_chain or full: pkcs7_der = ca_api.read_ca_chain(ca_id) diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py index 5bf4cfb..6bf5c03 100644 --- a/ipaserver/plugins/cert.py +++ b/ipaserver/plugins/cert.py @@ -1260,7 +1260,7 @@ def _get_cert_key(self, cert): return (DN(cert_obj.issuer), cert_obj.serial) def _get_cert_obj(self, cert, all, raw, pkey_only): - obj = {'certificate': unicode(base64.b64encode(cert))} + obj = {'certificate': base64.b64encode(cert).decode('ascii')} full = not pkey_only and all if not raw: diff --git a/ipaserver/secrets/client.py b/ipaserver/secrets/client.py index a04b9a6..a945e01 100644 --- a/ipaserver/secrets/client.py +++ b/ipaserver/secrets/client.py @@ -70,7 +70,8 @@ def init_creds(self): name = gssapi.Name(self.client_service, gssapi.NameType.hostbased_service) store = {'client_keytab': self.keytab, - 'ccache': 'MEMORY:Custodia_%s' % b64encode(os.urandom(8))} + 'ccache': 'MEMORY:Custodia_%s' % b64encode( + os.urandom(8)).decode('ascii')} return gssapi.Credentials(name=name, store=store, usage='initiate') def _auth_header(self): @@ -78,7 +79,8 @@ def _auth_header(self): self.creds = self.init_creds() ctx = gssapi.SecurityContext(name=self.service_name, creds=self.creds) authtok = ctx.step() - return {'Authorization': 'Negotiate %s' % b64encode(authtok)} + return {'Authorization': 'Negotiate %s' % b64encode( + authtok).decode('ascii')} def fetch_key(self, keyname, store=True): From df975b68875628940ce50c5470d34f30cc716762 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Tue, 24 Jan 2017 18:31:50 +0100 Subject: [PATCH 2/7] py3: base64.b64encode requires bytes as param Decimal must be changed to string first and then encoded to bytes https://fedorahosted.org/freeipa/ticket/4985 --- ipalib/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipalib/rpc.py b/ipalib/rpc.py index fb739f8..a3642a6 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -308,7 +308,7 @@ def json_encode_binary(val, version): encoded = encoded.decode('ascii') return {'__base64__': encoded} elif isinstance(val, Decimal): - return {'__base64__': base64.b64encode(str(val))} + return {'__base64__': base64.b64encode(str(val).encode('ascii'))} elif isinstance(val, DN): return str(val) elif isinstance(val, datetime.datetime): From 6669afc9ccec975607fbe0da597f81ed1f6dd64d Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Wed, 25 Jan 2017 14:56:07 +0100 Subject: [PATCH 3/7] py3: remove_entry_from_group: attribute name must be string Do not encode attribute names https://fedorahosted.org/freeipa/ticket/4985 --- ipaserver/plugins/ldap2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py index 71c095d..e671ecb 100644 --- a/ipaserver/plugins/ldap2.py +++ b/ipaserver/plugins/ldap2.py @@ -442,7 +442,7 @@ def remove_entry_from_group(self, dn, group_dn, member_attr='member'): # update group entry try: with self.error_handler(): - modlist = [(a, self.encode(b), self.encode(c)) + modlist = [(a, b, self.encode(c)) for a, b, c in modlist] self.conn.modify_s(str(group_dn), modlist) except errors.MidairCollision: From d02b38e92b0e48e70cfa7bd810636e5fa4944f58 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Wed, 25 Jan 2017 15:38:03 +0100 Subject: [PATCH 4/7] py3: _ptrrecord_precallaback: use bytes with labels DNS labels are bytes so bytes must be used for comparison https://fedorahosted.org/freeipa/ticket/4985 --- ipaserver/plugins/dns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py index 08f9c6d..0838161 100644 --- a/ipaserver/plugins/dns.py +++ b/ipaserver/plugins/dns.py @@ -3098,7 +3098,7 @@ def _ptrrecord_pre_callback(self, ldap, dn, entry_attrs, *keys, **options): # Classless zones (0/25.0.0.10.in-addr.arpa.) -> skip check # zone has to be checked without reverse domain suffix (in-addr.arpa.) - for sign in ('/', '-'): + for sign in (b'/', b'-'): for name in (zone, addr): for label in name.labels: if sign in label: From ce2f44b848b0109cc1abb6ae7ccfc3081c8c9d52 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Thu, 26 Jan 2017 10:25:46 +0100 Subject: [PATCH 5/7] py3: DNS: get_record_entry_attrs: do not modify dict during iteration In py3 keys() doesn't return list but iterator so it must be transformed to tuple otherwise iterator will be broken. https://fedorahosted.org/freeipa/ticket/4985 --- ipaserver/plugins/dns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py index 0838161..97f6527 100644 --- a/ipaserver/plugins/dns.py +++ b/ipaserver/plugins/dns.py @@ -3195,7 +3195,7 @@ def get_dns_masters(self): def get_record_entry_attrs(self, entry_attrs): entry_attrs = entry_attrs.copy() - for attr in entry_attrs.keys(): + for attr in tuple(entry_attrs.keys()): if attr not in self.params or self.params[attr].primary_key: del entry_attrs[attr] return entry_attrs From ac1a38a1ef3f16e761a78c0449b2a6f7acfd5eff Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Fri, 27 Jan 2017 10:48:32 +0100 Subject: [PATCH 6/7] py3: entry_to_dict: input can be both bytes and unicode https://fedorahosted.org/freeipa/ticket/4985 --- ipaserver/plugins/baseldap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py index 2f7889b..803c478 100644 --- a/ipaserver/plugins/baseldap.py +++ b/ipaserver/plugins/baseldap.py @@ -255,7 +255,8 @@ def entry_to_dict(entry, **options): value = list(entry.raw[attr]) for (i, v) in enumerate(value): try: - value[i] = v.decode('utf-8') + if isinstance(v, bytes): + value[i] = v.decode('utf-8') except UnicodeDecodeError: pass result[attr] = value From f14a85426c9c5ab5e4198b900f03b3b05d81bb26 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Fri, 27 Jan 2017 12:06:54 +0100 Subject: [PATCH 7/7] py3: _convert_to_idna: fix bytes/unicode mistmatch ToASCII() returns bytes, it must be decoded to unicode https://fedorahosted.org/freeipa/ticket/4985 --- ipaserver/plugins/dns.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py index 97f6527..40c9b51 100644 --- a/ipaserver/plugins/dns.py +++ b/ipaserver/plugins/dns.py @@ -1620,8 +1620,9 @@ def _convert_to_idna(value): idna_val = encodings.idna.nameprep(idna_val) idna_val = re.split(r'(?<!\\)\.', idna_val) idna_val = u'%s%s%s' % (start_dot, - u'.'.join(encodings.idna.ToASCII(x) - for x in idna_val), + u'.'.join( + encodings.idna.ToASCII(x).decode('ascii') + for x in idna_val), end_dot) return idna_val except Exception:
-- 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