From 98160ff6750eeeeddda03ed508e5ced4496809e0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 4 Jul 2023 18:22:49 +0200 Subject: [PATCH] Check no new unexpected keys were installed during the upgrade Signed-off-by: Jakub Jelen --- .../common/actors/gpgpubkeycheck/actor.py | 23 +++++++ .../libraries/gpgpubkeycheck.py | 68 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 repos/system_upgrade/common/actors/gpgpubkeycheck/actor.py create mode 100644 repos/system_upgrade/common/actors/gpgpubkeycheck/libraries/gpgpubkeycheck.py diff --git a/repos/system_upgrade/common/actors/gpgpubkeycheck/actor.py b/repos/system_upgrade/common/actors/gpgpubkeycheck/actor.py new file mode 100644 index 0000000000..3d11de381b --- /dev/null +++ b/repos/system_upgrade/common/actors/gpgpubkeycheck/actor.py @@ -0,0 +1,23 @@ +from leapp.actors import Actor +from leapp.libraries.actor import gpgpubkeycheck +from leapp.models import TrustedGpgKeys +from leapp.reporting import Report +from leapp.tags import ApplicationsPhaseTag, IPUWorkflowTag + + +class GpgPubkeyCheck(Actor): + """ + Checks no unexpected GPG keys were installed during the upgrade. + + This should be mostly sanity check and this should not happen + unless something went very wrong, regardless the gpgcheck was + used (default) or not (with --no-gpgcheck option). + """ + + name = 'gpg_pubkey_check' + consumes = (TrustedGpgKeys,) + produces = (Report,) + tags = (IPUWorkflowTag, ApplicationsPhaseTag,) + + def process(self): + gpgpubkeycheck.process() diff --git a/repos/system_upgrade/common/actors/gpgpubkeycheck/libraries/gpgpubkeycheck.py b/repos/system_upgrade/common/actors/gpgpubkeycheck/libraries/gpgpubkeycheck.py new file mode 100644 index 0000000000..873b05a551 --- /dev/null +++ b/repos/system_upgrade/common/actors/gpgpubkeycheck/libraries/gpgpubkeycheck.py @@ -0,0 +1,68 @@ +from leapp import reporting +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.common.gpg import get_path_to_gpg_certs, the_nogpgcheck_option_used +from leapp.libraries.common.rpms import get_installed_rpms +from leapp.libraries.stdlib import api +from leapp.models import TrustedGpgKeys + +FMT_LIST_SEPARATOR = '\n - ' + + +def process(): + """ + Verify the system does not have any unexpected gpg keys installed + + If the --no-gpgcheck option is used, this is skipped as we can not + guarantee that what was installed came from trusted source + """ + + if the_nogpgcheck_option_used(): + api.current_logger().warning('The --nogpgcheck option is used: Checking keys does not make sense.') + return + + try: + trusted_gpg_keys = next(api.consume(TrustedGpgKeys)) + except StopIteration: + raise StopActorExecutionError( + 'Could not check for valid GPG keys', details={'details': 'No TrustedGpgKeys facts'} + ) + + trusted_fps = [key.fingerprint for key in trusted_gpg_keys.items] + unexpected_fps = list() + + rpms = get_installed_rpms() + for rpm in rpms: + rpm = rpm.strip() + if not rpm: + continue + name, version, _, _, packager, _, _ = rpm.split('|') + if name != 'gpg-pubkey': + continue + fp = version + if fp not in trusted_fps: + unexpected_fps.append('{fp}: {packager}'.format(fp=fp, packager=packager)) + + if unexpected_fps: + summary = ( + 'The system contains unexpected GPG keys after upgrade. This can be caused by some manual intervention' + ' or by malicious attempt to hijack the installation process. The unexpected keys are the following:' + ' {sep}{key_list}' + .format( + sep=FMT_LIST_SEPARATOR, + key_list=FMT_LIST_SEPARATOR.join(unexpected_fps) + ) + ) + hint = ( + 'Verify the installed keys are expected. If so, make sure they are included in {} directory.' + .format(get_path_to_gpg_certs()) + ) + groups = [reporting.Groups.REPOSITORY, reporting.Groups.SECURITY] + reporting.create_report( + [ + reporting.Title('Unexpected GPG keys found after installation'), + reporting.Summary(summary), + reporting.Severity(reporting.Severity.HIGH), + reporting.Groups(groups), + reporting.Remediation(hint=hint), + ] + )