Krikri::PluginHelpers::CryptHash
ansible-core 2.21's password_hash backend. module_utils/utils/encrypt.py
swapped passlib for libxcrypt (libc crypt() + crypt_gensalt()), so a
salted hash now comes from the controller's own C library instead of a
Python reimplementation. That changes observable output for a
user-supplied salt: libxcrypt re-encodes the salt bytes with crypt's
base64 and always writes the scheme's rounds/cost marker, where passlib
used the salt text verbatim.
This mirrors CryptHash from that module (algorithm table, salt/size
rules, error strings) and calls the same libcrypt entry points, so the
hashes match what real Ansible produces on the same host.
The library is loaded at RUNTIME (dlopen), never linked in: ansible's own
_internal/_encryption/_crypt.py CryptFacade does exactly that (via
ctypes), probes the same libraries in the same order, and DEGRADES
gracefully when crypt_gensalt is missing (it builds the salt string by
hand instead, and rejects yescrypt). A build-time @[Link("crypt")]
instead broke every release build: macOS has no libcrypt at all
(ld: library 'crypt' not found) and Alpine ships only an 8-byte empty
libcrypt.a stub, so the musl-static Linux link died on undefined reference to crypt_gensalt.
Constants
encrypt.py's BaseHash.algorithms + CryptHash's own addition.
The filter's own passlib-era name mapping (core.py's get_encrypted_password) and the message it raises for a name it does not know.
AnsibleError from CryptHash.init when nothing could be loaded.
ansible's _SALT_CHARS, used only by the no-gensalt fallback.
Class methods
get_encrypted_password(): the filter-level name mapping plus its own rejection of anything outside the passlib-era set (live-verified vs 2.21.6, whose controller has passlib installed - without it the name reaches do_encrypt and fails with the crypt wording instead).
CryptHash.init plus CryptHash.hash(): the crypt library and the algorithm are checked first, then libxcrypt's own crypt_gensalt (with ansible's fallback when only a libc crypt() is available), then crypt().