Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve password_hash warning for unsupported algorithms #79872

Merged
merged 2 commits into from Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -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).
19 changes: 18 additions & 1 deletion lib/ansible/plugins/filter/core.py
Expand Up @@ -34,7 +34,7 @@
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
Expand Down Expand Up @@ -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):
Expand Down
24 changes: 24 additions & 0 deletions test/integration/targets/filter_core/tasks/main.yml
Expand Up @@ -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)}}'
Expand Down