summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSloane Hertel <19572925+s-hertel@users.noreply.github.com>2023-02-08 14:46:07 -0500
committerGitHub <noreply@github.com>2023-02-08 11:46:07 -0800
commitfcdd7493ae6241badf43caf5e120690c5b9bdd33 (patch)
tree7d72434825719e07ff3ad78db971dc0c1e0e38ff
parent9d65e122ff62b31133bce7148921f6aea9b6a394 (diff)
downloadansible-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.yml4
-rw-r--r--lib/ansible/plugins/filter/core.py19
-rw-r--r--test/integration/targets/filter_core/tasks/main.yml24
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)}}'