2015-01-09 16:37:31 +01:00
|
|
|
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
2017-09-17 05:35:50 +02:00
|
|
|
# (c) 2017 Ansible Project
|
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
2015-04-13 22:28:01 +02:00
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
|
|
__metaclass__ = type
|
|
|
|
|
2017-05-30 19:09:44 +02:00
|
|
|
import multiprocessing
|
2017-08-15 00:19:40 +02:00
|
|
|
import random
|
2015-10-02 06:35:22 +02:00
|
|
|
|
2017-05-30 19:09:44 +02:00
|
|
|
from ansible import constants as C
|
2017-11-13 17:51:18 +01:00
|
|
|
from ansible.errors import AnsibleError, AnsibleAssertionError
|
2017-08-15 00:19:40 +02:00
|
|
|
from ansible.module_utils.six import text_type
|
2017-05-30 19:09:44 +02:00
|
|
|
from ansible.module_utils._text import to_text, to_bytes
|
|
|
|
|
2017-08-15 00:19:40 +02:00
|
|
|
|
2015-01-09 16:37:31 +01:00
|
|
|
PASSLIB_AVAILABLE = False
|
|
|
|
try:
|
|
|
|
import passlib.hash
|
|
|
|
PASSLIB_AVAILABLE = True
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2015-10-19 20:29:51 +02:00
|
|
|
try:
|
|
|
|
from __main__ import display
|
|
|
|
except ImportError:
|
|
|
|
from ansible.utils.display import Display
|
|
|
|
display = Display()
|
|
|
|
|
2015-01-09 16:37:31 +01:00
|
|
|
__all__ = ['do_encrypt']
|
|
|
|
|
2016-04-25 18:13:42 +02:00
|
|
|
_LOCK = multiprocessing.Lock()
|
|
|
|
|
2017-09-17 05:35:50 +02:00
|
|
|
DEFAULT_PASSWORD_LENGTH = 20
|
|
|
|
|
2016-04-25 18:13:42 +02:00
|
|
|
|
2015-01-09 16:37:31 +01:00
|
|
|
def do_encrypt(result, encrypt, salt_size=None, salt=None):
|
|
|
|
if PASSLIB_AVAILABLE:
|
|
|
|
try:
|
|
|
|
crypt = getattr(passlib.hash, encrypt)
|
|
|
|
except:
|
|
|
|
raise AnsibleError("passlib does not support '%s' algorithm" % encrypt)
|
|
|
|
|
|
|
|
if salt_size:
|
|
|
|
result = crypt.encrypt(result, salt_size=salt_size)
|
|
|
|
elif salt:
|
2016-10-20 22:48:20 +02:00
|
|
|
if crypt._salt_is_bytes:
|
|
|
|
salt = to_bytes(salt, encoding='ascii', errors='strict')
|
|
|
|
else:
|
|
|
|
salt = to_text(salt, encoding='ascii', errors='strict')
|
2015-01-09 16:37:31 +01:00
|
|
|
result = crypt.encrypt(result, salt=salt)
|
|
|
|
else:
|
|
|
|
result = crypt.encrypt(result)
|
|
|
|
else:
|
|
|
|
raise AnsibleError("passlib must be installed to encrypt vars_prompt values")
|
|
|
|
|
2016-09-19 20:37:57 +02:00
|
|
|
# Hashes from passlib.hash should be represented as ascii strings of hex
|
|
|
|
# digits so this should not traceback. If it's not representable as such
|
|
|
|
# we need to traceback and then blacklist such algorithms because it may
|
|
|
|
# impact calling code.
|
|
|
|
return to_text(result, errors='strict')
|
2015-01-09 16:37:31 +01:00
|
|
|
|
2017-05-30 19:09:44 +02:00
|
|
|
|
2017-08-15 00:19:40 +02:00
|
|
|
def random_password(length=DEFAULT_PASSWORD_LENGTH, chars=C.DEFAULT_PASSWORD_CHARS):
|
|
|
|
'''Return a random password string of length containing only chars
|
|
|
|
|
|
|
|
:kwarg length: The number of characters in the new password. Defaults to 20.
|
|
|
|
:kwarg chars: The characters to choose from. The default is all ascii
|
|
|
|
letters, ascii digits, and these symbols ``.,:-_``
|
|
|
|
'''
|
2017-11-13 17:51:18 +01:00
|
|
|
if not isinstance(chars, text_type):
|
|
|
|
raise AnsibleAssertionError('%s (%s) is not a text_type' % (chars, type(chars)))
|
2017-08-15 00:19:40 +02:00
|
|
|
|
|
|
|
random_generator = random.SystemRandom()
|
|
|
|
return u''.join(random_generator.choice(chars) for dummy in range(length))
|