rpms/gdm/devel gdm-2.15.6-security-tokens.patch,1.1,1.2
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Tue Jul 18 05:59:40 UTC 2006
- Previous message (by thread): rpms/gdm/devel gdm-2.15.6-security-tokens.patch, NONE, 1.1 gdm.spec, 1.176, 1.177 gdm-2.15.5-security-tokens.patch, 1.4, NONE
- Next message (by thread): rpms/imake/devel xorg-cf-files-1.0.2-redhat.patch, NONE, 1.1 xorg-cf-files-1.0.2-xprint.patch, NONE, 1.1 .cvsignore, 1.6, 1.7 imake.spec, 1.26, 1.27 sources, 1.5, 1.6 xorg-cf-files-1.0.1-redhat.patch, 1.2, NONE xorg-cf-files-1.0.1-xprint.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: rstrode
Update of /cvs/dist/rpms/gdm/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv11971
Modified Files:
gdm-2.15.6-security-tokens.patch
Log Message:
add forgotton file to patch
gdm-2.15.6-security-tokens.patch:
config/Makefile.am | 35 +
config/gdm | 16
config/gdm-securitytokens | 10
config/gdm.conf.in | 7
config/securitytokens.conf.in | 4
configure.ac | 3
daemon/Makefile.am | 7
daemon/gdm.c | 148 +++++++
daemon/gdm.h | 5
daemon/gdmconfig.c | 26 +
daemon/gdmconfig.h | 3
daemon/securitytoken.c | 602 ++++++++++++++++++++++++++++++
daemon/securitytoken.h | 101 +++++
daemon/securitytokenmonitor.c | 840 ++++++++++++++++++++++++++++++++++++++++++
daemon/securitytokenmonitor.h | 81 ++++
daemon/verify-pam.c | 5
16 files changed, 1880 insertions(+), 13 deletions(-)
Index: gdm-2.15.6-security-tokens.patch
===================================================================
RCS file: /cvs/dist/rpms/gdm/devel/gdm-2.15.6-security-tokens.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- gdm-2.15.6-security-tokens.patch 18 Jul 2006 05:46:11 -0000 1.1
+++ gdm-2.15.6-security-tokens.patch 18 Jul 2006 05:59:38 -0000 1.2
@@ -2106,1787 +2106,11 @@
if ( ! create_pamh (d, pam_stack, login, &pamc, display, &pamerr)) {
if (started_timer)
gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
-deleted file mode 100644
--- /dev/null
-+++ gdm-2.15.6/utils/gdmsecuritytokenmonitor.c
-@@ -0,0 +1,197 @@
-+/* GDM Security Token monitor
-+ * Copyright (C) 2006 Ray Strode <rstrode at redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+#include "config.h"
-+
-+#include <locale.h>
-+#include <syslog.h>
-+
-+#include <glib.h>
-+#include <glib/gi18n.h>
-+
-+#include "securitytokenmonitor.h"
-+
-+static gchar *pkcs11_module;
-+static GOptionEntry options[] = {
-+ {
-+ "pkcs11-module", 0, 0, G_OPTION_ARG_STRING, &pkcs11_module,
-+ N_("PKCS#11 driver for security token"),
-+ N_("MODULE")
-+ },
-+ { NULL }
-+};
-+
-+static typedef struct
-+{
-+ ScSecurityMonitor *monitor;
-+ GMainLoop *event_loop;
-+} Daemon;
-+
-+static Daemon *daemon_new (void);
-+static void daemon_free (Monitor *monitor);
-+
-+static void gdm_handle_security_token_insertion (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token);
-+static void gdm_handle_security_token_removal (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token);
-+static void gdm_watch_for_security_tokens (const gchar *driver);
-+
-+static Daemon *
-+daemon_new (const gchar *driver)
-+{
-+ Daemon *daemon;
-+
-+
-+ daemon = g_slice_new0 (Daemon);
-+ daemon->event_loop = g_main_loop_new (NULL, FALSE);
-+
-+ return daemon;
-+}
-+
-+static gboolean
-+daemon_run (Daemon *daemon)
-+{
-+ pid_t pid;
-+ pid = fork ();
-+
-+ if (pid < 0)
-+ return FALSE;
-+
-+ if (pid != 0) {
-+ gint status;
-+
-+ waitpid (pid, &status, 0);
-+ _exit (status);
-+ }
-+
-+ daemon ();
-+
-+ gdm_watch_for_security_tokens (pkcs11_module);
-+ g_main_loop_run (daemon->event_loop);
-+
-+ return TRUE;
-+}
-+
-+static void
-+monitor_free (Monitor *monitor)
-+{
-+ if (daemon->loop != NULL) {
-+ g_main_loop_unref (daemon->loop);
-+ daemon->loop = NULL;
-+ }
-+ g_slice_free1 (Monitor, monitor);
-+}
-+
-+static void
-+gdm_handle_security_token_insertion (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token)
-+{
-+ GSList *li;
-+
-+ g_debug ("notifying local displays about token insertion");
-+#if 0
-+ for (li = displays; li != NULL; li = li->next) {
-+ GdmDisplay *d = li->data;
-+
-+ if (SERVER_IS_LOCAL (d)) {
-+ g_debug ("notifying display '%s'", d->name);
-+ send_slave_command (d, GDM_NOTIFY_RESET);
-+ } else {
-+ g_debug ("display '%s' is not local", d->name);
-+ }
-+ }
-+#endif
-+}
-+
-+static void
-+gdm_handle_security_token_removal (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token)
-+{
-+ GSList *li;
-+
-+ g_debug ("notifying local displays about token removal");
-+#if 0
-+ for (li = displays; li != NULL; li = li->next) {
-+ GdmDisplay *d = li->data;
-+
-+ if (SERVER_IS_LOCAL (d)) {
-+ g_debug ("notifying display '%s'", d->name);
-+ send_slave_command (d, GDM_NOTIFY_RESET);
-+ } else {
-+ g_debug ("display '%s' is not local", d->name);
-+ }
-+ }
-+#endif
-+}
-+
-+static void
-+gdm_watch_for_security_tokens (const gchar *driver)
-+{
-+ GError *error;
-+ ScSecurityTokenMonitor *monitor;
-+
-+ g_debug ("watching for security token insertion and removal events");
-+
-+ monitor = sc_security_token_monitor_new (driver);
-+ g_signal_connect (monitor,
-+ "security-token-inserted",
-+ G_CALLBACK (gdm_handle_security_token_insertion), NULL);
-+
-+ g_signal_connect (monitor,
-+ "security-token-removed",
-+ G_CALLBACK (gdm_handle_security_token_removal), NULL);
-+ error = NULL;
-+ if (!sc_security_token_monitor_start (monitor,
-+ &error)) {
-+ if (error != NULL) {
-+ syslog (LOG_ERR, "%s", error->message);
-+ g_error_free (error);
-+ } else {
-+ syslog (LOG_ERR, "could not start security token monitor");
-+
-+ }
-+ }
-+}
-+
-+gint
-+main (gint argc,
-+ gchar **argv)
-+{
-+ Daemon *daemon;
-+ GOptionContext *options_context;
-+
-+ setlocale (LC_ALL, "");
-+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
-+ textdomain (GETTEXT_PACKAGE);
-+
-+ g_type_init ();
-+
-+ options_context = g_option_context_new (_("- helps gdm monitor for security "
-+ "token insertion and deletion events"));
-+ g_option_context_add_main_entries (options_context, options, GETTEXT_PACKAGE);
-+ g_option_context_parse (options_context, &argc, &argv, NULL);
-+ g_option_context_free (options_context);
-+
-+ openlog ("gdm[security-token-monitor]", 0, LOG_DAEMON);
-+ daemon = daemon_new ();
-+
-+ if (!daemon_run ())
-+ return 1;
-+
-+ daemon_free (daemon);
-+ return 0;
-+}
---- /dev/null
-+++ gdm-2.15.6/utils/securitytoken.c
-@@ -0,0 +1,573 @@
-+/* securitytoken.c - security token
-+ *
-+ * Copyright (C) 2006 Ray Strode <rstrode at redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-+ * 02111-1307, USA.
-+ *
-+ * TODO: - doing this per project is a bad idea i think.
-+ * We should probably make this a system service
-+ * and use dbus.
-+ *
-+ * - We hardcode a driver right now. We should probably
-+ * look up the default list and go from there.
-+ */
-+#define SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
-+#include "securitytoken.h"
-+
-+#include <errno.h>
-+#include <string.h>
-+#include <unistd.h>
-+
-+#include <glib.h>
-+#include <glib/gi18n.h>
-+
-+#include <cert.h>
-+#include <nss.h>
-+#include <pk11func.h>
-+#include <prerror.h>
-+#include <secmod.h>
-+#include <secerr.h>
-+
-+/* wtf
-+ */
-+#include "/tmp/certhtml.c"
-+
-+#if defined (SC_SECURITY_TOKEN_ENABLE_TEST) || defined (SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST)
-+#define sc_debug(format, args...) g_printerr (format "\n", ##args)
-+#define sc_warning(format, args...) g_printerr (format "\n", ##args)
-+#else
-+#define sc_debug(format, args...)
-+#define sc_warning(format, args...)
-+#endif
-+
-+struct _ScSecurityTokenPrivate {
-+ SECMODModule *module;
-+ ScSecurityTokenState state;
-+
-+ CK_SLOT_ID slot_id;
-+ gint slot_series;
-+
-+ PK11SlotInfo *slot;
-+
-+ CERTCertificate *signing_certificate;
-+ CERTCertificate *encryption_certificate;
-+};
-+
-+static void sc_security_token_finalize (GObject *object);
-+static void sc_security_token_class_install_signals (ScSecurityTokenClass *token_class);
-+static void sc_security_token_class_install_properties (ScSecurityTokenClass *token_class);
-+static void sc_security_token_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec);
-+static void sc_security_token_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec);
-+
-+static void sc_security_token_set_slot_id (ScSecurityToken *token,
-+ gint slot_id);
-+static void sc_security_token_set_slot_series (ScSecurityToken *token,
-+ gint slot_series);
-+static void sc_security_token_set_module (ScSecurityToken *token,
-+ SECMODModule *module);
-+
-+static PK11SlotInfo *sc_security_token_find_slot_from_id (ScSecurityToken *token,
-+ gint slot_id);
-+static gboolean sc_security_token_fetch_certificates (ScSecurityToken *token);
-+
-+
-+#ifndef SC_SECURITY_TOKEN_DEFAULT_SLOT_ID
-+#define SC_SECURITY_TOKEN_DEFAULT_SLOT_ID ((gulong) -1)
-+#endif
-+
-+#ifndef SC_SECURITY_TOKEN_DEFAULT_SLOT_SERIES
-+#define SC_SECURITY_TOKEN_DEFAULT_SLOT_SERIES -1
-+#endif
-+
-+enum {
-+ PROP_0 = 0,
-+ PROP_SLOT_ID,
-+ PROP_SLOT_SERIES,
-+ PROP_MODULE,
-+ NUMBER_OF_PROPERTIES
-+};
-+
-+enum {
-+ INSERTED,
-+ REMOVED,
-+ NUMBER_OF_SIGNALS
-+};
-+
-+static guint sc_security_token_signals[NUMBER_OF_SIGNALS];
-+
-+G_DEFINE_TYPE (ScSecurityToken, sc_security_token, G_TYPE_OBJECT);
-+
-+static void
-+sc_security_token_class_init (ScSecurityTokenClass *token_class)
-+{
-+ GObjectClass *gobject_class;
-+
-+ gobject_class = G_OBJECT_CLASS (token_class);
-+
-+ gobject_class->finalize = sc_security_token_finalize;
-+
-+ sc_security_token_class_install_signals (token_class);
-+ sc_security_token_class_install_properties (token_class);
-+
-+ g_type_class_add_private (token_class,
-+ sizeof (ScSecurityTokenPrivate));
-+}
-+
-+static void
-+sc_security_token_class_install_signals (ScSecurityTokenClass *token_class)
-+{
-+ GObjectClass *object_class;
-+
-+ object_class = G_OBJECT_CLASS (token_class);
-+
-+ sc_security_token_signals[INSERTED] =
-+ g_signal_new ("inserted",
-+ G_OBJECT_CLASS_TYPE (object_class),
-+ G_SIGNAL_RUN_LAST,
-+ G_STRUCT_OFFSET (ScSecurityTokenClass,
-+ inserted),
-+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
-+ G_TYPE_NONE, 0);
-+ token_class->inserted = NULL;
-+
-+ sc_security_token_signals[REMOVED] =
-+ g_signal_new ("removed",
-+ G_OBJECT_CLASS_TYPE (object_class),
-+ G_SIGNAL_RUN_LAST,
-+ G_STRUCT_OFFSET (ScSecurityTokenClass,
-+ removed),
-+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
-+ G_TYPE_NONE, 0);
-+ token_class->removed = NULL;
-+}
-+
-+static void
-+sc_security_token_class_install_properties (ScSecurityTokenClass *token_class)
-+{
-+ GObjectClass *object_class;
-+ GParamSpec *param_spec;
-+
-+ object_class = G_OBJECT_CLASS (token_class);
-+ object_class->set_property = sc_security_token_set_property;
-+ object_class->get_property = sc_security_token_get_property;
-+
-+ param_spec = g_param_spec_ulong ("slot-id", _("Slot ID"),
-+ _("The slot the token is in"),
-+ 1, G_MAXULONG,
-+ SC_SECURITY_TOKEN_DEFAULT_SLOT_ID,
-+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-+ g_object_class_install_property (object_class, PROP_SLOT_ID, param_spec);
-+
-+ param_spec = g_param_spec_int ("slot-series", _("Slot Series"),
-+ _("per-slot token identifier"),
-+ -1, G_MAXINT,
-+ SC_SECURITY_TOKEN_DEFAULT_SLOT_SERIES,
-+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-+ g_object_class_install_property (object_class, PROP_SLOT_SERIES, param_spec);
-+
-+ /* FIXME: maybe make this a boxed type?
-+ */
-+ param_spec = g_param_spec_pointer ("module", _("Module"),
-+ _("security token driver"),
-+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
-+ g_object_class_install_property (object_class, PROP_MODULE, param_spec);
-+}
-+
-+static void
-+sc_security_token_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
-+{
-+ ScSecurityToken *token = SC_SECURITY_TOKEN (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_SLOT_ID:
-+ sc_security_token_set_slot_id (token,
-+ g_value_get_ulong (value));
-+ break;
-+
-+ case PROP_SLOT_SERIES:
-+ sc_security_token_set_slot_series (token,
-+ g_value_get_int (value));
-+ break;
-+
-+ case PROP_MODULE:
-+ sc_security_token_set_module (token,
-+ (SECMODModule *)
-+ g_value_get_pointer (value));
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ }
-+}
-+
-+CK_SLOT_ID
-+sc_security_token_get_slot_id (ScSecurityToken *token)
-+{
-+ return token->priv->slot_id;
-+}
-+
-+static void
-+sc_security_token_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec)
-+{
-+ ScSecurityToken *token = SC_SECURITY_TOKEN (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_SLOT_ID:
-+ g_value_set_ulong (value,
-+ (gulong) sc_security_token_get_slot_id (token));
-+ break;
-+
-+ case PROP_SLOT_SERIES:
-+ g_value_set_int (value,
-+ sc_security_token_get_slot_series (token));
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ }
-+}
-+
-+void
-+sc_security_token_set_slot_id (ScSecurityToken *token,
-+ gint slot_id)
-+{
-+ if (token->priv->slot_id != slot_id)
-+ {
-+ token->priv->slot_id = slot_id;
-+
-+ token->priv->slot = sc_security_token_find_slot_from_id (token,
-+ token->priv->slot_id);
-+
-+ g_object_notify (G_OBJECT (token), "slot-id");
-+ }
-+}
-+
-+void
-+sc_security_token_set_slot_series (ScSecurityToken *token,
-+ gint slot_series)
-+{
-+ if (token->priv->slot_series != slot_series)
-+ {
-+ token->priv->slot_series = slot_series;
-+ g_object_notify (G_OBJECT (token), "slot-series");
-+ }
-+}
-+
-+static void
-+sc_security_token_set_module (ScSecurityToken *token,
-+ SECMODModule *module)
-+{
-+ gboolean should_notify;
-+
-+ if (token->priv->module != module)
-+ should_notify = TRUE;
-+ else
-+ should_notify = FALSE;
-+
-+ if (token->priv->module != NULL) {
-+ SECMOD_DestroyModule (token->priv->module);
-+ token->priv->module = NULL;
-+ }
-+
-+ if (module != NULL)
-+ token->priv->module = SECMOD_ReferenceModule (module);
-+
-+ if (should_notify)
-+ g_object_notify (G_OBJECT (token), "module");
-+}
-+
-+gint
-+sc_security_token_get_slot_series (ScSecurityToken *token)
-+{
-+ return token->priv->slot_series;
-+}
-+
-+static void
-+sc_security_token_init (ScSecurityToken *token)
-+{
-+
-+ sc_debug ("initializing security token ");
-+
-+ token->priv = G_TYPE_INSTANCE_GET_PRIVATE (token,
-+ SC_TYPE_SECURITY_TOKEN,
-+ ScSecurityTokenPrivate);
-+}
-+
-+static void sc_security_token_finalize (GObject *object)
-+{
-+ ScSecurityToken *token;
-+ GObjectClass *gobject_class;
-+
-+ token = SC_SECURITY_TOKEN (object);
-+
-+ sc_security_token_set_module (token, NULL);
-+
-+ gobject_class =
-+ G_OBJECT_CLASS (sc_security_token_parent_class);
-+
-+ gobject_class->finalize (object);
-+}
-+
-+GQuark sc_security_token_error_quark (void)
-+{
-+ static GQuark error_quark = 0;
-+
-+ if (error_quark == 0)
-+ error_quark = g_quark_from_static_string ("sc-security-token-error-quark");
-+
-+ return error_quark;
-+}
-+
-+ScSecurityToken *
-+_sc_security_token_new (SECMODModule *module,
-+ CK_SLOT_ID slot_id,
-+ gint slot_series)
-+{
-+ ScSecurityToken *token;
-+
-+ g_return_val_if_fail (module != NULL, NULL);
-+ g_return_val_if_fail (slot_id >= 1, NULL);
-+ g_return_val_if_fail (slot_series > 0, NULL);
-+ g_return_val_if_fail (sizeof (gulong) == sizeof (slot_id), NULL);
-+
-+ token = SC_SECURITY_TOKEN (g_object_new (SC_TYPE_SECURITY_TOKEN,
-+ "module", module,
-+ "slot-id", (gulong) slot_id,
-+ "slot-series", slot_series,
-+ NULL));
-+ return token;
-+}
-+
-+void
-+_sc_security_token_set_state (ScSecurityToken *token,
-+ ScSecurityTokenState state)
-+{
-+ sc_security_token_fetch_certificates (token);
-+ if (token->priv->state != state)
-+ {
-+ token->priv->state = state;
-+
-+ if (state == SC_SECURITY_TOKEN_STATE_INSERTED) {
-+ g_signal_emit (token, sc_security_token_signals[INSERTED], 0);
-+ } else if (state == SC_SECURITY_TOKEN_STATE_REMOVED)
-+ g_signal_emit (token, sc_security_token_signals[REMOVED], 0);
-+ else
-+ g_assert_not_reached ();
-+ }
-+}
-+
-+/* So we could conceivably make the closure data a pointer to the token
-+ * or something similiar and then emit signals when we want passwords,
-+ * but it's probably easier to just get the password up front and use
-+ * it. So we just take the passed in g_malloc'd (well probably, who knows)
-+ * and strdup it using NSPR's memory allocation routines.
-+ */
-+static char *
-+sc_security_token_password_handler (PK11SlotInfo *slot,
-+ PRBool is_retrying,
-+ const gchar *password)
-+{
-+ if (is_retrying)
-+ return NULL;
-+
-+ return password != NULL? PL_strdup (password): NULL;
-+}
-+
-+gboolean
-+sc_security_token_unlock (ScSecurityToken *token,
-+ const gchar *password)
-+{
-+ SECStatus status;
-+
-+ PK11_SetPasswordFunc ((PK11PasswordFunc) sc_security_token_password_handler);
-+
-+ /* we pass PR_TRUE to load certificates
-+ */
-+ status = PK11_Authenticate (token->priv->slot, PR_TRUE, (gpointer) password);
-+
-+ if (status != SECSuccess) {
-+ sc_debug ("could not unlock token - %d", status);
-+ return FALSE;
-+ }
-+ return TRUE;
-+}
-+
-+static PK11SlotInfo *
-+sc_security_token_find_slot_from_id (ScSecurityToken *token,
-+ gint slot_id)
-+{
-+ int i;
-+
-+ for (i = 0; i < token->priv->module->slotCount; i++)
-+ if (PK11_GetSlotID (token->priv->module->slots[i]) == slot_id)
-+ return token->priv->module->slots[i];
-+
-+ return NULL;
-+}
-+
-+static gboolean
-+sc_security_token_fetch_certificates (ScSecurityToken *token)
-+{
-+ PK11SlotInfo *slot;
-+ CERTCertList *certificates;
-+ CERTCertListNode *node;
-+ SECStatus status;
-+ int i;
-+
-+ sc_security_token_unlock (token, "0000");
-+
-+ sc_debug ("fetching certificates for token in slot %lu",
-+ token->priv->slot_id);
-+
-+ slot = sc_security_token_find_slot_from_id (token,
-+ token->priv->slot_id);
-+
-+ g_assert (PK11_GetSlotID (slot) == token->priv->slot_id);
-+
-+ if (i == token->priv->module->slotCount) {
-+ sc_debug ("could not find slot %lu", token->priv->slot_id);
-+ return FALSE;
-+ }
-+
-+ certificates = PK11_ListCertsInSlot (slot);
-+
-+ sc_debug ("filtering out non-user certificates");
-+ if (CERT_FilterCertListForUserCerts (certificates) != SECSuccess) {
-+ CERT_DestroyCertList (certificates);
-+ sc_debug ("could not filter out non-user certificates");
-+ return FALSE;
-+ }
-+
-+ for (node = CERT_LIST_HEAD (certificates);
-+ !CERT_LIST_END (node, certificates);
-+ node = CERT_LIST_NEXT(node)) {
-+
-+ SECCertificateUsage cert_usages;
-+
-+ sc_debug ("verifying certificate for use");
-+ status = CERT_VerifyCertificateNow (NULL, node->cert, TRUE,
-+ 0, NULL, &cert_usages);
-+
-+ if (status != SECSuccess) {
-+ sc_debug ("could not be verified, skipping...");
-+ continue;
-+ }
-+
-+ sc_debug ("got cert with usages 0x%x", cert_usages);
-+
-+ if (token->priv->encryption_certificate == NULL) {
-+
-+ sc_debug ("checking if certificate can be used for data "
-+ "encryption");
-+ status = CERT_CheckCertUsage (node->cert,
-+ KU_DATA_ENCIPHERMENT);
-+
-+ if (status == SECSuccess) {
-+ token->priv->encryption_certificate =
-+ CERT_DupCertificate (node->cert);
-+ sc_debug ("using encryption certificate:\n%s",
-+ CERT_HTMLCertInfo (node->cert, PR_FALSE, PR_TRUE));
-+ } else {
-+ sc_debug ("certificate can not be used for encryption");
-+ }
-+ }
-+
-+ if (token->priv->signing_certificate == NULL) {
-+
-+ sc_debug ("checking if certificate can be used for data "
-+ "signing");
-+ status = CERT_CheckCertUsage (node->cert,
-+ KU_DIGITAL_SIGNATURE);
-+
-+ if (status == SECSuccess) {
-+ token->priv->signing_certificate =
-+ CERT_DupCertificate (node->cert);
-+
-+ sc_debug ("using signing certificate:\n%s",
-+ CERT_HTMLCertInfo (node->cert, PR_FALSE, PR_TRUE));
-+ } else {
-+ sc_debug ("certificate can not be used for signing things");
-+ }
-+ }
-+ }
-+ return TRUE;
-+}
-+
-+ScSecurityTokenRequest *
-+sc_security_token_upload_data (ScSecurityToken *token,
-+ const gchar *key,
-+ const gchar *data)
-+{
-+ return NULL;
-+}
-+
-+ScSecurityTokenRequest *
-+sc_security_token_download_data (ScSecurityToken *token,
-+ const gchar *key)
-+{
-+ return NULL;
-+}
-+
-+ScSecurityTokenRequest *
-+sc_security_token_delete_data (ScSecurityToken *token,
-+ const gchar *key)
-+{
-+ return NULL;
-+}
-+
-+#ifdef SC_SECURITY_TOKEN_ENABLE_TEST
-+#include <glib.h>
-+
-+static GMainLoop *event_loop;
-+
-+int
-+main (int argc,
-+ char *argv[])
-+{
-+ ScSecurityToken *token;
-+ GError *error;
-+
-+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR
-+ | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
-+
-+ g_type_init ();
-+
-+ g_message ("creating instance of 'security token' object...");
-+ token = _sc_security_token_new (NULL, 1, 1);
-+ g_message ("'security token' object created successfully");
-+
-+ g_message ("destroying previously created 'security token' object...");
-+ g_object_unref (token);
-+ token = NULL;
-+ g_message ("'security token' object destroyed successfully");
-+
-+ return 0;
-+}
-+#endif
---- /dev/null
-+++ gdm-2.15.6/utils/securitytoken.h
-@@ -0,0 +1,97 @@
-+/* securitytoken.h - api for reading and writing data to a security token
-+ *
-+ * Copyright (C) 2006 Ray Strode
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-+ * 02111-1307, USA.
-+ */
-+#ifndef SC_SECURITY_TOKEN_H
-+#define SC_SECURITY_TOKEN_H
-+
-+#include <glib.h>
-+#include <glib-object.h>
-+
-+#include <secmod.h>
-+
-+G_BEGIN_DECLS
-+#define SC_TYPE_SECURITY_TOKEN (sc_security_token_get_type ())
-+#define SC_SECURITY_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_SECURITY_TOKEN, ScSecurityToken))
-+#define SC_SECURITY_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_SECURITY_TOKEN, ScSecurityTokenClass))
-+#define SC_IS_SECURITY_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SECURITY_TOKEN))
-+#define SC_IS_SECURITY_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SECURITY_TOKEN))
-+#define SC_SECURITY_TOKEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SC_TYPE_SECURITY_TOKEN, ScSecurityTokenClass))
-+#define SC_SECURITY_TOKEN_ERROR (sc_security_token_error_quark ())
-+typedef struct _ScSecurityTokenClass ScSecurityTokenClass;
-+typedef struct _ScSecurityToken ScSecurityToken;
-+typedef struct _ScSecurityTokenPrivate ScSecurityTokenPrivate;
-+typedef enum _ScSecurityTokenError ScSecurityTokenError;
-+typedef enum _ScSecurityTokenState ScSecurityTokenState;
-+
-+typedef struct _ScSecurityTokenRequest ScSecurityTokenRequest;
-+
-+struct _ScSecurityToken {
-+ GObject parent;
-+
-+ /*< private > */
-+ ScSecurityTokenPrivate *priv;
-+};
-+
-+struct _ScSecurityTokenClass {
-+ GObjectClass parent_class;
-+
-+ void (* inserted) (ScSecurityToken *token);
-+ void (* removed) (ScSecurityToken *token);
-+};
-+
-+enum _ScSecurityTokenError {
-+ SC_SECURITY_TOKEN_ERROR_GENERIC = 0,
-+};
-+
-+enum _ScSecurityTokenState {
-+ SC_SECURITY_TOKEN_STATE_INSERTED = 0,
-+ SC_SECURITY_TOKEN_STATE_REMOVED,
-+};
-+
-+GType sc_security_token_get_type (void) G_GNUC_CONST;
-+GQuark sc_security_token_error_quark (void) G_GNUC_CONST;
-+
-+CK_SLOT_ID sc_security_token_get_slot_id (ScSecurityToken *token);
-+gint sc_security_token_get_slot_series (ScSecurityToken *token);
-+
-+gboolean sc_security_token_unlock (ScSecurityToken *token,
-+ const gchar *password);
-+
-+ScSecurityTokenRequest *sc_security_token_upload_data (ScSecurityToken *token,
-+ const gchar *key,
-+ const gchar *data);
-+
-+ScSecurityTokenRequest *sc_security_token_download_data (ScSecurityToken *token,
-+ const gchar *key);
-+
-+ScSecurityTokenRequest *sc_security_token_delete_data (ScSecurityToken *token,
-+ const gchar *key);
-+
-+/* don't under any circumstances call these functions */
-+#ifdef SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
-+
-+ScSecurityToken *_sc_security_token_new (SECMODModule *module,
-+ CK_SLOT_ID slot_id,
-+ gint slot_series);
-+void _sc_security_token_set_state (ScSecurityToken *token,
-+ ScSecurityTokenState state);
-+#endif
-+
-+G_END_DECLS
-+#endif /* SC_SECURITY_TOKEN_H */
---- /dev/null
-+++ gdm-2.15.6/utils/securitytokenmonitor.c
-@@ -0,0 +1,819 @@
-+/* securitytokenmonitor.c - monitor for security token insertion and
-+ * removal events
-+ *
-+ * Copyright (C) 2006 Ray Strode <rstrode at redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-+ * 02111-1307, USA.
-+ *
-+ * TODO: - doing this per project is a bad idea i think.
-+ * We should probably make this a system service
-+ * and use dbus.
-+ *
-+ * - We hardcode a driver right now. We should probably
-+ * look up the default list and go from there.
-+ */
-+#include "securitytokenmonitor.h"
-+
-+#define SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
-+#include "securitytoken.h"
-+
-+#include <errno.h>
-+#include <string.h>
-+#include <unistd.h>
-+
-+#include <glib.h>
-+#include <glib/gi18n.h>
-+
-+#include <prerror.h>
-+#include <nss.h>
-+#include <pk11func.h>
-+#include <secmod.h>
-+#include <secerr.h>
-+
-+#include "marshal.h"
-+
-+#ifndef SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST
-+#include "misc.h"
-+#endif
-+
-+#ifndef SC_SECURITY_TOKEN_MONITOR_DRIVER
-+#define SC_SECURITY_TOKEN_MONITOR_DRIVER LIBDIR"/pkcs11/libcoolkeypk11.so"
-+#endif
-+
-+#ifndef SC_SECURITY_TOKEN_MONITOR_NSS_DB
-+#define SC_SECURITY_TOKEN_MONITOR_NSS_DB SYSCONFDIR"/pki/nssdb"
-+#endif
-+
-+#ifndef SC_SECURITY_TOKEN_MONITOR_POLL_INTERVAL
-+#define SC_SECURITY_TOKEN_MONITOR_POLL_INTERVAL 100 /* ms */
-+#endif
-+
-+#ifndef sc_debug
-+#ifdef gdm_debug
-+#define sc_debug(fmt, args...) gdm_debug(fmt, ##args)
-+#elif defined (SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST)
-+#define sc_debug(fmt, args...) g_printerr(fmt "\n", ##args)
-+#else
-+#define sc_debug(fmt, args...)
-+#endif
-+#endif
-+
-+typedef enum _ScSecurityTokenMonitorState ScSecurityTokenMonitorState;
-+
-+enum _ScSecurityTokenMonitorState {
-+ SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED = 0,
-+ SC_SECURITY_TOKEN_MONITOR_STATE_STARTING,
-+ SC_SECURITY_TOKEN_MONITOR_STATE_STARTED,
-+ SC_SECURITY_TOKEN_MONITOR_STATE_STOPPING,
-+};
-+
-+struct _ScSecurityTokenMonitorPrivate {
-+ ScSecurityTokenMonitorState state;
-+
-+ gchar *module_path;
-+ SECMODModule *module;
-+ GHashTable *security_tokens;
-+
-+ guint32 nss_is_loaded : 1;
-+ guint32 is_unstoppable : 1;
-+
-+ guint poll_timeout_id;
-+};
-+
-+static void sc_security_token_monitor_finalize (GObject *object);
-+static void sc_security_token_monitor_class_install_signals (ScSecurityTokenMonitorClass *service_class);
-+static void sc_security_token_monitor_class_install_properties (ScSecurityTokenMonitorClass *service_class);
-+static void sc_security_token_monitor_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec);
-+static void sc_security_token_monitor_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec);
-+
-+static void
-+sc_security_token_monitor_set_module_path (ScSecurityTokenMonitor *monitor,
-+ const gchar *module_path);
-+
-+
-+static void sc_security_token_monitor_token_removed_handler (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token);
-+static void sc_security_token_monitor_token_inserted_handler (ScSecurityTokenMonitor *monitor_class,
-+ ScSecurityToken *token);
-+static gboolean sc_security_token_monitor_stop_now (ScSecurityTokenMonitor *monitor);
-+
-+static void sc_security_token_monitor_queue_stop (ScSecurityTokenMonitor *monitor);
-+
-+enum {
-+ PROP_0 = 0,
-+ PROP_MODULE_PATH,
-+ NUMBER_OF_PROPERTIES
-+};
-+
-+enum {
-+ SECURITY_TOKEN_INSERTED = 0,
-+ SECURITY_TOKEN_REMOVED,
-+ ERROR,
-+ NUMBER_OF_SIGNALS
-+};
-+
-+static guint sc_security_token_monitor_signals[NUMBER_OF_SIGNALS];
-+
-+G_DEFINE_TYPE (ScSecurityTokenMonitor,
-+ sc_security_token_monitor,
-+ G_TYPE_OBJECT);
-+
-+static void
-+sc_security_token_monitor_class_init (ScSecurityTokenMonitorClass *monitor_class)
-+{
-+ GObjectClass *gobject_class;
-+
-+ gobject_class = G_OBJECT_CLASS (monitor_class);
-+
-+ gobject_class->finalize = sc_security_token_monitor_finalize;
-+
-+ sc_security_token_monitor_class_install_signals (monitor_class);
-+ sc_security_token_monitor_class_install_properties (monitor_class);
-+
-+ g_type_class_add_private (monitor_class,
-+ sizeof (ScSecurityTokenMonitorPrivate));
-+}
-+
-+static void
-+sc_security_token_monitor_class_install_properties (ScSecurityTokenMonitorClass *token_class)
-+{
-+ GObjectClass *object_class;
-+ GParamSpec *param_spec;
-+
-+ object_class = G_OBJECT_CLASS (token_class);
-+ object_class->set_property = sc_security_token_monitor_set_property;
-+ object_class->get_property = sc_security_token_monitor_get_property;
-+
-+ param_spec = g_param_spec_string ("module-path", _("Module Path"),
-+ _("path to security token PKCS #11 driver"),
-+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-+ g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec);
-+}
-+
-+static void
-+sc_security_token_monitor_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
-+{
-+ ScSecurityTokenMonitor *monitor = SC_SECURITY_TOKEN_MONITOR (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_MODULE_PATH:
-+ sc_security_token_monitor_set_module_path (monitor,
-+ g_value_get_string (value));
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ }
-+}
-+
-+static void
-+sc_security_token_monitor_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec)
-+{
-+ ScSecurityTokenMonitor *monitor = SC_SECURITY_TOKEN_MONITOR (object);
-+ gchar *module_path;
-+
-+ switch (prop_id)
-+ {
-+ case PROP_MODULE_PATH:
-+ module_path = sc_security_token_monitor_get_module_path (monitor);
-+ g_value_set_string (value, module_path);
-+ g_free (module_path);
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ }
-+}
-+
-+gchar *
-+sc_security_token_monitor_get_module_path (ScSecurityTokenMonitor *monitor)
-+{
-+ return monitor->priv->module_path;
-+}
-+
-+static void
-+sc_security_token_monitor_set_module_path (ScSecurityTokenMonitor *monitor,
-+ const gchar *module_path)
-+{
-+ if (module_path == NULL)
-+ module_path = SC_SECURITY_TOKEN_MONITOR_DRIVER;
-+
-+ g_assert (module_path != NULL);
-+
-+ if (((monitor->priv->module_path == NULL) ||
-+ (strcmp (monitor->priv->module_path, module_path) != 0))) {
-+ g_free (monitor->priv->module_path);
-+ monitor->priv->module_path = g_strdup (module_path);
-+ g_object_notify (G_OBJECT (monitor), "module-path");
-+ }
-+}
-+
-+static void
-+sc_security_token_monitor_token_removed_handler (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token)
-+{
-+ sc_debug ("informing security token of its removal");
-+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_REMOVED);
-+}
-+
-+static void
-+sc_security_token_monitor_token_inserted_handler (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token)
-+{
-+ sc_debug ("informing security token of its insertion");
-+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_INSERTED);
-+}
-+
-+static void
-+sc_security_token_monitor_class_install_signals (ScSecurityTokenMonitorClass *monitor_class)
-+{
-+ GObjectClass *object_class;
-+
-+ object_class = G_OBJECT_CLASS (monitor_class);
-+
-+ sc_security_token_monitor_signals[SECURITY_TOKEN_INSERTED] =
-+ g_signal_new ("security-token-inserted",
-+ G_OBJECT_CLASS_TYPE (object_class),
-+ G_SIGNAL_RUN_FIRST,
-+ G_STRUCT_OFFSET (ScSecurityTokenMonitorClass,
-+ security_token_inserted),
-+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
-+ G_TYPE_NONE, 1, G_TYPE_POINTER);
-+ monitor_class->security_token_inserted = sc_security_token_monitor_token_inserted_handler;
-+
-+ sc_security_token_monitor_signals[SECURITY_TOKEN_REMOVED] =
-+ g_signal_new ("security-token-removed",
-+ G_OBJECT_CLASS_TYPE (object_class),
-+ G_SIGNAL_RUN_FIRST,
-+ G_STRUCT_OFFSET (ScSecurityTokenMonitorClass,
-+ security_token_removed),
-+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
-+ G_TYPE_NONE, 1, G_TYPE_POINTER);
-+ monitor_class->security_token_removed = sc_security_token_monitor_token_removed_handler;
-+
-+ sc_security_token_monitor_signals[ERROR] =
-+ g_signal_new ("error",
-+ G_OBJECT_CLASS_TYPE (object_class),
-+ G_SIGNAL_RUN_LAST,
-+ G_STRUCT_OFFSET (ScSecurityTokenMonitorClass, error),
-+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
-+ G_TYPE_NONE, 1, G_TYPE_POINTER);
-+ monitor_class->error = NULL;
-+}
-+
-+static gboolean
-+sc_slot_id_equal (CK_SLOT_ID *slot_id_1,
-+ CK_SLOT_ID *slot_id_2)
-+{
-+ g_assert (slot_id_1 != NULL);
-+ g_assert (slot_id_2 != NULL);
-+
-+ return *slot_id_1 == *slot_id_2;
-+}
-+
-+static gboolean
-+sc_slot_id_hash (CK_SLOT_ID *slot_id)
-+{
-+ guint32 upper_bits, lower_bits;
-+ gint temp;
-+
-+ if (sizeof (CK_SLOT_ID) == sizeof (gint))
-+ return g_int_hash (slot_id);
-+
-+ upper_bits = ((*slot_id) >> 31) - 1;
-+ lower_bits = (*slot_id) & 0xffffffff;
-+
-+ /* The upper bits are almost certainly always zero,
-+ * so let's degenerate to g_int_hash for the
-+ * (very) common case
-+ */
-+ temp = lower_bits + upper_bits;
-+ return upper_bits + g_int_hash (&temp);
-+}
-+
-+static void
-+sc_security_token_monitor_init (ScSecurityTokenMonitor *monitor)
-+{
-+ sc_debug ("initializing security token monitor");
-+
-+ monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
-+ SC_TYPE_SECURITY_TOKEN_MONITOR,
-+ ScSecurityTokenMonitorPrivate);
-+ monitor->priv->poll_timeout_id = 0;
-+ monitor->priv->security_tokens = NULL;
-+ monitor->priv->is_unstoppable = FALSE;
-+}
-+
-+static void
-+sc_security_token_monitor_finalize (GObject *object)
-+{
-+ ScSecurityTokenMonitor *monitor;
-+ GObjectClass *gobject_class;
-+
-+ monitor = SC_SECURITY_TOKEN_MONITOR (object);
-+ gobject_class =
-+ G_OBJECT_CLASS (sc_security_token_monitor_parent_class);
-+
-+ sc_security_token_monitor_stop_now (monitor);
-+
-+ gobject_class->finalize (object);
-+}
-+
-+GQuark
-+sc_security_token_monitor_error_quark (void)
-+{
-+ static GQuark error_quark = 0;
-+
-+ if (error_quark == 0)
-+ error_quark = g_quark_from_static_string ("sc-security-token-monitor-error-quark");
-+
-+ return error_quark;
-+}
-+
-+ScSecurityTokenMonitor *
-+sc_security_token_monitor_new (const gchar *module_path)
-+{
-+ ScSecurityTokenMonitor *instance;
-+
-+ instance = SC_SECURITY_TOKEN_MONITOR (g_object_new (SC_TYPE_SECURITY_TOKEN_MONITOR,
-+ "module-path", module_path,
-+ NULL));
-+
-+ return instance;
-+}
-+
-+static void
-+sc_security_token_monitor_emit_error (ScSecurityTokenMonitor *monitor,
-+ GError *error)
-+{
-+ monitor->priv->is_unstoppable = TRUE;
-+ g_signal_emit (monitor, sc_security_token_monitor_signals[ERROR], 0,
-+ error);
-+ monitor->priv->is_unstoppable = FALSE;
-+}
-+
-+static void
-+sc_security_token_monitor_emit_security_token_inserted (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token)
-+{
-+ monitor->priv->is_unstoppable = TRUE;
-+ g_signal_emit (monitor, sc_security_token_monitor_signals[SECURITY_TOKEN_INSERTED], 0,
-+ token);
-+ monitor->priv->is_unstoppable = FALSE;
-+}
-+
-+static void
-+sc_security_token_monitor_emit_security_token_removed (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token)
-+{
-+ ScSecurityTokenMonitorState old_state;
-+
-+ old_state = monitor->priv->state;
-+ monitor->priv->is_unstoppable = TRUE;
-+ g_signal_emit (monitor, sc_security_token_monitor_signals[SECURITY_TOKEN_REMOVED], 0,
-+ token);
-+ monitor->priv->is_unstoppable = FALSE;
-+}
-+
-+static gboolean
-+sc_security_token_monitor_check_for_and_process_events (ScSecurityTokenMonitor *monitor)
-+{
-+ PK11SlotInfo *slot;
-+ CK_SLOT_ID slot_id, *key;
-+ gint slot_series, token_slot_series;
-+ ScSecurityToken *token;
-+
-+ slot = SECMOD_WaitForAnyTokenEvent (monitor->priv->module, CKF_DONT_BLOCK,
-+ PR_INTERVAL_NO_WAIT);
-+
-+ if (slot == NULL) {
-+ GError *error;
-+ int error_code;
-+
-+ error_code = PORT_GetError ();
-+ if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT))
-+ return TRUE;
-+
-+ /* FIXME: is there a function to convert from a PORT error
-+ * code to a translated string?
-+ */
-+ error = g_error_new (SC_SECURITY_TOKEN_MONITOR_ERROR,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
-+ _("encountered unexpected error while "
-+ "waiting for security token events"));
-+ g_error_free (error);
-+
-+ return FALSE;
-+ }
-+
-+ /* the slot id and series together uniquely identify a token.
-+ * You can never have two tokens with the same slot id at the
-+ * same time, however (I think), so we can key off of it.
-+ */
-+ slot_id = PK11_GetSlotID (slot);
-+ slot_series = PK11_GetSlotSeries (slot);
-+
-+ /* First check to see if there is a token that we're currently
-+ * tracking in the slot.
-+ */
-+ key = g_new (CK_SLOT_ID, 1);
-+ *key = slot_id;
-+ token = g_hash_table_lookup (monitor->priv->security_tokens, key);
-+
-+ if (token != NULL)
-+ token_slot_series = sc_security_token_get_slot_series (token);
-+
-+ if (PK11_IsPresent (slot)) {
-+ /* Now, check to see if their is a new token in the slot.
-+ * If there was a different token in the slot now than
-+ * there was before, then we need to emit a removed signal
-+ * for the old token.
-+ *
-+ * FIXME: So, I *think* the reason we need to do this is
-+ * for the case where a token is removed and another
-+ * inserted faster than the internal poll granualarity of
-+ * NSS. In that case we won't get a separate removed event
-+ * so we need to handle it ourselves. But what happens if
-+ * a token is removed, another inserted, then removed, and
-+ * another inserted really fast? Shouldn't we emit
-+ * several removed/inserted events? If so, can we depend
-+ * on the difference of the series numbers to determine
-+ * how many events to emit? It's all hard to trigger
-+ * corner cases that probably don't matter anyhow, though.
-+ */
-+ if ((token != NULL) &&
-+ token_slot_series != slot_series) {
-+ sc_security_token_monitor_emit_security_token_removed (monitor, token);
-+ }
-+
-+ token = _sc_security_token_new (monitor->priv->module,
-+ slot_id, slot_series);
-+
-+ g_hash_table_replace (monitor->priv->security_tokens,
-+ key, token);
-+ key = NULL;
-+
-+ sc_security_token_monitor_emit_security_token_inserted (monitor, token);
-+ } else {
-+ /* if we aren't tracking the token, just discard the event.
-+ * We don't want unpaired remove events. Note on startup
-+ * NSS will generate an "insertion" event if a token is
-+ * already inserted in the slot.
-+ */
-+ if ((token != NULL)) {
-+ /* FIXME: i'm not sure about this code. Maybe we
-+ * shouldn't do this at all, or maybe we should do it
-+ * n times (where n = slot_series - token_slot_series + 1)
-+ * (see the comment in the if part of this if/else
-+ * clause for more information)
-+ *
-+ * Right now, i'm just doing it once.
-+ */
-+ if ((slot_series - token_slot_series) > 1) {
-+
-+ sc_security_token_monitor_emit_security_token_removed (monitor, token);
-+ g_hash_table_remove (monitor->priv->security_tokens, key);
-+
-+ token = _sc_security_token_new (monitor->priv->module,
-+ slot_id, slot_series);
-+ g_hash_table_replace (monitor->priv->security_tokens,
-+ key, token);
-+ key = NULL;
-+ sc_security_token_monitor_emit_security_token_inserted (monitor, token);
-+ }
-+
-+ sc_security_token_monitor_emit_security_token_removed (monitor, token);
-+
-+ g_hash_table_remove (monitor->priv->security_tokens, key);
-+ token = NULL;
-+ }
-+ }
-+
-+ g_free (key);
-+ PK11_FreeSlot (slot);
-+
-+ return TRUE;
-+}
-+
-+static void
-+sc_security_token_monitor_polling_stopped_handler (ScSecurityTokenMonitor *monitor)
-+{
-+ monitor->priv->poll_timeout_id = 0;
-+ sc_security_token_monitor_stop_now (monitor);
-+}
-+
-+gboolean
-+sc_security_token_monitor_start (ScSecurityTokenMonitor *monitor,
-+ GError **error)
-+{
-+ SECStatus status = SECSuccess;
-+ gchar *module_spec;
-+
-+ if (monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STARTED) {
-+ sc_debug ("security token monitor already started");
-+ return TRUE;
-+ }
-+
-+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STARTING;
-+
-+ if (!monitor->priv->nss_is_loaded) {
-+ sc_debug ("attempting to load NSS database '%s'",
-+ SC_SECURITY_TOKEN_MONITOR_NSS_DB);
-+ status = NSS_NoDB_Init (SC_SECURITY_TOKEN_MONITOR_NSS_DB);
-+ }
-+
-+ if (status != SECSuccess) {
-+ gsize error_message_size;
-+ gchar *error_message;
-+
-+ error_message_size = PR_GetErrorTextLength ();
-+
-+ if (error_message_size == 0) {
-+ sc_debug ("NSS security system could not be initialized");
-+ g_set_error (error,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
-+ _("NSS security system could not be initialized"));
-+ goto out;
-+ }
-+
-+ error_message = g_slice_alloc0 (error_message_size);
-+ PR_GetErrorText (error_message);
-+
-+ g_set_error (error,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
-+ "%s", error_message);
-+ sc_debug ("NSS security system could not be initialized - %s",
-+ error_message);
-+
-+ g_slice_free1 (error_message_size, error_message);
-+
-+ goto out;
-+ }
-+ sc_debug ("NSS database sucessfully loaded");
-+ monitor->priv->nss_is_loaded = TRUE;
-+
-+ if (monitor->priv->module == NULL) {
-+ g_assert (monitor->priv->module_path != NULL);
-+ module_spec = g_strdup_printf ("library=\"%s\" name=\"SecurityToken\"",
-+ monitor->priv->module_path);
-+ sc_debug ("loading security token driver using spec '%s'",
-+ module_spec);
-+
-+ /* FIXME: this API is apparently deprecated, find out what is replacing it
-+ */
-+ monitor->priv->module = SECMOD_LoadUserModule (module_spec,
-+ NULL /* parent */,
-+ FALSE /* recurse */);
-+ g_free (module_spec);
-+ }
-+
-+ if ((monitor->priv->module == NULL) || !monitor->priv->module->loaded) {
-+ gsize error_message_size;
-+ gchar *error_message;
-+
-+ error_message_size = PR_GetErrorTextLength ();
-+
-+ if (error_message_size == 0) {
-+ sc_debug ("security token driver '%s' could not be loaded",
-+ monitor->priv->module_path);
-+ g_set_error (error,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
-+ _
-+ ("security token driver '%s' could not be loaded"),
-+ monitor->priv->module_path);
-+ goto out;
-+ }
-+
-+ error_message = g_slice_alloc0 (error_message_size);
-+ PR_GetErrorText (error_message);
-+
-+ g_set_error (error,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
-+ "%s", error_message);
-+
-+ sc_debug ("security token driver '%s' could not be loaded - %s",
-+ monitor->priv->module_path, error_message);
-+ g_slice_free1 (error_message_size, error_message);
-+
-+ goto out;
-+ }
-+
-+ /* FIXME: so it sort of sucks that we have to poll here. NSS
-+ * does offer a non-blocking API (that we use), but there is
-+ * no way to wake up the event loop when new events arrive, so
-+ * we just have to poll periodically. An alternative would be
-+ * to fork (or bring in threads, ick) and use the blocking api
-+ * plus a message pipe, but that's significantly more
-+ * complicated to implement. Maybe a better solution is to
-+ * move all this off to Yet Another Daemon Process and have it
-+ * emit dbus signals that we watch for.
-+ */
-+ monitor->priv->poll_timeout_id =
-+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
-+ SC_SECURITY_TOKEN_MONITOR_POLL_INTERVAL,
-+ (GSourceFunc)
-+ sc_security_token_monitor_check_for_and_process_events,
-+ monitor, (GDestroyNotify)
-+ sc_security_token_monitor_polling_stopped_handler);
-+
-+ monitor->priv->security_tokens =
-+ g_hash_table_new_full ((GHashFunc) sc_slot_id_hash,
-+ (GEqualFunc) sc_slot_id_equal,
-+ (GDestroyNotify) g_free,
-+ (GDestroyNotify) g_object_unref);
-+
-+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STARTED;
-+
-+out:
-+ /* don't leave it in a half started state
-+ */
-+ if (monitor->priv->state != SC_SECURITY_TOKEN_MONITOR_STATE_STARTED) {
-+ sc_debug
-+ ("security token monitor could not be completely started");
-+ sc_security_token_monitor_stop (monitor);
-+ } else
-+ sc_debug ("security token monitor started");
-+
-+ return monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STARTED;
-+}
-+
-+static gboolean
-+sc_security_token_monitor_stop_now (ScSecurityTokenMonitor *monitor)
-+{
-+ if (monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED)
-+ return FALSE;
-+
-+ sc_debug ("stopping security token monitor");
-+
-+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED;
-+ if (monitor->priv->security_tokens != NULL) {
-+ g_hash_table_destroy (monitor->priv->security_tokens);
-+ monitor->priv->security_tokens = NULL;
-+ }
-+
-+ if (monitor->priv->poll_timeout_id != 0) {
-+ g_source_remove (monitor->priv->poll_timeout_id);
-+ monitor->priv->poll_timeout_id = 0;
-+ }
-+
-+#ifdef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
-+ if (monitor->priv->module != NULL) {
-+ SECMOD_DestroyModule (monitor->priv->module);
-+ monitor->priv->module = NULL;
-+ }
-+
-+ if (monitor->priv->nss_is_loaded) {
-+ NSS_Shutdown ();
-+ monitor->priv->nss_is_loaded = FALSE;
-+ }
-+#endif
-+ sc_debug ("security token monitor stopped");
-+
-+ return FALSE;
-+}
-+
-+static void
-+sc_security_token_monitor_queue_stop (ScSecurityTokenMonitor *monitor)
-+{
-+
-+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STOPPING;
-+
-+ g_idle_add ((GSourceFunc) sc_security_token_monitor_stop_now, monitor);
-+}
-+
-+void
-+sc_security_token_monitor_stop (ScSecurityTokenMonitor *monitor)
-+{
-+ if (monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED)
-+ return;
-+
-+ if (monitor->priv->is_unstoppable) {
-+ sc_security_token_monitor_queue_stop (monitor);
-+ return;
-+ }
-+
-+ sc_security_token_monitor_stop_now (monitor);
-+}
-+
-+#ifdef SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST
-+#include <glib.h>
-+
-+static GMainLoop *event_loop;
-+static gboolean should_exit_on_next_remove = FALSE;
-+
-+static gboolean on_timeout (ScSecurityTokenMonitor *monitor)
-+{
-+ GError *error;
-+ g_print ("Re-enabling monitor.\n");
-+
-+ if (!sc_security_token_monitor_start (monitor, &error)) {
-+ g_warning ("could not start security token monitor - %s",
-+ error->message);
-+ g_error_free (error);
-+ return 1;
-+ }
-+ g_print ("Please re-insert security token\n");
-+
-+ should_exit_on_next_remove = TRUE;
-+
-+ return FALSE;
-+}
-+
-+static void
-+on_device_inserted (ScSecurityTokenMonitor * monitor,
-+ ScSecurityToken *token)
-+{
-+ g_print ("security token inserted!\n");
-+ g_print ("Please remove it.\n");
-+}
-+
-+static void
-+on_device_removed (ScSecurityTokenMonitor * monitor,
-+ ScSecurityToken *token)
-+{
-+ g_print ("security token removed!\n");
-+
-+ if (should_exit_on_next_remove)
-+ g_main_loop_quit (event_loop);
-+ else {
-+ g_print ("disabling monitor for 2 seconds\n");
-+ sc_security_token_monitor_stop (monitor);
-+ g_timeout_add (2000, (GSourceFunc) on_timeout, monitor);
-+ }
-+}
-+
-+int
-+main (int argc,
-+ char *argv[])
-+{
-+ ScSecurityTokenMonitor *monitor;
-+ GError *error;
-+
-+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR
-+ | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
-+
-+ g_type_init ();
-+
-+ g_message ("creating instance of 'security token monitor' object...");
-+ monitor = sc_security_token_monitor_new (NULL);
-+ g_message ("'security token monitor' object created successfully");
-+
-+ g_signal_connect (monitor, "security-token-inserted",
-+ G_CALLBACK (on_device_inserted), NULL);
-+
-+ g_signal_connect (monitor, "security-token-removed",
-+ G_CALLBACK (on_device_removed), NULL);
-+
-+ g_message ("starting listener...");
-+
-+ error = NULL;
-+ if (!sc_security_token_monitor_start (monitor, &error)) {
-+ g_warning ("could not start security token monitor - %s",
-+ error->message);
-+ g_error_free (error);
-+ return 1;
-+ }
-+
-+ event_loop = g_main_loop_new (NULL, FALSE);
-+ g_main_loop_run (event_loop);
-+ g_main_loop_unref (event_loop);
-+ event_loop = NULL;
-+
-+ g_message ("destroying previously created 'security token monitor' object...");
-+ g_object_unref (monitor);
-+ monitor = NULL;
-+ g_message ("'security token monitor' object destroyed successfully");
-+
-+ return 0;
-+}
-+#endif
---- /dev/null
-+++ gdm-2.15.6/utils/securitytokenmonitor.h
-@@ -0,0 +1,82 @@
-+/* securitytokenmonitor.h - monitor for security token insertion and
-+ * removal events
-+ *
-+ * Copyright (C) 2006 Ray Strode
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-+ * 02111-1307, USA.
-+ */
-+#ifndef SC_SECURITY_TOKEN_MONITOR_H
-+#define SC_SECURITY_TOKEN_MONITOR_H
-+
-+#define SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
-+#include "securitytoken.h"
-+
-+#include <glib.h>
-+#include <glib-object.h>
-+
-+G_BEGIN_DECLS
-+#define SC_TYPE_SECURITY_TOKEN_MONITOR (sc_security_token_monitor_get_type ())
-+#define SC_SECURITY_TOKEN_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_SECURITY_TOKEN_MONITOR, ScSecurityTokenMonitor))
-+#define SC_SECURITY_TOKEN_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_SECURITY_TOKEN_MONITOR, ScSecurityTokenMonitorClass))
-+#define SC_IS_SECURITY_TOKEN_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SECURITY_TOKEN_MONITOR))
-+#define SC_IS_SECURITY_TOKEN_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SECURITY_TOKEN_MONITOR))
-+#define SC_SECURITY_TOKEN_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SC_TYPE_SECURITY_TOKEN_MONITOR, ScSecurityTokenMonitorClass))
-+#define SC_SECURITY_TOKEN_MONITOR_ERROR (sc_security_token_monitor_error_quark ())
-+typedef struct _ScSecurityTokenMonitor ScSecurityTokenMonitor;
-+typedef struct _ScSecurityTokenMonitorClass ScSecurityTokenMonitorClass;
-+typedef struct _ScSecurityTokenMonitorPrivate ScSecurityTokenMonitorPrivate;
-+typedef enum _ScSecurityTokenMonitorError ScSecurityTokenMonitorError;
-+
-+struct _ScSecurityTokenMonitor {
-+ GObject parent;
-+
-+ /*< private > */
-+ ScSecurityTokenMonitorPrivate *priv;
-+};
-+
-+struct _ScSecurityTokenMonitorClass {
-+ GObjectClass parent_class;
-+
-+ /* Signals */
-+ void (*security_token_inserted) (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token);
-+ void (*security_token_removed) (ScSecurityTokenMonitor *monitor,
-+ ScSecurityToken *token);
-+ void (*error) (ScSecurityTokenMonitor *monitor,
-+ GError *error);
-+};
-+
-+enum _ScSecurityTokenMonitorError {
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_GENERIC = 0,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
-+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
-+};
-+
-+GType sc_security_token_monitor_get_type (void) G_GNUC_CONST;
-+GQuark sc_security_token_monitor_error_quark (void) G_GNUC_CONST;
-+
-+ScSecurityTokenMonitor *sc_security_token_monitor_new (const gchar *module);
-+
-+
-+gboolean sc_security_token_monitor_start (ScSecurityTokenMonitor *monitor,
-+ GError **error);
-+
-+void sc_security_token_monitor_stop (ScSecurityTokenMonitor *monitor);
-+
-+gchar *sc_security_token_monitor_get_module_path (ScSecurityTokenMonitor *monitor);
-+
-+G_END_DECLS
-+#endif /* SC_SECURITY_TOKEN_MONITOR_H */
++++ gdm-2.15.6/config/securitytokens.conf.in
+@@ -0,0 +1,4 @@
++[SecurityTokens]
++Enable=true
++#Driver=@libdir@/pkcs11/libcoolkeypk11.so
++#PamStack=gdm-securitytokens
+
- Previous message (by thread): rpms/gdm/devel gdm-2.15.6-security-tokens.patch, NONE, 1.1 gdm.spec, 1.176, 1.177 gdm-2.15.5-security-tokens.patch, 1.4, NONE
- Next message (by thread): rpms/imake/devel xorg-cf-files-1.0.2-redhat.patch, NONE, 1.1 xorg-cf-files-1.0.2-xprint.patch, NONE, 1.1 .cvsignore, 1.6, 1.7 imake.spec, 1.26, 1.27 sources, 1.5, 1.6 xorg-cf-files-1.0.1-redhat.patch, 1.2, NONE xorg-cf-files-1.0.1-xprint.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list