Blame SOURCES/0001-smartcard-Wait-until-smartcards-are-inspected-before.patch

c8e532
From 0665bd86221d3c9012f0391d8e4939a2d12b6417 Mon Sep 17 00:00:00 2001
c8e532
From: Ray Strode <rstrode@redhat.com>
c8e532
Date: Fri, 9 Feb 2018 16:39:12 -0500
c8e532
Subject: [PATCH 1/2] smartcard: Wait until smartcards are inspected before
c8e532
 locking screen
c8e532
c8e532
There's a race condition in the code where we check if the screen should
c8e532
be locked (because the smartcard is removed) before we necessarly check
c8e532
the smartcard's insertion status.
c8e532
c8e532
This commit fixes the race by iterating through all smartcards at
c8e532
startup and checking their status explicitly.
c8e532
---
c8e532
 plugins/smartcard/gsd-smartcard-manager.c | 61 ++++++++++++++++++-----
c8e532
 1 file changed, 49 insertions(+), 12 deletions(-)
c8e532
c8e532
diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c
c8e532
index a6245425..94ffdd90 100644
c8e532
--- a/plugins/smartcard/gsd-smartcard-manager.c
c8e532
+++ b/plugins/smartcard/gsd-smartcard-manager.c
c8e532
@@ -37,64 +37,73 @@
c8e532
 #include <secmod.h>
c8e532
 #include <secerr.h>
c8e532
 
c8e532
 #define GSD_SMARTCARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerPrivate))
c8e532
 
c8e532
 #define GSD_SESSION_MANAGER_LOGOUT_MODE_FORCE 2
c8e532
 
c8e532
 struct GsdSmartcardManagerPrivate
c8e532
 {
c8e532
         guint start_idle_id;
c8e532
         GsdSmartcardService *service;
c8e532
         GList *smartcards_watch_tasks;
c8e532
         GCancellable *cancellable;
c8e532
 
c8e532
         GsdSessionManager *session_manager;
c8e532
         GsdScreenSaver *screen_saver;
c8e532
 
c8e532
         GSettings *settings;
c8e532
 
c8e532
         NSSInitContext *nss_context;
c8e532
 };
c8e532
 
c8e532
 #define CONF_SCHEMA "org.gnome.settings-daemon.peripherals.smartcard"
c8e532
 #define KEY_REMOVE_ACTION "removal-action"
c8e532
 
c8e532
 static void     gsd_smartcard_manager_class_init  (GsdSmartcardManagerClass *klass);
c8e532
 static void     gsd_smartcard_manager_init        (GsdSmartcardManager      *self);
c8e532
 static void     gsd_smartcard_manager_finalize    (GObject                  *object);
c8e532
 static void     lock_screen                       (GsdSmartcardManager *self);
c8e532
 static void     log_out                           (GsdSmartcardManager *self);
c8e532
+static void     on_smartcards_from_driver_watched (GsdSmartcardManager *self,
c8e532
+                                                   GAsyncResult        *result,
c8e532
+                                                   GTask               *task);
c8e532
 G_DEFINE_TYPE (GsdSmartcardManager, gsd_smartcard_manager, G_TYPE_OBJECT)
c8e532
 G_DEFINE_QUARK (gsd-smartcard-manager-error, gsd_smartcard_manager_error)
c8e532
 G_LOCK_DEFINE_STATIC (gsd_smartcards_watch_tasks);
c8e532
 
c8e532
+typedef struct {
c8e532
+        SECMODModule *driver;
c8e532
+        guint         idle_id;
c8e532
+        GError       *error;
c8e532
+} DriverRegistrationOperation;
c8e532
+
c8e532
 static gpointer manager_object = NULL;
c8e532
 
c8e532
 static void
c8e532
 gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *klass)
c8e532
 {
c8e532
         GObjectClass   *object_class = G_OBJECT_CLASS (klass);
c8e532
 
c8e532
         object_class->finalize = gsd_smartcard_manager_finalize;
c8e532
 
c8e532
         gsd_smartcard_utils_register_error_domain (GSD_SMARTCARD_MANAGER_ERROR,
c8e532
                                                    GSD_TYPE_SMARTCARD_MANAGER_ERROR);
c8e532
         g_type_class_add_private (klass, sizeof (GsdSmartcardManagerPrivate));
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 gsd_smartcard_manager_init (GsdSmartcardManager *self)
c8e532
 {
c8e532
         self->priv = GSD_SMARTCARD_MANAGER_GET_PRIVATE (self);
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 load_nss (GsdSmartcardManager *self)
c8e532
 {
c8e532
         GsdSmartcardManagerPrivate *priv = self->priv;
c8e532
         NSSInitContext *context = NULL;
c8e532
 
c8e532
         /* The first field in the NSSInitParameters structure
c8e532
          * is the size of the structure. NSS requires this, so
c8e532
          * that it can change the size of the structure in future
c8e532
          * versions of NSS in a detectable way
c8e532
@@ -291,135 +300,168 @@ watch_smartcards_from_driver (GTask                    *task,
c8e532
                         break;
c8e532
                 }
c8e532
 
c8e532
                 if (!watch_succeeded) {
c8e532
                         g_task_return_error (task, error);
c8e532
                         break;
c8e532
                 }
c8e532
         }
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 destroy_watch_smartcards_operation (WatchSmartcardsOperation *operation)
c8e532
 {
c8e532
         SECMOD_DestroyModule (operation->driver);
c8e532
         g_hash_table_unref (operation->smartcards);
c8e532
         g_free (operation);
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 on_smartcards_watch_task_destroyed (GsdSmartcardManager *self,
c8e532
                                     GTask               *freed_task)
c8e532
 {
c8e532
         GsdSmartcardManagerPrivate *priv = self->priv;
c8e532
 
c8e532
         G_LOCK (gsd_smartcards_watch_tasks);
c8e532
         priv->smartcards_watch_tasks = g_list_remove (priv->smartcards_watch_tasks,
c8e532
                                                       freed_task);
c8e532
         G_UNLOCK (gsd_smartcards_watch_tasks);
c8e532
 }
c8e532
 
c8e532
+static void
c8e532
+sync_initial_tokens_from_driver (GsdSmartcardManager *self,
c8e532
+                                 SECMODModule        *driver,
c8e532
+                                 GHashTable          *smartcards,
c8e532
+                                 GCancellable        *cancellable)
c8e532
+{
c8e532
+        GsdSmartcardManagerPrivate *priv = self->priv;
c8e532
+        int i;
c8e532
+
c8e532
+        for (i = 0; i < driver->slotCount; i++) {
c8e532
+                PK11SlotInfo *card;
c8e532
+
c8e532
+                card = driver->slots[i];
c8e532
+
c8e532
+                if (PK11_IsPresent (card)) {
c8e532
+                        CK_SLOT_ID slot_id;
c8e532
+                        slot_id = PK11_GetSlotID (card);
c8e532
+
c8e532
+                        g_debug ("Detected smartcard in slot %d at start up", (int) slot_id);
c8e532
+
c8e532
+                        g_hash_table_replace (smartcards,
c8e532
+                                              GINT_TO_POINTER ((int) slot_id),
c8e532
+                                              PK11_ReferenceSlot (card));
c8e532
+                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
c8e532
+                }
c8e532
+        }
c8e532
+}
c8e532
+
c8e532
 static void
c8e532
 watch_smartcards_from_driver_async (GsdSmartcardManager *self,
c8e532
                                     SECMODModule        *driver,
c8e532
                                     GCancellable        *cancellable,
c8e532
                                     GAsyncReadyCallback  callback,
c8e532
                                     gpointer             user_data)
c8e532
 {
c8e532
         GsdSmartcardManagerPrivate *priv = self->priv;
c8e532
         GTask *task;
c8e532
         WatchSmartcardsOperation *operation;
c8e532
 
c8e532
         operation = g_new0 (WatchSmartcardsOperation, 1);
c8e532
         operation->driver = SECMOD_ReferenceModule (driver);
c8e532
         operation->smartcards = g_hash_table_new_full (g_direct_hash,
c8e532
                                                        g_direct_equal,
c8e532
                                                        NULL,
c8e532
                                                        (GDestroyNotify) PK11_FreeSlot);
c8e532
 
c8e532
         task = g_task_new (self, cancellable, callback, user_data);
c8e532
 
c8e532
         g_task_set_task_data (task,
c8e532
                               operation,
c8e532
                               (GDestroyNotify) destroy_watch_smartcards_operation);
c8e532
 
c8e532
         G_LOCK (gsd_smartcards_watch_tasks);
c8e532
         priv->smartcards_watch_tasks = g_list_prepend (priv->smartcards_watch_tasks,
c8e532
                                                        task);
c8e532
         g_object_weak_ref (G_OBJECT (task),
c8e532
                            (GWeakNotify) on_smartcards_watch_task_destroyed,
c8e532
                            self);
c8e532
         G_UNLOCK (gsd_smartcards_watch_tasks);
c8e532
 
c8e532
+        sync_initial_tokens_from_driver (self, driver, operation->smartcards, cancellable);
c8e532
+
c8e532
         g_task_run_in_thread (task, (GTaskThreadFunc) watch_smartcards_from_driver);
c8e532
 }
c8e532
 
c8e532
 static gboolean
c8e532
 register_driver_finish (GsdSmartcardManager  *self,
c8e532
                         GAsyncResult         *result,
c8e532
                         GError              **error)
c8e532
 {
c8e532
         return g_task_propagate_boolean (G_TASK (result), error);
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 on_driver_registered (GsdSmartcardManager *self,
c8e532
                       GAsyncResult        *result,
c8e532
                       GTask               *task)
c8e532
 {
c8e532
         GError *error = NULL;
c8e532
+        DriverRegistrationOperation *operation;
c8e532
+        GsdSmartcardManagerPrivate *priv = self->priv;
c8e532
+
c8e532
+        operation = g_task_get_task_data (G_TASK (result));
c8e532
 
c8e532
         if (!register_driver_finish (self, result, &error)) {
c8e532
                 g_task_return_error (task, error);
c8e532
                 g_object_unref (task);
c8e532
                 return;
c8e532
         }
c8e532
 
c8e532
-        g_task_return_boolean (task, TRUE);
c8e532
+        watch_smartcards_from_driver_async (self,
c8e532
+                                            operation->driver,
c8e532
+                                            priv->cancellable,
c8e532
+                                            (GAsyncReadyCallback) on_smartcards_from_driver_watched,
c8e532
+                                            task);
c8e532
 
c8e532
+        g_task_return_boolean (task, TRUE);
c8e532
         g_object_unref (task);
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 on_smartcards_from_driver_watched (GsdSmartcardManager *self,
c8e532
                                    GAsyncResult        *result,
c8e532
                                    GTask               *task)
c8e532
 {
c8e532
         g_debug ("Done watching smartcards from driver");
c8e532
 }
c8e532
 
c8e532
-typedef struct {
c8e532
-        SECMODModule *driver;
c8e532
-        guint         idle_id;
c8e532
-        GError       *error;
c8e532
-} DriverRegistrationOperation;
c8e532
-
c8e532
 static void
c8e532
 destroy_driver_registration_operation (DriverRegistrationOperation *operation)
c8e532
 {
c8e532
         SECMOD_DestroyModule (operation->driver);
c8e532
         g_free (operation);
c8e532
 }
c8e532
 
c8e532
 static gboolean
c8e532
 on_task_thread_to_complete_driver_registration (GTask *task)
c8e532
 {
c8e532
         DriverRegistrationOperation *operation;
c8e532
         operation = g_task_get_task_data (task);
c8e532
 
c8e532
         if (operation->error != NULL)
c8e532
                 g_task_return_error (task, operation->error);
c8e532
         else
c8e532
                 g_task_return_boolean (task, TRUE);
c8e532
 
c8e532
         return G_SOURCE_REMOVE;
c8e532
 }
c8e532
 
c8e532
 static gboolean
c8e532
 on_main_thread_to_register_driver (GTask *task)
c8e532
 {
c8e532
         GsdSmartcardManager *self;
c8e532
         GsdSmartcardManagerPrivate *priv;
c8e532
         DriverRegistrationOperation *operation;
c8e532
         GSource *source;
c8e532
 
c8e532
         self = g_task_get_source_object (task);
c8e532
@@ -450,65 +492,60 @@ register_driver (GsdSmartcardManager *self,
c8e532
 
c8e532
         task = g_task_new (self, cancellable, callback, user_data);
c8e532
         operation = g_new0 (DriverRegistrationOperation, 1);
c8e532
         operation->driver = SECMOD_ReferenceModule (driver);
c8e532
         g_task_set_task_data (task,
c8e532
                               operation,
c8e532
                               (GDestroyNotify) destroy_driver_registration_operation);
c8e532
 
c8e532
         operation->idle_id = g_idle_add ((GSourceFunc) on_main_thread_to_register_driver, task);
c8e532
         g_source_set_name_by_id (operation->idle_id, "[gnome-settings-daemon] on_main_thread_to_register_driver");
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 activate_driver (GsdSmartcardManager *self,
c8e532
                  SECMODModule        *driver,
c8e532
                  GCancellable        *cancellable,
c8e532
                  GAsyncReadyCallback  callback,
c8e532
                  gpointer             user_data)
c8e532
 {
c8e532
         GTask *task;
c8e532
 
c8e532
         g_debug ("Activating driver '%s'", driver->commonName);
c8e532
 
c8e532
         task = g_task_new (self, cancellable, callback, user_data);
c8e532
 
c8e532
         register_driver (self,
c8e532
                          driver,
c8e532
                          cancellable,
c8e532
                          (GAsyncReadyCallback) on_driver_registered,
c8e532
                          task);
c8e532
-        watch_smartcards_from_driver_async (self,
c8e532
-                                            driver,
c8e532
-                                            cancellable,
c8e532
-                                            (GAsyncReadyCallback) on_smartcards_from_driver_watched,
c8e532
-                                            task);
c8e532
 }
c8e532
 
c8e532
 typedef struct
c8e532
 {
c8e532
   int pending_drivers_count;
c8e532
   int activated_drivers_count;
c8e532
 } ActivateAllDriversOperation;
c8e532
 
c8e532
 static gboolean
c8e532
 activate_driver_async_finish (GsdSmartcardManager  *self,
c8e532
                               GAsyncResult         *result,
c8e532
                               GError              **error)
c8e532
 {
c8e532
         return g_task_propagate_boolean (G_TASK (result), error);
c8e532
 }
c8e532
 
c8e532
 static void
c8e532
 try_to_complete_all_drivers_activation (GTask *task)
c8e532
 {
c8e532
         ActivateAllDriversOperation *operation;
c8e532
 
c8e532
         operation = g_task_get_task_data (task);
c8e532
 
c8e532
         if (operation->pending_drivers_count > 0)
c8e532
                 return;
c8e532
 
c8e532
         if (operation->activated_drivers_count > 0)
c8e532
                 g_task_return_boolean (task, TRUE);
c8e532
         else
c8e532
                 g_task_return_new_error (task, GSD_SMARTCARD_MANAGER_ERROR,
c8e532
-- 
c8e532
2.17.0
c8e532