rpmconf-matt: Switch from dnf-download-signed (which I forgot to
authorMatt McCutchen <matt@mattmccutchen.net>
Wed, 16 Sep 2020 20:43:30 +0000 (16:43 -0400)
committerMatt McCutchen <matt@mattmccutchen.net>
Wed, 16 Sep 2020 20:43:30 +0000 (16:43 -0400)
distribute) to plain "dnf download" and add a notice about the security
implications.

rpmconf-matt

index a24f736..4cb5093 100755 (executable)
@@ -1,6 +1,17 @@
 #!/usr/bin/env python3
 # rpmconf-matt [--sync-only]
 
+# SECURITY NOTICE: If your system is missing the original version (.rpmbase) of
+# a configuration file you have modified, rpmconf-matt will automatically get it
+# by downloading the original package with "dnf download", which (IIUC) does not
+# check the package's GPG signature even if dnf is normally configured to do so.
+# (TODO: File an upstream bug about this?)  rpmconf-matt checks the digest of
+# the file before using it, but a fuzzed package might be able to compromise
+# your system during extraction.  This is less of a problem if your repository
+# metadata is integrity protected (e.g., by SSL on the metalink or repomd)
+# because "dnf download" checks the digest of the downloaded package before
+# exiting successfully.
+
 # Known blockers to submission to Fedora: Basically removing assumptions specific to my setup.
 # - Decide how to name it vs. existing "rpmconf" in Fedora
 # - Make it configurable what part of the filesystem to scan.  Is there a
@@ -165,22 +176,7 @@ def rpmconf(syncOnly=False):
        if needPackages:
                print('Downloading %d packages.' % len(needPackages))
                packages_tmpdir = tempfile.mkdtemp(prefix='rpmconf-packages')
-               # Make sure the cpio archive is covered by a valid signature
-               # before we use it.  Since dnf-download-signed currently doesn't
-               # check that the package is the one we asked for, this only
-               # ensures that the cpio archive is safe to extract.  Then we
-               # check the digest on each needed file before using it.  We're
-               # still correct if an attacker substitutes a different signed
-               # package in which the files we need have the same content.
-               # ~ Matt 2019-05-18
-               #
-               # Ideally, we'd only require a signature if the package came
-               # from a repository with gpgcheck=1.  Right now, I use no
-               # unsigned packages.  If I build my own packages again, I can
-               # either sign them or just fix them manually if they reach this
-               # code.
-               # ~ Matt 2017-11-11
-               subprocess.check_call(['dnf-download-signed'] + list(needPackages), cwd=packages_tmpdir)
+               subprocess.check_call(['dnf', 'download'] + list(needPackages), cwd=packages_tmpdir)
                for nevra, neededPkg in needPackages.items():
                        packagePath = '%s/%s.rpm' % (packages_tmpdir, neededPkg.nvra)
                        extract_tmpdir = tempfile.mkdtemp(prefix='rpmconf-extract-%s' % nevra)