openssh_keypair: bugfix make regenerating keypairs via force possible… (#57801)

* openssh_keypair: bugfix make regenerating keypairs via force possible / add invalid file handling

* openssh_keypair: change permissions of read-only file instead of deleting it for regeneration; add changelog fragment

* address review feedbak, refactor

* add integration tests for bigfixes

* linter: fix indent

* fixup integration tests: use force when regenerating an invalid file

* linter: fix indent

* openssh_keypair: address review feedback

* openssh_keypair: fixup, remove backtick

* openssh_keypair: address review feedback

* Only pass 'y' into stdin of ssh-keygen when file exists.
This commit is contained in:
lolcube 2019-06-24 21:45:49 +02:00 committed by Felix Fontein
parent b78d23d4ad
commit 547a29805e
4 changed files with 74 additions and 2 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- openssh_keypair - make regeneration of valid keypairs with the ``force`` option possible, add better handling for invalid files

View file

@ -116,6 +116,7 @@ public_key:
''' '''
import os import os
import stat
import errno import errno
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
@ -180,8 +181,13 @@ class Keypair(object):
args.extend(['-C', ""]) args.extend(['-C', ""])
try: try:
if os.path.exists(self.path) and not os.access(self.path, os.W_OK):
os.chmod(self.path, stat.S_IWUSR + stat.S_IRUSR)
self.changed = True self.changed = True
module.run_command(args) stdin_data = None
if os.path.exists(self.path):
stdin_data = 'y'
module.run_command(args, data=stdin_data)
proc = module.run_command([module.get_bin_path('ssh-keygen', True), '-lf', self.path]) proc = module.run_command([module.get_bin_path('ssh-keygen', True), '-lf', self.path])
self.fingerprint = proc[1].split() self.fingerprint = proc[1].split()
pubkey = module.run_command([module.get_bin_path('ssh-keygen', True), '-yf', self.path]) pubkey = module.run_command([module.get_bin_path('ssh-keygen', True), '-yf', self.path])
@ -201,7 +207,13 @@ class Keypair(object):
return os.path.exists(self.path) return os.path.exists(self.path)
if _check_state(): if _check_state():
proc = module.run_command([module.get_bin_path('ssh-keygen', True), '-lf', self.path]) 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):
module.fail_json(msg='%s is a directory. Please specify a path to a file.' % (self.path))
return False
fingerprint = proc[1].split() fingerprint = proc[1].split()
pubkey = module.run_command([module.get_bin_path('ssh-keygen', True), '-yf', self.path]) pubkey = module.run_command([module.get_bin_path('ssh-keygen', True), '-yf', self.path])
pubkey = pubkey[1].strip('\n') pubkey = pubkey[1].strip('\n')

View file

@ -27,4 +27,44 @@
path: '{{ output_dir }}/privatekey5' path: '{{ output_dir }}/privatekey5'
register: publickey_gen register: publickey_gen
- name: Generate privatekey6
openssh_keypair:
path: '{{ output_dir }}/privatekey6'
type: rsa
- name: Regenerate privatekey6 via force
openssh_keypair:
path: '{{ output_dir }}/privatekey6'
type: rsa
force: yes
register: output_regenerated_via_force
- name: Create broken key
copy:
dest: '{{ item }}'
content: ''
mode: '0700'
loop:
- '{{ output_dir }}/privatekeybroken'
- '{{ output_dir }}/privatekeybroken.pub'
- name: Regenerate broken key
openssh_keypair:
path: '{{ output_dir }}/privatekeybroken'
type: rsa
register: output_broken
- name: Generate read-only private key
openssh_keypair:
path: '{{ output_dir }}/privatekeyreadonly'
type: rsa
mode: '0200'
- name: Regenerate read-only private key via force
openssh_keypair:
path: '{{ output_dir }}/privatekeyreadonly'
type: rsa
force: yes
register: output_read_only
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml

View file

@ -1,3 +1,4 @@
---
- name: Log privatekey1 return values - name: Log privatekey1 return values
debug: debug:
var: privatekey1_result var: privatekey1_result
@ -73,3 +74,20 @@
assert: assert:
that: that:
- "publickey_gen.public_key == lookup('file', output_dir ~ '/privatekey5.pub').strip('\n')" - "publickey_gen.public_key == lookup('file', output_dir ~ '/privatekey5.pub').strip('\n')"
- name: Verify that privatekey6 will be regenerated via force
assert:
that:
- output_regenerated_via_force is changed
- name: Verify that broken key will be regenerated
assert:
that:
- output_broken is changed
- name: Verify that read-only key will be regenerated
assert:
that:
- output_read_only is changed