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

Reply via email to