[seahorse] pgp: GpgmeKeyring: don't load private and public keys simultaneously



commit d0badd14b49b1ab6a5c159088a6937c6a39a8b10
Author: Ivan Shapovalov <intelfx intelfx name>
Date:   Mon Oct 28 05:34:47 2019 +0300

    pgp: GpgmeKeyring: don't load private and public keys simultaneously
    
    When trust-model tofu or tofu-pgp is used, loading both at the same time hits a
    deadlock in GnuPG: https://dev.gnupg.org/T3748 (discovered in context of GPA).
    
    Upstream never fixed it properly, instead opting for the workaround in form of
    loading private and public keys sequentially. Let's do the same.
    
    Fixes #2.

 pgp/seahorse-gpgme-keyring.c | 41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
---
diff --git a/pgp/seahorse-gpgme-keyring.c b/pgp/seahorse-gpgme-keyring.c
index e942aa37..163f9d0f 100644
--- a/pgp/seahorse-gpgme-keyring.c
+++ b/pgp/seahorse-gpgme-keyring.c
@@ -411,29 +411,37 @@ scheduled_dummy (gpointer user_data)
 }
 
 typedef struct {
-       gboolean public_done;
-       gboolean secret_done;
+       SeahorseGpgmeKeyring *self;
+       const gchar **patterns;
 } keyring_load_closure;
 
+static void
+on_keyring_public_list_complete (GObject *source,
+                                 GAsyncResult *result,
+                                 gpointer user_data);
+
 static void
 on_keyring_secret_list_complete (GObject *source,
                                  GAsyncResult *result,
                                  gpointer user_data)
 {
        g_autoptr(GTask) task = G_TASK (user_data);
+       GCancellable *cancellable = g_task_get_cancellable (task);
        keyring_load_closure *closure = g_task_get_task_data (task);
+       SeahorseGpgmeKeyring *self = closure->self;
+       const gchar **patterns = closure->patterns;
        g_autoptr(GError) error = NULL;
 
-       closure->secret_done = TRUE;
-
        if (!seahorse_gpgme_keyring_list_finish (SEAHORSE_GPGME_KEYRING (source),
                                                 result, &error)) {
                g_task_return_error (task, g_steal_pointer (&error));
-        return;
-    }
+               return;
+       }
 
-       if (closure->public_done)
-               g_task_return_boolean (task, TRUE);
+       /* Public keys */
+       seahorse_gpgme_keyring_list_async (self, patterns, 0, FALSE, cancellable,
+                                          on_keyring_public_list_complete,
+                                          g_steal_pointer (&task));
 }
 
 static void
@@ -442,19 +450,15 @@ on_keyring_public_list_complete (GObject *source,
                                  gpointer user_data)
 {
        g_autoptr(GTask) task = G_TASK (user_data);
-       keyring_load_closure *closure = g_task_get_task_data (task);
        g_autoptr(GError) error = NULL;
 
-       closure->public_done = TRUE;
-
        if (!seahorse_gpgme_keyring_list_finish (SEAHORSE_GPGME_KEYRING (source),
                                                 result, &error)) {
                g_task_return_error (task, g_steal_pointer (&error));
-        return;
-    }
+               return;
+       }
 
-       if (closure->secret_done)
-               g_task_return_boolean (task, TRUE);
+       g_task_return_boolean (task, TRUE);
 }
 
 static void
@@ -477,6 +481,8 @@ seahorse_gpgme_keyring_load_full_async (SeahorseGpgmeKeyring *self,
 
        task = g_task_new (self, cancellable, callback, user_data);
        closure = g_new0 (keyring_load_closure, 1);
+       closure->self = self;
+       closure->patterns = patterns;
        g_task_set_task_data (task, closure, g_free);
 
        /* Secret keys */
@@ -484,10 +490,7 @@ seahorse_gpgme_keyring_load_full_async (SeahorseGpgmeKeyring *self,
                                           on_keyring_secret_list_complete,
                                           g_object_ref (task));
 
-       /* Public keys */
-       seahorse_gpgme_keyring_list_async (self, patterns, 0, FALSE, cancellable,
-                                          on_keyring_public_list_complete,
-                                          g_steal_pointer (&task));
+       /* Public keys -- see on_keyring_secret_list_complete() */
 }
 
 SeahorseGpgmeKey *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]