mirror of https://github.com/ansible/ansible.git
Move ansible.utils.hashing to ansible.module_utils.common.hashing
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>pull/84053/head
parent
17623add2f
commit
85963c55b0
@ -0,0 +1,130 @@
|
||||
# Copyright: Contributors to the Ansible project
|
||||
# Copyright: (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
from hashlib import sha1
|
||||
|
||||
try:
|
||||
from hashlib import md5 as _md5
|
||||
except ImportError:
|
||||
# Assume we're running in FIPS mode here
|
||||
_md5 = None # type: ignore[assignment]
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
|
||||
|
||||
def _get_available_hash_algorithms():
|
||||
"""Return a dictionary of available hash function names and their associated function."""
|
||||
algorithms = {}
|
||||
for algorithm_name in hashlib.algorithms_available:
|
||||
algorithm_func = getattr(hashlib, algorithm_name, None)
|
||||
if algorithm_func:
|
||||
try:
|
||||
# Make sure the algorithm is actually available for use.
|
||||
# Not all algorithms listed as available are actually usable.
|
||||
# For example, md5 is not available in FIPS mode.
|
||||
algorithm_func()
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
algorithms[algorithm_name] = algorithm_func
|
||||
|
||||
return algorithms
|
||||
|
||||
|
||||
AVAILABLE_HASH_ALGORITHMS = _get_available_hash_algorithms()
|
||||
|
||||
|
||||
def generate_secure_checksum(data, hash_func=hashlib.sha256):
|
||||
"""Generates a secure checksum for the given data using the specified hash function.
|
||||
|
||||
Args:
|
||||
data: The data to be hashed.
|
||||
hash_func: The hash function to use (default: hashlib.sha256).
|
||||
|
||||
Returns:
|
||||
A hexadecimal string representing the checksum.
|
||||
"""
|
||||
|
||||
digest = hash_func()
|
||||
data = to_bytes(data, errors='surrogate_or_strict')
|
||||
digest.update(data)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def generate_secure_file_checksum(filename, hash_func=hashlib.sha256, write_to=None):
|
||||
"""Return a secure hash hex digest of local file, None if file is not present or a directory.
|
||||
|
||||
Args:
|
||||
filename: The filename to be hashed.
|
||||
hash_func: The hash function to use (default: hashlib.sha256).
|
||||
write_to: The file handle to write to (default: None).
|
||||
|
||||
Returns:
|
||||
A hexadecimal string representing the checksum.
|
||||
"""
|
||||
b_filename = to_bytes(filename, errors='surrogate_or_strict')
|
||||
|
||||
if not os.path.exists(b_filename) or os.path.isdir(to_bytes(filename, errors='strict')):
|
||||
return None
|
||||
|
||||
digest = hash_func()
|
||||
blocksize = 64 * 1024
|
||||
try:
|
||||
infile = open(os.path.realpath(b_filename), 'rb')
|
||||
block = infile.read(blocksize)
|
||||
while block:
|
||||
if write_to is not None:
|
||||
write_to.write(block)
|
||||
write_to.flush()
|
||||
digest.update(block)
|
||||
block = infile.read(blocksize)
|
||||
infile.close()
|
||||
except IOError as e:
|
||||
raise e
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
#
|
||||
# Backwards compat functions. Some modules include md5s in their return values
|
||||
# Continue to support that for now. As of ansible-1.8, all of those modules
|
||||
# should also return "checksum" (sha1 for now)
|
||||
# Do not use md5 unless it is needed for:
|
||||
# 1) Optional backwards compatibility
|
||||
# 2) Compliance with a third party protocol
|
||||
|
||||
def secure_hash_s(data, hash_func=sha1):
|
||||
# deprecated: description='Use generate_secure_checksum instead' core_version='2.21'
|
||||
# Backward compatibility
|
||||
return generate_secure_checksum(data=data, hash_func=hash_func)
|
||||
|
||||
|
||||
def secure_hash(filename, hash_func=sha1):
|
||||
# deprecated: description='Use generate_secure_file_checksum instead' core_version='2.21'
|
||||
# Backward compatibility
|
||||
return generate_secure_file_checksum(filename=filename, hash_func=hash_func)
|
||||
|
||||
#
|
||||
# MD5 will not work on systems which are FIPS-140-2 compliant.
|
||||
#
|
||||
|
||||
|
||||
def md5s(data):
|
||||
if not _md5: # type: ignore[truthy-function]
|
||||
raise ValueError('MD5 not available. Possibly running in FIPS mode')
|
||||
return secure_hash_s(data, _md5)
|
||||
|
||||
|
||||
def md5(filename):
|
||||
if not _md5: # type: ignore[truthy-function]
|
||||
raise ValueError('MD5 not available. Possibly running in FIPS mode')
|
||||
return secure_hash(filename, _md5)
|
||||
|
||||
|
||||
# The checksum algorithm must match with the algorithm in ShellModule.checksum() method
|
||||
checksum = secure_hash
|
||||
checksum_s = secure_hash_s
|
Loading…
Reference in New Issue