From 4fbdd671c4bf47f3075e32dd92c25a4f616544fd Mon Sep 17 00:00:00 2001 From: Maxim Babushkin Date: Tue, 5 Nov 2019 12:32:58 +0200 Subject: [PATCH] openssh_keypair - Add logic to handle password protected or broken key * The ssh key may be created manually prior the task execution with a passphrase. And the task will be executed on the same key. * The ssh key may be broken and not usable. The module will check the private key and if the key is password protected or broken, it will be overridden. The check of the ssh key performed by retrieve the public key from the private key. --- ...nssh_keypair-add-password-protected-key-check.yml | 2 ++ lib/ansible/modules/crypto/openssh_keypair.py | 12 ++++++++++++ .../targets/openssh_keypair/tasks/main.yml | 8 ++++++++ .../targets/openssh_keypair/tests/validate.yml | 5 +++++ 4 files changed, 27 insertions(+) create mode 100644 changelogs/fragments/64436-openssh_keypair-add-password-protected-key-check.yml diff --git a/changelogs/fragments/64436-openssh_keypair-add-password-protected-key-check.yml b/changelogs/fragments/64436-openssh_keypair-add-password-protected-key-check.yml new file mode 100644 index 00000000000000..3ac996edefb71e --- /dev/null +++ b/changelogs/fragments/64436-openssh_keypair-add-password-protected-key-check.yml @@ -0,0 +1,2 @@ +bugfixes: + - openssh_keypair - add logic to handle password protected or broken key diff --git a/lib/ansible/modules/crypto/openssh_keypair.py b/lib/ansible/modules/crypto/openssh_keypair.py index 63117f91dc714c..8222060ad7635a 100644 --- a/lib/ansible/modules/crypto/openssh_keypair.py +++ b/lib/ansible/modules/crypto/openssh_keypair.py @@ -63,6 +63,8 @@ - Provides a new comment to the public key. When checking if the key is in the correct state this will be ignored. type: str version_added: "2.9" +notes: + - In case the ssh key is broken or password protected, it will be regenerated. extends_documentation_fragment: files ''' @@ -240,7 +242,17 @@ def isPrivateKeyValid(self, module, perms_required=True): def _check_state(): return os.path.exists(self.path) + def _check_pass_protected_or_broken_key(): + key_state = module.run_command([module.get_bin_path('ssh-keygen', True), + '-P', '', '-yf', self.path], check_rc=False) + if 'incorrect passphrase' in key_state[2] or 'load failed' in key_state[2]: + return True + return False + if _check_state(): + if _check_pass_protected_or_broken_key(): + return False + proc = module.run_command([module.get_bin_path('ssh-keygen', True), '-lf', self.path], check_rc=False) if not proc[0] == 0: if os.path.isdir(self.path): diff --git a/test/integration/targets/openssh_keypair/tasks/main.yml b/test/integration/targets/openssh_keypair/tasks/main.yml index 0ff369787d36b8..7905601ed293d4 100644 --- a/test/integration/targets/openssh_keypair/tasks/main.yml +++ b/test/integration/targets/openssh_keypair/tasks/main.yml @@ -79,4 +79,12 @@ comment: 'test_modified@privatekey7' register: privatekey7_modified_result +- name: Generate password protected key + command: 'ssh-keygen -f {{ output_dir }}/privatekey8 -N password' + +- name: Try to modify the password protected key - should be overridden + openssh_keypair: + path: '{{ output_dir }}/privatekey8' + register: privatekey8_result + - import_tasks: ../tests/validate.yml diff --git a/test/integration/targets/openssh_keypair/tests/validate.yml b/test/integration/targets/openssh_keypair/tests/validate.yml index 4d61b050aa473f..7bf06b3872de65 100644 --- a/test/integration/targets/openssh_keypair/tests/validate.yml +++ b/test/integration/targets/openssh_keypair/tests/validate.yml @@ -107,3 +107,8 @@ assert: that: - privatekey7_modified_result.comment == 'test_modified@privatekey7' + +- name: Check that password protected key has been regenerated + assert: + that: + - privatekey8_result is changed