summaryrefslogtreecommitdiffstats
path: root/lib/ansible/utils/encrypt.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-05 16:16:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-05 16:16:49 +0000
commit48e387c5c12026a567eb7b293a3a590241c0cecb (patch)
tree80f2573be2d7d534b8ac4d2a852fe43f7ac35324 /lib/ansible/utils/encrypt.py
parentReleasing progress-linux version 2.16.6-1~progress7.99u1. (diff)
downloadansible-core-48e387c5c12026a567eb7b293a3a590241c0cecb.tar.xz
ansible-core-48e387c5c12026a567eb7b293a3a590241c0cecb.zip
Merging upstream version 2.17.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/ansible/utils/encrypt.py')
-rw-r--r--lib/ansible/utils/encrypt.py109
1 files changed, 4 insertions, 105 deletions
diff --git a/lib/ansible/utils/encrypt.py b/lib/ansible/utils/encrypt.py
index 541c5c8..3a279b7 100644
--- a/lib/ansible/utils/encrypt.py
+++ b/lib/ansible/utils/encrypt.py
@@ -1,13 +1,10 @@
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
# (c) 2017 Ansible Project
# 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
+from __future__ import annotations
import random
-import re
import string
-import sys
from collections import namedtuple
@@ -17,8 +14,8 @@ from ansible.module_utils.six import text_type
from ansible.module_utils.common.text.converters import to_text, to_bytes
from ansible.utils.display import Display
-PASSLIB_E = CRYPT_E = None
-HAS_CRYPT = PASSLIB_AVAILABLE = False
+PASSLIB_E = None
+PASSLIB_AVAILABLE = False
try:
import passlib
import passlib.hash
@@ -31,12 +28,6 @@ try:
except Exception as e:
PASSLIB_E = e
-try:
- import crypt
- HAS_CRYPT = True
-except Exception as e:
- CRYPT_E = e
-
display = Display()
@@ -84,96 +75,6 @@ class BaseHash(object):
self.algorithm = algorithm
-class CryptHash(BaseHash):
- def __init__(self, algorithm):
- super(CryptHash, self).__init__(algorithm)
-
- if not HAS_CRYPT:
- raise AnsibleError("crypt.crypt cannot be used as the 'crypt' python library is not installed or is unusable.", orig_exc=CRYPT_E)
-
- if sys.platform.startswith('darwin'):
- raise AnsibleError("crypt.crypt not supported on Mac OS X/Darwin, install passlib python module")
-
- if algorithm not in self.algorithms:
- raise AnsibleError("crypt.crypt does not support '%s' algorithm" % self.algorithm)
-
- display.deprecated(
- "Encryption using the Python crypt module is deprecated. The "
- "Python crypt module is deprecated and will be removed from "
- "Python 3.13. Install the passlib library for continued "
- "encryption functionality.",
- version="2.17",
- )
-
- self.algo_data = self.algorithms[algorithm]
-
- def hash(self, secret, salt=None, salt_size=None, rounds=None, ident=None):
- salt = self._salt(salt, salt_size)
- rounds = self._rounds(rounds)
- ident = self._ident(ident)
- return self._hash(secret, salt, rounds, ident)
-
- def _salt(self, salt, salt_size):
- salt_size = salt_size or self.algo_data.salt_size
- ret = salt or random_salt(salt_size)
- if re.search(r'[^./0-9A-Za-z]', ret):
- raise AnsibleError("invalid characters in salt")
- if self.algo_data.salt_exact and len(ret) != self.algo_data.salt_size:
- raise AnsibleError("invalid salt size")
- elif not self.algo_data.salt_exact and len(ret) > self.algo_data.salt_size:
- raise AnsibleError("invalid salt size")
- return ret
-
- def _rounds(self, rounds):
- if self.algorithm == 'bcrypt':
- # crypt requires 2 digits for rounds
- return rounds or self.algo_data.implicit_rounds
- elif rounds == self.algo_data.implicit_rounds:
- # Passlib does not include the rounds if it is the same as implicit_rounds.
- # Make crypt lib behave the same, by not explicitly specifying the rounds in that case.
- return None
- else:
- return rounds
-
- def _ident(self, ident):
- if not ident:
- return self.algo_data.crypt_id
- if self.algorithm == 'bcrypt':
- return ident
- return None
-
- def _hash(self, secret, salt, rounds, ident):
- saltstring = ""
- if ident:
- saltstring = "$%s" % ident
-
- if rounds:
- if self.algorithm == 'bcrypt':
- saltstring += "$%d" % rounds
- else:
- saltstring += "$rounds=%d" % rounds
-
- saltstring += "$%s" % salt
-
- # crypt.crypt throws OSError on Python >= 3.9 if it cannot parse saltstring.
- try:
- result = crypt.crypt(secret, saltstring)
- orig_exc = None
- except OSError as e:
- result = None
- orig_exc = e
-
- # None as result would be interpreted by some modules (user module)
- # as no password at all.
- if not result:
- raise AnsibleError(
- "crypt.crypt does not support '%s' algorithm" % self.algorithm,
- orig_exc=orig_exc,
- )
-
- return result
-
-
class PasslibHash(BaseHash):
def __init__(self, algorithm):
super(PasslibHash, self).__init__(algorithm)
@@ -274,6 +175,4 @@ def passlib_or_crypt(secret, algorithm, salt=None, salt_size=None, rounds=None,
def do_encrypt(result, encrypt, salt_size=None, salt=None, ident=None, rounds=None):
if PASSLIB_AVAILABLE:
return PasslibHash(encrypt).hash(result, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
- if HAS_CRYPT:
- return CryptHash(encrypt).hash(result, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
- raise AnsibleError("Unable to encrypt nor hash, either crypt or passlib must be installed.", orig_exc=CRYPT_E)
+ raise AnsibleError("Unable to encrypt nor hash, passlib must be installed", orig_exc=PASSLIB_E)