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..14ab33b652412d 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 ''' @@ -171,7 +173,7 @@ def __init__(self, module): def generate(self, module): # generate a keypair - if not self.isPrivateKeyValid(module, perms_required=False) or self.force: + if self.force or not self.isPrivateKeyValid(module, perms_required=False): args = [ module.get_bin_path('ssh-keygen', True), '-q', @@ -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