From 6128ab3ff48a8b770d1a71fffdaeb0ebed2da82f Mon Sep 17 00:00:00 2001 From: Chris Church Date: Tue, 11 Aug 2015 16:30:27 -0400 Subject: [PATCH] Add an error message when running a job and trying to use an OpenSSH formatted key on an older version of OpenSSH. --- awx/main/tasks.py | 12 ++++++++++++ awx/main/tests/tasks.py | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 6ce2817234..16c4012e0c 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -54,6 +54,12 @@ __all__ = ['RunJob', 'RunSystemJob', 'RunProjectUpdate', 'RunInventoryUpdate', HIDDEN_PASSWORD = '**********' +OPENSSH_KEY_ERROR = u'''\ +It looks like you're trying to use a private key in OpenSSH format, which \ +isn't supported by the installed version of OpenSSH on this Tower instance. \ +Try upgrading OpenSSH or providing your private key in an different format. \ +''' + logger = logging.getLogger('awx.main.tasks') @task() @@ -287,6 +293,12 @@ class BaseTask(Task): if private_data is not None: ssh_ver = get_ssh_version() ssh_too_old = True if ssh_ver == "unknown" else Version(ssh_ver) < Version("6.0") + openssh_keys_supported = ssh_ver != "unknown" and Version(ssh_ver) >= Version("6.5") + for name, data in private_data.iteritems(): + # Bail out now if a private key was provided in OpenSSH format + # and we're running an earlier version (<6.5). + if 'OPENSSH PRIVATE KEY' in data and not openssh_keys_supported: + raise RuntimeError(OPENSSH_KEY_ERROR) for name, data in private_data.iteritems(): # For credentials used with ssh-add, write to a named pipe which # will be read then closed, instead of leaving the SSH key on disk. diff --git a/awx/main/tests/tasks.py b/awx/main/tests/tasks.py index 20cefc1d5f..487ff2605f 100644 --- a/awx/main/tests/tasks.py +++ b/awx/main/tests/tasks.py @@ -2,6 +2,7 @@ # All Rights Reserved. # Python +from distutils.version import LooseVersion as Version import glob import json import os @@ -1090,6 +1091,24 @@ class RunJobTest(BaseJobExecutionTest): self.assertFalse('"--private-key=' in job.job_args) self.assertTrue('ssh-agent' in job.job_args) + def test_openssh_key_format(self): + ssh_ver = get_ssh_version() + openssh_keys_supported = ssh_ver != "unknown" and Version(ssh_ver) >= Version("6.5") + self.create_test_credential(ssh_key_data=TEST_OPENSSH_KEY_DATA) + self.create_test_project(TEST_PLAYBOOK) + job_template = self.create_test_job_template() + job = self.create_test_job(job_template=job_template) + self.assertEqual(job.status, 'new') + self.assertFalse(job.passwords_needed_to_start) + self.assertTrue(job.signal_start()) + job = Job.objects.get(pk=job.pk) + if openssh_keys_supported: + self.check_job_result(job, 'successful') + self.assertFalse('"--private-key=' in job.job_args) + self.assertTrue('ssh-agent' in job.job_args) + else: + self.check_job_result(job, 'error', expect_traceback=True) + def test_locked_ssh_key_with_password(self): self.create_test_credential(ssh_key_data=TEST_SSH_KEY_DATA_LOCKED, ssh_key_unlock=TEST_SSH_KEY_DATA_UNLOCK)