Skip to content

Commit

Permalink
DNS key verification: Fix handling keys without an e-mail address
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ppisar committed Nov 14, 2023
1 parent ab7d465 commit dd1084d
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion dnf/dnssec.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ def _cache_miss(input_key):
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 == 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:
Expand Down Expand Up @@ -273,7 +277,13 @@ def _query_db_for_gpg_keys():
return_list = []
for pkg in packages:
packager = dnf.rpm.getheader(pkg, 'packager')
email = re.search('<(.*@.*)>', packager).group(1)
if packager == None:
email = None
else:
email = re.search('<(.*@.*)>', packager).group(1)
if email == 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.
Expand Down

0 comments on commit dd1084d

Please sign in to comment.