From 1011959d88f151a5e676baf9641278109677e19c Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Mon, 2 Feb 2015 10:21:07 -0800 Subject: [PATCH] Move the hashing util functions to their own file to mirror v2 --- lib/ansible/utils/__init__.py | 68 +------------------------- lib/ansible/utils/hashing.py | 91 +++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 67 deletions(-) create mode 100644 lib/ansible/utils/hashing.py diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 44db63e2769..7c4d82914bd 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -29,6 +29,7 @@ from ansible import __version__ from ansible.utils.display_functions import * from ansible.utils.plugins import * from ansible.utils.su_prompts import * +from ansible.utils.hashing import secure_hash, secure_hash_s, checksum, checksum_s, md5, md5s from ansible.callbacks import display from ansible.module_utils.splitter import split_args, unquote import ansible.constants as C @@ -67,23 +68,6 @@ try: except ImportError: import json -# Note, sha1 is the only hash algorithm compatible with python2.4 and with -# FIPS-140 mode (as of 11-2014) -try: - from hashlib import sha1 as sha1 -except ImportError: - from sha import sha as sha1 - -# Backwards compat only -try: - from hashlib import md5 as _md5 -except ImportError: - try: - from md5 import md5 as _md5 - except ImportError: - # Assume we're running in FIPS mode here - _md5 = None - PASSLIB_AVAILABLE = False try: import passlib.hash @@ -832,56 +816,6 @@ def merge_hash(a, b): return result -def secure_hash_s(data, hash_func=sha1): - ''' Return a secure hash hex digest of data. ''' - - digest = hash_func() - try: - digest.update(data) - except UnicodeEncodeError: - digest.update(data.encode('utf-8')) - return digest.hexdigest() - -def secure_hash(filename, hash_func=sha1): - ''' Return a secure hash hex digest of local file, None if file is not present or a directory. ''' - - if not os.path.exists(filename) or os.path.isdir(filename): - return None - digest = hash_func() - blocksize = 64 * 1024 - try: - infile = open(filename, 'rb') - block = infile.read(blocksize) - while block: - digest.update(block) - block = infile.read(blocksize) - infile.close() - except IOError, e: - raise errors.AnsibleError("error while accessing the file %s, error was: %s" % (filename, e)) - return digest.hexdigest() - -# The checksum algorithm must match with the algorithm in ShellModule.checksum() method -checksum = secure_hash -checksum_s = secure_hash_s - -# Backwards compat. 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 m5 unless it is needed for: -# 1) Optional backwards compatibility -# 2) Compliance with a third party protocol -# -# MD5 will not work on systems which are FIPS-140-2 compliant. -def md5s(data): - if not _md5: - raise ValueError('MD5 not available. Possibly running in FIPS mode') - return secure_hash_s(data, _md5) - -def md5(filename): - if not _md5: - raise ValueError('MD5 not available. Possibly running in FIPS mode') - return secure_hash(filename, _md5) - def default(value, function): ''' syntactic sugar around lazy evaluation of defaults ''' if value is None: diff --git a/lib/ansible/utils/hashing.py b/lib/ansible/utils/hashing.py new file mode 100644 index 00000000000..a7d142e5bd4 --- /dev/null +++ b/lib/ansible/utils/hashing.py @@ -0,0 +1,91 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os + +# Note, sha1 is the only hash algorithm compatible with python2.4 and with +# FIPS-140 mode (as of 11-2014) +try: + from hashlib import sha1 as sha1 +except ImportError: + from sha import sha as sha1 + +# Backwards compat only +try: + from hashlib import md5 as _md5 +except ImportError: + try: + from md5 import md5 as _md5 + except ImportError: + # Assume we're running in FIPS mode here + _md5 = None + +def secure_hash_s(data, hash_func=sha1): + ''' Return a secure hash hex digest of data. ''' + + digest = hash_func() + try: + digest.update(data) + except UnicodeEncodeError: + digest.update(data.encode('utf-8')) + return digest.hexdigest() + +def secure_hash(filename, hash_func=sha1): + ''' Return a secure hash hex digest of local file, None if file is not present or a directory. ''' + + if not os.path.exists(filename) or os.path.isdir(filename): + return None + digest = hash_func() + blocksize = 64 * 1024 + try: + infile = open(filename, 'rb') + block = infile.read(blocksize) + while block: + digest.update(block) + block = infile.read(blocksize) + infile.close() + except IOError, e: + raise errors.AnsibleError("error while accessing the file %s, error was: %s" % (filename, e)) + return digest.hexdigest() + +# The checksum algorithm must match with the algorithm in ShellModule.checksum() method +checksum = secure_hash +checksum_s = secure_hash_s + +# 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 +# +# MD5 will not work on systems which are FIPS-140-2 compliant. + +def md5s(data): + if not _md5: + raise ValueError('MD5 not available. Possibly running in FIPS mode') + return secure_hash_s(data, _md5) + +def md5(filename): + if not _md5: + raise ValueError('MD5 not available. Possibly running in FIPS mode') + return secure_hash(filename, _md5) +