From 53a5a9397140e35337cf17f0de0792a11f0b9a5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Tue, 14 Nov 2023 13:48:03 +0100
Subject: [PATCH 2/3] DNS key verification: Fix handling keys without an e-mail
address
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If an PGP key is stored in an RPM database without a "packager" RPM
header, or without an e-mail address there, DNS verification crashed
on converting the undefined address into a DNS domain. That was the
case of Fedora 13 key:
# dnf-3 upgrade
Traceback (most recent call last):
File "/usr/bin/dnf-3", line 62, in <module>
main.user_main(sys.argv[1:], exit_code=True)
File "/usr/lib/python3.12/site-packages/dnf/cli/main.py", line 201, in user_main
errcode = main(args)
^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/dnf/cli/main.py", line 67, in main
return _main(base, args, cli_class, option_parser_class)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/dnf/cli/main.py", line 106, in _main
return cli_run(cli, base)
^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/dnf/cli/main.py", line 122, in cli_run
cli.run()
File "/usr/lib/python3.12/site-packages/dnf/cli/cli.py", line 1040, in run
self._process_demands()
File "/usr/lib/python3.12/site-packages/dnf/cli/cli.py", line 741, in _process_demands
self.base.fill_sack(
File "/usr/lib/python3.12/site-packages/dnf/base.py", line 403, in fill_sack
dnf.dnssec.RpmImportedKeys.check_imported_keys_validity()
File "/usr/lib/python3.12/site-packages/dnf/dnssec.py", line 286, in check_imported_keys_validity
keys = RpmImportedKeys._query_db_for_gpg_keys()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/dnf/dnssec.py", line 276, in _query_db_for_gpg_keys
email = re.search('<(.*@.*)>', packager).group(1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.12/re/__init__.py", line 177, in search
return _compile(pattern, flags).search(string)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected string or bytes-like object, got 'NoneType'
This patch defends the crash at two places: In
_query_db_for_gpg_keys() because here we know a NEVRA of the key
and can produce a meaningful message. And in _cache_miss() because
we can get there independenly and called email2location() would also
crash.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
dnf/dnssec.py | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/dnf/dnssec.py b/dnf/dnssec.py
index ba5b80c7..fcce0c6d 100644
--- a/dnf/dnssec.py
+++ b/dnf/dnssec.py
@@ -185,6 +185,10 @@ class DNSSECKeyVerification:
if ctx.add_ta_file("/var/lib/unbound/root.key") != 0:
logger.debug("Unbound context: Failed to add trust anchor file")
+ if input_key.email is None:
+ logger.debug("A key has no associated e-mail address")
+ return Validity.ERROR
+
status, result = ctx.resolve(email2location(input_key.email),
RR_TYPE_OPENPGPKEY, unbound.RR_CLASS_IN)
if status != 0:
@@ -273,7 +277,16 @@ class RpmImportedKeys:
return_list = []
for pkg in packages:
packager = dnf.rpm.getheader(pkg, 'packager')
- email = re.search('<(.*@.*)>', packager).group(1)
+ if packager is None:
+ email = None
+ else:
+ email = re.search('<(.*@.*)>', packager).group(1)
+ if email is None:
+ logger.debug(any_msg(_(
+ "Exempting key package {} from a validation "
+ "because it's not bound to any e-mail address").format(
+ dnf.rpm.getheader(pkg, 'nevra'))))
+ continue
description = dnf.rpm.getheader(pkg, 'description')
# Extract Radix-64-encoded PGP key. Without armor headers and
# a checksum.
--
2.42.0