From 93fd323457f3bab0f5f5cb48c745cdb72d64a7a6 Mon Sep 17 00:00:00 2001 From: Matthew Krupcale Date: Fri, 30 Nov 2018 02:47:58 -0500 Subject: [PATCH] Add support for newer FreeIPA SHA256 SSH public key hashes (#40803) * lib/ansible/modules/identity/ipa/ipa_user.py: - Check any existing `ipa_user` SSH public key fingerprints for the hash algorithm to use - Generate `module_user` SSH public key fingerprint based on detected or default algorithm --- lib/ansible/modules/identity/ipa/ipa_user.py | 22 +++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/ansible/modules/identity/ipa/ipa_user.py b/lib/ansible/modules/identity/ipa/ipa_user.py index 4ef8f61f68f..77f782e8304 100644 --- a/lib/ansible/modules/identity/ipa/ipa_user.py +++ b/lib/ansible/modules/identity/ipa/ipa_user.py @@ -194,7 +194,10 @@ def get_user_diff(client, ipa_user, module_user): # These are used for comparison. sshpubkey = None if 'ipasshpubkey' in module_user: - module_user['sshpubkeyfp'] = [get_ssh_key_fingerprint(pubkey) for pubkey in module_user['ipasshpubkey']] + hash_algo = 'md5' + if 'sshpubkeyfp' in ipa_user and ipa_user['sshpubkeyfp'][0][:7].upper() == 'SHA256:': + hash_algo = 'sha256' + module_user['sshpubkeyfp'] = [get_ssh_key_fingerprint(pubkey, hash_algo) for pubkey in module_user['ipasshpubkey']] # Remove the ipasshpubkey element as it is not returned from IPA but save it's value to be used later on sshpubkey = module_user['ipasshpubkey'] del module_user['ipasshpubkey'] @@ -208,11 +211,16 @@ def get_user_diff(client, ipa_user, module_user): return result -def get_ssh_key_fingerprint(ssh_key): +def get_ssh_key_fingerprint(ssh_key, hash_algo='sha256'): """ Return the public key fingerprint of a given public SSH key - in format "FB:0C:AC:0A:07:94:5B:CE:75:6E:63:32:13:AD:AD:D7 [user@host] (ssh-rsa)" + in format "[fp] [user@host] (ssh-rsa)" where fp is of the format: + FB:0C:AC:0A:07:94:5B:CE:75:6E:63:32:13:AD:AD:D7 + for md5 or + SHA256:[base64] + for sha256 :param ssh_key: + :param hash_algo: :return: """ parts = ssh_key.strip().split() @@ -221,8 +229,12 @@ def get_ssh_key_fingerprint(ssh_key): key_type = parts[0] key = base64.b64decode(parts[1].encode('ascii')) - fp_plain = hashlib.md5(key).hexdigest() - key_fp = ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])).upper() + if hash_algo == 'md5': + fp_plain = hashlib.md5(key).hexdigest() + key_fp = ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])).upper() + elif hash_algo == 'sha256': + fp_plain = base64.b64encode(hashlib.sha256(key).digest()).decode('ascii').rstrip('=') + key_fp = 'SHA256:{fp}'.format(fp=fp_plain) if len(parts) < 3: return "%s (%s)" % (key_fp, key_type) else: