URL: https://github.com/freeipa/freeipa/pull/427 Author: MartinBasti Title: #427: [Py3] WSGI part 2 Action: synchronized
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 162cbe92129170f45267e38e14ebdb31e09ab4cd 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/8] 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 | 2 +- ipaserver/plugins/ca.py | 4 +--- ipaserver/plugins/cert.py | 2 +- ipaserver/secrets/client.py | 6 ++++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py index e7bf43c..24b6db7 100644 --- a/ipaserver/plugins/baseldap.py +++ b/ipaserver/plugins/baseldap.py @@ -1036,7 +1036,7 @@ 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)) + delval = base64.b64encode(delval).decode('ascii') raise errors.AttrValueNotFound(attr=attr, value=delval) # normalize all values diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py index 4f24278..3a052a1 100644 --- a/ipaserver/plugins/ca.py +++ b/ipaserver/plugins/ca.py @@ -4,8 +4,6 @@ import base64 -import six - from ipalib import api, errors, output, Bytes, DNParam, Flag, Str from ipalib.constants import IPA_CA_CN from ipalib.plugable import Registry @@ -176,7 +174,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 29b280bf7e3c88de40647adc3b06bf84f4b827f1 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/8] 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 356ec42..3dc7936 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 91876550e768b362fdab729ee21dfe8187937c83 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Mon, 6 Feb 2017 18:39:11 +0100 Subject: [PATCH 3/8] py3: rpc.py: __base64__ value must be unicode rpc.py expects that __base64__ value is unicode not bytes https://fedorahosted.org/freeipa/ticket/4985 --- ipalib/rpc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ipalib/rpc.py b/ipalib/rpc.py index 3dc7936..57486c3 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -308,7 +308,8 @@ def json_encode_binary(val, version): encoded = encoded.decode('ascii') return {'__base64__': encoded} elif isinstance(val, Decimal): - return {'__base64__': base64.b64encode(str(val).encode('ascii'))} + return {'__base64__': base64.b64encode( + str(val).encode('ascii')).decode('ascii')} elif isinstance(val, DN): return str(val) elif isinstance(val, datetime.datetime): From 6810cab636660df386543896dbf98bc46f680e3b Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Wed, 25 Jan 2017 14:56:07 +0100 Subject: [PATCH 4/8] 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 ec72c19a3d9e68b925fc29b0c0c4cfe6388683db Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Wed, 25 Jan 2017 15:38:03 +0100 Subject: [PATCH 5/8] 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 457ed6d30f3a2f1d3f8c5fa50b65728b9e48d3ef Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Thu, 26 Jan 2017 10:25:46 +0100 Subject: [PATCH 6/8] 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 f726e73bcb0a401ee4304e7961ee4c21f8abd0ef 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/8] 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: From 0f3c4623b13f0624f2af37fcc1d6fd8023654c89 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Mon, 6 Feb 2017 18:42:08 +0100 Subject: [PATCH 8/8] py3: ipaldap: properly encode DNSName to bytes The encode method of LDAPClient didn't return DNSName as bytes but string in py3. In py2 it returns non-unicode string so it can be encoded safely by ascii as to_text() method returns only ascii characters. https://fedorahosted.org/freeipa/ticket/4985 --- ipapython/ipaldap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 497b947..37d23d7 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -849,7 +849,7 @@ def encode(self, val): Principal)): return six.text_type(val).encode('utf-8') elif isinstance(val, DNSName): - return val.to_text() + return val.to_text().encode('ascii') elif isinstance(val, bytes): return val elif isinstance(val, list):
-- 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