Skip to content

Commit

Permalink
openssh_keypair - Add logic to handle password protected or broken key (
Browse files Browse the repository at this point in the history
ansible#64436)

* 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.

Set the "self.force" check before the "isPrivateKeyValid" check.
In case of any issue with the "isPrivateKeyValid" function, the user
will be able to force the regeneration of the key with the "force: yes"
argument.

(cherry picked from commit da73bbd)
  • Loading branch information
MaxBab authored and felixfontein committed Dec 2, 2019
1 parent 04d32c5 commit f8d439a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
@@ -0,0 +1,2 @@
bugfixes:
- openssh_keypair - add logic to handle password protected or broken key
14 changes: 13 additions & 1 deletion lib/ansible/modules/crypto/openssh_keypair.py
Expand Up @@ -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
'''
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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):
Expand Down
8 changes: 8 additions & 0 deletions test/integration/targets/openssh_keypair/tasks/main.yml
Expand Up @@ -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
5 changes: 5 additions & 0 deletions test/integration/targets/openssh_keypair/tests/validate.yml
Expand Up @@ -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

0 comments on commit f8d439a

Please sign in to comment.