From 34d65647bf391c67468fb17732b254845a2ce16f Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Thu, 6 Nov 2014 21:25:55 -0800 Subject: [PATCH] Move from md5 to sha1 to work on FIPS-140 enabled systems --- lib/ansible/modules/files/assemble.py | 21 ++++++++++++------ lib/ansible/modules/files/copy.py | 15 ++++++++----- lib/ansible/modules/files/fetch.py | 5 +++-- lib/ansible/modules/files/stat.py | 22 ++++++++++++++++--- lib/ansible/modules/network/basics/get_url.py | 21 ++++++++++++------ lib/ansible/modules/network/basics/uri.py | 14 ++++++------ 6 files changed, 67 insertions(+), 31 deletions(-) diff --git a/lib/ansible/modules/files/assemble.py b/lib/ansible/modules/files/assemble.py index a16431b9f52..a66c82f432a 100644 --- a/lib/ansible/modules/files/assemble.py +++ b/lib/ansible/modules/files/assemble.py @@ -153,8 +153,9 @@ def main(): ) changed = False - pathmd5 = None - destmd5 = None + path_md5 = None # Deprecated + path_hash = None + dest_hash = None src = os.path.expanduser(module.params['src']) dest = os.path.expanduser(module.params['dest']) backup = module.params['backup'] @@ -175,23 +176,29 @@ def main(): module.fail_json(msg="Invalid Regexp (%s) in \"%s\"" % (e, regexp)) path = assemble_from_fragments(src, delimiter, compiled_regexp) - pathmd5 = module.md5(path) + path_hash = module.sha1(path) if os.path.exists(dest): - destmd5 = module.md5(dest) + dest_hash = module.sha1(dest) - if pathmd5 != destmd5: - if backup and destmd5 is not None: + if path_hash != dest_hash: + if backup and dest_hash is not None: module.backup_local(dest) shutil.copy(path, dest) changed = True + # Backwards compat. This won't return data if FIPS mode is active + try: + pathmd5 = module.md5(path) + except ValueError: + pathmd5 = None + os.remove(path) file_args = module.load_file_common_arguments(module.params) changed = module.set_fs_attributes_if_different(file_args, changed) # Mission complete - module.exit_json(src=src, dest=dest, md5sum=pathmd5, changed=changed, msg="OK") + module.exit_json(src=src, dest=dest, md5sum=pathmd5, checksum=path_hash, changed=changed, msg="OK") # import module snippets from ansible.module_utils.basic import * diff --git a/lib/ansible/modules/files/copy.py b/lib/ansible/modules/files/copy.py index eff46dae982..9ee8e42c31a 100644 --- a/lib/ansible/modules/files/copy.py +++ b/lib/ansible/modules/files/copy.py @@ -167,8 +167,13 @@ def main(): if not os.access(src, os.R_OK): module.fail_json(msg="Source %s not readable" % (src)) - md5sum_src = module.md5(src) - md5sum_dest = None + checksum_src = module.sha1(src) + checksum_dest = None + # Backwards compat only. This will be None in FIPS mode + try: + md5sum_src = module.md5(src) + except ValueError: + md5sum_src = None changed = False @@ -198,7 +203,7 @@ def main(): basename = original_basename dest = os.path.join(dest, basename) if os.access(dest, os.R_OK): - md5sum_dest = module.md5(dest) + checksum_dest = module.sha1(dest) else: if not os.path.exists(os.path.dirname(dest)): try: @@ -215,7 +220,7 @@ def main(): module.fail_json(msg="Destination %s not writable" % (os.path.dirname(dest))) backup_file = None - if md5sum_src != md5sum_dest or os.path.islink(dest): + if checksum_src != checksum_dest or os.path.islink(dest): try: if backup: if os.path.exists(dest): @@ -238,7 +243,7 @@ def main(): changed = False res_args = dict( - dest = dest, src = src, md5sum = md5sum_src, changed = changed + dest = dest, src = src, md5sum = md5sum_src, checksum = checksum_src, changed = changed ) if backup_file: res_args['backup_file'] = backup_file diff --git a/lib/ansible/modules/files/fetch.py b/lib/ansible/modules/files/fetch.py index 5b47d87a856..fd631e6ebe6 100644 --- a/lib/ansible/modules/files/fetch.py +++ b/lib/ansible/modules/files/fetch.py @@ -34,13 +34,14 @@ options: required: false choices: [ "yes", "no" ] default: "no" - validate_md5: + validate_checksum: version_added: "1.4" description: - - Verify that the source and destination md5sums match after the files are fetched. + - Verify that the source and destination checksums match after the files are fetched. required: false choices: [ "yes", "no" ] default: "yes" + aliases: [ "validate_md5" ] flat: version_added: "1.2" description: diff --git a/lib/ansible/modules/files/stat.py b/lib/ansible/modules/files/stat.py index 75429424afb..484da2136d9 100644 --- a/lib/ansible/modules/files/stat.py +++ b/lib/ansible/modules/files/stat.py @@ -36,10 +36,17 @@ options: aliases: [] get_md5: description: - - Whether to return the md5 sum of the file + - Whether to return the md5 sum of the file. Will return None if we're unable to use md5 (Common for FIPS-140 compliant systems) required: false default: yes aliases: [] + get_checksum: + description: + - Whether to return a checksum of the file (currently sha1) + required: false + default: yes + aliases: [] + version_added: "1.8" author: Bruce Pennypacker ''' @@ -73,7 +80,8 @@ def main(): argument_spec = dict( path = dict(required=True), follow = dict(default='no', type='bool'), - get_md5 = dict(default='yes', type='bool') + get_md5 = dict(default='yes', type='bool'), + get_checksum = dict(default='yes', type='bool') ), supports_check_mode = True ) @@ -82,6 +90,7 @@ def main(): path = os.path.expanduser(path) follow = module.params.get('follow') get_md5 = module.params.get('get_md5') + get_checksum = module.params.get('get_checksum') try: if follow: @@ -135,7 +144,14 @@ def main(): d['lnk_source'] = os.path.realpath(path) if S_ISREG(mode) and get_md5 and os.access(path,os.R_OK): - d['md5'] = module.md5(path) + # Will fail on FIPS-140 compliant systems + try: + d['md5'] = module.md5(path) + except ValueError: + d['md5'] = None + + if S_ISREG(mode) and get_checksum and os.access(path,os.R_OK): + d['checksum'] = module.sha1(path) try: diff --git a/lib/ansible/modules/network/basics/get_url.py b/lib/ansible/modules/network/basics/get_url.py index c3b81129a27..b0d27859420 100644 --- a/lib/ansible/modules/network/basics/get_url.py +++ b/lib/ansible/modules/network/basics/get_url.py @@ -154,7 +154,7 @@ def url_get(module, url, dest, use_proxy, last_mod_time, force, timeout=10): if info['status'] == 304: module.exit_json(url=url, dest=dest, changed=False, msg=info.get('msg', '')) - # create a temporary file and copy content to do md5-based replacement + # create a temporary file and copy content to do checksum-based replacement if info['status'] != 200: module.fail_json(msg="Request failed", status_code=info['status'], response=info['msg'], url=url, dest=dest) @@ -241,8 +241,8 @@ def main(): filename = url_filename(info['url']) dest = os.path.join(dest, filename) - md5sum_src = None - md5sum_dest = None + checksum_src = None + checksum_dest = None # raise an error if there is no tmpsrc file if not os.path.exists(tmpsrc): @@ -251,7 +251,7 @@ def main(): if not os.access(tmpsrc, os.R_OK): os.remove(tmpsrc) module.fail_json( msg="Source %s not readable" % (tmpsrc)) - md5sum_src = module.md5(tmpsrc) + checksum_src = module.sha1(tmpsrc) # check if there is no dest file if os.path.exists(dest): @@ -262,13 +262,13 @@ def main(): if not os.access(dest, os.R_OK): os.remove(tmpsrc) module.fail_json( msg="Destination %s not readable" % (dest)) - md5sum_dest = module.md5(dest) + checksum_dest = module.sha1(dest) else: if not os.access(os.path.dirname(dest), os.W_OK): os.remove(tmpsrc) module.fail_json( msg="Destination %s not writable" % (os.path.dirname(dest))) - if md5sum_src != md5sum_dest: + if checksum_src != checksum_dest: try: shutil.copyfile(tmpsrc, dest) except Exception, err: @@ -303,8 +303,15 @@ def main(): file_args['path'] = dest changed = module.set_fs_attributes_if_different(file_args, changed) + # Backwards compat only. We'll return None on FIPS enabled systems + try: + md5sum = module.md5(dest) + except ValueError: + md5sum = None + # Mission complete - module.exit_json(url=url, dest=dest, src=tmpsrc, md5sum=md5sum_src, + + module.exit_json(url=url, dest=dest, src=tmpsrc, md5sum=md5sum, checksum=checksum_src, sha256sum=sha256sum, changed=changed, msg=info.get('msg', '')) # import module snippets diff --git a/lib/ansible/modules/network/basics/uri.py b/lib/ansible/modules/network/basics/uri.py index 8d62463df72..95bf5c705fe 100644 --- a/lib/ansible/modules/network/basics/uri.py +++ b/lib/ansible/modules/network/basics/uri.py @@ -194,8 +194,8 @@ def write_file(module, url, dest, content): module.fail_json(msg="failed to create temporary content file: %s" % str(err)) f.close() - md5sum_src = None - md5sum_dest = None + checksum_src = None + checksum_dest = None # raise an error if there is no tmpsrc file if not os.path.exists(tmpsrc): @@ -204,7 +204,7 @@ def write_file(module, url, dest, content): if not os.access(tmpsrc, os.R_OK): os.remove(tmpsrc) module.fail_json( msg="Source %s not readable" % (tmpsrc)) - md5sum_src = module.md5(tmpsrc) + checksum_src = module.sha1(tmpsrc) # check if there is no dest file if os.path.exists(dest): @@ -215,19 +215,19 @@ def write_file(module, url, dest, content): if not os.access(dest, os.R_OK): os.remove(tmpsrc) module.fail_json( msg="Destination %s not readable" % (dest)) - md5sum_dest = module.md5(dest) + checksum_dest = module.sha1(dest) else: if not os.access(os.path.dirname(dest), os.W_OK): os.remove(tmpsrc) module.fail_json( msg="Destination dir %s not writable" % (os.path.dirname(dest))) - - if md5sum_src != md5sum_dest: + + if checksum_src != checksum_dest: try: shutil.copyfile(tmpsrc, dest) except Exception, err: os.remove(tmpsrc) module.fail_json(msg="failed to copy %s to %s: %s" % (tmpsrc, dest, str(err))) - + os.remove(tmpsrc)