URL: https://github.com/freeipa/freeipa/pull/1289 Author: tiran Title: #1289: Python 3 support for DNSSEC Action: opened
PR body: """ https://pagure.io/freeipa/issue/4985 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/1289/head:pr1289 git checkout pr1289
From b64dc9a4e8e4b835ad7fd80adcbd17ee60ce7423 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Mon, 26 Jun 2017 14:23:44 +0200 Subject: [PATCH 1/6] py3: ipa-dnskeysyncd: fix bytes issues LDAP client returns values as bytes, thus ipa-dnskeysyncd must work with bytes properly. https://pagure.io/freeipa/issue/4985 --- ipaserver/dnssec/keysyncer.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ipaserver/dnssec/keysyncer.py b/ipaserver/dnssec/keysyncer.py index c3af9156bc..958ebb353a 100644 --- a/ipaserver/dnssec/keysyncer.py +++ b/ipaserver/dnssec/keysyncer.py @@ -46,7 +46,7 @@ def _get_objclass(self, attrs): Given set of attributes has to have exactly one supported object class. """ - supported_objclasses = set(['idnszone', 'idnsseckey', 'ipk11publickey']) + supported_objclasses = {b'idnszone', b'idnsseckey', b'ipk11publickey'} present_objclasses = set([o.lower() for o in attrs[OBJCLASS_ATTR]]).intersection(supported_objclasses) assert len(present_objclasses) == 1, attrs[OBJCLASS_ATTR] return present_objclasses.pop() @@ -55,44 +55,44 @@ def __get_signing_attr(self, attrs): """Get SIGNING_ATTR from dictionary with LDAP zone attributes. Returned value is normalized to TRUE or FALSE, defaults to FALSE.""" - values = attrs.get(SIGNING_ATTR, ['FALSE']) + values = attrs.get(SIGNING_ATTR, [b'FALSE']) assert len(values) == 1, '%s is expected to be single-valued' \ % SIGNING_ATTR return values[0].upper() def __is_dnssec_enabled(self, attrs): """Test if LDAP DNS zone with given attributes is DNSSEC enabled.""" - return self.__get_signing_attr(attrs) == 'TRUE' + return self.__get_signing_attr(attrs) == b'TRUE' def __is_replica_pubkey(self, attrs): vals = attrs.get('ipk11label', []) if len(vals) != 1: return False - return vals[0].startswith('dnssec-replica:') + return vals[0].startswith(b'dnssec-replica:') def application_add(self, uuid, dn, newattrs): objclass = self._get_objclass(newattrs) - if objclass == 'idnszone': + if objclass == b'idnszone': self.zone_add(uuid, dn, newattrs) - elif objclass == 'idnsseckey': + elif objclass == b'idnsseckey': self.key_meta_add(uuid, dn, newattrs) - elif objclass == 'ipk11publickey' and \ + elif objclass == b'ipk11publickey' and \ self.__is_replica_pubkey(newattrs): self.hsm_master_sync() def application_del(self, uuid, dn, oldattrs): objclass = self._get_objclass(oldattrs) - if objclass == 'idnszone': + if objclass == b'idnszone': self.zone_del(uuid, dn, oldattrs) - elif objclass == 'idnsseckey': + elif objclass == b'idnsseckey': self.key_meta_del(uuid, dn, oldattrs) - elif objclass == 'ipk11publickey' and \ + elif objclass == b'ipk11publickey' and \ self.__is_replica_pubkey(oldattrs): self.hsm_master_sync() def application_sync(self, uuid, dn, newattrs, oldattrs): objclass = self._get_objclass(oldattrs) - if objclass == 'idnszone': + if objclass == b'idnszone': olddn = ldap.dn.str2dn(oldattrs['dn']) newdn = ldap.dn.str2dn(newattrs['dn']) assert olddn == newdn, 'modrdn operation is not supported' @@ -105,10 +105,10 @@ def application_sync(self, uuid, dn, newattrs, oldattrs): else: self.zone_del(uuid, olddn, oldattrs) - elif objclass == 'idnsseckey': + elif objclass == b'idnsseckey': self.key_metadata_sync(uuid, dn, oldattrs, newattrs) - elif objclass == 'ipk11publickey' and \ + elif objclass == b'ipk11publickey' and \ self.__is_replica_pubkey(newattrs): self.hsm_master_sync() From eeedb5186043524d945fd5fdd15ab6e8e0910e67 Mon Sep 17 00:00:00 2001 From: Martin Basti <mba...@redhat.com> Date: Tue, 4 Jul 2017 16:16:11 +0200 Subject: [PATCH 2/6] py3: bindmgr: fix iteration over bytes In py3 iteration over bytes returns integers, in py2 interation over bytes returns string. https://pagure.io/freeipa/issue/4985 --- ipaserver/dnssec/bindmgr.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/ipaserver/dnssec/bindmgr.py b/ipaserver/dnssec/bindmgr.py index 7d0b59596e..32975fc543 100644 --- a/ipaserver/dnssec/bindmgr.py +++ b/ipaserver/dnssec/bindmgr.py @@ -11,6 +11,8 @@ import shutil import stat +import six + import ipalib.constants from ipapython.dn import DN from ipapython import ipautil @@ -141,17 +143,21 @@ def get_zone_dir_name(self, zone): escaped = "" for label in zone: for char in label: - c = ord(char) - if ((c >= 0x30 and c <= 0x39) or # digit - (c >= 0x41 and c <= 0x5A) or # uppercase - (c >= 0x61 and c <= 0x7A) or # lowercase - c == 0x2D or # hyphen - c == 0x5F): # underscore - if (c >= 0x41 and c <= 0x5A): # downcase - c += 0x20 - escaped += chr(c) + if six.PY2: + # PY3 char is already int + char = ord(char) + if ( + (char >= 0x30 and char <= 0x39) or # digit + (char >= 0x41 and char <= 0x5A) or # uppercase + (char >= 0x61 and char <= 0x7A) or # lowercase + char == 0x2D or # hyphen + char == 0x5F # underscore + ): + if char >= 0x41 and char <= 0x5A: # downcase + char += 0x20 + escaped += chr(char) else: - escaped += "%%%02X" % c + escaped += "%%%02X" % char escaped += '.' # strip trailing period From 6717e32de97d8ec747720854d29c9e2a0de7cd34 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Wed, 23 Aug 2017 14:28:49 +0200 Subject: [PATCH 3/6] py3: bindmgr: fix bytes issues LDAP client returns values as bytes, thus bindmgr must work with bytes properly. https://pagure.io/freeipa/issue/4985 Signed-off-by: Tomas Krizek <tkri...@redhat.com> --- ipaserver/dnssec/bindmgr.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ipaserver/dnssec/bindmgr.py b/ipaserver/dnssec/bindmgr.py index 32975fc543..69dff3deea 100644 --- a/ipaserver/dnssec/bindmgr.py +++ b/ipaserver/dnssec/bindmgr.py @@ -56,8 +56,10 @@ def dn2zone_name(self, dn): return dns.name.from_text(dn[idx - 1]['idnsname']) def time_ldap2bindfmt(self, str_val): + if isinstance(str_val, bytes): + str_val = str_val.decode('utf-8') dt = datetime.strptime(str_val, ipalib.constants.LDAP_GENERALIZED_TIME_FORMAT) - return dt.strftime(time_bindfmt) + return dt.strftime(time_bindfmt).encode('utf-8') def dates2params(self, ldap_attrs): """Convert LDAP timestamps to list of parameters suitable @@ -106,15 +108,15 @@ def install_key(self, zone, uuid, attrs, workdir): """Run dnssec-keyfromlabel on given LDAP object. :returns: base file name of output files, e.g. Kaaa.test.+008+19719""" logger.info('attrs: %s', attrs) - assert attrs.get('idnsseckeyzone', ['FALSE'])[0] == 'TRUE', \ - 'object %s is not a DNS zone key' % attrs['dn'] + assert attrs.get('idnsseckeyzone', [b'FALSE'])[0] == b'TRUE', \ + b'object %s is not a DNS zone key' % attrs['dn'] - uri = "%s;pin-source=%s" % (attrs['idnsSecKeyRef'][0], paths.DNSSEC_SOFTHSM_PIN) + uri = b"%s;pin-source=%s" % (attrs['idnsSecKeyRef'][0], paths.DNSSEC_SOFTHSM_PIN.encode('utf-8')) cmd = [paths.DNSSEC_KEYFROMLABEL, '-K', workdir, '-a', attrs['idnsSecAlgorithm'][0], '-l', uri] cmd += self.dates2params(attrs) - if attrs.get('idnsSecKeySep', ['FALSE'])[0].upper() == 'TRUE': + if attrs.get('idnsSecKeySep', [b'FALSE'])[0].upper() == b'TRUE': cmd += ['-f', 'KSK'] - if attrs.get('idnsSecKeyRevoke', ['FALSE'])[0].upper() == 'TRUE': + if attrs.get('idnsSecKeyRevoke', [b'FALSE'])[0].upper() == b'TRUE': cmd += ['-R', datetime.now().strftime(time_bindfmt)] cmd.append(zone.to_text()) From 95b20a498b56e0db1bffe8408a42ef95000d1c86 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Fri, 25 Aug 2017 15:45:24 +0200 Subject: [PATCH 4/6] py3 dnssec: convert hexlify to str hexlify returns bytes and needs to be casted to string before printing it out. Related: https://pagure.io/freeipa/issue/4985 Signed-off-by: Tomas Krizek <tkri...@redhat.com> --- daemons/dnssec/ipa-dnskeysync-replica | 21 ++++++++++++--------- daemons/dnssec/ipa-ods-exporter | 17 ++++++++--------- ipaserver/dnssec/ldapkeydb.py | 30 ++++++++++++++++++++---------- ipaserver/dnssec/localhsm.py | 20 ++++++++++---------- 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/daemons/dnssec/ipa-dnskeysync-replica b/daemons/dnssec/ipa-dnskeysync-replica index 5a64b84cb4..ee641ae508 100755 --- a/daemons/dnssec/ipa-dnskeysync-replica +++ b/daemons/dnssec/ipa-dnskeysync-replica @@ -8,7 +8,6 @@ Download keys from LDAP to local HSM. This program should be run only on replicas, not on DNSSEC masters. """ -from binascii import hexlify from gssapi.exceptions import GSSError import logging import os @@ -24,7 +23,7 @@ from ipaplatform.paths import paths from ipaserver.dnssec.abshsm import (sync_pkcs11_metadata, ldap2p11helper_api_params, wrappingmech_name2id) -from ipaserver.dnssec.ldapkeydb import LdapKeyDB +from ipaserver.dnssec.ldapkeydb import LdapKeyDB, str_hexlify from ipaserver.dnssec.localhsm import LocalHSM logger = logging.getLogger(os.path.basename(__file__)) @@ -36,7 +35,7 @@ WORKDIR = '/tmp' def hex_set(s): out = set() for i in s: - out.add("0x%s" % hexlify(i)) + out.add("0x%s" % str_hexlify(i)) return out def update_metadata_set(source_set, target_set): @@ -72,7 +71,9 @@ def ldap2replica_master_keys_sync(ldapkeydb, localhsm): hex_set(new_keys)) for mkey_id in new_keys: mkey_ldap = ldapkeydb.master_keys[mkey_id] - assert mkey_ldap.wrapped_entries, "Master key 0x%s in LDAP is missing key material referenced by ipaSecretKeyRefObject attribute" % hexlify(mkey_id) + assert mkey_ldap.wrapped_entries, ("Master key 0x%s in LDAP is " \ + "missing key material referenced by ipaSecretKeyRefObject " \ + "attribute") % str_hexlify(mkey_id) for wrapped_ldap in mkey_ldap.wrapped_entries: unwrapping_key = find_unwrapping_key( localhsm, wrapped_ldap.single_value['ipaWrappingKey']) @@ -80,14 +81,16 @@ def ldap2replica_master_keys_sync(ldapkeydb, localhsm): break # TODO: Could it happen in normal cases? - assert unwrapping_key is not None, "Local HSM does not contain suitable unwrapping key for master key 0x%s" % hexlify(mkey_id) + assert unwrapping_key is not None, ("Local HSM does not contain " \ + "suitable unwrapping key for master key 0x%s") % \ + str_hexlify(mkey_id) params = ldap2p11helper_api_params(mkey_ldap) params['data'] = wrapped_ldap.single_value['ipaSecretKey'] params['unwrapping_key'] = unwrapping_key.handle params['wrapping_mech'] = wrappingmech_name2id[wrapped_ldap.single_value['ipaWrappingMech']] logger.debug('Importing new master key: 0x%s %s', - hexlify(mkey_id), params) + str_hexlify(mkey_id), params) localhsm.p11.import_wrapped_secret_key(**params) # synchronize metadata about master keys in LDAP @@ -108,14 +111,14 @@ def ldap2replica_zone_keys_sync(ldapkeydb, localhsm): for zkey_id in new_keys: zkey_ldap = ldapkeydb.zone_keypairs[zkey_id] logger.debug('Looking for unwrapping key "%s" for zone key 0x%s', - zkey_ldap['ipaWrappingKey'], hexlify(zkey_id)) + zkey_ldap['ipaWrappingKey'], str_hexlify(zkey_id)) unwrapping_key = find_unwrapping_key( localhsm, zkey_ldap['ipaWrappingKey']) assert unwrapping_key is not None, \ "Local HSM does not contain suitable unwrapping key for ' \ - 'zone key 0x%s" % hexlify(zkey_id) + 'zone key 0x%s" % str_hexlify(zkey_id) - logger.debug('Importing zone key pair 0x%s', hexlify(zkey_id)) + logger.debug('Importing zone key pair 0x%s', str_hexlify(zkey_id)) localhsm.import_private_key(zkey_ldap, zkey_ldap['ipaPrivateKey'], unwrapping_key) localhsm.import_public_key(zkey_ldap, zkey_ldap['ipaPublicKey']) diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter index b1e69df864..a37d8d32ff 100755 --- a/daemons/dnssec/ipa-ods-exporter +++ b/daemons/dnssec/ipa-ods-exporter @@ -16,7 +16,6 @@ Purpose of this replacement is to upload keys generated by OpenDNSSEC to LDAP. """ from __future__ import print_function -from binascii import hexlify from datetime import datetime import dateutil.tz import dns.dnssec @@ -38,7 +37,7 @@ from ipapython.dn import DN from ipapython import ipaldap from ipaplatform.paths import paths from ipaserver.dnssec.abshsm import sync_pkcs11_metadata, wrappingmech_name2id -from ipaserver.dnssec.ldapkeydb import LdapKeyDB +from ipaserver.dnssec.ldapkeydb import LdapKeyDB, str_hexlify from ipaserver.dnssec.localhsm import LocalHSM logger = logging.getLogger(os.path.basename(__file__)) @@ -299,8 +298,8 @@ def ldap2master_replica_keys_sync(ldapkeydb, localhsm): new_key_ldap = ldapkeydb.replica_pubkeys_wrap[key_id] logger.debug('label=%s, id=%s, data=%s', new_key_ldap['ipk11label'], - hexlify(new_key_ldap['ipk11id']), - hexlify(new_key_ldap['ipapublickey'])) + str_hexlify(new_key_ldap['ipk11id']), + str_hexlify(new_key_ldap['ipapublickey'])) localhsm.import_public_key(new_key_ldap, new_key_ldap['ipapublickey']) # set CKA_WRAP = FALSE for all replica keys removed from LDAP @@ -339,7 +338,7 @@ def master2ldap_master_keys_sync(ldapkeydb, localhsm): # synchronize master key metadata to LDAP for mkey_id, mkey_local in localhsm.master_keys.items(): logger.debug('synchronizing master key metadata: 0x%s', - hexlify(mkey_id)) + str_hexlify(mkey_id)) sync_pkcs11_metadata('master2ldap_master', mkey_local, ldapkeydb.master_keys[mkey_id]) # re-wrap all master keys in LDAP with new replica keys (as necessary) @@ -349,7 +348,7 @@ def master2ldap_master_keys_sync(ldapkeydb, localhsm): for mkey_id, mkey_ldap in ldapkeydb.master_keys.items(): logger.debug('processing master key data: 0x%s', - hexlify(mkey_id)) + str_hexlify(mkey_id)) # check that all active replicas have own copy of master key used_replica_keys = set() @@ -367,13 +366,13 @@ def master2ldap_master_keys_sync(ldapkeydb, localhsm): new_replica_keys = enabled_replica_key_ids - used_replica_keys logger.debug('master key 0x%s is not wrapped with replica keys %s', - hexlify(mkey_id), hex_set(new_replica_keys)) + str_hexlify(mkey_id), hex_set(new_replica_keys)) # wrap master key with new replica keys mkey_local = localhsm.find_keys(id=mkey_id).popitem()[1] for replica_key_id in new_replica_keys: logger.info('adding master key 0x%s wrapped with replica key 0x%s', - hexlify(mkey_id), hexlify(replica_key_id)) + str_hexlify(mkey_id), str_hexlify(replica_key_id)) replica_key = localhsm.replica_pubkeys_wrap[replica_key_id] keydata = localhsm.p11.export_wrapped_key(mkey_local.handle, replica_key.handle, @@ -446,7 +445,7 @@ def master2ldap_zone_keys_purge(ldapkeydb, localhsm): def hex_set(s): out = set() for i in s: - out.add("0x%s" % hexlify(i)) + out.add("0x%s" % str_hexlify(i)) return out def receive_systemd_command(): diff --git a/ipaserver/dnssec/ldapkeydb.py b/ipaserver/dnssec/ldapkeydb.py index 30c21ab5c2..99e8a403b0 100644 --- a/ipaserver/dnssec/ldapkeydb.py +++ b/ipaserver/dnssec/ldapkeydb.py @@ -29,7 +29,7 @@ def uri_escape(val): """convert val to %-notation suitable for ID component in URI""" assert len(val) > 0, "zero-length URI component detected" - hexval = hexlify(val) + hexval = str_hexlify(val) out = '%' # pylint: disable=E1127 out += '%'.join(hexval[i:i+2] for i in range(0, len(hexval), 2)) @@ -112,6 +112,13 @@ def get_default_attrs(object_classes): return result +def str_hexlify(data): + out = hexlify(data) + if isinstance(out, bytes): + out = out.decode('utf-8') + return out + + class Key(collections.MutableMapping): """abstraction to hide LDAP entry weirdnesses: - non-normalized attribute names @@ -197,7 +204,7 @@ def _delete_key(self): "Key._delete_key() called before Key.schedule_deletion()") assert self._delentry, "Key._delete_key() called more than once" logger.debug('deleting key id 0x%s DN %s from LDAP', - hexlify(self._delentry.single_value['ipk11id']), + str_hexlify(self._delentry.single_value['ipk11id']), self._delentry.dn) self.ldap.delete_entry(self._delentry) self._delentry = None @@ -260,8 +267,8 @@ def add_wrapped_data(self, data, wrapping_mech, replica_key_id): logger.info('adding master key 0x%s wrapped with replica key 0x%s to ' '%s', - hexlify(self['ipk11id']), - hexlify(replica_key_id), + str_hexlify(self['ipk11id']), + str_hexlify(replica_key_id), entry_dn) self.ldap.add_entry(entry) if 'ipaSecretKeyRef' not in self.entry: @@ -294,7 +301,9 @@ def _get_key_dict(self, key_type, ldap_filter): assert 'ipk11id' in key, 'key is missing ipk11Id in %s' % key.entry.dn key_id = key['ipk11id'] - assert key_id not in keys, 'duplicate ipk11Id=0x%s in "%s" and "%s"' % (hexlify(key_id), key.entry.dn, keys[key_id].entry.dn) + assert key_id not in keys, \ + 'duplicate ipk11Id=0x%s in "%s" and "%s"' % \ + (str_hexlify(key_id), key.entry.dn, keys[key_id].entry.dn) assert 'ipk11label' in key, 'key "%s" is missing ipk11Label' % key.entry.dn assert 'objectclass' in key.entry, 'key "%s" is missing objectClass attribute' % key.entry.dn @@ -365,7 +374,8 @@ def import_zone_key(self, pubkey, pubkey_data, privkey, new_key.entry['ipaPublicKey'] = pubkey_data self.ldap.add_entry(new_key.entry) - logger.debug('imported zone key id: 0x%s', hexlify(new_key['ipk11id'])) + logger.debug('imported zone key id: 0x%s', + str_hexlify(new_key['ipk11id'])) @property def replica_pubkeys_wrap(self): @@ -392,7 +402,7 @@ def master_keys(self): 'secret key dn="%s" ipk11id=0x%s ipk11label="%s" with ipk11UnWrap = TRUE does not have '\ '"%s" key label' % ( key.entry.dn, - hexlify(key['ipk11id']), + str_hexlify(key['ipk11id']), str(key['ipk11label']), prefix) @@ -437,19 +447,19 @@ def zone_keypairs(self): print('replica public keys: CKA_WRAP = TRUE') print('====================================') for pubkey_id, pubkey in ldapkeydb.replica_pubkeys_wrap.items(): - print(hexlify(pubkey_id)) + print(str_hexlify(pubkey_id)) pprint(pubkey) print('') print('master keys') print('===========') for mkey_id, mkey in ldapkeydb.master_keys.items(): - print(hexlify(mkey_id)) + print(str_hexlify(mkey_id)) pprint(mkey) print('') print('zone key pairs') print('==============') for key_id, key in ldapkeydb.zone_keypairs.items(): - print(hexlify(key_id)) + print(str_hexlify(key_id)) pprint(key) diff --git a/ipaserver/dnssec/localhsm.py b/ipaserver/dnssec/localhsm.py index 50a11714ff..7d384da7a9 100755 --- a/ipaserver/dnssec/localhsm.py +++ b/ipaserver/dnssec/localhsm.py @@ -5,17 +5,17 @@ from __future__ import print_function -from binascii import hexlify import collections import os from pprint import pprint from ipaplatform.paths import paths - from ipaserver import p11helper as _ipap11helper from ipaserver.dnssec.abshsm import (attrs_name2id, attrs_id2name, AbstractHSM, keytype_id2name, keytype_name2id, ldap2p11helper_api_params) +from ipaserver.dnssec.ldapkeydb import str_hexlify + private_key_api_params = set(["label", "id", "data", "unwrapping_key", "wrapping_mech", "key_type", "cka_always_authenticate", "cka_copyable", @@ -44,7 +44,7 @@ def __init__(self, p11, handle): except _ipap11helper.NotFound: raise _ipap11helper.NotFound('key without ipk11label: id 0x%s' - % hexlify(cka_id)) + % str_hexlify(cka_id)) def __getitem__(self, key): key = key.lower() @@ -113,7 +113,7 @@ def find_keys(self, **kwargs): key = Key(self.p11, h) o_id = key['ipk11id'] assert o_id not in keys, 'duplicate ipk11Id = 0x%s; keys = %s' % ( - hexlify(o_id), keys) + str_hexlify(o_id), keys) keys[o_id] = key return keys @@ -138,7 +138,7 @@ def master_keys(self): prefix = 'dnssec-master' assert key['ipk11label'] == prefix, \ 'secret key ipk11id=0x%s ipk11label="%s" with ipk11UnWrap = TRUE does not have '\ - '"%s" key label' % (hexlify(key['ipk11id']), + '"%s" key label' % (str_hexlify(key['ipk11id']), str(key['ipk11label']), prefix) return keys @@ -194,33 +194,33 @@ def import_private_key(self, source, data, unwrapping_key): print('replica public keys: CKA_WRAP = TRUE') print('====================================') for pubkey_id, pubkey in localhsm.replica_pubkeys_wrap.items(): - print(hexlify(pubkey_id)) + print(str_hexlify(pubkey_id)) pprint(pubkey) print('') print('replica public keys: all') print('========================') for pubkey_id, pubkey in localhsm.replica_pubkeys.items(): - print(hexlify(pubkey_id)) + print(str_hexlify(pubkey_id)) pprint(pubkey) print('') print('master keys') print('===========') for mkey_id, mkey in localhsm.master_keys.items(): - print(hexlify(mkey_id)) + print(str_hexlify(mkey_id)) pprint(mkey) print('') print('zone public keys') print('================') for key_id, key in localhsm.zone_pubkeys.items(): - print(hexlify(key_id)) + print(str_hexlify(key_id)) pprint(key) print('') print('zone private keys') print('=================') for key_id, key in localhsm.zone_privkeys.items(): - print(hexlify(key_id)) + print(str_hexlify(key_id)) pprint(key) From 0cd0a6fa7c1aa0ec0c5541b8490c2d35bd48a2fd Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Mon, 28 Aug 2017 19:39:07 +0200 Subject: [PATCH 5/6] spec: bump python3-pyldap for py3 dnssec Newer version of python3-pyldap contains a fix necessary for Python3 porting: https://github.com/pyldap/pyldap/issues/103 Related: https://pagure.io/freeipa/issue/4985 Signed-off-by: Tomas Krizek <tkri...@redhat.com> --- freeipa.spec.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freeipa.spec.in b/freeipa.spec.in index 33f5474c44..92ad6800e8 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -403,7 +403,7 @@ Requires: %{name}-common = %{version}-%{release} Requires: python3-ipaclient = %{version}-%{release} Requires: python3-custodia >= 0.3.1 # we need pre-requires since earlier versions may break upgrade -Requires(pre): python3-pyldap >= 2.4.35.1-2 +Requires(pre): python3-pyldap >= 2.4.37 Requires: python3-lxml Requires: python3-gssapi >= 1.2.0 Requires: python3-sssdconfig @@ -739,7 +739,7 @@ Requires: python3-six Requires: python3-jwcrypto >= 0.4.2 Requires: python3-cffi # we need pre-requires since earlier versions may break upgrade -Requires(pre): python3-pyldap >= 2.4.35.1-2 +Requires(pre): python3-pyldap >= 2.4.37 Requires: python3-requests Requires: python3-dns >= 1.15 Requires: python3-netifaces >= 0.10.4 From ae330a2fcfd03503a548e587f39ea0f13c219b9b Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Wed, 15 Nov 2017 15:46:33 +0100 Subject: [PATCH 6/6] More DNSSEC house keeping Related: https://pagure.io/freeipa/issue/4985 Signed-off-by: Christian Heimes <chei...@redhat.com> --- ipaserver/dnssec/bindmgr.py | 46 ++++++++++++++++++++++---------------------- ipaserver/dnssec/localhsm.py | 13 ++++++------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/ipaserver/dnssec/bindmgr.py b/ipaserver/dnssec/bindmgr.py index 69dff3deea..9224c21f28 100644 --- a/ipaserver/dnssec/bindmgr.py +++ b/ipaserver/dnssec/bindmgr.py @@ -106,18 +106,27 @@ def ldap_event(self, op, uuid, attrs): def install_key(self, zone, uuid, attrs, workdir): """Run dnssec-keyfromlabel on given LDAP object. - :returns: base file name of output files, e.g. Kaaa.test.+008+19719""" + :returns: base file name of output files, e.g. Kaaa.test.+008+19719 + """ logger.info('attrs: %s', attrs) assert attrs.get('idnsseckeyzone', [b'FALSE'])[0] == b'TRUE', \ b'object %s is not a DNS zone key' % attrs['dn'] - uri = b"%s;pin-source=%s" % (attrs['idnsSecKeyRef'][0], paths.DNSSEC_SOFTHSM_PIN.encode('utf-8')) - cmd = [paths.DNSSEC_KEYFROMLABEL, '-K', workdir, '-a', attrs['idnsSecAlgorithm'][0], '-l', uri] - cmd += self.dates2params(attrs) + uri = b"%s;pin-source=%s" % ( + attrs['idnsSecKeyRef'][0], + paths.DNSSEC_SOFTHSM_PIN.encode('utf-8') + ) + cmd = [ + paths.DNSSEC_KEYFROMLABEL, + '-K', workdir, + '-a', attrs['idnsSecAlgorithm'][0], + '-l', uri + ] + cmd.extend(self.dates2params(attrs)) if attrs.get('idnsSecKeySep', [b'FALSE'])[0].upper() == b'TRUE': - cmd += ['-f', 'KSK'] + cmd.extend(['-f', 'KSK']) if attrs.get('idnsSecKeyRevoke', [b'FALSE'])[0].upper() == b'TRUE': - cmd += ['-R', datetime.now().strftime(time_bindfmt)] + cmd.extend(['-R', datetime.now().strftime(time_bindfmt)]) cmd.append(zone.to_text()) # keys has to be readable by ODS & named @@ -142,28 +151,19 @@ def get_zone_dir_name(self, zone): # strip final (empty) label zone = zone.relativize(dns.name.root) - escaped = "" + escaped = [] for label in zone: for char in label: - if six.PY2: - # PY3 char is already int - char = ord(char) - if ( - (char >= 0x30 and char <= 0x39) or # digit - (char >= 0x41 and char <= 0x5A) or # uppercase - (char >= 0x61 and char <= 0x7A) or # lowercase - char == 0x2D or # hyphen - char == 0x5F # underscore - ): - if char >= 0x41 and char <= 0x5A: # downcase - char += 0x20 - escaped += chr(char) + if six.PY3: + char = chr(char) + if char.isalnum() or char in "-_": + escaped.append(char.lower()) else: - escaped += "%%%02X" % char - escaped += '.' + escaped.append("%%%02X" % ord(char)) + escaped.append('.') # strip trailing period - return escaped[:-1] + return ''.join(escaped[:-1]) def sync_zone(self, zone): logger.info('Synchronizing zone %s', zone) diff --git a/ipaserver/dnssec/localhsm.py b/ipaserver/dnssec/localhsm.py index 7d384da7a9..3dc708f677 100755 --- a/ipaserver/dnssec/localhsm.py +++ b/ipaserver/dnssec/localhsm.py @@ -43,8 +43,8 @@ def __init__(self, p11, handle): assert len(cka_label) != 0, 'ipk11label length should not be 0' except _ipap11helper.NotFound: - raise _ipap11helper.NotFound('key without ipk11label: id 0x%s' - % str_hexlify(cka_id)) + raise _ipap11helper.NotFound( + 'key without ipk11label: id 0x%s' % str_hexlify(cka_id)) def __getitem__(self, key): key = key.lower() @@ -184,7 +184,6 @@ def import_private_key(self, source, data, unwrapping_key): return Key(self.p11, h) - if __name__ == '__main__': if 'SOFTHSM2_CONF' not in os.environ: os.environ['SOFTHSM2_CONF'] = paths.DNSSEC_SOFTHSM2_CONF @@ -214,13 +213,13 @@ def import_private_key(self, source, data, unwrapping_key): print('') print('zone public keys') print('================') - for key_id, key in localhsm.zone_pubkeys.items(): + for key_id, zkey in localhsm.zone_pubkeys.items(): print(str_hexlify(key_id)) - pprint(key) + pprint(zkey) print('') print('zone private keys') print('=================') - for key_id, key in localhsm.zone_privkeys.items(): + for key_id, zkey in localhsm.zone_privkeys.items(): print(str_hexlify(key_id)) - pprint(key) + pprint(zkey)
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org