From 05dc76f3b2090b54a9c48e64bdaba2cb6ad3b344 Mon Sep 17 00:00:00 2001 From: Andreas Olsson Date: Sun, 25 Jun 2017 19:05:16 +0200 Subject: [PATCH] In the git module let ssh do its own host checking There are too many possible special cases for Ansible to be able to precheck known_hosts files without introducing all kinds of false failures. * Alternative known_hosts paths * Alternative host name aliases * ssh host certificates * SSHFP + DNSSEC Fixes #24860 --- lib/ansible/module_utils/known_hosts.py | 20 ---------- lib/ansible/modules/source_control/git.py | 39 +++++++------------ .../targets/git/tasks/missing_hostkey.yml | 1 - 3 files changed, 15 insertions(+), 45 deletions(-) diff --git a/lib/ansible/module_utils/known_hosts.py b/lib/ansible/module_utils/known_hosts.py index bda5ac33e2..ec79f38af5 100644 --- a/lib/ansible/module_utils/known_hosts.py +++ b/lib/ansible/module_utils/known_hosts.py @@ -43,26 +43,6 @@ except ImportError: HASHED_KEY_MAGIC = "|1|" -def add_git_host_key(module, url, accept_hostkey=True, create_dir=True): - - """ idempotently add a git url hostkey """ - - if is_ssh_url(url): - - fqdn, port = get_fqdn_and_port(url) - - if fqdn: - known_host = check_hostkey(module, fqdn) - if not known_host: - if accept_hostkey: - rc, out, err = add_host_key(module, fqdn, port=port, create_dir=create_dir) - if rc != 0: - module.fail_json(msg="failed to add %s hostkey: %s" % (fqdn, out + err)) - else: - module.fail_json(msg="%s has an unknown hostkey. Set accept_hostkey to True " - "or manually add the hostkey prior to running the git module" % fqdn) - - def is_ssh_url(url): """ check if url is ssh """ diff --git a/lib/ansible/modules/source_control/git.py b/lib/ansible/modules/source_control/git.py index 7869353908..8ed88fac35 100644 --- a/lib/ansible/modules/source_control/git.py +++ b/lib/ansible/modules/source_control/git.py @@ -60,9 +60,8 @@ options: choices: [ "yes", "no" ] version_added: "1.5" description: - - if C(yes), adds the hostkey for the repo url if not already - added. If ssh_opts contains "-o StrictHostKeyChecking=no", - this parameter is ignored. + - if C(yes), ensure that "-o StrictHostKeyChecking=no" is + present as an ssh options. ssh_opts: required: false default: None @@ -281,7 +280,6 @@ from distutils.version import LooseVersion from ansible.module_utils.basic import AnsibleModule, get_module_path from ansible.module_utils.basic import get_exception -from ansible.module_utils.known_hosts import add_git_host_key from ansible.module_utils.six import b, string_types from ansible.module_utils._text import to_native @@ -368,6 +366,9 @@ else BASEOPTS=$GIT_SSH_OPTS fi +# Let ssh fail rather than prompt +BASEOPTS="$BASEOPTS -o BatchMode=yes" + if [ -z "$GIT_KEY" ]; then ssh $BASEOPTS "$@" else @@ -777,15 +778,6 @@ def submodules_fetch(git_path, module, remote, track_submodules, dest): if not os.path.exists(os.path.join(dest, path, '.git')): changed = True - # add the submodule repo's hostkey - if line.strip().startswith('url'): - repo = line.split('=', 1)[1].strip() - if module.params['ssh_opts'] is not None: - if "-o StrictHostKeyChecking=no" not in module.params['ssh_opts']: - add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) - else: - add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) - # Check for updates to existing modules if not changed: # Fetch updates @@ -1031,6 +1023,13 @@ def main(): result = dict(changed=False, warnings=list()) + if module.params['accept_hostkey']: + if ssh_opts is not None: + if "-o StrictHostKeyChecking=no" not in ssh_opts: + ssh_opts += " -o StrictHostKeyChecking=no" + else: + ssh_opts = "-o StrictHostKeyChecking=no" + # evaluate and set the umask before doing anything else if umask is not None: if not isinstance(umask, string_types): @@ -1064,18 +1063,10 @@ def main(): # create a wrapper script and export # GIT_SSH= as an environment variable # for git to use the wrapper script - ssh_wrapper = None - if key_file or ssh_opts: - ssh_wrapper = write_ssh_wrapper() - set_git_ssh(ssh_wrapper, key_file, ssh_opts) - module.add_cleanup_file(path=ssh_wrapper) + ssh_wrapper = write_ssh_wrapper() + set_git_ssh(ssh_wrapper, key_file, ssh_opts) + module.add_cleanup_file(path=ssh_wrapper) - # add the git repo's hostkey - if module.params['ssh_opts'] is not None: - if "-o StrictHostKeyChecking=no" not in module.params['ssh_opts']: - add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) - else: - add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) git_version_used = git_version(git_path, module) if depth is not None and git_version_used < LooseVersion('1.9.1'): diff --git a/test/integration/targets/git/tasks/missing_hostkey.yml b/test/integration/targets/git/tasks/missing_hostkey.yml index ce19eea96f..c58b5834f0 100644 --- a/test/integration/targets/git/tasks/missing_hostkey.yml +++ b/test/integration/targets/git/tasks/missing_hostkey.yml @@ -16,7 +16,6 @@ - assert: that: - 'git_result.failed' - - 'git_result.msg == "github.com has an unknown hostkey. Set accept_hostkey to True or manually add the hostkey prior to running the git module"' - name: checkout git@github.com repo with accept_hostkey (expected pass) git: