diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index b83b3762158..8df490bf0aa 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -100,6 +100,29 @@ try: except ImportError: has_journal = False +AVAILABLE_HASH_ALGORITHMS = dict() +try: + import hashlib + + # python 2.7.9+ and 2.7.0+ + for attribute in ('available_algorithms', 'algorithms'): + algorithms = getattr(hashlib, attribute, None) + if algorithms: + break + if algorithms is None: + # python 2.5+ + algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') + for algorithm in algorithms: + AVAILABLE_HASH_ALGORITHMS[algorithm] = getattr(hashlib, algorithm) +except ImportError: + import sha + AVAILABLE_HASH_ALGORITHMS = {'sha1': sha.sha} + try: + import md5 + AVAILABLE_HASH_ALGORITHMS['md5'] = md5.md5 + except ImportError: + pass + try: from ast import literal_eval as _literal_eval except ImportError: @@ -1320,38 +1343,6 @@ class AnsibleModule(object): or stat.S_IXGRP & os.stat(path)[stat.ST_MODE] or stat.S_IXOTH & os.stat(path)[stat.ST_MODE]) - def get_available_hash_algorithms(self): - ''' Get all hash algorithms that are available on this system as a dict. - For example: { - 'md5': md5.md5, - 'sha1': sha.sha - } - ''' - available_hash_algorithms = dict() - try: - import hashlib - - # python 2.7.9+ and 2.7.0+ - for attribute in ('available_algorithms', 'algorithms'): - algorithms = getattr(hashlib, attribute, None) - if algorithms: - break - if algorithms is None: - # python 2.5+ - algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') - for algorithm in algorithms: - available_hash_algorithms[algorithm] = getattr(hashlib, algorithm) - except ImportError: - import sha - available_hash_algorithms = {'sha1': sha.sha} - try: - import md5 - available_hash_algorithms['md5'] = md5.md5 - except ImportError: - pass - - return available_hash_algorithms - def digest_from_file(self, filename, algorithm): ''' Return hex digest of local file for a digest_method specified by name, or None if file is not present. ''' if not os.path.exists(filename): @@ -1364,10 +1355,10 @@ class AnsibleModule(object): digest_method = algorithm else: try: - digest_method = self.get_available_hash_algorithms()[algorithm]() + digest_method = AVAILABLE_HASH_ALGORITHMS[algorithm]() except KeyError: self.fail_json(msg="Could not hash file '%s' with algorithm '%s'. Available algorithms: %s" % - (filename, algorithm, ', '.join(self.get_available_hash_algorithms()))) + (filename, algorithm, ', '.join(AVAILABLE_HASH_ALGORITHMS))) blocksize = 64 * 1024 infile = open(filename, 'rb') @@ -1389,6 +1380,8 @@ class AnsibleModule(object): Most uses of this function can use the module.sha1 function instead. ''' + if 'md5' not in AVAILABLE_HASH_ALGORITHMS: + raise ValueError('MD5 not available. Possibly running in FIPS mode') return self.digest_from_file(filename, 'md5') def sha1(self, filename):