|
|
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, ¶meters, 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 |
|