bstinson / rpms / rpm-ostree

Forked from rpms/rpm-ostree 5 years ago
Clone

Blame SOURCES/libdnf-gpg.patch

7d8bc5
From b2ded5a4da58940159f5d337e9e29c5de5cc0f7a Mon Sep 17 00:00:00 2001
7d8bc5
From: Colin Walters <walters@verbum.org>
7d8bc5
Date: Thu, 2 Feb 2017 10:00:06 -0500
7d8bc5
Subject: [PATCH 1/2] repo: Enable GPG by default
7d8bc5
7d8bc5
This increases compatibility with dnf/yum. It was very surprising to me that we
7d8bc5
didn't do this. Most repos do seem to use `gpgcheck=1`, but I'm fairly certain
7d8bc5
I've seen repo configs in the wild that actually depend on it, though after
7d8bc5
looking at a few (ceph, postgres), I can't find one yet.
7d8bc5
7d8bc5
Still, I think it's worth making this change. I suspect very few people will
7d8bc5
edit `/etc/yum/yum.conf` to globally disable GPG checking, versus disabling it
7d8bc5
per repository.
7d8bc5
---
7d8bc5
 libdnf/dnf-repo.c | 11 ++++++++++-
7d8bc5
 1 file changed, 10 insertions(+), 1 deletion(-)
7d8bc5
7d8bc5
diff --git a/libdnf/dnf-repo.c b/libdnf/dnf-repo.c
7d8bc5
index 08e0d8b..017c82d 100644
7d8bc5
--- a/libdnf/libdnf/dnf-repo.c
7d8bc5
+++ b/libdnf/libdnf/dnf-repo.c
7d8bc5
@@ -858,7 +858,16 @@ dnf_repo_set_keyfile_data(DnfRepo *repo, GError **error)
7d8bc5
     /* gpgkey is optional for gpgcheck=1, but required for repo_gpgcheck=1 */
7d8bc5
     g_free(priv->gpgkey);
7d8bc5
     priv->gpgkey = g_key_file_get_string(priv->keyfile, priv->id, "gpgkey", NULL);
7d8bc5
-    priv->gpgcheck_pkgs = dnf_repo_get_boolean(priv->keyfile, priv->id, "gpgcheck", NULL);
7d8bc5
+    /* Currently, we don't have a global configuration file.  The way this worked in yum
7d8bc5
+     * is that the yum package enabled gpgcheck=1 by default in /etc/yum.conf.  Basically,
7d8bc5
+     * I don't think many people changed that.  It's just saner to disable it in the individual
7d8bc5
+     * repo files as required.  To claim compatibility with yum repository files, I think
7d8bc5
+     * we need to basically hard code the yum.conf defaults here.
7d8bc5
+     */
7d8bc5
+    if (!g_key_file_has_key (priv->keyfile, priv->id, "gpgcheck", NULL))
7d8bc5
+        priv->gpgcheck_pkgs = TRUE;
7d8bc5
+    else
7d8bc5
+        priv->gpgcheck_pkgs = dnf_repo_get_boolean(priv->keyfile, priv->id, "gpgcheck", NULL);
7d8bc5
     priv->gpgcheck_md = dnf_repo_get_boolean(priv->keyfile, priv->id, "repo_gpgcheck", NULL);
7d8bc5
     if (priv->gpgcheck_md && priv->gpgkey == NULL) {
7d8bc5
         g_set_error_literal(error,
7d8bc5
-- 
7d8bc5
2.9.3
7d8bc5
7d8bc5
7d8bc5
From 0d68ebac7d39a9278ebb5259c4912efa55c080da Mon Sep 17 00:00:00 2001
7d8bc5
From: Colin Walters <walters@verbum.org>
7d8bc5
Date: Tue, 31 Jan 2017 17:14:37 -0500
7d8bc5
Subject: [PATCH 2/2] transaction: Export parts of the GPG functionality
7d8bc5
7d8bc5
rpm-ostree doesn't use `dnf_transaction_commit()`, because it uses libostree to
7d8bc5
store the RPMs, and bubblewrap to run `%post`s. However, we do need the GPG
7d8bc5
functionality.
7d8bc5
---
7d8bc5
 libdnf/libdnf/dnf-transaction.c | 193 ++++++++++++++++++++++++++++-------------------
7d8bc5
 libdnf/libdnf/dnf-transaction.h |  11 +++
7d8bc5
 2 files changed, 127 insertions(+), 77 deletions(-)
7d8bc5
7d8bc5
diff --git a/libdnf/libdnf/dnf-transaction.c b/libdnf/libdnf/dnf-transaction.c
7d8bc5
index 62fcc51..dd73245 100644
7d8bc5
--- a/libdnf/libdnf/dnf-transaction.c
7d8bc5
+++ b/libdnf/libdnf/dnf-transaction.c
7d8bc5
@@ -328,17 +328,88 @@ dnf_transaction_ensure_repo_list(DnfTransaction *transaction,
7d8bc5
     return TRUE;
7d8bc5
 }
7d8bc5
 
7d8bc5
+gboolean
7d8bc5
+dnf_transaction_gpgcheck_package (DnfTransaction *transaction,
7d8bc5
+                                  DnfPackage     *pkg,
7d8bc5
+                                  GError        **error)
7d8bc5
+{
7d8bc5
+    DnfTransactionPrivate *priv = GET_PRIVATE(transaction);
7d8bc5
+    GError *error_local = NULL;
7d8bc5
+    DnfRepo *repo;
7d8bc5
+    const gchar *fn;
7d8bc5
+
7d8bc5
+    /* ensure the filename is set */
7d8bc5
+    if (!dnf_transaction_ensure_repo(transaction, pkg, error)) {
7d8bc5
+        g_prefix_error(error, "Failed to check untrusted: ");
7d8bc5
+        return FALSE;
7d8bc5
+    }
7d8bc5
+
7d8bc5
+    /* find the location of the local file */
7d8bc5
+    fn = dnf_package_get_filename(pkg);
7d8bc5
+    if (fn == NULL) {
7d8bc5
+        g_set_error(error,
7d8bc5
+                    DNF_ERROR,
7d8bc5
+                    DNF_ERROR_FILE_NOT_FOUND,
7d8bc5
+                    "Downloaded file for %s not found",
7d8bc5
+                    dnf_package_get_name(pkg));
7d8bc5
+        return FALSE;
7d8bc5
+    }
7d8bc5
+
7d8bc5
+    /* check file */
7d8bc5
+    if (!dnf_keyring_check_untrusted_file(priv->keyring, fn, &error_local)) {
7d8bc5
+
7d8bc5
+        /* probably an i/o error */
7d8bc5
+        if (!g_error_matches(error_local,
7d8bc5
+                             DNF_ERROR,
7d8bc5
+                             DNF_ERROR_GPG_SIGNATURE_INVALID)) {
7d8bc5
+            g_propagate_error(error, error_local);
7d8bc5
+            return FALSE;
7d8bc5
+        }
7d8bc5
+
7d8bc5
+        /* if the repo is signed this is ALWAYS an error */
7d8bc5
+        repo = dnf_package_get_repo(pkg);
7d8bc5
+        if (repo != NULL && dnf_repo_get_gpgcheck(repo)) {
7d8bc5
+            g_set_error(error,
7d8bc5
+                        DNF_ERROR,
7d8bc5
+                        DNF_ERROR_FILE_INVALID,
7d8bc5
+                        "package %s cannot be verified "
7d8bc5
+                        "and repo %s is GPG enabled: %s",
7d8bc5
+                        dnf_package_get_nevra(pkg),
7d8bc5
+                        dnf_repo_get_id(repo),
7d8bc5
+                        error_local->message);
7d8bc5
+            g_error_free(error_local);
7d8bc5
+            return FALSE;
7d8bc5
+        }
7d8bc5
+
7d8bc5
+        /* we can only install signed packages in this mode */
7d8bc5
+        if ((priv->flags & DNF_TRANSACTION_FLAG_ONLY_TRUSTED) > 0) {
7d8bc5
+            g_propagate_error(error, error_local);
7d8bc5
+            return FALSE;
7d8bc5
+        }
7d8bc5
+
7d8bc5
+        /* we can install unsigned packages */
7d8bc5
+        g_warning("ignoring as allow-untrusted: %s",
7d8bc5
+                error_local->message);
7d8bc5
+        g_clear_error(&error_local);
7d8bc5
+    }
7d8bc5
+
7d8bc5
+    return TRUE;
7d8bc5
+}
7d8bc5
+
7d8bc5
 /**
7d8bc5
  * dnf_transaction_check_untrusted:
7d8bc5
+ * @transaction: Transaction
7d8bc5
+ * @goal: Target goal
7d8bc5
+ * @error: Error
7d8bc5
+ *
7d8bc5
+ * Verify GPG signatures for all pending packages to be changed as part
7d8bc5
+ * of @goal.
7d8bc5
  */
7d8bc5
-static gboolean
7d8bc5
+gboolean
7d8bc5
 dnf_transaction_check_untrusted(DnfTransaction *transaction,
7d8bc5
                                 HyGoal goal,
7d8bc5
                                 GError **error)
7d8bc5
 {
7d8bc5
-    DnfTransactionPrivate *priv = GET_PRIVATE(transaction);
7d8bc5
-    DnfPackage *pkg;
7d8bc5
-    const gchar *fn;
7d8bc5
     guint i;
7d8bc5
     g_autoptr(GPtrArray) install = NULL;
7d8bc5
 
7d8bc5
@@ -354,64 +425,10 @@ dnf_transaction_check_untrusted(DnfTransaction *transaction,
7d8bc5
 
7d8bc5
     /* find any packages in untrusted repos */
7d8bc5
     for (i = 0; i < install->len; i++) {
7d8bc5
-        GError *error_local = NULL;
7d8bc5
-        DnfRepo *repo;
7d8bc5
-        pkg = g_ptr_array_index(install, i);
7d8bc5
+        DnfPackage *pkg = g_ptr_array_index(install, i);
7d8bc5
 
7d8bc5
-        /* ensure the filename is set */
7d8bc5
-        if (!dnf_transaction_ensure_repo(transaction, pkg, error)) {
7d8bc5
-            g_prefix_error(error, "Failed to check untrusted: ");
7d8bc5
+        if (!dnf_transaction_gpgcheck_package (transaction, pkg, error))
7d8bc5
             return FALSE;
7d8bc5
-        }
7d8bc5
-
7d8bc5
-        /* find the location of the local file */
7d8bc5
-        fn = dnf_package_get_filename(pkg);
7d8bc5
-        if (fn == NULL) {
7d8bc5
-            g_set_error(error,
7d8bc5
-                        DNF_ERROR,
7d8bc5
-                        DNF_ERROR_FILE_NOT_FOUND,
7d8bc5
-                        "Downloaded file for %s not found",
7d8bc5
-                        dnf_package_get_name(pkg));
7d8bc5
-            return FALSE;
7d8bc5
-        }
7d8bc5
-
7d8bc5
-        /* check file */
7d8bc5
-        if (!dnf_keyring_check_untrusted_file(priv->keyring, fn, &error_local)) {
7d8bc5
-
7d8bc5
-            /* probably an i/o error */
7d8bc5
-            if (!g_error_matches(error_local,
7d8bc5
-                                 DNF_ERROR,
7d8bc5
-                                 DNF_ERROR_GPG_SIGNATURE_INVALID)) {
7d8bc5
-                g_propagate_error(error, error_local);
7d8bc5
-                return FALSE;
7d8bc5
-            }
7d8bc5
-
7d8bc5
-            /* if the repo is signed this is ALWAYS an error */
7d8bc5
-            repo = dnf_package_get_repo(pkg);
7d8bc5
-            if (repo != NULL && dnf_repo_get_gpgcheck(repo)) {
7d8bc5
-                g_set_error(error,
7d8bc5
-                            DNF_ERROR,
7d8bc5
-                            DNF_ERROR_FILE_INVALID,
7d8bc5
-                            "package %s cannot be verified "
7d8bc5
-                            "and repo %s is GPG enabled: %s",
7d8bc5
-                            dnf_package_get_nevra(pkg),
7d8bc5
-                            dnf_repo_get_id(repo),
7d8bc5
-                            error_local->message);
7d8bc5
-                g_error_free(error_local);
7d8bc5
-                return FALSE;
7d8bc5
-            }
7d8bc5
-
7d8bc5
-            /* we can only install signed packages in this mode */
7d8bc5
-            if ((priv->flags & DNF_TRANSACTION_FLAG_ONLY_TRUSTED) > 0) {
7d8bc5
-                g_propagate_error(error, error_local);
7d8bc5
-                return FALSE;
7d8bc5
-            }
7d8bc5
-
7d8bc5
-            /* we can install unsigned packages */
7d8bc5
-            g_debug("ignoring as allow-untrusted: %s",
7d8bc5
-                 error_local->message);
7d8bc5
-            g_clear_error(&error_local);
7d8bc5
-        }
7d8bc5
     }
7d8bc5
     return TRUE;
7d8bc5
 }
7d8bc5
@@ -1167,6 +1184,44 @@ dnf_transaction_reset(DnfTransaction *transaction)
7d8bc5
 }
7d8bc5
 
7d8bc5
 /**
7d8bc5
+ * dnf_transaction_import_keys:
7d8bc5
+ * @transaction: a #DnfTransaction instance.
7d8bc5
+ * @error: A #GError or %NULL
7d8bc5
+ *
7d8bc5
+ * Imports all keys from /etc/pki/rpm-gpg as well as any
7d8bc5
+ * downloaded per-repo keys.  Note this is called automatically
7d8bc5
+ * by dnf_transaction_commit().
7d8bc5
+ **/
7d8bc5
+gboolean
7d8bc5
+dnf_transaction_import_keys(DnfTransaction *transaction,
7d8bc5
+                            GError **error)
7d8bc5
+{
7d8bc5
+    guint i;
7d8bc5
+
7d8bc5
+    DnfTransactionPrivate *priv = GET_PRIVATE(transaction);
7d8bc5
+    /* import all system wide GPG keys */
7d8bc5
+    if (!dnf_keyring_add_public_keys(priv->keyring, error))
7d8bc5
+        return FALSE;
7d8bc5
+
7d8bc5
+    /* import downloaded repo GPG keys */
7d8bc5
+    for (i = 0; i < priv->repos->len; i++) {
7d8bc5
+        DnfRepo *repo = g_ptr_array_index(priv->repos, i);
7d8bc5
+        const gchar *pubkey;
7d8bc5
+
7d8bc5
+        /* does this file actually exist */
7d8bc5
+        pubkey = dnf_repo_get_public_key(repo);
7d8bc5
+        if (g_file_test(pubkey, G_FILE_TEST_EXISTS)) {
7d8bc5
+            /* import */
7d8bc5
+            if (!dnf_keyring_add_public_key(priv->keyring, pubkey, error))
7d8bc5
+                return FALSE;
7d8bc5
+        }
7d8bc5
+    }
7d8bc5
+
7d8bc5
+    return TRUE;
7d8bc5
+}
7d8bc5
+
7d8bc5
+
7d8bc5
+/**
7d8bc5
  * dnf_transaction_commit:
7d8bc5
  * @transaction: a #DnfTransaction instance.
7d8bc5
  * @goal: A #HyGoal
7d8bc5
@@ -1237,26 +1292,10 @@ dnf_transaction_commit(DnfTransaction *transaction,
7d8bc5
     if (!ret)
7d8bc5
         goto out;
7d8bc5
 
7d8bc5
-    /* import all system wide GPG keys */
7d8bc5
-    ret = dnf_keyring_add_public_keys(priv->keyring, error);
7d8bc5
+    ret = dnf_transaction_import_keys(transaction, error);
7d8bc5
     if (!ret)
7d8bc5
         goto out;
7d8bc5
 
7d8bc5
-    /* import downloaded repo GPG keys */
7d8bc5
-    for (i = 0; i < priv->repos->len; i++) {
7d8bc5
-        DnfRepo *repo = g_ptr_array_index(priv->repos, i);
7d8bc5
-        const gchar *pubkey;
7d8bc5
-
7d8bc5
-        /* does this file actually exist */
7d8bc5
-        pubkey = dnf_repo_get_public_key(repo);
7d8bc5
-        if (g_file_test(pubkey, G_FILE_TEST_EXISTS)) {
7d8bc5
-            /* import */
7d8bc5
-            ret = dnf_keyring_add_public_key(priv->keyring, pubkey, error);
7d8bc5
-            if (!ret)
7d8bc5
-                goto out;
7d8bc5
-        }
7d8bc5
-    }
7d8bc5
-
7d8bc5
     /* find any packages without valid GPG signatures */
7d8bc5
     ret = dnf_transaction_check_untrusted(transaction, goal, error);
7d8bc5
     if (!ret)
7d8bc5
diff --git a/libdnf/libdnf/dnf-transaction.h b/libdnf/libdnf/dnf-transaction.h
7d8bc5
index 6131374..84d1365 100644
7d8bc5
--- a/libdnf/libdnf/dnf-transaction.h
7d8bc5
+++ b/libdnf/libdnf/dnf-transaction.h
7d8bc5
@@ -95,6 +95,17 @@ gboolean         dnf_transaction_depsolve               (DnfTransaction *transac
7d8bc5
 gboolean         dnf_transaction_download               (DnfTransaction *transaction,
7d8bc5
                                                          DnfState       *state,
7d8bc5
                                                          GError         **error);
7d8bc5
+
7d8bc5
+gboolean         dnf_transaction_import_keys            (DnfTransaction *transaction,
7d8bc5
+                                                         GError **error);
7d8bc5
+
7d8bc5
+gboolean         dnf_transaction_gpgcheck_package        (DnfTransaction *transaction,
7d8bc5
+                                                          DnfPackage     *pkg,
7d8bc5
+                                                          GError        **error);
7d8bc5
+gboolean         dnf_transaction_check_untrusted        (DnfTransaction *transaction,
7d8bc5
+                                                         HyGoal          goal,
7d8bc5
+                                                         GError        **error);
7d8bc5
+
7d8bc5
 gboolean         dnf_transaction_commit                 (DnfTransaction *transaction,
7d8bc5
                                                          HyGoal          goal,
7d8bc5
                                                          DnfState       *state,
7d8bc5
-- 
7d8bc5
2.9.3
7d8bc5