Blame SOURCES/libdnf-gpg.patch

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