rpm_key - add fingerprint parameter (#58373)

This parameter can be used to verify keys before they are imported by providing the long form fingerprint of the key.
This commit is contained in:
Tim Rupp 2019-07-01 06:57:45 -07:00 committed by Sam Doran
parent d2ccf90610
commit 580b013837
2 changed files with 86 additions and 6 deletions

View file

@ -17,7 +17,7 @@ DOCUMENTATION = '''
--- ---
module: rpm_key module: rpm_key
author: author:
- Hector Acosta (@hacosta) <hector.acosta@gazzang.com> - Hector Acosta (@hacosta) <hector.acosta@gazzang.com>
short_description: Adds or removes a gpg key from the rpm db short_description: Adds or removes a gpg key from the rpm db
description: description:
- Adds or removes (rpm --import) a gpg key to your rpm database. - Adds or removes (rpm --import) a gpg key to your rpm database.
@ -25,7 +25,8 @@ version_added: "1.3"
options: options:
key: key:
description: description:
- Key that will be modified. Can be a url, a file, or a keyid if the key already exists in the database. - Key that will be modified. Can be a url, a file on the managed node, or a keyid if the key
already exists in the database.
required: true required: true
state: state:
description: description:
@ -34,10 +35,16 @@ options:
choices: [ absent, present ] choices: [ absent, present ]
validate_certs: validate_certs:
description: description:
- If C(no) and the C(key) is a url starting with https, SSL certificates will not be validated. This should only be used - If C(no) and the C(key) is a url starting with https, SSL certificates will not be validated.
on personally controlled sites using self-signed certificates. - This should only be used on personally controlled sites using self-signed certificates.
type: bool type: bool
default: 'yes' default: 'yes'
fingerprint:
description:
- The long-form fingerprint of the key being imported.
- This will be used to verify the specified key.
type: str
version_added: 2.9
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -55,6 +62,11 @@ EXAMPLES = '''
- rpm_key: - rpm_key:
state: absent state: absent
key: DEADB33F key: DEADB33F
# Verify the key, using a fingerprint, before import
- rpm_key:
key: /path/to/RPM-GPG-KEY.dag.txt
fingerprint: EBC6 E12C 62B1 C734 026B 2122 A20E 5214 6B8D 79E6
''' '''
import re import re
import os.path import os.path
@ -83,6 +95,9 @@ class RpmKey(object):
self.rpm = self.module.get_bin_path('rpm', True) self.rpm = self.module.get_bin_path('rpm', True)
state = module.params['state'] state = module.params['state']
key = module.params['key'] key = module.params['key']
fingerprint = module.params['fingerprint']
if fingerprint:
fingerprint = fingerprint.replace(' ', '').upper()
self.gpg = self.module.get_bin_path('gpg') self.gpg = self.module.get_bin_path('gpg')
if not self.gpg: if not self.gpg:
@ -107,6 +122,12 @@ class RpmKey(object):
else: else:
if not keyfile: if not keyfile:
self.module.fail_json(msg="When importing a key, a valid file must be given") self.module.fail_json(msg="When importing a key, a valid file must be given")
if fingerprint:
has_fingerprint = self.getfingerprint(keyfile)
if fingerprint != has_fingerprint:
self.module.fail_json(
msg="The specified fingerprint, '%s', does not match the key fingerprint '%s'" % (fingerprint, has_fingerprint)
)
self.import_key(keyfile) self.import_key(keyfile)
if should_cleanup_keyfile: if should_cleanup_keyfile:
self.module.cleanup(keyfile) self.module.cleanup(keyfile)
@ -153,6 +174,26 @@ class RpmKey(object):
self.module.fail_json(msg="Unexpected gpg output") self.module.fail_json(msg="Unexpected gpg output")
def getfingerprint(self, keyfile):
stdout, stderr = self.execute_command([
self.gpg, '--no-tty', '--batch', '--with-colons',
'--fixed-list-mode', '--with-fingerprint', keyfile
])
for line in stdout.splitlines():
line = line.strip()
if line.startswith('fpr:'):
# As mentioned here,
#
# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
#
# The description of the `fpr` field says
#
# "fpr :: Fingerprint (fingerprint is in field 10)"
#
return line.split(':')[9]
self.module.fail_json(msg="Unexpected gpg output")
def is_keyid(self, keystr): def is_keyid(self, keystr):
"""Verifies if a key, as provided by the user is a keyid""" """Verifies if a key, as provided by the user is a keyid"""
return re.match('(0x)?[0-9a-f]{8}', keystr, flags=re.IGNORECASE) return re.match('(0x)?[0-9a-f]{8}', keystr, flags=re.IGNORECASE)
@ -189,6 +230,7 @@ def main():
argument_spec=dict( argument_spec=dict(
state=dict(type='str', default='present', choices=['absent', 'present']), state=dict(type='str', default='present', choices=['absent', 'present']),
key=dict(type='str', required=True), key=dict(type='str', required=True),
fingerprint=dict(type='str'),
validate_certs=dict(type='bool', default=True), validate_certs=dict(type='bool', default=True),
), ),
supports_check_mode=True, supports_check_mode=True,

View file

@ -138,6 +138,44 @@
assert: assert:
that: "'rsa sha1 (md5) pgp md5 OK' in sl_check.stdout or 'digests signatures OK' in sl_check.stdout" that: "'rsa sha1 (md5) pgp md5 OK' in sl_check.stdout or 'digests signatures OK' in sl_check.stdout"
- name: Issue 20325 - Verify fingerprint of key, invalid fingerprint - EXPECTED FAILURE
rpm_key:
key: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/rpm_key/RPM-GPG-KEY.dag
fingerprint: 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
register: result
failed_when: result is success
- name: Issue 20325 - Assert Verify fingerprint of key, invalid fingerprint
assert:
that:
- result is success
- result is not changed
- "'does not match the key fingerprint' in result.msg"
- name: Issue 20325 - Verify fingerprint of key, valid fingerprint
rpm_key:
key: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/rpm_key/RPM-GPG-KEY.dag
fingerprint: EBC6 E12C 62B1 C734 026B 2122 A20E 5214 6B8D 79E6
register: result
- name: Issue 20325 - Assert Verify fingerprint of key, valid fingerprint
assert:
that:
- result is success
- result is changed
- name: Issue 20325 - Verify fingerprint of key, valid fingerprint - Idempotent check
rpm_key:
key: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/rpm_key/RPM-GPG-KEY.dag
fingerprint: EBC6 E12C 62B1 C734 026B 2122 A20E 5214 6B8D 79E6
register: result
- name: Issue 20325 - Assert Verify fingerprint of key, valid fingerprint - Idempotent check
assert:
that:
- result is success
- result is not changed
# #
# Cleanup # Cleanup
# #