mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-05 10:10:31 -07:00
Support checking for expired and untrusted keys
Adds state `trusted`. Fixes #9949
This commit is contained in:
parent
4a2cc71141
commit
fbf5f16363
3 changed files with 276 additions and 78 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
minor_change:
|
||||||
|
- pacman_key - support verifying that keys are trusted and not expired (https://github.com/ansible-collections/community.general/pull/9950)
|
|
@ -78,9 +78,9 @@ options:
|
||||||
default: /etc/pacman.d/gnupg
|
default: /etc/pacman.d/gnupg
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- Ensures that the key is present (added) or absent (revoked).
|
- Ensures that the key is present (added), trusted (signed and not expired) or absent (revoked).
|
||||||
default: present
|
default: present
|
||||||
choices: [absent, present]
|
choices: [absent, present, trusted]
|
||||||
type: str
|
type: str
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -129,12 +129,55 @@ from ansible.module_utils.urls import fetch_url
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
|
||||||
|
|
||||||
|
class GpgListResult:
|
||||||
|
"""Wraps gpg --list-* output."""
|
||||||
|
|
||||||
|
def __init__(self, line) -> None:
|
||||||
|
self._parts = line.split(':')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kind(self):
|
||||||
|
return self._parts[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def valid(self):
|
||||||
|
return self._parts[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_fully_valid(self):
|
||||||
|
return self.valid == 'f'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def key(self):
|
||||||
|
return self._parts[4]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_id(self):
|
||||||
|
return self._parts[9]
|
||||||
|
|
||||||
|
|
||||||
|
def gpg_get_first(lines, kind, attr):
|
||||||
|
for line in lines:
|
||||||
|
glr = GpgListResult(line)
|
||||||
|
if glr.kind == kind:
|
||||||
|
return getattr(glr, attr)
|
||||||
|
|
||||||
|
|
||||||
|
def gpg_gather_all(lines, kind, attr):
|
||||||
|
result = []
|
||||||
|
for line in lines:
|
||||||
|
glr = GpgListResult(line)
|
||||||
|
if glr.kind == kind:
|
||||||
|
result.append(getattr(glr, attr))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class PacmanKey(object):
|
class PacmanKey(object):
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
self.module = module
|
self.module = module
|
||||||
# obtain binary paths for gpg & pacman-key
|
# obtain binary paths for gpg & pacman-key
|
||||||
self.gpg = module.get_bin_path('gpg', required=True)
|
self.gpg_binary = module.get_bin_path('gpg', required=True)
|
||||||
self.pacman_key = module.get_bin_path('pacman-key', required=True)
|
self.pacman_key_binary = module.get_bin_path('pacman-key', required=True)
|
||||||
|
|
||||||
# obtain module parameters
|
# obtain module parameters
|
||||||
keyid = module.params['id']
|
keyid = module.params['id']
|
||||||
|
@ -150,43 +193,68 @@ class PacmanKey(object):
|
||||||
|
|
||||||
# sanitise key ID & check if key exists in the keyring
|
# sanitise key ID & check if key exists in the keyring
|
||||||
keyid = self.sanitise_keyid(keyid)
|
keyid = self.sanitise_keyid(keyid)
|
||||||
key_present = self.key_in_keyring(keyring, keyid)
|
key_validity = self.key_validity(keyring, keyid)
|
||||||
|
key_present = len(key_validity) > 0
|
||||||
|
key_valid = any(key_validity)
|
||||||
|
|
||||||
# check mode
|
# check mode
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
if state == "present":
|
if state in ['present', 'trusted']:
|
||||||
changed = (key_present and force_update) or not key_present
|
changed = (key_present and force_update) or not key_present
|
||||||
|
if not changed and state == 'trusted':
|
||||||
|
changed = not (key_valid and self.key_is_trusted(keyring, keyid))
|
||||||
module.exit_json(changed=changed)
|
module.exit_json(changed=changed)
|
||||||
elif state == "absent":
|
if state == 'absent':
|
||||||
if key_present:
|
module.exit_json(changed=key_present)
|
||||||
module.exit_json(changed=True)
|
|
||||||
module.exit_json(changed=False)
|
|
||||||
|
|
||||||
if state == "present":
|
|
||||||
if key_present and not force_update:
|
|
||||||
module.exit_json(changed=False)
|
|
||||||
|
|
||||||
|
if state in ['present', 'trusted']:
|
||||||
|
trusted = key_valid and self.key_is_trusted(keyring, keyid)
|
||||||
|
if not force_update:
|
||||||
|
if (state == 'present' and key_present) or (state == 'trusted' and trusted):
|
||||||
|
module.exit_json(changed=False)
|
||||||
|
changed = False
|
||||||
if data:
|
if data:
|
||||||
file = self.save_key(data)
|
file = self.save_key(data)
|
||||||
self.add_key(keyring, file, keyid, verify)
|
self.add_key(keyring, file, keyid, verify)
|
||||||
module.exit_json(changed=True)
|
changed = True
|
||||||
elif file:
|
elif file:
|
||||||
self.add_key(keyring, file, keyid, verify)
|
self.add_key(keyring, file, keyid, verify)
|
||||||
module.exit_json(changed=True)
|
changed = True
|
||||||
elif url:
|
elif url:
|
||||||
data = self.fetch_key(url)
|
data = self.fetch_key(url)
|
||||||
file = self.save_key(data)
|
file = self.save_key(data)
|
||||||
self.add_key(keyring, file, keyid, verify)
|
self.add_key(keyring, file, keyid, verify)
|
||||||
module.exit_json(changed=True)
|
changed = True
|
||||||
elif keyserver:
|
elif keyserver:
|
||||||
self.recv_key(keyring, keyid, keyserver)
|
self.recv_key(keyring, keyid, keyserver)
|
||||||
module.exit_json(changed=True)
|
changed = True
|
||||||
elif state == "absent":
|
if changed or (state == 'trusted' and not trusted):
|
||||||
|
self.lsign_key(keyring=keyring, keyid=keyid)
|
||||||
|
changed = True
|
||||||
|
module.exit_json(changed=changed)
|
||||||
|
elif state == 'absent':
|
||||||
if key_present:
|
if key_present:
|
||||||
self.remove_key(keyring, keyid)
|
self.remove_key(keyring, keyid)
|
||||||
module.exit_json(changed=True)
|
module.exit_json(changed=True)
|
||||||
module.exit_json(changed=False)
|
module.exit_json(changed=False)
|
||||||
|
|
||||||
|
def gpg(self, args, /, keyring=None, **kwargs):
|
||||||
|
cmd = [self.gpg_binary]
|
||||||
|
if keyring:
|
||||||
|
cmd.append(f'--homedir={keyring}')
|
||||||
|
cmd.extend(['--no-permission-warning', '--with-colons', '--quiet', '--batch', '--no-tty'])
|
||||||
|
return self.module.run_command(cmd + args, **kwargs)
|
||||||
|
|
||||||
|
def pacman_key(self, args, /, keyring, **kwargs):
|
||||||
|
return self.module.run_command(
|
||||||
|
[self.pacman_key_binary, '--gpgdir', keyring] + args,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
def pacman_machine_key(self, keyring):
|
||||||
|
_, stdout, _ = self.gpg(['--list-secret-key'], keyring=keyring)
|
||||||
|
return gpg_get_first(stdout.splitlines(), 'sec', 'key')
|
||||||
|
|
||||||
def is_hexadecimal(self, string):
|
def is_hexadecimal(self, string):
|
||||||
"""Check if a given string is valid hexadecimal"""
|
"""Check if a given string is valid hexadecimal"""
|
||||||
try:
|
try:
|
||||||
|
@ -216,14 +284,11 @@ class PacmanKey(object):
|
||||||
|
|
||||||
def recv_key(self, keyring, keyid, keyserver):
|
def recv_key(self, keyring, keyid, keyserver):
|
||||||
"""Receives key via keyserver"""
|
"""Receives key via keyserver"""
|
||||||
cmd = [self.pacman_key, '--gpgdir', keyring, '--keyserver', keyserver, '--recv-keys', keyid]
|
self.pacman_key(['--keyserver', keyserver, '--recv-keys', keyid], keyring=keyring, check_rc=True)
|
||||||
self.module.run_command(cmd, check_rc=True)
|
|
||||||
self.lsign_key(keyring, keyid)
|
|
||||||
|
|
||||||
def lsign_key(self, keyring, keyid):
|
def lsign_key(self, keyring, keyid):
|
||||||
"""Locally sign key"""
|
"""Locally sign key"""
|
||||||
cmd = [self.pacman_key, '--gpgdir', keyring]
|
self.pacman_key(['--lsign-key', keyid], keyring=keyring, check_rc=True)
|
||||||
self.module.run_command(cmd + ['--lsign-key', keyid], check_rc=True)
|
|
||||||
|
|
||||||
def save_key(self, data):
|
def save_key(self, data):
|
||||||
"Saves key data to a temporary file"
|
"Saves key data to a temporary file"
|
||||||
|
@ -238,14 +303,11 @@ class PacmanKey(object):
|
||||||
"""Add key to pacman's keyring"""
|
"""Add key to pacman's keyring"""
|
||||||
if verify:
|
if verify:
|
||||||
self.verify_keyfile(keyfile, keyid)
|
self.verify_keyfile(keyfile, keyid)
|
||||||
cmd = [self.pacman_key, '--gpgdir', keyring, '--add', keyfile]
|
self.pacman_key(['--add', keyfile], keyring=keyring, check_rc=True)
|
||||||
self.module.run_command(cmd, check_rc=True)
|
|
||||||
self.lsign_key(keyring, keyid)
|
|
||||||
|
|
||||||
def remove_key(self, keyring, keyid):
|
def remove_key(self, keyring, keyid):
|
||||||
"""Remove key from pacman's keyring"""
|
"""Remove key from pacman's keyring"""
|
||||||
cmd = [self.pacman_key, '--gpgdir', keyring, '--delete', keyid]
|
self.pacman_key(['--delete', keyid], keyring=keyring, check_rc=True)
|
||||||
self.module.run_command(cmd, check_rc=True)
|
|
||||||
|
|
||||||
def verify_keyfile(self, keyfile, keyid):
|
def verify_keyfile(self, keyfile, keyid):
|
||||||
"""Verify that keyfile matches the specified key ID"""
|
"""Verify that keyfile matches the specified key ID"""
|
||||||
|
@ -254,48 +316,29 @@ class PacmanKey(object):
|
||||||
elif keyid is None:
|
elif keyid is None:
|
||||||
self.module.fail_json(msg="expected a key ID, got none")
|
self.module.fail_json(msg="expected a key ID, got none")
|
||||||
|
|
||||||
rc, stdout, stderr = self.module.run_command(
|
rc, stdout, stderr = self.gpg(
|
||||||
[
|
['--with-fingerprint', '--show-keys', keyfile],
|
||||||
self.gpg,
|
|
||||||
'--with-colons',
|
|
||||||
'--with-fingerprint',
|
|
||||||
'--batch',
|
|
||||||
'--no-tty',
|
|
||||||
'--show-keys',
|
|
||||||
keyfile
|
|
||||||
],
|
|
||||||
check_rc=True,
|
check_rc=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
extracted_keyid = None
|
extracted_keyid = gpg_get_first(stdout.splitlines(), 'fpr', 'user_id')
|
||||||
for line in stdout.splitlines():
|
|
||||||
if line.startswith('fpr:'):
|
|
||||||
extracted_keyid = line.split(':')[9]
|
|
||||||
break
|
|
||||||
|
|
||||||
if extracted_keyid != keyid:
|
if extracted_keyid != keyid:
|
||||||
self.module.fail_json(msg="key ID does not match. expected %s, got %s" % (keyid, extracted_keyid))
|
self.module.fail_json(msg="key ID does not match. expected %s, got %s" % (keyid, extracted_keyid))
|
||||||
|
|
||||||
def key_in_keyring(self, keyring, keyid):
|
def key_validity(self, keyring, keyid):
|
||||||
"Check if the key ID is in pacman's keyring"
|
"Check if the key ID is in pacman's keyring and not expired"
|
||||||
rc, stdout, stderr = self.module.run_command(
|
rc, stdout, stderr = self.gpg(['--no-default-keyring', '--list-keys', keyid], keyring=keyring, check_rc=False)
|
||||||
[
|
|
||||||
self.gpg,
|
|
||||||
'--with-colons',
|
|
||||||
'--batch',
|
|
||||||
'--no-tty',
|
|
||||||
'--no-default-keyring',
|
|
||||||
'--keyring=%s/pubring.gpg' % keyring,
|
|
||||||
'--list-keys', keyid
|
|
||||||
],
|
|
||||||
check_rc=False,
|
|
||||||
)
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
if stderr.find("No public key") >= 0:
|
if stderr.find("No public key") >= 0:
|
||||||
return False
|
return []
|
||||||
else:
|
else:
|
||||||
self.module.fail_json(msg="gpg returned an error: %s" % stderr)
|
self.module.fail_json(msg="gpg returned an error: %s" % stderr)
|
||||||
return True
|
return gpg_gather_all(stdout.splitlines(), 'uid', 'is_fully_valid')
|
||||||
|
|
||||||
|
def key_is_trusted(self, keyring, keyid):
|
||||||
|
"""Check if key is signed and not expired."""
|
||||||
|
_, stdout, _ = self.gpg(['--check-signatures', keyid], keyring=keyring)
|
||||||
|
return self.pacman_machine_key(keyring) in gpg_gather_all(stdout.splitlines(), 'sig', 'key')
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -309,7 +352,11 @@ def main():
|
||||||
verify=dict(type='bool', default=True),
|
verify=dict(type='bool', default=True),
|
||||||
force_update=dict(type='bool', default=False),
|
force_update=dict(type='bool', default=False),
|
||||||
keyring=dict(type='path', default='/etc/pacman.d/gnupg'),
|
keyring=dict(type='path', default='/etc/pacman.d/gnupg'),
|
||||||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
state=dict(
|
||||||
|
type='str',
|
||||||
|
default='present',
|
||||||
|
choices=['absent', 'present', 'trusted'],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
mutually_exclusive=(('data', 'file', 'url', 'keyserver'),),
|
mutually_exclusive=(('data', 'file', 'url', 'keyserver'),),
|
||||||
|
|
|
@ -17,8 +17,9 @@ MOCK_BIN_PATH = '/mocked/path'
|
||||||
TESTING_KEYID = '14F26682D0916CDD81E37B6D61B7B526D98F0353'
|
TESTING_KEYID = '14F26682D0916CDD81E37B6D61B7B526D98F0353'
|
||||||
TESTING_KEYFILE_PATH = '/tmp/pubkey.asc'
|
TESTING_KEYFILE_PATH = '/tmp/pubkey.asc'
|
||||||
|
|
||||||
# gpg --{show,list}-key output (key present)
|
# gpg --{show,list}-key output (key present, but expired)
|
||||||
GPG_SHOWKEY_OUTPUT = '''tru::1:1616373715:0:3:1:5
|
GPG_SHOWKEY_OUTPUT_EXPIRED = """
|
||||||
|
tru::1:1616373715:0:3:1:5
|
||||||
pub:-:4096:1:61B7B526D98F0353:1437155332:::-:::scSC::::::23::0:
|
pub:-:4096:1:61B7B526D98F0353:1437155332:::-:::scSC::::::23::0:
|
||||||
fpr:::::::::14F26682D0916CDD81E37B6D61B7B526D98F0353:
|
fpr:::::::::14F26682D0916CDD81E37B6D61B7B526D98F0353:
|
||||||
uid:-::::1437155332::E57D1F9BFF3B404F9F30333629369B08DF5E2161::Mozilla Software Releases <release@mozilla.com>::::::::::0:
|
uid:-::::1437155332::E57D1F9BFF3B404F9F30333629369B08DF5E2161::Mozilla Software Releases <release@mozilla.com>::::::::::0:
|
||||||
|
@ -27,24 +28,76 @@ fpr:::::::::F2EF4E6E6AE75B95F11F1EB51C69C4E55E9905DB:
|
||||||
sub:e:4096:1:BBBEBDBB24C6F355:1498143157:1561215157:::::s::::::23:
|
sub:e:4096:1:BBBEBDBB24C6F355:1498143157:1561215157:::::s::::::23:
|
||||||
fpr:::::::::DCEAC5D96135B91C4EA672ABBBBEBDBB24C6F355:
|
fpr:::::::::DCEAC5D96135B91C4EA672ABBBBEBDBB24C6F355:
|
||||||
sub:e:4096:1:F1A6668FBB7D572E:1559247338:1622319338:::::s::::::23:
|
sub:e:4096:1:F1A6668FBB7D572E:1559247338:1622319338:::::s::::::23:
|
||||||
fpr:::::::::097B313077AE62A02F84DA4DF1A6668FBB7D572E:'''
|
fpr:::::::::097B313077AE62A02F84DA4DF1A6668FBB7D572E:
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
# gpg --{show,list}-key output (key present and trusted)
|
||||||
|
GPG_SHOWKEY_OUTPUT_TRUSTED = """
|
||||||
|
tru::1:1616373715:0:3:1:5
|
||||||
|
pub:f:4096:1:61B7B526D98F0353:1437155332:::-:::scSC::::::23::0:
|
||||||
|
fpr:::::::::14F26682D0916CDD81E37B6D61B7B526D98F0353:
|
||||||
|
uid:f::::1437155332::E57D1F9BFF3B404F9F30333629369B08DF5E2161::Mozilla Software Releases <release@mozilla.com>::::::::::0:
|
||||||
|
sub:e:4096:1:1C69C4E55E9905DB:1437155572:1500227572:::::s::::::23:
|
||||||
|
fpr:::::::::F2EF4E6E6AE75B95F11F1EB51C69C4E55E9905DB:
|
||||||
|
sub:e:4096:1:BBBEBDBB24C6F355:1498143157:1561215157:::::s::::::23:
|
||||||
|
fpr:::::::::DCEAC5D96135B91C4EA672ABBBBEBDBB24C6F355:
|
||||||
|
sub:e:4096:1:F1A6668FBB7D572E:1559247338:1622319338:::::s::::::23:
|
||||||
|
fpr:::::::::097B313077AE62A02F84DA4DF1A6668FBB7D572E:
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
GPG_LIST_SECRET_KEY_OUTPUT = """
|
||||||
|
sec:u:2048:1:58FCCBCC131FCCAB:1406639814:::u:::scSC:::+:::23::0:
|
||||||
|
fpr:::::::::AC0F357BE07F1493C34DCAB258FCCBCC131FCCAB:
|
||||||
|
grp:::::::::C1227FFDD039AD942F777EA0639E1F1EAA96AB12:
|
||||||
|
uid:u::::1406639814::79311EDEA01302E0DBBB2F33AE799F8BB677652F::Pacman Keyring Master Key <pacman@localhost>::::::::::0:
|
||||||
|
""".lstrip()
|
||||||
|
|
||||||
|
GPG_CHECK_SIGNATURES_OUTPUT = """
|
||||||
|
tru::1:1742507906:1750096255:3:1:5
|
||||||
|
pub:f:4096:1:61B7B526D98F0353:1437155332:::-:::scSC::::::23:1742507897:1 https\x3a//185.125.188.26\x3a443:
|
||||||
|
fpr:::::::::14F26682D0916CDD81E37B6D61B7B526D98F0353:
|
||||||
|
uid:f::::1437155332::E57D1F9BFF3B404F9F30333629369B08DF5E2161::Mozilla Software Releases <release@mozilla.com>:::::::::1742507897:1:
|
||||||
|
sig:!::1:61B7B526D98F0353:1437155332::::Mozilla Software Releases <release@mozilla.com>:13x:::::2:
|
||||||
|
sig:!::1:58FCCBCC131FCCAB:1742507905::::Pacman Keyring Master Key <pacman@localhost>:10l::AC0F357BE07F1493C34DCAB258FCCBCC131FCCAB:::8:
|
||||||
|
sub:f:4096:1:E36D3B13F3D93274:1683308659:1746380659:::::s::::::23:
|
||||||
|
fpr:::::::::ADD7079479700DCADFDD5337E36D3B13F3D93274:
|
||||||
|
sig:!::1:61B7B526D98F0353:1683308659::::Mozilla Software Releases <release@mozilla.com>:18x::14F26682D0916CDD81E37B6D61B7B526D98F0353:::10:
|
||||||
|
sub:e:4096:1:1C69C4E55E9905DB:1437155572:1500227572:::::s::::::23:
|
||||||
|
fpr:::::::::F2EF4E6E6AE75B95F11F1EB51C69C4E55E9905DB:
|
||||||
|
sig:!::1:61B7B526D98F0353:1437155572::::Mozilla Software Releases <release@mozilla.com>:18x:::::2:
|
||||||
|
sub:e:4096:1:BBBEBDBB24C6F355:1498143157:1561215157:::::s::::::23:
|
||||||
|
fpr:::::::::DCEAC5D96135B91C4EA672ABBBBEBDBB24C6F355:
|
||||||
|
sig:!::1:61B7B526D98F0353:1498143157::::Mozilla Software Releases <release@mozilla.com>:18x::14F26682D0916CDD81E37B6D61B7B526D98F0353:::8:
|
||||||
|
sub:e:4096:1:F1A6668FBB7D572E:1559247338:1622319338:::::s::::::23:
|
||||||
|
fpr:::::::::097B313077AE62A02F84DA4DF1A6668FBB7D572E:
|
||||||
|
sig:!::1:61B7B526D98F0353:1559247338::::Mozilla Software Releases <release@mozilla.com>:18x::14F26682D0916CDD81E37B6D61B7B526D98F0353:::10:
|
||||||
|
sub:e:4096:1:EBE41E90F6F12F6D:1621282261:1684354261:::::s::::::23:
|
||||||
|
fpr:::::::::4360FE2109C49763186F8E21EBE41E90F6F12F6D:
|
||||||
|
sig:!::1:61B7B526D98F0353:1621282261::::Mozilla Software Releases <release@mozilla.com>:18x::14F26682D0916CDD81E37B6D61B7B526D98F0353:::10:
|
||||||
|
""".strip()
|
||||||
|
|
||||||
# gpg --{show,list}-key output (key absent)
|
# gpg --{show,list}-key output (key absent)
|
||||||
GPG_NOKEY_OUTPUT = '''gpg: error reading key: No public key
|
GPG_NOKEY_OUTPUT = """
|
||||||
tru::1:1616373715:0:3:1:5'''
|
gpg: error reading key: No public key
|
||||||
|
tru::1:1616373715:0:3:1:5
|
||||||
|
""".strip()
|
||||||
|
|
||||||
# pacman-key output (successful invocation)
|
# pacman-key output (successful invocation)
|
||||||
PACMAN_KEY_SUCCESS = '''==> Updating trust database...
|
PACMAN_KEY_SUCCESS = """
|
||||||
gpg: next trustdb check due at 2021-08-02'''
|
==> Updating trust database...
|
||||||
|
gpg: next trustdb check due at 2021-08-02
|
||||||
|
""".strip()
|
||||||
|
|
||||||
# expected command for gpg --list-keys KEYID
|
# expected command for gpg --list-keys KEYID
|
||||||
RUN_CMD_LISTKEYS = [
|
RUN_CMD_LISTKEYS = [
|
||||||
MOCK_BIN_PATH,
|
MOCK_BIN_PATH,
|
||||||
|
'--homedir=/etc/pacman.d/gnupg',
|
||||||
|
'--no-permission-warning',
|
||||||
'--with-colons',
|
'--with-colons',
|
||||||
|
'--quiet',
|
||||||
'--batch',
|
'--batch',
|
||||||
'--no-tty',
|
'--no-tty',
|
||||||
'--no-default-keyring',
|
'--no-default-keyring',
|
||||||
'--keyring=/etc/pacman.d/gnupg/pubring.gpg',
|
|
||||||
'--list-keys',
|
'--list-keys',
|
||||||
TESTING_KEYID,
|
TESTING_KEYID,
|
||||||
]
|
]
|
||||||
|
@ -52,10 +105,12 @@ RUN_CMD_LISTKEYS = [
|
||||||
# expected command for gpg --show-keys KEYFILE
|
# expected command for gpg --show-keys KEYFILE
|
||||||
RUN_CMD_SHOW_KEYFILE = [
|
RUN_CMD_SHOW_KEYFILE = [
|
||||||
MOCK_BIN_PATH,
|
MOCK_BIN_PATH,
|
||||||
|
'--no-permission-warning',
|
||||||
'--with-colons',
|
'--with-colons',
|
||||||
'--with-fingerprint',
|
'--quiet',
|
||||||
'--batch',
|
'--batch',
|
||||||
'--no-tty',
|
'--no-tty',
|
||||||
|
'--with-fingerprint',
|
||||||
'--show-keys',
|
'--show-keys',
|
||||||
TESTING_KEYFILE_PATH,
|
TESTING_KEYFILE_PATH,
|
||||||
]
|
]
|
||||||
|
@ -69,6 +124,29 @@ RUN_CMD_LSIGN_KEY = [
|
||||||
TESTING_KEYID,
|
TESTING_KEYID,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
RUN_CMD_LIST_SECRET_KEY = [
|
||||||
|
MOCK_BIN_PATH,
|
||||||
|
'--homedir=/etc/pacman.d/gnupg',
|
||||||
|
'--no-permission-warning',
|
||||||
|
'--with-colons',
|
||||||
|
'--quiet',
|
||||||
|
'--batch',
|
||||||
|
'--no-tty',
|
||||||
|
'--list-secret-key',
|
||||||
|
]
|
||||||
|
|
||||||
|
# expected command for gpg --check-signatures
|
||||||
|
RUN_CMD_CHECK_SIGNATURES = [
|
||||||
|
MOCK_BIN_PATH,
|
||||||
|
'--homedir=/etc/pacman.d/gnupg',
|
||||||
|
'--no-permission-warning',
|
||||||
|
'--with-colons',
|
||||||
|
'--quiet',
|
||||||
|
'--batch',
|
||||||
|
'--no-tty',
|
||||||
|
'--check-signatures',
|
||||||
|
TESTING_KEYID,
|
||||||
|
]
|
||||||
|
|
||||||
TESTCASES = [
|
TESTCASES = [
|
||||||
#
|
#
|
||||||
|
@ -152,7 +230,7 @@ TESTCASES = [
|
||||||
{'check_rc': False},
|
{'check_rc': False},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT,
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -222,7 +300,7 @@ TESTCASES = [
|
||||||
{'check_rc': False},
|
{'check_rc': False},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT,
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -248,7 +326,77 @@ TESTCASES = [
|
||||||
{'check_rc': False},
|
{'check_rc': False},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT,
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
'changed': False,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
# state trusted & key expired
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'state': 'trusted',
|
||||||
|
'id': TESTING_KEYID,
|
||||||
|
'data': 'FAKEDATA',
|
||||||
|
'_ansible_check_mode': True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'state_trusted_key_expired',
|
||||||
|
'run_command.calls': [
|
||||||
|
(
|
||||||
|
RUN_CMD_LISTKEYS,
|
||||||
|
{
|
||||||
|
'check_rc': False,
|
||||||
|
},
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
'changed': True,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
# state & key trusted
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'state': 'trusted',
|
||||||
|
'id': TESTING_KEYID,
|
||||||
|
'data': 'FAKEDATA',
|
||||||
|
'_ansible_check_mode': True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'state_and_key_trusted',
|
||||||
|
'run_command.calls': [
|
||||||
|
(
|
||||||
|
RUN_CMD_LISTKEYS,
|
||||||
|
{
|
||||||
|
'check_rc': False,
|
||||||
|
},
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
GPG_SHOWKEY_OUTPUT_TRUSTED,
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
RUN_CMD_CHECK_SIGNATURES,
|
||||||
|
{},
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
GPG_CHECK_SIGNATURES_OUTPUT,
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
RUN_CMD_LIST_SECRET_KEY,
|
||||||
|
{},
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
GPG_LIST_SECRET_KEY_OUTPUT,
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -270,7 +418,7 @@ TESTCASES = [
|
||||||
{'check_rc': False},
|
{'check_rc': False},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT,
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -339,7 +487,7 @@ TESTCASES = [
|
||||||
{'check_rc': True},
|
{'check_rc': True},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT,
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -397,7 +545,7 @@ TESTCASES = [
|
||||||
{'check_rc': True},
|
{'check_rc': True},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT.replace('61B7B526D98F0353', '61B7B526D98F0354'),
|
GPG_SHOWKEY_OUTPUT_EXPIRED.replace('61B7B526D98F0353', '61B7B526D98F0354'),
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -485,7 +633,7 @@ gpg: imported: 1
|
||||||
{'check_rc': True},
|
{'check_rc': True},
|
||||||
(
|
(
|
||||||
0,
|
0,
|
||||||
GPG_SHOWKEY_OUTPUT,
|
GPG_SHOWKEY_OUTPUT_EXPIRED,
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Reference in a new issue