Blame SOURCES/0001-smartcard-use-NSS_InitContext-instead-of-NSS_Initial.patch

14e627
From 2273e9d04010d2c37c5995f8505c047ca1764232 Mon Sep 17 00:00:00 2001
14e627
From: Ray Strode <rstrode@redhat.com>
14e627
Date: Tue, 16 Jun 2015 09:45:46 -0400
14e627
Subject: [PATCH] smartcard: use NSS_InitContext instead of NSS_Initialize
14e627
14e627
NSS_Initialize is a noop if called multiple times.  We
14e627
currently call NSS_Initialize twice in gnome-settings-daemon.
14e627
Once by NMClient and once by the smartcard plugin.  NMClient
14e627
does it first, and it does it without initializing the secmod
14e627
database. When the smartcard plugin tries to initialize NSS
14e627
with the secmod database later, it's call is turned to a noop.
14e627
14e627
This commit changes the smartcard plugin to use NSS_InitContext
14e627
instead, which can properly handle being initialized multiple
14e627
times with different configurations.  See:
14e627
14e627
https://wiki.mozilla.org/NSS_Library_Init
14e627
14e627
https://bugzilla.gnome.org/show_bug.cgi?id=751040
14e627
---
14e627
 plugins/smartcard/gsd-smartcard-manager.c | 28 ++++++++++++++++++----------
14e627
 1 file changed, 18 insertions(+), 10 deletions(-)
14e627
14e627
diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c
14e627
index e81ace2..2564acd 100644
14e627
--- a/plugins/smartcard/gsd-smartcard-manager.c
14e627
+++ b/plugins/smartcard/gsd-smartcard-manager.c
14e627
@@ -27,147 +27,155 @@
14e627
 #include "gnome-settings-profile.h"
14e627
 #include "gnome-settings-bus.h"
14e627
 #include "gsd-smartcard-manager.h"
14e627
 #include "gsd-smartcard-service.h"
14e627
 #include "gsd-smartcard-enum-types.h"
14e627
 #include "gsd-smartcard-utils.h"
14e627
 
14e627
 #include <prerror.h>
14e627
 #include <prinit.h>
14e627
 #include <nss.h>
14e627
 #include <pk11func.h>
14e627
 #include <secmod.h>
14e627
 #include <secerr.h>
14e627
 
14e627
 #define GSD_SMARTCARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerPrivate))
14e627
 
14e627
 #define GSD_SESSION_MANAGER_LOGOUT_MODE_FORCE 2
14e627
 
14e627
 struct GsdSmartcardManagerPrivate
14e627
 {
14e627
         guint start_idle_id;
14e627
         GsdSmartcardService *service;
14e627
         GList *smartcards_watch_tasks;
14e627
         GCancellable *cancellable;
14e627
 
14e627
         GsdSessionManager *session_manager;
14e627
         GsdScreenSaver *screen_saver;
14e627
 
14e627
         GSettings *settings;
14e627
 
14e627
-        guint32 nss_is_loaded : 1;
14e627
+        NSSInitContext *nss_context;
14e627
 };
14e627
 
14e627
 #define CONF_SCHEMA "org.gnome.settings-daemon.peripherals.smartcard"
14e627
 #define KEY_REMOVE_ACTION "removal-action"
14e627
 
14e627
 static void     gsd_smartcard_manager_class_init  (GsdSmartcardManagerClass *klass);
14e627
 static void     gsd_smartcard_manager_init        (GsdSmartcardManager      *self);
14e627
 static void     gsd_smartcard_manager_finalize    (GObject                  *object);
14e627
 static void     lock_screen                       (GsdSmartcardManager *self);
14e627
 static void     log_out                           (GsdSmartcardManager *self);
14e627
 G_DEFINE_TYPE (GsdSmartcardManager, gsd_smartcard_manager, G_TYPE_OBJECT)
14e627
 G_DEFINE_QUARK (gsd-smartcard-manager-error, gsd_smartcard_manager_error)
14e627
 G_LOCK_DEFINE_STATIC (gsd_smartcards_watch_tasks);
14e627
 
14e627
 static gpointer manager_object = NULL;
14e627
 
14e627
 static void
14e627
 gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *klass)
14e627
 {
14e627
         GObjectClass   *object_class = G_OBJECT_CLASS (klass);
14e627
 
14e627
         object_class->finalize = gsd_smartcard_manager_finalize;
14e627
 
14e627
         gsd_smartcard_utils_register_error_domain (GSD_SMARTCARD_MANAGER_ERROR,
14e627
                                                    GSD_TYPE_SMARTCARD_MANAGER_ERROR);
14e627
         g_type_class_add_private (klass, sizeof (GsdSmartcardManagerPrivate));
14e627
 }
14e627
 
14e627
 static void
14e627
 gsd_smartcard_manager_init (GsdSmartcardManager *self)
14e627
 {
14e627
         self->priv = GSD_SMARTCARD_MANAGER_GET_PRIVATE (self);
14e627
 }
14e627
 
14e627
 static void
14e627
 load_nss (GsdSmartcardManager *self)
14e627
 {
14e627
         GsdSmartcardManagerPrivate *priv = self->priv;
14e627
-        SECStatus status = SECSuccess;
14e627
+        NSSInitContext *context = NULL;
14e627
+
14e627
+        /* The first field in the NSSInitParameters structure
14e627
+         * is the size of the structure. NSS requires this, so
14e627
+         * that it can change the size of the structure in future
14e627
+         * versions of NSS in a detectable way
14e627
+         */
14e627
+        NSSInitParameters parameters = { sizeof (parameters), };
14e627
         static const guint32 flags = NSS_INIT_READONLY
14e627
                                    | NSS_INIT_FORCEOPEN
14e627
                                    | NSS_INIT_NOROOTINIT
14e627
                                    | NSS_INIT_OPTIMIZESPACE
14e627
                                    | NSS_INIT_PK11RELOAD;
14e627
 
14e627
         g_debug ("attempting to load NSS database '%s'",
14e627
                  GSD_SMARTCARD_MANAGER_NSS_DB);
14e627
 
14e627
         PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
14e627
 
14e627
-        status = NSS_Initialize (GSD_SMARTCARD_MANAGER_NSS_DB,
14e627
-                                 "", "", SECMOD_DB, flags);
14e627
+        context = NSS_InitContext (GSD_SMARTCARD_MANAGER_NSS_DB,
14e627
+                                   "", "", SECMOD_DB, &parameters, flags);
14e627
 
14e627
-        if (status != SECSuccess) {
14e627
+        if (context == NULL) {
14e627
                 gsize error_message_size;
14e627
                 char *error_message;
14e627
 
14e627
                 error_message_size = PR_GetErrorTextLength ();
14e627
 
14e627
                 if (error_message_size == 0) {
14e627
                         g_debug ("NSS security system could not be initialized");
14e627
                 } else {
14e627
                         error_message = g_alloca (error_message_size);
14e627
                         PR_GetErrorText (error_message);
14e627
 
14e627
                         g_debug ("NSS security system could not be initialized - %s",
14e627
                                  error_message);
14e627
                 }
14e627
-                priv->nss_is_loaded = FALSE;
14e627
+
14e627
+                priv->nss_context = NULL;
14e627
                 return;
14e627
 
14e627
         }
14e627
 
14e627
         g_debug ("NSS database '%s' loaded", GSD_SMARTCARD_MANAGER_NSS_DB);
14e627
-        priv->nss_is_loaded = TRUE;
14e627
+        priv->nss_context = context;
14e627
 }
14e627
 
14e627
 static void
14e627
 unload_nss (GsdSmartcardManager *self)
14e627
 {
14e627
         g_debug ("attempting to unload NSS security system with database '%s'",
14e627
                  GSD_SMARTCARD_MANAGER_NSS_DB);
14e627
 
14e627
-        if (self->priv->nss_is_loaded) {
14e627
-                NSS_Shutdown ();
14e627
-                self->priv->nss_is_loaded = FALSE;
14e627
+        if (self->priv->nss_context != NULL) {
14e627
+                g_clear_pointer (&self->priv->nss_context,
14e627
+                                 NSS_ShutdownContext);
14e627
                 g_debug ("NSS database '%s' unloaded", GSD_SMARTCARD_MANAGER_NSS_DB);
14e627
         } else {
14e627
                 g_debug ("NSS database '%s' already not loaded", GSD_SMARTCARD_MANAGER_NSS_DB);
14e627
         }
14e627
 }
14e627
 
14e627
 typedef struct
14e627
 {
14e627
         SECMODModule *driver;
14e627
         GHashTable *smartcards;
14e627
         int number_of_consecutive_errors;
14e627
 } WatchSmartcardsOperation;
14e627
 
14e627
 static void
14e627
 on_watch_cancelled (GCancellable             *cancellable,
14e627
                     WatchSmartcardsOperation *operation)
14e627
 {
14e627
         SECMOD_CancelWait (operation->driver);
14e627
 }
14e627
 
14e627
 static gboolean
14e627
 watch_one_event_from_driver (GsdSmartcardManager       *self,
14e627
                              WatchSmartcardsOperation  *operation,
14e627
                              GCancellable              *cancellable,
14e627
                              GError                   **error)
14e627
 {
14e627
         GsdSmartcardManagerPrivate *priv = self->priv;
14e627
         PK11SlotInfo *card, *old_card;
14e627
         CK_SLOT_ID slot_id;
14e627
         gulong handler_id;
14e627
-- 
14e627
2.5.0
14e627