Last active
September 28, 2021 13:24
-
-
Save sivel/f72ef00347d54b5524592786fddcd8da to your computer and use it in GitHub Desktop.
Ansible filter plugin to encrypt a string with yescrypt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (c) 2021 Matt Martz <[email protected]> | |
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | |
from __future__ import (absolute_import, division, print_function) | |
__metaclass__ = type | |
import ctypes | |
from ansible.errors import AnsibleFilterError | |
from ansible.module_utils.common.text.converters import to_bytes, to_text | |
from ansible.utils.encrypt import random_salt | |
try: | |
_libcrypt = ctypes.CDLL('libcrypt.so.1') | |
HAS_LIBCRYPT = True | |
except OSError: | |
HAS_LIBCRYPT = False | |
else: | |
crypt_gensalt = _libcrypt.crypt_gensalt | |
crypt_gensalt.argtypes = [ctypes.c_char_p, ctypes.c_long, ctypes.c_char_p, ctypes.c_int] | |
crypt_gensalt.restype = ctypes.c_char_p | |
crypt = _libcrypt.crypt | |
crypt.argtypes = [ctypes.c_char_p, ctypes.c_char_p] | |
crypt.restype = ctypes.c_char_p | |
def yescrypt(word, salt=None, salt_length=20): | |
if not HAS_LIBCRYPT: | |
raise AnsibleFilterError('cannot locate libcrypt.so.1') | |
if not salt: | |
setting = crypt_gensalt( | |
b'$y$', | |
9, | |
to_bytes(random_salt(salt_length)), | |
salt_length | |
) | |
else: | |
setting = b'$y$jDT$%s' % to_bytes(salt) | |
try: | |
return to_text(crypt(to_bytes(word), setting)) | |
except ctypes.ArgumentError as e: | |
raise AnsibleFilterError('libcrypt likely missing yescrypt support: %s' % e) | |
class FilterModule(object): | |
def filters(self): | |
return { | |
'yescrypt': yescrypt, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment