Issue 1:
From @schwatvogel on 2016-09-30T12:52:18Z

ISSUE TYPE

Bug Report

COMPONENT NAME

ansible-modules-core/packaging/os/rpm_key.py

ANSIBLE VERSION

ansible 2.1.0.0

CONFIGURATION

not relevant

OS / ENVIRONMENT

N/A

Redhat/Centos rpm-based

SUMMARY

Function is_key_imported does not work reliably because

Function getkeyid only extracts the last part of the first signature packet,

therefore the key will be imported on every ansible run

STEPS TO REPRODUCE

Install the Mono gpg key (from the Ubuntu keyserver, as per official docu):

http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

Short Summary:

getkeyid() essentially runs

gpg --no-tty --batch --with-colons --fixed-list-mode --list-packets /tmp/key.1 |grep signature

And returns the last 8 characters of the first key id it finds.

Then is_key_imported() runs

rpm -qa gpg-pubkey and matches the keyid against the first key part of the filename:

gpg-pubkey-d3d831ef-53dfa827

This does'nt work with the Mono key because

gpg --no-tty --batch --with-colons --fixed-list-mode --list-packets /tmp/key.1 |grep signature

returns:

:signature packet: algo 1, keyid C90F9CB90E1FAD0C
:signature packet: algo 1, keyid A6A19B38D3D831EF
:signature packet: algo 1, keyid A6A19B38D3D831EF

and so the last 8 characters of the second keyid match the first 8 character set of the rpm key information

Perhaps verifying the Fingerprint of the keys, or verify the full key ids(patch following):

--- rpm_key.py 2016-09-30 13:38:31.000000000 +0200
+++ new_rpm_key.py 2016-09-30 14:49:18.000000000 +0200
@@ -149,33 +149,27 @@
stdout, stderr = self.execute_command([gpg, '--no-tty', '--batch', '--with-colons', '--fixed-list-mode', '--list-packets', keyfile])
for line in stdout.splitlines():
line = line.strip()
- if line.startswith(':signature packet:'):
- # We want just the last 8 characters of the keyid
- keyid = line.split()[-1].strip()[8:]
+ if "keyid:" in line:
+ keyid = line.split()[-1]
return keyid
self.json_fail(msg="Unexpected gpg output")

def is_keyid(self, keystr):
"""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]{16}', keystr, flags=re.IGNORECASE)

def execute_command(self, cmd):
- rc, stdout, stderr = self.module.run_command(cmd)
+ rc, stdout, stderr = self.module.run_command(cmd,use_unsafe_shell=True)
if rc != 0:
self.module.fail_json(msg=stderr)
return stdout, stderr

def is_key_imported(self, keyid):
- stdout, stderr = self.execute_command([self.rpm, '-qa', 'gpg-pubkey'])
+ cmd=self.rpm+' -q gpg-pubkey --qf "%{description}" | gpg --no-tty --batch --with-colons --fixed-list-mode --list-packets -'
+ stdout, stderr = self.execute_command(cmd)
for line in stdout.splitlines():
- line = line.strip()
- if not line:
- continue
- match = re.match('gpg-pubkey-([0-9a-f]+)-([0-9a-f]+)', line)
- if not match:
- self.module.fail_json(msg="rpm returned unexpected output [%s]" % line)
- else:
- if keyid == match.group(1):
+ if "keyid: " in line:
+ if keyid.upper() == line.split()[-1].upper():
return True
return False```

Copied from original issue: ansible/ansible-modules-core#5103

Issue 2:
ISSUE TYPE

Bug Report

COMPONENT NAME

ansible/modules/packaging/os/rpm_key.py

ANSIBLE VERSION

ansible 2.2.1.0

CONFIGURATION

not relevant

OS / ENVIRONMENT

N/A

Redhat/Centos rpm-based

SUMMARY

Function is_key_imported does not work reliably because

Function getkeyid only extracts the last part of the first signature packet,ignoring the significant other ids

therefore the key will be imported on every ansible run

STEPS TO REPRODUCE

Install the Mono gpg key (from the Ubuntu keyserver, as per official docu):

http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

Short Summary:

getkeyid() essentially runs

gpg --no-tty --batch --with-colons --fixed-list-mode --list-packets /tmp/key.1 |grep signature

And returns the last 8 characters of the first key id it finds:

90E1FAD0C

instead of all keyids in this package:

C90F9CB90E1FAD0C
01150A655BBD8102
A6A19B38D3D831EF
A6A19B38D3D831EF

Then is_key_imported() runs

rpm -qa gpg-pubkey and matches the keyid against the first key part of the filename:

gpg-pubkey-d3d831ef-53dfa827

This does'nt work with the Mono key because the partial keyid in the filename is from the second keyid in the key

Possible Solutions:

Perhaps verifying the Fingerprint of the keys, or

verify the full key ids:

Fetching the full 16 Character key-ids (all of them not just the first)

and verify them against all installed key ids (not just rpm names)

by listing all installed gpgkeys and extracting the keyids in the same way, as the are extracted from the reference keys:

rpm -qa gpg-pubkey --qf "%{description}"| gpg --no-tty --batch --with-colons --fixed-list-mode --list-packets -