diff options
author | Sloane Hertel <19572925+s-hertel@users.noreply.github.com> | 2023-02-08 14:46:07 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-08 11:46:07 -0800 |
commit | fcdd7493ae6241badf43caf5e120690c5b9bdd33 (patch) | |
tree | 7d72434825719e07ff3ad78db971dc0c1e0e38ff | |
parent | 9d65e122ff62b31133bce7148921f6aea9b6a394 (diff) | |
download | ansible-fcdd7493ae6241badf43caf5e120690c5b9bdd33.tar.gz |
improve password_hash warning for unsupported algorithms (#79872)
* password_hash - give a warning for unsupported algorithms (that raise a TypeError)
* add suggested changes, a test and changelog
-rw-r--r-- | changelogs/fragments/deprecate-non-enforced-password_hash-type-choices.yml | 4 | ||||
-rw-r--r-- | lib/ansible/plugins/filter/core.py | 19 | ||||
-rw-r--r-- | test/integration/targets/filter_core/tasks/main.yml | 24 |
3 files changed, 46 insertions, 1 deletions
diff --git a/changelogs/fragments/deprecate-non-enforced-password_hash-type-choices.yml b/changelogs/fragments/deprecate-non-enforced-password_hash-type-choices.yml new file mode 100644 index 0000000000..a5d82a3309 --- /dev/null +++ b/changelogs/fragments/deprecate-non-enforced-password_hash-type-choices.yml @@ -0,0 +1,4 @@ +deprecated_features: + - password_hash - deprecate using passlib.hash.hashtype if hashtype isn't in the list of documented choices. +bugfixes: + - password_hash - handle errors using unknown passlib hashtypes more gracefully (https://github.com/ansible/ansible/issues/45392). diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py index 5906408fa7..671f9f5042 100644 --- a/lib/ansible/plugins/filter/core.py +++ b/lib/ansible/plugins/filter/core.py @@ -34,7 +34,7 @@ from ansible.parsing.ajson import AnsibleJSONEncoder from ansible.parsing.yaml.dumper import AnsibleDumper from ansible.template import recursive_check_defined from ansible.utils.display import Display -from ansible.utils.encrypt import passlib_or_crypt +from ansible.utils.encrypt import passlib_or_crypt, PASSLIB_AVAILABLE from ansible.utils.hashing import md5s, checksum_s from ansible.utils.unicode import unicode_wrap from ansible.utils.vars import merge_hash @@ -281,10 +281,27 @@ def get_encrypted_password(password, hashtype='sha512', salt=None, salt_size=Non } hashtype = passlib_mapping.get(hashtype, hashtype) + + unknown_passlib_hashtype = False + if PASSLIB_AVAILABLE and hashtype not in passlib_mapping and hashtype not in passlib_mapping.values(): + unknown_passlib_hashtype = True + display.deprecated( + f"Checking for unsupported password_hash passlib hashtype '{hashtype}'. " + "This will be an error in the future as all supported hashtypes must be documented.", + version='2.19' + ) + try: return passlib_or_crypt(password, hashtype, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident) except AnsibleError as e: reraise(AnsibleFilterError, AnsibleFilterError(to_native(e), orig_exc=e), sys.exc_info()[2]) + except Exception as e: + if unknown_passlib_hashtype: + # This can occur if passlib.hash has the hashtype attribute, but it has a different signature than the valid choices. + # In 2.19 this will replace the deprecation warning above and the extra exception handling can be deleted. + choices = ', '.join(passlib_mapping) + raise AnsibleFilterError(f"{hashtype} is not in the list of supported passlib algorithms: {choices}") from e + raise def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE): diff --git a/test/integration/targets/filter_core/tasks/main.yml b/test/integration/targets/filter_core/tasks/main.yml index 2d08419167..ebf9962dec 100644 --- a/test/integration/targets/filter_core/tasks/main.yml +++ b/test/integration/targets/filter_core/tasks/main.yml @@ -454,6 +454,30 @@ - password_hash_2 is failed - "'not support' in password_hash_2.msg" +- name: install passlib if needed + pip: + name: passlib + state: present + register: installed_passlib + +- name: test using passlib with an unsupported hash type + set_fact: + foo: '{{"hey"|password_hash("msdcc")}}' + ignore_errors: yes + register: unsupported_hash_type + +- name: remove passlib if it was installed + pip: + name: passlib + state: absent + when: installed_passlib.changed + +- assert: + that: + - unsupported_hash_type.msg == msg + vars: + msg: "msdcc is not in the list of supported passlib algorithms: md5, blowfish, sha256, sha512" + - name: Verify to_uuid throws on weird namespace set_fact: foo: '{{"hey"|to_uuid(namespace=22)}}' |