|
|
d873dd1 |
--- /dev/null 2007-03-12 21:48:12.974260066 -0400
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/securitytokenmonitor.h 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -0,0 +1,84 @@
|
|
|
d873dd1 |
+/* securitytokenmonitor.h - monitor for security token insertion and
|
|
|
d873dd1 |
+ * removal events
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * Copyright (C) 2006 Ray Strode
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
d873dd1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
d873dd1 |
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
|
d873dd1 |
+ * any later version.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
d873dd1 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d873dd1 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
d873dd1 |
+ * GNU General Public License for more details.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * You should have received a copy of the GNU General Public License
|
|
|
d873dd1 |
+ * along with this program; if not, write to the Free Software
|
|
|
d873dd1 |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
d873dd1 |
+ * 02111-1307, USA.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_H
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR_H
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
|
|
|
d873dd1 |
+#include "securitytoken.h"
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <glib.h>
|
|
|
d873dd1 |
+#include <glib-object.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+G_BEGIN_DECLS
|
|
|
d873dd1 |
+#define SC_TYPE_SECURITY_TOKEN_MONITOR (sc_security_token_monitor_get_type ())
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_SECURITY_TOKEN_MONITOR, ScSecurityTokenMonitor))
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_SECURITY_TOKEN_MONITOR, ScSecurityTokenMonitorClass))
|
|
|
d873dd1 |
+#define SC_IS_SECURITY_TOKEN_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SECURITY_TOKEN_MONITOR))
|
|
|
d873dd1 |
+#define SC_IS_SECURITY_TOKEN_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SECURITY_TOKEN_MONITOR))
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SC_TYPE_SECURITY_TOKEN_MONITOR, ScSecurityTokenMonitorClass))
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR_ERROR (sc_security_token_monitor_error_quark ())
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenMonitor ScSecurityTokenMonitor;
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenMonitorClass ScSecurityTokenMonitorClass;
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenMonitorPrivate ScSecurityTokenMonitorPrivate;
|
|
|
d873dd1 |
+typedef enum _ScSecurityTokenMonitorError ScSecurityTokenMonitorError;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityTokenMonitor {
|
|
|
d873dd1 |
+ GObject parent;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /*< private > */
|
|
|
d873dd1 |
+ ScSecurityTokenMonitorPrivate *priv;
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityTokenMonitorClass {
|
|
|
d873dd1 |
+ GObjectClass parent_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* Signals */
|
|
|
d873dd1 |
+ void (*security_token_inserted) (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token);
|
|
|
d873dd1 |
+ void (*security_token_removed) (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token);
|
|
|
d873dd1 |
+ void (*error) (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ GError *error);
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum _ScSecurityTokenMonitorError {
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_GENERIC = 0,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WATCHING_FOR_EVENTS,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_REPORTING_EVENTS
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+GType sc_security_token_monitor_get_type (void) G_GNUC_CONST;
|
|
|
d873dd1 |
+GQuark sc_security_token_monitor_error_quark (void) G_GNUC_CONST;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ScSecurityTokenMonitor *sc_security_token_monitor_new (const gchar *module);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gboolean sc_security_token_monitor_start (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ GError **error);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+void sc_security_token_monitor_stop (ScSecurityTokenMonitor *monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gchar *sc_security_token_monitor_get_module_path (ScSecurityTokenMonitor *monitor);
|
|
|
d873dd1 |
+gboolean sc_security_token_monitor_login_token_is_inserted (ScSecurityTokenMonitor *monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+G_END_DECLS
|
|
|
d873dd1 |
+#endif /* SC_SECURITY_TOKEN_MONITOR_H */
|
|
|
d873dd1 |
--- /dev/null 2007-03-12 21:48:12.974260066 -0400
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/securitytoken.h 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -0,0 +1,94 @@
|
|
|
d873dd1 |
+/* securitytoken.h - api for reading and writing data to a security token
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * Copyright (C) 2006 Ray Strode
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
d873dd1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
d873dd1 |
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
|
d873dd1 |
+ * any later version.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
d873dd1 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d873dd1 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
d873dd1 |
+ * GNU General Public License for more details.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * You should have received a copy of the GNU General Public License
|
|
|
d873dd1 |
+ * along with this program; if not, write to the Free Software
|
|
|
d873dd1 |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
d873dd1 |
+ * 02111-1307, USA.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_H
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_H
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <glib.h>
|
|
|
d873dd1 |
+#include <glib-object.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <secmod.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+G_BEGIN_DECLS
|
|
|
d873dd1 |
+#define SC_TYPE_SECURITY_TOKEN (sc_security_token_get_type ())
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_SECURITY_TOKEN, ScSecurityToken))
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_SECURITY_TOKEN, ScSecurityTokenClass))
|
|
|
d873dd1 |
+#define SC_IS_SECURITY_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SECURITY_TOKEN))
|
|
|
d873dd1 |
+#define SC_IS_SECURITY_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SECURITY_TOKEN))
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SC_TYPE_SECURITY_TOKEN, ScSecurityTokenClass))
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_ERROR (sc_security_token_error_quark ())
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenClass ScSecurityTokenClass;
|
|
|
d873dd1 |
+typedef struct _ScSecurityToken ScSecurityToken;
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenPrivate ScSecurityTokenPrivate;
|
|
|
d873dd1 |
+typedef enum _ScSecurityTokenError ScSecurityTokenError;
|
|
|
d873dd1 |
+typedef enum _ScSecurityTokenState ScSecurityTokenState;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenRequest ScSecurityTokenRequest;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityToken {
|
|
|
d873dd1 |
+ GObject parent;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /*< private > */
|
|
|
d873dd1 |
+ ScSecurityTokenPrivate *priv;
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityTokenClass {
|
|
|
d873dd1 |
+ GObjectClass parent_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ void (* inserted) (ScSecurityToken *token);
|
|
|
d873dd1 |
+ void (* removed) (ScSecurityToken *token);
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum _ScSecurityTokenError {
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_ERROR_GENERIC = 0,
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum _ScSecurityTokenState {
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_STATE_INSERTED = 0,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_STATE_REMOVED,
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+GType sc_security_token_get_type (void) G_GNUC_CONST;
|
|
|
d873dd1 |
+GQuark sc_security_token_error_quark (void) G_GNUC_CONST;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+CK_SLOT_ID sc_security_token_get_slot_id (ScSecurityToken *token);
|
|
|
d873dd1 |
+gint sc_security_token_get_slot_series (ScSecurityToken *token);
|
|
|
d873dd1 |
+ScSecurityTokenState sc_security_token_get_state (ScSecurityToken *token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gchar *sc_security_token_get_name (ScSecurityToken *token);
|
|
|
d873dd1 |
+gboolean sc_security_token_is_login_token (ScSecurityToken *token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gboolean sc_security_token_unlock (ScSecurityToken *token,
|
|
|
d873dd1 |
+ const gchar *password);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+/* don't under any circumstances call these functions */
|
|
|
d873dd1 |
+#ifdef SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ScSecurityToken *_sc_security_token_new (SECMODModule *module,
|
|
|
d873dd1 |
+ CK_SLOT_ID slot_id,
|
|
|
d873dd1 |
+ gint slot_series);
|
|
|
d873dd1 |
+ScSecurityToken *_sc_security_token_new_from_name (SECMODModule *module,
|
|
|
d873dd1 |
+ const gchar *name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+void _sc_security_token_set_state (ScSecurityToken *token,
|
|
|
d873dd1 |
+ ScSecurityTokenState state);
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+G_END_DECLS
|
|
|
d873dd1 |
+#endif /* SC_SECURITY_TOKEN_H */
|
|
|
d873dd1 |
--- gnome-screensaver-2.18.0/src/gs-monitor.c.securitytoken 2007-02-22 23:39:09.000000000 -0500
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/gs-monitor.c 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -41,10 +41,15 @@
|
|
|
d873dd1 |
#include "gs-prefs.h"
|
|
|
d873dd1 |
#include "gs-debug.h"
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+#include "securitytokenmonitor.h"
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
static void gs_monitor_class_init (GSMonitorClass *klass);
|
|
|
d873dd1 |
static void gs_monitor_init (GSMonitor *monitor);
|
|
|
d873dd1 |
static void gs_monitor_finalize (GObject *object);
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+static void gs_monitor_simulate_user_activity (GSMonitor *monitor);
|
|
|
d873dd1 |
+static void gs_monitor_lock_screen (GSMonitor *monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
#define GS_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_MONITOR, GSMonitorPrivate))
|
|
|
d873dd1 |
|
|
|
d873dd1 |
struct GSMonitorPrivate
|
|
|
d873dd1 |
@@ -56,6 +61,8 @@
|
|
|
d873dd1 |
GSFade *fade;
|
|
|
d873dd1 |
GSGrab *grab;
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *security_token_monitor;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
guint release_grab_id;
|
|
|
d873dd1 |
};
|
|
|
d873dd1 |
|
|
|
d873dd1 |
@@ -100,6 +107,36 @@
|
|
|
d873dd1 |
gs_listener_emit_auth_request_end (monitor->priv->listener);
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+security_token_inserted_cb (ScSecurityTokenMonitor *token_monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token,
|
|
|
d873dd1 |
+ GSMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gs_monitor_simulate_user_activity (monitor);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+gs_monitor_should_lock_on_login_security_token_removal (void)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ /* FIXME: lame hack
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ return system ("pkcs11_setup rm_action | grep -q lock") == 0;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+security_token_removed_cb (ScSecurityTokenMonitor *token_monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token,
|
|
|
d873dd1 |
+ GSMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (gs_monitor_should_lock_on_login_security_token_removal () &&
|
|
|
d873dd1 |
+ sc_security_token_is_login_token (token))
|
|
|
d873dd1 |
+ gs_monitor_lock_screen (monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* If we're already locked and the lock dialog is up, kill it.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ gs_manager_cancel_unlock_request (monitor->priv->manager);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
static gboolean
|
|
|
d873dd1 |
watcher_idle_cb (GSWatcher *watcher,
|
|
|
d873dd1 |
gboolean is_idle,
|
|
|
d873dd1 |
@@ -210,37 +247,6 @@
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
|
|
|
d873dd1 |
static void
|
|
|
d873dd1 |
-gs_monitor_lock_screen (GSMonitor *monitor)
|
|
|
d873dd1 |
-{
|
|
|
d873dd1 |
- gboolean res;
|
|
|
d873dd1 |
- gboolean locked;
|
|
|
d873dd1 |
-
|
|
|
d873dd1 |
- /* set lock flag before trying to activate screensaver
|
|
|
d873dd1 |
- in case something tries to react to the ActiveChanged signal */
|
|
|
d873dd1 |
-
|
|
|
d873dd1 |
- gs_manager_get_lock_active (monitor->priv->manager, &locked);
|
|
|
d873dd1 |
- gs_manager_set_lock_active (monitor->priv->manager, TRUE);
|
|
|
d873dd1 |
- res = gs_listener_set_active (monitor->priv->listener, TRUE);
|
|
|
d873dd1 |
- if (! res) {
|
|
|
d873dd1 |
- /* If we've failed then restore lock status */
|
|
|
d873dd1 |
- gs_manager_set_lock_active (monitor->priv->manager, locked);
|
|
|
d873dd1 |
- gs_debug ("Unable to lock the screen");
|
|
|
d873dd1 |
- }
|
|
|
d873dd1 |
-}
|
|
|
d873dd1 |
-
|
|
|
d873dd1 |
-static void
|
|
|
d873dd1 |
-gs_monitor_simulate_user_activity (GSMonitor *monitor)
|
|
|
d873dd1 |
-{
|
|
|
d873dd1 |
- /* in case the screen isn't blanked reset the
|
|
|
d873dd1 |
- idle watcher */
|
|
|
d873dd1 |
- gs_watcher_reset (monitor->priv->watcher);
|
|
|
d873dd1 |
-
|
|
|
d873dd1 |
- /* request that the manager unlock -
|
|
|
d873dd1 |
- will pop up a dialog if necessary */
|
|
|
d873dd1 |
- gs_manager_request_unlock (monitor->priv->manager);
|
|
|
d873dd1 |
-}
|
|
|
d873dd1 |
-
|
|
|
d873dd1 |
-static void
|
|
|
d873dd1 |
listener_lock_cb (GSListener *listener,
|
|
|
d873dd1 |
GSMonitor *monitor)
|
|
|
d873dd1 |
{
|
|
|
d873dd1 |
@@ -424,6 +430,27 @@
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
|
|
|
d873dd1 |
static void
|
|
|
d873dd1 |
+disconnect_security_token_monitor_signals (GSMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ g_signal_handlers_disconnect_by_func (monitor->priv->security_token_monitor,
|
|
|
d873dd1 |
+ security_token_removed_cb, monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_signal_handlers_disconnect_by_func (monitor->priv->security_token_monitor,
|
|
|
d873dd1 |
+ security_token_inserted_cb, monitor);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+connect_security_token_monitor_signals (GSMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ g_signal_connect (monitor->priv->security_token_monitor,
|
|
|
d873dd1 |
+ "security-token-removed",
|
|
|
d873dd1 |
+ G_CALLBACK (security_token_removed_cb), monitor);
|
|
|
d873dd1 |
+ g_signal_connect (monitor->priv->security_token_monitor,
|
|
|
d873dd1 |
+ "security-token-inserted",
|
|
|
d873dd1 |
+ G_CALLBACK (security_token_inserted_cb), monitor);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
disconnect_prefs_signals (GSMonitor *monitor)
|
|
|
d873dd1 |
{
|
|
|
d873dd1 |
g_signal_handlers_disconnect_by_func (monitor->priv->prefs, _gs_monitor_update_from_prefs, monitor);
|
|
|
d873dd1 |
@@ -457,6 +484,26 @@
|
|
|
d873dd1 |
monitor->priv->manager = gs_manager_new ();
|
|
|
d873dd1 |
connect_manager_signals (monitor);
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+ /* PKCS11_LOGIN_TOKEN_NAME is set if the user logged in with a
|
|
|
d873dd1 |
+ * security token.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (g_getenv ("PKCS11_LOGIN_TOKEN_NAME") != NULL) {
|
|
|
d873dd1 |
+ monitor->priv->security_token_monitor = sc_security_token_monitor_new (NULL);
|
|
|
d873dd1 |
+ sc_security_token_monitor_start (monitor->priv->security_token_monitor,
|
|
|
d873dd1 |
+ NULL);
|
|
|
d873dd1 |
+ connect_security_token_monitor_signals (monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* if the user logged in with a security token but it's
|
|
|
d873dd1 |
+ * not currently inserted, then they must have yanked it
|
|
|
d873dd1 |
+ * before we started. lock the screen immediately
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (gs_monitor_should_lock_on_login_security_token_removal () &&
|
|
|
d873dd1 |
+ !sc_security_token_monitor_login_token_is_inserted (monitor->priv->security_token_monitor))
|
|
|
d873dd1 |
+ gs_monitor_lock_screen (monitor);
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ monitor->priv->security_token_monitor = NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
_gs_monitor_update_from_prefs (monitor, monitor->priv->prefs);
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
|
|
|
d873dd1 |
@@ -472,6 +519,12 @@
|
|
|
d873dd1 |
|
|
|
d873dd1 |
g_return_if_fail (monitor->priv != NULL);
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+ if (monitor->priv->security_token_monitor != NULL) {
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop (monitor->priv->security_token_monitor);
|
|
|
d873dd1 |
+ disconnect_security_token_monitor_signals (monitor);
|
|
|
d873dd1 |
+ g_object_unref (monitor->priv->security_token_monitor);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
disconnect_watcher_signals (monitor);
|
|
|
d873dd1 |
disconnect_listener_signals (monitor);
|
|
|
d873dd1 |
disconnect_manager_signals (monitor);
|
|
|
d873dd1 |
@@ -509,3 +562,34 @@
|
|
|
d873dd1 |
|
|
|
d873dd1 |
return TRUE;
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+gs_monitor_simulate_user_activity (GSMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ /* in case the screen isn't blanked reset the
|
|
|
d873dd1 |
+ idle watcher */
|
|
|
d873dd1 |
+ gs_watcher_reset (monitor->priv->watcher);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* request that the manager unlock -
|
|
|
d873dd1 |
+ will pop up a dialog if necessary */
|
|
|
d873dd1 |
+ gs_manager_request_unlock (monitor->priv->manager);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+gs_monitor_lock_screen (GSMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gboolean res;
|
|
|
d873dd1 |
+ gboolean locked;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* set lock flag before trying to activate screensaver
|
|
|
d873dd1 |
+ in case something tries to react to the ActiveChanged signal */
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gs_manager_get_lock_active (monitor->priv->manager, &locked);
|
|
|
d873dd1 |
+ gs_manager_set_lock_active (monitor->priv->manager, TRUE);
|
|
|
d873dd1 |
+ res = gs_listener_set_active (monitor->priv->listener, TRUE);
|
|
|
d873dd1 |
+ if (! res) {
|
|
|
d873dd1 |
+ /* If we've failed then restore lock status */
|
|
|
d873dd1 |
+ gs_manager_set_lock_active (monitor->priv->manager, locked);
|
|
|
d873dd1 |
+ gs_debug ("Unable to lock the screen");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
--- gnome-screensaver-2.18.0/src/gs-auth-pam.c.securitytoken 2007-02-22 23:39:09.000000000 -0500
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/gs-auth-pam.c 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -354,6 +354,13 @@
|
|
|
d873dd1 |
status2,
|
|
|
d873dd1 |
(status2 == PAM_SUCCESS ? "Success" : "Failure"));
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* iterate the glib event loop inbetween processing pam
|
|
|
d873dd1 |
+ * messages so that the user interface can be updated
|
|
|
d873dd1 |
+ * to reflect changes that are a result of the pam
|
|
|
d873dd1 |
+ * messages
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ while (g_main_context_iteration (NULL, FALSE));
|
|
|
d873dd1 |
}
|
|
|
d873dd1 |
|
|
|
d873dd1 |
if (message_handled_condition != NULL) {
|
|
|
d873dd1 |
--- /dev/null 2007-03-12 21:48:12.974260066 -0400
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/securitytokenmonitor.c 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -0,0 +1,1743 @@
|
|
|
d873dd1 |
+/* securitytokenmonitor.c - monitor for security token insertion and
|
|
|
d873dd1 |
+ * removal events
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
d873dd1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
d873dd1 |
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
|
d873dd1 |
+ * any later version.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
d873dd1 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d873dd1 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
d873dd1 |
+ * GNU General Public License for more details.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * You should have received a copy of the GNU General Public License
|
|
|
d873dd1 |
+ * along with this program; if not, write to the Free Software
|
|
|
d873dd1 |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
d873dd1 |
+ * 02111-1307, USA.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * TODO: - doing this per project is a bad idea i think.
|
|
|
d873dd1 |
+ * We should probably make this a system service
|
|
|
d873dd1 |
+ * and use dbus.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+#define _GNU_SOURCE
|
|
|
d873dd1 |
+#include "securitytokenmonitor.h"
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
|
|
|
d873dd1 |
+#include "securitytoken.h"
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <dirent.h>
|
|
|
d873dd1 |
+#include <errno.h>
|
|
|
d873dd1 |
+#include <fcntl.h>
|
|
|
d873dd1 |
+#include <limits.h>
|
|
|
d873dd1 |
+#include <poll.h>
|
|
|
d873dd1 |
+#include <signal.h>
|
|
|
d873dd1 |
+#include <stdlib.h>
|
|
|
d873dd1 |
+#include <string.h>
|
|
|
d873dd1 |
+#include <sys/resource.h>
|
|
|
d873dd1 |
+#include <sys/time.h>
|
|
|
d873dd1 |
+#include <sys/wait.h>
|
|
|
d873dd1 |
+#include <unistd.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <glib.h>
|
|
|
d873dd1 |
+#include <glib/gi18n.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <prerror.h>
|
|
|
d873dd1 |
+#include <nss.h>
|
|
|
d873dd1 |
+#include <pk11func.h>
|
|
|
d873dd1 |
+#include <secmod.h>
|
|
|
d873dd1 |
+#include <secerr.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_DRIVER
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR_DRIVER LIBDIR"/pkcs11/libcoolkeypk11.so"
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_NSS_DB
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_MONITOR_NSS_DB SYSCONFDIR"/pki/nssdb"
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_MAX_OPEN_FILE_DESCRIPTORS
|
|
|
d873dd1 |
+#define SC_MAX_OPEN_FILE_DESCRIPTORS 1024
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_OPEN_FILE_DESCRIPTORS_DIR
|
|
|
d873dd1 |
+#define SC_OPEN_FILE_DESCRIPTORS_DIR "/proc/self/fd"
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef sc_debug
|
|
|
d873dd1 |
+#if defined (SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST)
|
|
|
d873dd1 |
+#define sc_debug(fmt, args...) g_printerr("[%u] " fmt " \n", getpid(), ##args)
|
|
|
d873dd1 |
+#else
|
|
|
d873dd1 |
+#define sc_debug(fmt, args...)
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+typedef enum _ScSecurityTokenMonitorState ScSecurityTokenMonitorState;
|
|
|
d873dd1 |
+typedef struct _ScSecurityTokenMonitorWorker ScSecurityTokenMonitorWorker;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum _ScSecurityTokenMonitorState {
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED = 0,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_STATE_STARTING,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_STATE_STARTED,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_STATE_STOPPING,
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityTokenMonitorPrivate {
|
|
|
d873dd1 |
+ ScSecurityTokenMonitorState state;
|
|
|
d873dd1 |
+ SECMODModule *module;
|
|
|
d873dd1 |
+ gchar *module_path;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ GSource *security_token_event_source;
|
|
|
d873dd1 |
+ GPid security_token_event_watcher_pid;
|
|
|
d873dd1 |
+ GHashTable *security_tokens;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ guint poll_timeout_id;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ guint32 is_unstoppable : 1;
|
|
|
d873dd1 |
+ guint32 nss_is_loaded : 1;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
|
|
|
d873dd1 |
+ GArray *fds_to_close_on_fork;
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityTokenMonitorWorker {
|
|
|
d873dd1 |
+ SECMODModule *module;
|
|
|
d873dd1 |
+ GHashTable *security_tokens;
|
|
|
d873dd1 |
+ gint write_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ guint32 nss_is_loaded : 1;
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void sc_security_token_monitor_finalize (GObject *object);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_class_install_signals (ScSecurityTokenMonitorClass *service_class);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_class_install_properties (ScSecurityTokenMonitorClass *service_class);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_set_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ const GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_get_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_set_module_path (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ const gchar *module_path);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_token_removed_handler (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_token_inserted_handler (ScSecurityTokenMonitor *monitor_class,
|
|
|
d873dd1 |
+ ScSecurityToken *token);
|
|
|
d873dd1 |
+static gboolean sc_security_token_monitor_stop_now (ScSecurityTokenMonitor *monitor);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_queue_stop (ScSecurityTokenMonitor *monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean sc_security_token_monitor_create_worker (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ gint *worker_fd, GPid *worker_pid);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static ScSecurityTokenMonitorWorker * sc_security_token_monitor_worker_new (gint write_fd);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_worker_free (ScSecurityTokenMonitorWorker *worker);
|
|
|
d873dd1 |
+static void sc_security_token_monitor_worker_die_with_parent (ScSecurityTokenMonitorWorker *worker);
|
|
|
d873dd1 |
+static gboolean sc_open_pipe (gint *write_fd, gint *read_fd);
|
|
|
d873dd1 |
+static gboolean sc_read_bytes (gint fd, gpointer bytes, gsize num_bytes);
|
|
|
d873dd1 |
+static gboolean sc_write_bytes (gint fd, gconstpointer bytes, gsize num_bytes);
|
|
|
d873dd1 |
+static ScSecurityToken *sc_read_security_token (gint fd, SECMODModule *module);
|
|
|
d873dd1 |
+static gboolean sc_write_security_token (gint fd, ScSecurityToken *token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum {
|
|
|
d873dd1 |
+ PROP_0 = 0,
|
|
|
d873dd1 |
+ PROP_MODULE_PATH,
|
|
|
d873dd1 |
+ NUMBER_OF_PROPERTIES
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum {
|
|
|
d873dd1 |
+ SECURITY_TOKEN_INSERTED = 0,
|
|
|
d873dd1 |
+ SECURITY_TOKEN_REMOVED,
|
|
|
d873dd1 |
+ ERROR,
|
|
|
d873dd1 |
+ NUMBER_OF_SIGNALS
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static guint sc_security_token_monitor_signals[NUMBER_OF_SIGNALS];
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+G_DEFINE_TYPE (ScSecurityTokenMonitor,
|
|
|
d873dd1 |
+ sc_security_token_monitor,
|
|
|
d873dd1 |
+ G_TYPE_OBJECT);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_class_init (ScSecurityTokenMonitorClass *monitor_class)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GObjectClass *gobject_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class = G_OBJECT_CLASS (monitor_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class->finalize = sc_security_token_monitor_finalize;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_class_install_signals (monitor_class);
|
|
|
d873dd1 |
+ sc_security_token_monitor_class_install_properties (monitor_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_type_class_add_private (monitor_class,
|
|
|
d873dd1 |
+ sizeof (ScSecurityTokenMonitorPrivate));
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_class_install_properties (ScSecurityTokenMonitorClass *token_class)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GObjectClass *object_class;
|
|
|
d873dd1 |
+ GParamSpec *param_spec;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ object_class = G_OBJECT_CLASS (token_class);
|
|
|
d873dd1 |
+ object_class->set_property = sc_security_token_monitor_set_property;
|
|
|
d873dd1 |
+ object_class->get_property = sc_security_token_monitor_get_property;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ param_spec = g_param_spec_string ("module-path", _("Module Path"),
|
|
|
d873dd1 |
+ _("path to security token PKCS #11 driver"),
|
|
|
d873dd1 |
+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
|
d873dd1 |
+ g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_set_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ const GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *monitor = SC_SECURITY_TOKEN_MONITOR (object);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ switch (prop_id)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ case PROP_MODULE_PATH:
|
|
|
d873dd1 |
+ sc_security_token_monitor_set_module_path (monitor,
|
|
|
d873dd1 |
+ g_value_get_string (value));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ default:
|
|
|
d873dd1 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_get_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *monitor = SC_SECURITY_TOKEN_MONITOR (object);
|
|
|
d873dd1 |
+ gchar *module_path;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ switch (prop_id)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ case PROP_MODULE_PATH:
|
|
|
d873dd1 |
+ module_path = sc_security_token_monitor_get_module_path (monitor);
|
|
|
d873dd1 |
+ g_value_set_string (value, module_path);
|
|
|
d873dd1 |
+ g_free (module_path);
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ default:
|
|
|
d873dd1 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gchar *
|
|
|
d873dd1 |
+sc_security_token_monitor_get_module_path (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ return monitor->priv->module_path;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_set_module_path (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ const gchar *module_path)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if ((monitor->priv->module_path == NULL) && (module_path == NULL))
|
|
|
d873dd1 |
+ return;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (((monitor->priv->module_path == NULL) ||
|
|
|
d873dd1 |
+ (module_path == NULL) ||
|
|
|
d873dd1 |
+ (strcmp (monitor->priv->module_path, module_path) != 0))) {
|
|
|
d873dd1 |
+ g_free (monitor->priv->module_path);
|
|
|
d873dd1 |
+ monitor->priv->module_path = g_strdup (module_path);
|
|
|
d873dd1 |
+ g_object_notify (G_OBJECT (monitor), "module-path");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_token_removed_handler (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ sc_debug ("informing security token of its removal");
|
|
|
d873dd1 |
+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_REMOVED);
|
|
|
d873dd1 |
+ sc_debug ("done");
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_token_inserted_handler (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ sc_debug ("informing security token of its insertion");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_INSERTED);
|
|
|
d873dd1 |
+ sc_debug ("done");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_class_install_signals (ScSecurityTokenMonitorClass *monitor_class)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GObjectClass *object_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ object_class = G_OBJECT_CLASS (monitor_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_signals[SECURITY_TOKEN_INSERTED] =
|
|
|
d873dd1 |
+ g_signal_new ("security-token-inserted",
|
|
|
d873dd1 |
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
|
d873dd1 |
+ G_SIGNAL_RUN_FIRST,
|
|
|
d873dd1 |
+ G_STRUCT_OFFSET (ScSecurityTokenMonitorClass,
|
|
|
d873dd1 |
+ security_token_inserted),
|
|
|
d873dd1 |
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
|
|
d873dd1 |
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
|
d873dd1 |
+ monitor_class->security_token_inserted = sc_security_token_monitor_token_inserted_handler;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_signals[SECURITY_TOKEN_REMOVED] =
|
|
|
d873dd1 |
+ g_signal_new ("security-token-removed",
|
|
|
d873dd1 |
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
|
d873dd1 |
+ G_SIGNAL_RUN_FIRST,
|
|
|
d873dd1 |
+ G_STRUCT_OFFSET (ScSecurityTokenMonitorClass,
|
|
|
d873dd1 |
+ security_token_removed),
|
|
|
d873dd1 |
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
|
|
d873dd1 |
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
|
d873dd1 |
+ monitor_class->security_token_removed = sc_security_token_monitor_token_removed_handler;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_signals[ERROR] =
|
|
|
d873dd1 |
+ g_signal_new ("error",
|
|
|
d873dd1 |
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
|
d873dd1 |
+ G_SIGNAL_RUN_LAST,
|
|
|
d873dd1 |
+ G_STRUCT_OFFSET (ScSecurityTokenMonitorClass, error),
|
|
|
d873dd1 |
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
|
|
d873dd1 |
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
|
d873dd1 |
+ monitor_class->error = NULL;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_slot_id_equal (CK_SLOT_ID *slot_id_1,
|
|
|
d873dd1 |
+ CK_SLOT_ID *slot_id_2)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ g_assert (slot_id_1 != NULL);
|
|
|
d873dd1 |
+ g_assert (slot_id_2 != NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return *slot_id_1 == *slot_id_2;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_slot_id_hash (CK_SLOT_ID *slot_id)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ guint32 upper_bits, lower_bits;
|
|
|
d873dd1 |
+ gint temp;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (sizeof (CK_SLOT_ID) == sizeof (gint))
|
|
|
d873dd1 |
+ return g_int_hash (slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ upper_bits = ((*slot_id) >> 31) - 1;
|
|
|
d873dd1 |
+ lower_bits = (*slot_id) & 0xffffffff;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* The upper bits are almost certainly always zero,
|
|
|
d873dd1 |
+ * so let's degenerate to g_int_hash for the
|
|
|
d873dd1 |
+ * (very) common case
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ temp = lower_bits + upper_bits;
|
|
|
d873dd1 |
+ return upper_bits + g_int_hash (&temp);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_init (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ sc_debug ("initializing security token monitor");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
|
|
|
d873dd1 |
+ SC_TYPE_SECURITY_TOKEN_MONITOR,
|
|
|
d873dd1 |
+ ScSecurityTokenMonitorPrivate);
|
|
|
d873dd1 |
+ monitor->priv->poll_timeout_id = 0;
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = FALSE;
|
|
|
d873dd1 |
+ monitor->priv->module = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->security_tokens =
|
|
|
d873dd1 |
+ g_hash_table_new_full (g_str_hash,
|
|
|
d873dd1 |
+ g_str_equal,
|
|
|
d873dd1 |
+ (GDestroyNotify) g_free,
|
|
|
d873dd1 |
+ (GDestroyNotify) g_object_unref);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
|
|
|
d873dd1 |
+ monitor->priv->fds_to_close_on_fork = g_array_new (FALSE, FALSE, sizeof (gint));
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_finalize (GObject *object)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *monitor;
|
|
|
d873dd1 |
+ GObjectClass *gobject_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor = SC_SECURITY_TOKEN_MONITOR (object);
|
|
|
d873dd1 |
+ gobject_class =
|
|
|
d873dd1 |
+ G_OBJECT_CLASS (sc_security_token_monitor_parent_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop_now (monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_hash_table_destroy (monitor->priv->security_tokens);
|
|
|
d873dd1 |
+ monitor->priv->security_tokens = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
|
|
|
d873dd1 |
+ g_array_free (monitor->priv->fds_to_close_on_fork, TRUE);
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class->finalize (object);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+GQuark
|
|
|
d873dd1 |
+sc_security_token_monitor_error_quark (void)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ static GQuark error_quark = 0;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (error_quark == 0)
|
|
|
d873dd1 |
+ error_quark = g_quark_from_static_string ("sc-security-token-monitor-error-quark");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return error_quark;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ScSecurityTokenMonitor *
|
|
|
d873dd1 |
+sc_security_token_monitor_new (const gchar *module_path)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *instance;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ instance = SC_SECURITY_TOKEN_MONITOR (g_object_new (SC_TYPE_SECURITY_TOKEN_MONITOR,
|
|
|
d873dd1 |
+ "module-path", module_path,
|
|
|
d873dd1 |
+ NULL));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return instance;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_emit_error (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ GError *error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = TRUE;
|
|
|
d873dd1 |
+ g_signal_emit (monitor, sc_security_token_monitor_signals[ERROR], 0,
|
|
|
d873dd1 |
+ error);
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_emit_security_token_inserted (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = TRUE;
|
|
|
d873dd1 |
+ g_signal_emit (monitor, sc_security_token_monitor_signals[SECURITY_TOKEN_INSERTED], 0,
|
|
|
d873dd1 |
+ token);
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_emit_security_token_removed (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitorState old_state;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ old_state = monitor->priv->state;
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = TRUE;
|
|
|
d873dd1 |
+ g_signal_emit (monitor, sc_security_token_monitor_signals[SECURITY_TOKEN_REMOVED], 0,
|
|
|
d873dd1 |
+ token);
|
|
|
d873dd1 |
+ monitor->priv->is_unstoppable = FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_check_for_and_process_events (GIOChannel *io_channel,
|
|
|
d873dd1 |
+ GIOCondition condition,
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+ gboolean should_stop;
|
|
|
d873dd1 |
+ guchar event_type;
|
|
|
d873dd1 |
+ gchar *token_name;
|
|
|
d873dd1 |
+ gint fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = NULL;
|
|
|
d873dd1 |
+ should_stop = (condition & G_IO_HUP) || (condition & G_IO_ERR);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (should_stop)
|
|
|
d873dd1 |
+ sc_debug ("received %s on event socket, stopping "
|
|
|
d873dd1 |
+ "monitor...",
|
|
|
d873dd1 |
+ (condition & G_IO_HUP) && (condition & G_IO_ERR)?
|
|
|
d873dd1 |
+ "error and hangup" :
|
|
|
d873dd1 |
+ (condition & G_IO_HUP)?
|
|
|
d873dd1 |
+ "hangup" : "error");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!(condition & G_IO_IN))
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ fd = g_io_channel_unix_get_fd (io_channel);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ event_type = '\0';
|
|
|
d873dd1 |
+ if (!sc_read_bytes (fd, &event_type, 1)) {
|
|
|
d873dd1 |
+ should_stop = TRUE;
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = sc_read_security_token (fd, monitor->priv->module);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token == NULL) {
|
|
|
d873dd1 |
+ should_stop = TRUE;
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token_name = sc_security_token_get_name (token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ switch (event_type) {
|
|
|
d873dd1 |
+ case 'I':
|
|
|
d873dd1 |
+ g_hash_table_replace (monitor->priv->security_tokens,
|
|
|
d873dd1 |
+ token_name, token);
|
|
|
d873dd1 |
+ token_name = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_emit_security_token_inserted (monitor, token);
|
|
|
d873dd1 |
+ token = NULL;
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ case 'R':
|
|
|
d873dd1 |
+ sc_security_token_monitor_emit_security_token_removed (monitor, token);
|
|
|
d873dd1 |
+ if (!g_hash_table_remove (monitor->priv->security_tokens, token_name))
|
|
|
d873dd1 |
+ sc_debug ("got removal event of unknown token!");
|
|
|
d873dd1 |
+ g_free (token_name);
|
|
|
d873dd1 |
+ token_name = NULL;
|
|
|
d873dd1 |
+ token = NULL;
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ default:
|
|
|
d873dd1 |
+ g_free (token_name);
|
|
|
d873dd1 |
+ token_name = NULL;
|
|
|
d873dd1 |
+ g_object_unref (token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ should_stop = TRUE;
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+out:
|
|
|
d873dd1 |
+ if (should_stop) {
|
|
|
d873dd1 |
+ GError *error;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error = g_error_new (SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WATCHING_FOR_EVENTS,
|
|
|
d873dd1 |
+ "%s", (condition & G_IO_IN) ? g_strerror (errno) : _("received error or hang up from event source"));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_emit_error (monitor, error);
|
|
|
d873dd1 |
+ g_error_free (error);
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop_now (monitor);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_event_processing_stopped_handler (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ monitor->priv->security_token_event_source = NULL;
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop_now (monitor);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+/* sorta complex function that is nothing more than fork() without having
|
|
|
d873dd1 |
+ * to worry about reaping the child later with waitpid
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+static GPid
|
|
|
d873dd1 |
+sc_fork_and_disown (void)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ pid_t child_pid;
|
|
|
d873dd1 |
+ GPid grandchild_pid;
|
|
|
d873dd1 |
+ gint write_fd, read_fd;
|
|
|
d873dd1 |
+ gint saved_errno;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ write_fd = -1;
|
|
|
d873dd1 |
+ read_fd = -1;
|
|
|
d873dd1 |
+ if (!sc_open_pipe (&write_fd, &read_fd))
|
|
|
d873dd1 |
+ return (GPid) -1;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ child_pid = fork ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (child_pid < 0) {
|
|
|
d873dd1 |
+ close (write_fd);
|
|
|
d873dd1 |
+ close (read_fd);
|
|
|
d873dd1 |
+ return (GPid) child_pid;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (child_pid == 0) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* close the end of the pipe we're not going to use
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ close (read_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* fork again
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ child_pid = fork ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* in the event of error, write out negative errno
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (child_pid < 0) {
|
|
|
d873dd1 |
+ child_pid = -1 * errno;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_write_bytes (write_fd, &child_pid, sizeof (child_pid));
|
|
|
d873dd1 |
+ close (write_fd);
|
|
|
d873dd1 |
+ _exit (1);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* otherwise write out the pid of the child and exit
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (child_pid != 0) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ signal (SIGPIPE, SIG_IGN);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_write_bytes (write_fd, &child_pid, sizeof (child_pid))) {
|
|
|
d873dd1 |
+ kill (SIGKILL, child_pid);
|
|
|
d873dd1 |
+ _exit (2);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ close (write_fd);
|
|
|
d873dd1 |
+ _exit (0);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ close (write_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* we're done, we've forked without having to worry about
|
|
|
d873dd1 |
+ * reaping the child later
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ g_assert (child_pid == 0);
|
|
|
d873dd1 |
+ return (GPid) 0;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* close the end of the pipe we're not going to use
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ close (write_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ grandchild_pid = -1;
|
|
|
d873dd1 |
+ if (!sc_read_bytes (read_fd, &grandchild_pid, sizeof (grandchild_pid))) {
|
|
|
d873dd1 |
+ grandchild_pid = -1;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ saved_errno = errno;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* close the other end of the pipe since we're done with it
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ close (read_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* wait for child to die (and emancipate the grandchild)
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ waitpid (child_pid, NULL, 0);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ errno = saved_errno;
|
|
|
d873dd1 |
+ return (GPid) grandchild_pid;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_open_pipe (gint *write_fd,
|
|
|
d873dd1 |
+ gint *read_fd)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gint pipe_fds[2] = { -1, -1 };
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_assert (write_fd != NULL);
|
|
|
d873dd1 |
+ g_assert (read_fd != NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (pipe (pipe_fds) < 0)
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (fcntl (pipe_fds[0], F_SETFD, FD_CLOEXEC) < 0) {
|
|
|
d873dd1 |
+ close (pipe_fds[0]);
|
|
|
d873dd1 |
+ close (pipe_fds[1]);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (fcntl (pipe_fds[1], F_SETFD, FD_CLOEXEC) < 0) {
|
|
|
d873dd1 |
+ close (pipe_fds[0]);
|
|
|
d873dd1 |
+ close (pipe_fds[1]);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ *read_fd = pipe_fds[0];
|
|
|
d873dd1 |
+ *write_fd = pipe_fds[1];
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_stop_watching_for_events (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (monitor->priv->security_token_event_source != NULL) {
|
|
|
d873dd1 |
+ g_source_destroy (monitor->priv->security_token_event_source);
|
|
|
d873dd1 |
+ monitor->priv->security_token_event_source = NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (monitor->priv->security_token_event_watcher_pid > 0) {
|
|
|
d873dd1 |
+ kill (monitor->priv->security_token_event_watcher_pid, SIGKILL);
|
|
|
d873dd1 |
+ monitor->priv->security_token_event_watcher_pid = 0;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_load_nss (GError **error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ SECStatus status = SECSuccess;
|
|
|
d873dd1 |
+ static const guint32 flags =
|
|
|
d873dd1 |
+ NSS_INIT_READONLY| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
|
|
|
d873dd1 |
+ NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT |
|
|
|
d873dd1 |
+ NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("attempting to load NSS database '%s'",
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_NSS_DB);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ status = NSS_Initialize (SC_SECURITY_TOKEN_MONITOR_NSS_DB,
|
|
|
d873dd1 |
+ "", "", SECMOD_DB, flags);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (status != SECSuccess) {
|
|
|
d873dd1 |
+ gsize error_message_size;
|
|
|
d873dd1 |
+ gchar *error_message;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error_message_size = PR_GetErrorTextLength ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (error_message_size == 0) {
|
|
|
d873dd1 |
+ sc_debug ("NSS security system could not be initialized");
|
|
|
d873dd1 |
+ g_set_error (error,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
|
|
|
d873dd1 |
+ _("NSS security system could not be initialized"));
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error_message = g_slice_alloc0 (error_message_size);
|
|
|
d873dd1 |
+ PR_GetErrorText (error_message);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_set_error (error,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
|
|
|
d873dd1 |
+ "%s", error_message);
|
|
|
d873dd1 |
+ sc_debug ("NSS security system could not be initialized - %s",
|
|
|
d873dd1 |
+ error_message);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_slice_free1 (error_message_size, error_message);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("NSS database sucessfully loaded");
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+out:
|
|
|
d873dd1 |
+ sc_debug ("NSS database couldn't be sucessfully loaded");
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static SECMODModule *
|
|
|
d873dd1 |
+sc_load_driver (gchar *module_path,
|
|
|
d873dd1 |
+ GError **error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ SECMODModule *module;
|
|
|
d873dd1 |
+ gchar *module_spec;
|
|
|
d873dd1 |
+ gboolean module_explicitly_specified;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("attempting to load driver...");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ module = NULL;
|
|
|
d873dd1 |
+ module_explicitly_specified = module_path != NULL;
|
|
|
d873dd1 |
+ if (module_explicitly_specified) {
|
|
|
d873dd1 |
+ module_spec = g_strdup_printf ("library=\"%s\"", module_path);
|
|
|
d873dd1 |
+ sc_debug ("loading security token driver using spec '%s'",
|
|
|
d873dd1 |
+ module_spec);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ module = SECMOD_LoadUserModule (module_spec,
|
|
|
d873dd1 |
+ NULL /* parent */,
|
|
|
d873dd1 |
+ FALSE /* recurse */);
|
|
|
d873dd1 |
+ g_free (module_spec);
|
|
|
d873dd1 |
+ module_spec = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ SECMODModuleList *modules, *tmp;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ modules = SECMOD_GetDefaultModuleList ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (tmp = modules; tmp != NULL; tmp = tmp->next) {
|
|
|
d873dd1 |
+ if (!SECMOD_HasRemovableSlots (tmp->module) ||
|
|
|
d873dd1 |
+ !tmp->module->loaded)
|
|
|
d873dd1 |
+ continue;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ module = SECMOD_ReferenceModule (tmp->module);
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* fallback to compiled in driver path
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (module == NULL) {
|
|
|
d873dd1 |
+ if (g_file_test (SC_SECURITY_TOKEN_MONITOR_DRIVER,
|
|
|
d873dd1 |
+ G_FILE_TEST_IS_REGULAR)) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ module_spec = g_strdup_printf ("library=\"%s\"", module_path);
|
|
|
d873dd1 |
+ sc_debug ("loading security token driver using spec '%s'",
|
|
|
d873dd1 |
+ module_spec);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ module = SECMOD_LoadUserModule (module_spec,
|
|
|
d873dd1 |
+ NULL /* parent */,
|
|
|
d873dd1 |
+ FALSE /* recurse */);
|
|
|
d873dd1 |
+ g_free (module_spec);
|
|
|
d873dd1 |
+ module_spec = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!module_explicitly_specified && module == NULL) {
|
|
|
d873dd1 |
+ g_set_error (error,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
|
|
|
d873dd1 |
+ _("no suitable security token driver could be found"));
|
|
|
d873dd1 |
+ } else if (module == NULL || !module->loaded) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gsize error_message_size;
|
|
|
d873dd1 |
+ gchar *error_message;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (module != NULL && !module->loaded) {
|
|
|
d873dd1 |
+ sc_debug ("module found but not loaded?!");
|
|
|
d873dd1 |
+ SECMOD_DestroyModule (module);
|
|
|
d873dd1 |
+ module = NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error_message_size = PR_GetErrorTextLength ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (error_message_size == 0) {
|
|
|
d873dd1 |
+ sc_debug ("security token driver '%s' could not be loaded",
|
|
|
d873dd1 |
+ module_path);
|
|
|
d873dd1 |
+ g_set_error (error,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
|
|
|
d873dd1 |
+ _("security token driver '%s' could not be "
|
|
|
d873dd1 |
+ "loaded"), module_path);
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error_message = g_slice_alloc0 (error_message_size);
|
|
|
d873dd1 |
+ PR_GetErrorText (error_message);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_set_error (error,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_LOADING_DRIVER,
|
|
|
d873dd1 |
+ "%s", error_message);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("security token driver '%s' could not be loaded - %s",
|
|
|
d873dd1 |
+ module_path, error_message);
|
|
|
d873dd1 |
+ g_slice_free1 (error_message_size, error_message);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+out:
|
|
|
d873dd1 |
+ return module;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_get_all_tokens (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ int i;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (i = 0; i < monitor->priv->module->slotCount; i++) {
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+ CK_SLOT_ID slot_id;
|
|
|
d873dd1 |
+ gint slot_series;
|
|
|
d873dd1 |
+ gchar *token_name;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ slot_id = PK11_GetSlotID (monitor->priv->module->slots[i]);
|
|
|
d873dd1 |
+ slot_series = PK11_GetSlotSeries (monitor->priv->module->slots[i]);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = _sc_security_token_new (monitor->priv->module,
|
|
|
d873dd1 |
+ slot_id, slot_series);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token_name = sc_security_token_get_name (token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_hash_table_replace (monitor->priv->security_tokens,
|
|
|
d873dd1 |
+ token_name, token);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_start (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ GError **error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GError *watching_error;
|
|
|
d873dd1 |
+ gint worker_fd;
|
|
|
d873dd1 |
+ GPid worker_pid;
|
|
|
d873dd1 |
+ GIOChannel *io_channel;
|
|
|
d873dd1 |
+ GSource *source;
|
|
|
d873dd1 |
+ GIOFlags channel_flags;
|
|
|
d873dd1 |
+ GError *nss_error;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STARTED) {
|
|
|
d873dd1 |
+ sc_debug ("security token monitor already started");
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STARTING;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ worker_fd = -1;
|
|
|
d873dd1 |
+ worker_pid = 0;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ nss_error = NULL;
|
|
|
d873dd1 |
+ if (!monitor->priv->nss_is_loaded && !sc_load_nss (&nss_error)) {
|
|
|
d873dd1 |
+ g_propagate_error (error, nss_error);
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ monitor->priv->nss_is_loaded = TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (monitor->priv->module == NULL)
|
|
|
d873dd1 |
+ monitor->priv->module = sc_load_driver (monitor->priv->module_path, &nss_error);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (monitor->priv->module == NULL) {
|
|
|
d873dd1 |
+ g_propagate_error (error, nss_error);
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_create_worker (monitor, &worker_fd, &worker_pid)) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_set_error (error,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WATCHING_FOR_EVENTS,
|
|
|
d873dd1 |
+ _("could not watch for incoming token events - %s"),
|
|
|
d873dd1 |
+ g_strerror (errno));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ goto out;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->security_token_event_watcher_pid = worker_pid;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ io_channel = g_io_channel_unix_new (worker_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ channel_flags = g_io_channel_get_flags (io_channel);
|
|
|
d873dd1 |
+ watching_error = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ source = g_io_create_watch (io_channel, G_IO_IN | G_IO_HUP);
|
|
|
d873dd1 |
+ g_io_channel_unref (io_channel);
|
|
|
d873dd1 |
+ io_channel = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->security_token_event_source = source;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_source_set_callback (monitor->priv->security_token_event_source,
|
|
|
d873dd1 |
+ (GSourceFunc) (GIOFunc)
|
|
|
d873dd1 |
+ sc_security_token_monitor_check_for_and_process_events,
|
|
|
d873dd1 |
+ monitor,
|
|
|
d873dd1 |
+ (GDestroyNotify)
|
|
|
d873dd1 |
+ sc_security_token_monitor_event_processing_stopped_handler);
|
|
|
d873dd1 |
+ g_source_attach (monitor->priv->security_token_event_source, NULL);
|
|
|
d873dd1 |
+ g_source_unref (monitor->priv->security_token_event_source);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* populate the hash with tokens that are already inserted
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ sc_security_token_monitor_get_all_tokens (monitor);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STARTED;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+out:
|
|
|
d873dd1 |
+ /* don't leave it in a half started state
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (monitor->priv->state != SC_SECURITY_TOKEN_MONITOR_STATE_STARTED) {
|
|
|
d873dd1 |
+ sc_debug ("security token monitor could not be completely started");
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop (monitor);
|
|
|
d873dd1 |
+ } else
|
|
|
d873dd1 |
+ sc_debug ("security token monitor started");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STARTED;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_stop_now (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED)
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED;
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop_watching_for_events (monitor);
|
|
|
d873dd1 |
+#ifdef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
|
|
|
d873dd1 |
+ if (monitor->priv->module != NULL) {
|
|
|
d873dd1 |
+ SECMOD_DestroyModule (monitor->priv->module);
|
|
|
d873dd1 |
+ monitor->priv->module = NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (monitor->priv->nss_is_loaded) {
|
|
|
d873dd1 |
+ NSS_Shutdown ();
|
|
|
d873dd1 |
+ monitor->priv->nss_is_loaded = FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+ sc_debug ("security token monitor stopped");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_queue_stop (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ monitor->priv->state = SC_SECURITY_TOKEN_MONITOR_STATE_STOPPING;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_idle_add ((GSourceFunc) sc_security_token_monitor_stop_now, monitor);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+void
|
|
|
d873dd1 |
+sc_security_token_monitor_stop (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (monitor->priv->state == SC_SECURITY_TOKEN_MONITOR_STATE_STOPPED)
|
|
|
d873dd1 |
+ return;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (monitor->priv->is_unstoppable) {
|
|
|
d873dd1 |
+ sc_security_token_monitor_queue_stop (monitor);
|
|
|
d873dd1 |
+ return;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop_now (monitor);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_check_for_login_token (CK_SLOT_ID slot_id,
|
|
|
d873dd1 |
+ ScSecurityToken *token,
|
|
|
d873dd1 |
+ gboolean *is_inserted)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ g_assert (is_inserted != NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (sc_security_token_is_login_token (token))
|
|
|
d873dd1 |
+ *is_inserted = TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_login_token_is_inserted (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gboolean is_inserted;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ is_inserted = FALSE;
|
|
|
d873dd1 |
+ g_hash_table_foreach (monitor->priv->security_tokens,
|
|
|
d873dd1 |
+ (GHFunc)
|
|
|
d873dd1 |
+ sc_security_token_monitor_check_for_login_token,
|
|
|
d873dd1 |
+ &is_inserted);
|
|
|
d873dd1 |
+ return is_inserted;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gint
|
|
|
d873dd1 |
+sc_get_max_open_fds (void)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ struct rlimit open_fd_limit;
|
|
|
d873dd1 |
+ const gint fallback_limit = SC_MAX_OPEN_FILE_DESCRIPTORS;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (getrlimit (RLIMIT_NOFILE, &open_fd_limit) < 0) {
|
|
|
d873dd1 |
+ sc_debug ("could not get file descriptor limit: %s",
|
|
|
d873dd1 |
+ g_strerror (errno));
|
|
|
d873dd1 |
+ sc_debug ("returning fallback file descriptor limit of %d",
|
|
|
d873dd1 |
+ fallback_limit);
|
|
|
d873dd1 |
+ return fallback_limit;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (open_fd_limit.rlim_cur == RLIM_INFINITY) {
|
|
|
d873dd1 |
+ sc_debug ("currently no file descriptor limit, returning fallback limit of %d",
|
|
|
d873dd1 |
+ fallback_limit);
|
|
|
d873dd1 |
+ return fallback_limit;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return (gint) open_fd_limit.rlim_cur;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_close_all_fds (int *fds_to_keep_open)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ int max_open_fds, fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("closing all file descriptors");
|
|
|
d873dd1 |
+ max_open_fds = sc_get_max_open_fds ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (fd = 0; fd < max_open_fds; fd++) {
|
|
|
d873dd1 |
+ int i;
|
|
|
d873dd1 |
+ gboolean should_close_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ should_close_fd = TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (fds_to_keep_open != NULL) {
|
|
|
d873dd1 |
+ for (i = 0; fds_to_keep_open[i] >= 0; i++) {
|
|
|
d873dd1 |
+ if (fd == fds_to_keep_open[i]) {
|
|
|
d873dd1 |
+ should_close_fd = FALSE;
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (should_close_fd) {
|
|
|
d873dd1 |
+ sc_debug ("closing file descriptor '%d'", fd);
|
|
|
d873dd1 |
+ close (fd);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_close_open_fds (int *fds_to_keep_open)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ /* using DIR instead of GDir because we need access to dirfd so
|
|
|
d873dd1 |
+ * that we can iterate through the fds and close them in one sweep.
|
|
|
d873dd1 |
+ * (if we just closed all of them then we would close the one we're using
|
|
|
d873dd1 |
+ * for reading the directory!)
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ DIR *dir;
|
|
|
d873dd1 |
+ struct dirent *entry;
|
|
|
d873dd1 |
+ gint fd, opendir_fd;
|
|
|
d873dd1 |
+ gboolean should_use_fallback;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ should_use_fallback = FALSE;
|
|
|
d873dd1 |
+ opendir_fd = -1;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ dir = opendir (SC_OPEN_FILE_DESCRIPTORS_DIR);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (dir != NULL)
|
|
|
d873dd1 |
+ opendir_fd = dirfd (dir);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if ((dir == NULL) || (opendir_fd < 0)) {
|
|
|
d873dd1 |
+ sc_debug ("could not open "SC_OPEN_FILE_DESCRIPTORS_DIR": %s", g_strerror (errno));
|
|
|
d873dd1 |
+ should_use_fallback = TRUE;
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ sc_debug ("reading files in '"SC_OPEN_FILE_DESCRIPTORS_DIR"'");
|
|
|
d873dd1 |
+ while ((entry = readdir (dir)) != NULL) {
|
|
|
d873dd1 |
+ gint i;
|
|
|
d873dd1 |
+ glong filename_as_number;
|
|
|
d873dd1 |
+ gchar *byte_after_number;
|
|
|
d873dd1 |
+ gboolean should_close_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ errno = 0;
|
|
|
d873dd1 |
+ if (entry->d_name[0] == '.')
|
|
|
d873dd1 |
+ continue;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("scanning filename '%s' for file descriptor number",
|
|
|
d873dd1 |
+ entry->d_name);
|
|
|
d873dd1 |
+ fd = -1;
|
|
|
d873dd1 |
+ filename_as_number = strtol (entry->d_name, &byte_after_number, 10);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_assert (byte_after_number != NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if ((*byte_after_number != '\0') ||
|
|
|
d873dd1 |
+ (filename_as_number < 0) ||
|
|
|
d873dd1 |
+ (filename_as_number >= G_MAXINT)) {
|
|
|
d873dd1 |
+ sc_debug ("filename '%s' does not appear to represent a "
|
|
|
d873dd1 |
+ "file descriptor: %s",
|
|
|
d873dd1 |
+ entry->d_name, strerror (errno));
|
|
|
d873dd1 |
+ should_use_fallback = TRUE;
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ fd = (gint) filename_as_number;
|
|
|
d873dd1 |
+ sc_debug ("filename '%s' represents file descriptor '%d'",
|
|
|
d873dd1 |
+ entry->d_name, fd);
|
|
|
d873dd1 |
+ should_use_fallback = FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (fd == opendir_fd) {
|
|
|
d873dd1 |
+ should_close_fd = FALSE;
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ should_close_fd = TRUE;
|
|
|
d873dd1 |
+ if (fds_to_keep_open != NULL)
|
|
|
d873dd1 |
+ for (i = 0; fds_to_keep_open[i] >= 0; i++) {
|
|
|
d873dd1 |
+ if (fd == fds_to_keep_open[i]) {
|
|
|
d873dd1 |
+ should_close_fd = FALSE;
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (should_close_fd) {
|
|
|
d873dd1 |
+ sc_debug ("closing file descriptor '%d'", fd);
|
|
|
d873dd1 |
+ close (fd);
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ sc_debug ("will not close file descriptor '%d' because it "
|
|
|
d873dd1 |
+ "is still needed", fd);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (entry != NULL)
|
|
|
d873dd1 |
+ should_use_fallback = TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("closing directory '"SC_OPEN_FILE_DESCRIPTORS_DIR"'");
|
|
|
d873dd1 |
+ closedir (dir);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* if /proc isn't mounted or something else is screwy,
|
|
|
d873dd1 |
+ * fall back to closing everything
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (should_use_fallback)
|
|
|
d873dd1 |
+ sc_close_all_fds (fds_to_keep_open);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_close_fds (gint *fds,
|
|
|
d873dd1 |
+ gint num_fds)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gint i;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (i = 0; i < num_fds; i++)
|
|
|
d873dd1 |
+ close (fds[i]);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static ScSecurityTokenMonitorWorker *
|
|
|
d873dd1 |
+sc_security_token_monitor_worker_new (gint write_fd)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitorWorker *worker;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ worker = g_slice_new0 (ScSecurityTokenMonitorWorker);
|
|
|
d873dd1 |
+ worker->write_fd = write_fd;
|
|
|
d873dd1 |
+ worker->module = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ worker->security_tokens =
|
|
|
d873dd1 |
+ g_hash_table_new_full ((GHashFunc) sc_slot_id_hash,
|
|
|
d873dd1 |
+ (GEqualFunc) sc_slot_id_equal,
|
|
|
d873dd1 |
+ (GDestroyNotify) g_free,
|
|
|
d873dd1 |
+ (GDestroyNotify) g_object_unref);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return worker;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_worker_free (ScSecurityTokenMonitorWorker *worker)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (worker->security_tokens != NULL) {
|
|
|
d873dd1 |
+ g_hash_table_destroy (worker->security_tokens);
|
|
|
d873dd1 |
+ worker->security_tokens = NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_slice_free (ScSecurityTokenMonitorWorker, worker);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+/* This function checks to see if the helper's connection to the
|
|
|
d873dd1 |
+ * parent process has been closed. If it has, we assume the
|
|
|
d873dd1 |
+ * parent has died (or is otherwise done with the connection)
|
|
|
d873dd1 |
+ * and so we die, too. We do this from a signal handler (yuck!)
|
|
|
d873dd1 |
+ * because there isn't a nice way to cancel the
|
|
|
d873dd1 |
+ * SECMOD_WaitForAnyTokenEvent call, which just sits and blocks
|
|
|
d873dd1 |
+ * indefinitely. There is a SECMOD_CancelWait wait function
|
|
|
d873dd1 |
+ * that we could call if we would have gone multithreaded like
|
|
|
d873dd1 |
+ * NSS really wants us to do, but that call isn't signal handler
|
|
|
d873dd1 |
+ * safe, so we just _exit() instead (eww).
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+worker_io_signal_handler (int signal_number,
|
|
|
d873dd1 |
+ siginfo_t *signal_info,
|
|
|
d873dd1 |
+ void *data)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ int number_of_events;
|
|
|
d873dd1 |
+ int old_errno;
|
|
|
d873dd1 |
+ struct pollfd poll_fds[1] = { { 0 } };
|
|
|
d873dd1 |
+ int parent_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ old_errno = errno;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* pipe fd set up to talk to the parent */
|
|
|
d873dd1 |
+ parent_fd = signal_info->si_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* We only care about disconnection events
|
|
|
d873dd1 |
+ * (which get unmasked implicitly), so we just
|
|
|
d873dd1 |
+ * pass 0 for the event mask
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ poll_fds[0].events = 0;
|
|
|
d873dd1 |
+ poll_fds[0].fd = parent_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ do {
|
|
|
d873dd1 |
+ number_of_events = poll (poll_fds, G_N_ELEMENTS (poll_fds), 0);
|
|
|
d873dd1 |
+ } while ((number_of_events < 0) && (errno == EINTR));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_assert (number_of_events <= G_N_ELEMENTS (poll_fds));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (number_of_events < 0)
|
|
|
d873dd1 |
+ _exit (errno);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* pipe disconnected; parent died
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if (number_of_events > 0) {
|
|
|
d873dd1 |
+ g_assert (!(poll_fds[0].revents & POLLNVAL));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if ((poll_fds[0].revents & POLLHUP) ||
|
|
|
d873dd1 |
+ (poll_fds[0].revents & POLLERR)) {
|
|
|
d873dd1 |
+ _exit (poll_fds[0].revents);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ errno = old_errno;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_monitor_worker_die_with_parent (ScSecurityTokenMonitorWorker *worker)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ struct sigaction action = { { 0 } };
|
|
|
d873dd1 |
+ gint flags;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* dirty hack to clean up worker if parent goes away
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ sigemptyset (&action.sa_mask);
|
|
|
d873dd1 |
+ action.sa_sigaction = worker_io_signal_handler;
|
|
|
d873dd1 |
+ action.sa_flags = SA_SIGINFO;
|
|
|
d873dd1 |
+ sigaction (SIGIO, &action, NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ flags = fcntl (worker->write_fd, F_GETFL, 0);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ fcntl (worker->write_fd, F_SETOWN, getpid ());
|
|
|
d873dd1 |
+ fcntl (worker->write_fd, F_SETFL, flags | O_ASYNC);
|
|
|
d873dd1 |
+ fcntl (worker->write_fd, F_SETSIG, SIGIO);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_read_bytes (gint fd, gpointer bytes, gsize num_bytes)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ size_t bytes_left;
|
|
|
d873dd1 |
+ size_t total_bytes_read;
|
|
|
d873dd1 |
+ ssize_t bytes_read;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ bytes_left = (size_t) num_bytes;
|
|
|
d873dd1 |
+ total_bytes_read = 0;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ do {
|
|
|
d873dd1 |
+ bytes_read = read (fd, bytes + total_bytes_read, bytes_left);
|
|
|
d873dd1 |
+ g_assert (bytes_read <= (ssize_t) bytes_left);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (bytes_read <= 0) {
|
|
|
d873dd1 |
+ if ((bytes_read < 0) && (errno == EINTR || errno == EAGAIN))
|
|
|
d873dd1 |
+ continue;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ bytes_left = 0;
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ bytes_left -= bytes_read;
|
|
|
d873dd1 |
+ total_bytes_read += bytes_read;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ } while (bytes_left > 0);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (total_bytes_read < (size_t) num_bytes)
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_write_bytes (gint fd, gconstpointer bytes, gsize num_bytes)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ size_t bytes_left;
|
|
|
d873dd1 |
+ size_t total_bytes_written;
|
|
|
d873dd1 |
+ ssize_t bytes_written;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ bytes_left = (size_t) num_bytes;
|
|
|
d873dd1 |
+ total_bytes_written = 0;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ do {
|
|
|
d873dd1 |
+ bytes_written = write (fd, bytes + total_bytes_written, bytes_left);
|
|
|
d873dd1 |
+ g_assert (bytes_written <= (ssize_t) bytes_left);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (bytes_written <= 0) {
|
|
|
d873dd1 |
+ if ((bytes_written < 0) && (errno == EINTR || errno == EAGAIN))
|
|
|
d873dd1 |
+ continue;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ bytes_left = 0;
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ bytes_left -= bytes_written;
|
|
|
d873dd1 |
+ total_bytes_written += bytes_written;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ } while (bytes_left > 0);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (total_bytes_written < (size_t) num_bytes)
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static ScSecurityToken *
|
|
|
d873dd1 |
+sc_read_security_token (gint fd, SECMODModule *module)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+ gchar *token_name;
|
|
|
d873dd1 |
+ gsize token_name_size;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token_name_size = 0;
|
|
|
d873dd1 |
+ if (!sc_read_bytes (fd, &token_name_size, sizeof (token_name_size)))
|
|
|
d873dd1 |
+ return NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token_name = g_slice_alloc0 (token_name_size);
|
|
|
d873dd1 |
+ if (!sc_read_bytes (fd, token_name, token_name_size)) {
|
|
|
d873dd1 |
+ g_slice_free1 (token_name_size, token_name);
|
|
|
d873dd1 |
+ return NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ token = _sc_security_token_new_from_name (module, token_name);
|
|
|
d873dd1 |
+ g_slice_free1 (token_name_size, token_name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return token;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_write_security_token (gint fd,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gsize token_name_size;
|
|
|
d873dd1 |
+ gchar *token_name;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token_name = sc_security_token_get_name (token);
|
|
|
d873dd1 |
+ token_name_size = strlen (token_name) + 1;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_write_bytes (fd, &token_name_size, sizeof (token_name_size))) {
|
|
|
d873dd1 |
+ g_free (token_name);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_write_bytes (fd, token_name, token_name_size)) {
|
|
|
d873dd1 |
+ g_free (token_name);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ g_free (token_name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_worker_emit_security_token_removed (ScSecurityTokenMonitorWorker *worker,
|
|
|
d873dd1 |
+ ScSecurityToken *token,
|
|
|
d873dd1 |
+ GError **error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ sc_debug ("token '%s' removed!", sc_security_token_get_name (token));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_write_bytes (worker->write_fd, "R", 1))
|
|
|
d873dd1 |
+ goto error_out;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_write_security_token (worker->write_fd, token))
|
|
|
d873dd1 |
+ goto error_out;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+error_out:
|
|
|
d873dd1 |
+ g_set_error (error, SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_REPORTING_EVENTS,
|
|
|
d873dd1 |
+ "%s", g_strerror (errno));
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_worker_emit_security_token_inserted (ScSecurityTokenMonitorWorker *worker,
|
|
|
d873dd1 |
+ ScSecurityToken *token,
|
|
|
d873dd1 |
+ GError **error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GError *write_error;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ write_error = NULL;
|
|
|
d873dd1 |
+ sc_debug ("token '%s' inserted!", sc_security_token_get_name (token));
|
|
|
d873dd1 |
+ if (!sc_write_bytes (worker->write_fd, "I", 1))
|
|
|
d873dd1 |
+ goto error_out;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_write_security_token (worker->write_fd, token))
|
|
|
d873dd1 |
+ goto error_out;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+error_out:
|
|
|
d873dd1 |
+ g_set_error (error, SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_REPORTING_EVENTS,
|
|
|
d873dd1 |
+ "%s", g_strerror (errno));
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_worker_watch_for_and_process_event (ScSecurityTokenMonitorWorker *worker,
|
|
|
d873dd1 |
+ GError **error)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ PK11SlotInfo *slot;
|
|
|
d873dd1 |
+ CK_SLOT_ID slot_id, *key;
|
|
|
d873dd1 |
+ gint slot_series, token_slot_series;
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+ GError *processing_error;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("waiting for token event");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* FIXME: we return FALSE quite a bit in this function without cleaning up
|
|
|
d873dd1 |
+ * resources. By returning FALSE we're going to ultimately exit anyway, but
|
|
|
d873dd1 |
+ * we should still be tidier about things.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ slot = SECMOD_WaitForAnyTokenEvent (worker->module, 0, PR_SecondsToInterval (1));
|
|
|
d873dd1 |
+ processing_error = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (slot == NULL) {
|
|
|
d873dd1 |
+ int error_code;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error_code = PORT_GetError ();
|
|
|
d873dd1 |
+ if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT)) {
|
|
|
d873dd1 |
+ sc_debug ("spurrious event occurred");
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* FIXME: is there a function to convert from a PORT error
|
|
|
d873dd1 |
+ * code to a translated string?
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ g_set_error (error, SC_SECURITY_TOKEN_MONITOR_ERROR,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_MONITOR_ERROR_WITH_NSS,
|
|
|
d873dd1 |
+ _("encountered unexpected error while "
|
|
|
d873dd1 |
+ "waiting for security token events"));
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* the slot id and series together uniquely identify a token.
|
|
|
d873dd1 |
+ * You can never have two tokens with the same slot id at the
|
|
|
d873dd1 |
+ * same time, however (I think), so we can key off of it.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ slot_id = PK11_GetSlotID (slot);
|
|
|
d873dd1 |
+ slot_series = PK11_GetSlotSeries (slot);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* First check to see if there is a token that we're currently
|
|
|
d873dd1 |
+ * tracking in the slot.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ key = g_new (CK_SLOT_ID, 1);
|
|
|
d873dd1 |
+ *key = slot_id;
|
|
|
d873dd1 |
+ token = g_hash_table_lookup (worker->security_tokens, key);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token != NULL)
|
|
|
d873dd1 |
+ token_slot_series = sc_security_token_get_slot_series (token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (PK11_IsPresent (slot)) {
|
|
|
d873dd1 |
+ /* Now, check to see if their is a new token in the slot.
|
|
|
d873dd1 |
+ * If there was a different token in the slot now than
|
|
|
d873dd1 |
+ * there was before, then we need to emit a removed signal
|
|
|
d873dd1 |
+ * for the old token (we don't want unpaired insertion events).
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if ((token != NULL) &&
|
|
|
d873dd1 |
+ token_slot_series != slot_series) {
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_worker_emit_security_token_removed (worker, token, &processing_error)) {
|
|
|
d873dd1 |
+ g_propagate_error (error, processing_error);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = _sc_security_token_new (worker->module,
|
|
|
d873dd1 |
+ slot_id, slot_series);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_hash_table_replace (worker->security_tokens,
|
|
|
d873dd1 |
+ key, token);
|
|
|
d873dd1 |
+ key = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_worker_emit_security_token_inserted (worker, token, &processing_error)) {
|
|
|
d873dd1 |
+ g_propagate_error (error, processing_error);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ /* if we aren't tracking the token, just discard the event.
|
|
|
d873dd1 |
+ * We don't want unpaired remove events. Note on startup
|
|
|
d873dd1 |
+ * NSS will generate an "insertion" event if a token is
|
|
|
d873dd1 |
+ * already inserted in the slot.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if ((token != NULL)) {
|
|
|
d873dd1 |
+ /* FIXME: i'm not sure about this code. Maybe we
|
|
|
d873dd1 |
+ * shouldn't do this at all, or maybe we should do it
|
|
|
d873dd1 |
+ * n times (where n = slot_series - token_slot_series + 1)
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * Right now, i'm just doing it once.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ if ((slot_series - token_slot_series) > 1) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_worker_emit_security_token_removed (worker, token, &processing_error)) {
|
|
|
d873dd1 |
+ g_propagate_error (error, processing_error);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ g_hash_table_remove (worker->security_tokens, key);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = _sc_security_token_new (worker->module,
|
|
|
d873dd1 |
+ slot_id, slot_series);
|
|
|
d873dd1 |
+ g_hash_table_replace (worker->security_tokens,
|
|
|
d873dd1 |
+ key, token);
|
|
|
d873dd1 |
+ key = NULL;
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_worker_emit_security_token_inserted (worker, token, &processing_error)) {
|
|
|
d873dd1 |
+ g_propagate_error (error, processing_error);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_worker_emit_security_token_removed (worker, token, &processing_error)) {
|
|
|
d873dd1 |
+ g_propagate_error (error, processing_error);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_hash_table_remove (worker->security_tokens, key);
|
|
|
d873dd1 |
+ token = NULL;
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ sc_debug ("got spurious remove event");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_free (key);
|
|
|
d873dd1 |
+ PK11_FreeSlot (slot);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_monitor_create_worker (ScSecurityTokenMonitor *monitor,
|
|
|
d873dd1 |
+ gint *worker_fd, GPid *worker_pid)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GPid child_pid;
|
|
|
d873dd1 |
+ gint write_fd, read_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ write_fd = -1;
|
|
|
d873dd1 |
+ read_fd = -1;
|
|
|
d873dd1 |
+ if (!sc_open_pipe (&write_fd, &read_fd))
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ child_pid = sc_fork_and_disown ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (child_pid < 0)
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (child_pid == 0) {
|
|
|
d873dd1 |
+ GError *error;
|
|
|
d873dd1 |
+ ScSecurityTokenMonitorWorker *worker;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+/* FIXME: Gotta figure out why this isn't working
|
|
|
d873dd1 |
+*/
|
|
|
d873dd1 |
+#ifdef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
|
|
|
d873dd1 |
+ gint fds_to_keep_open[] = { -1, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, -1 };
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ SECMOD_DestroyModule (monitor->priv->module);
|
|
|
d873dd1 |
+ monitor->priv->module = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ NSS_Shutdown ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ fds_to_keep_open[0] = write_fd;
|
|
|
d873dd1 |
+ sc_close_open_fds (fds_to_keep_open);
|
|
|
d873dd1 |
+ read_fd = -1;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_load_nss (&error)) {
|
|
|
d873dd1 |
+ sc_debug ("could not load nss - %s", error->message);
|
|
|
d873dd1 |
+ g_error_free (error);
|
|
|
d873dd1 |
+ _exit (1);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+#else
|
|
|
d873dd1 |
+ g_array_append_val (monitor->priv->fds_to_close_on_fork, read_fd);
|
|
|
d873dd1 |
+ /* Junky workaround to keep from leaking fds
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ sc_close_fds ((gint *) monitor->priv->fds_to_close_on_fork->data,
|
|
|
d873dd1 |
+ monitor->priv->fds_to_close_on_fork->len);
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+ error = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ worker = sc_security_token_monitor_worker_new (write_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_monitor_worker_die_with_parent (worker);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ worker->module = sc_load_driver (monitor->priv->module_path, &error);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (worker->module == NULL) {
|
|
|
d873dd1 |
+ sc_debug ("could not load nss driver - %s", error->message);
|
|
|
d873dd1 |
+ g_error_free (error);
|
|
|
d873dd1 |
+ _exit (2);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ while (sc_security_token_monitor_worker_watch_for_and_process_event (worker, &error));
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("could not process token event - %s", error->message);
|
|
|
d873dd1 |
+ sc_security_token_monitor_worker_free (worker);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ _exit (0);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ close (write_fd);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_MONITOR_DRIVER_CAN_BE_RELOADED_AFTER_BEING_DESTROYED
|
|
|
d873dd1 |
+ g_array_append_val (monitor->priv->fds_to_close_on_fork, read_fd);
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (worker_pid)
|
|
|
d873dd1 |
+ *worker_pid = child_pid;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (worker_fd)
|
|
|
d873dd1 |
+ *worker_fd = read_fd;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifdef SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST
|
|
|
d873dd1 |
+#include <glib.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static GMainLoop *event_loop;
|
|
|
d873dd1 |
+static gboolean should_exit_on_next_remove = FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+on_timeout (ScSecurityTokenMonitor *monitor)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GError *error;
|
|
|
d873dd1 |
+ g_print ("Re-enabling monitor.\n");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_start (monitor, &error)) {
|
|
|
d873dd1 |
+ g_warning ("could not start security token monitor - %s",
|
|
|
d873dd1 |
+ error->message);
|
|
|
d873dd1 |
+ g_error_free (error);
|
|
|
d873dd1 |
+ return 1;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ g_print ("Please re-insert security token\n");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ should_exit_on_next_remove = TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+on_device_inserted (ScSecurityTokenMonitor * monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ g_print ("security token inserted!\n");
|
|
|
d873dd1 |
+ g_print ("Please remove it.\n");
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+on_device_removed (ScSecurityTokenMonitor * monitor,
|
|
|
d873dd1 |
+ ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ g_print ("security token removed!\n");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (should_exit_on_next_remove)
|
|
|
d873dd1 |
+ g_main_loop_quit (event_loop);
|
|
|
d873dd1 |
+ else {
|
|
|
d873dd1 |
+ g_print ("disabling monitor for 2 seconds\n");
|
|
|
d873dd1 |
+ sc_security_token_monitor_stop (monitor);
|
|
|
d873dd1 |
+ g_timeout_add (2000, (GSourceFunc) on_timeout, monitor);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+int
|
|
|
d873dd1 |
+main (int argc,
|
|
|
d873dd1 |
+ char *argv[])
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityTokenMonitor *monitor;
|
|
|
d873dd1 |
+ GError *error;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR
|
|
|
d873dd1 |
+ | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_type_init ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_message ("creating instance of 'security token monitor' object...");
|
|
|
d873dd1 |
+ monitor = sc_security_token_monitor_new (NULL);
|
|
|
d873dd1 |
+ g_message ("'security token monitor' object created successfully");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_signal_connect (monitor, "security-token-inserted",
|
|
|
d873dd1 |
+ G_CALLBACK (on_device_inserted), NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_signal_connect (monitor, "security-token-removed",
|
|
|
d873dd1 |
+ G_CALLBACK (on_device_removed), NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_message ("starting listener...");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ error = NULL;
|
|
|
d873dd1 |
+ if (!sc_security_token_monitor_start (monitor, &error)) {
|
|
|
d873dd1 |
+ g_warning ("could not start security token monitor - %s",
|
|
|
d873dd1 |
+ error->message);
|
|
|
d873dd1 |
+ g_error_free (error);
|
|
|
d873dd1 |
+ return 1;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ event_loop = g_main_loop_new (NULL, FALSE);
|
|
|
d873dd1 |
+ g_main_loop_run (event_loop);
|
|
|
d873dd1 |
+ g_main_loop_unref (event_loop);
|
|
|
d873dd1 |
+ event_loop = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_message ("destroying previously created 'security token monitor' object...");
|
|
|
d873dd1 |
+ g_object_unref (monitor);
|
|
|
d873dd1 |
+ monitor = NULL;
|
|
|
d873dd1 |
+ g_message ("'security token monitor' object destroyed successfully");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return 0;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
--- /dev/null 2007-03-12 21:48:12.974260066 -0400
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/securitytoken.c 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -0,0 +1,680 @@
|
|
|
d873dd1 |
+/* securitytoken.c - security token
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
d873dd1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
d873dd1 |
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
|
d873dd1 |
+ * any later version.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
d873dd1 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d873dd1 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
d873dd1 |
+ * GNU General Public License for more details.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * You should have received a copy of the GNU General Public License
|
|
|
d873dd1 |
+ * along with this program; if not, write to the Free Software
|
|
|
d873dd1 |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
d873dd1 |
+ * 02111-1307, USA.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * TODO: - doing this per project is a bad idea i think.
|
|
|
d873dd1 |
+ * We should probably make this a system service
|
|
|
d873dd1 |
+ * and use dbus.
|
|
|
d873dd1 |
+ *
|
|
|
d873dd1 |
+ * - We hardcode a driver right now. We should probably
|
|
|
d873dd1 |
+ * look up the default list and go from there.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_ENABLE_INTERNAL_API
|
|
|
d873dd1 |
+#include "securitytoken.h"
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <errno.h>
|
|
|
d873dd1 |
+#include <string.h>
|
|
|
d873dd1 |
+#include <unistd.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <glib.h>
|
|
|
d873dd1 |
+#include <glib/gi18n.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#include <cert.h>
|
|
|
d873dd1 |
+#include <nss.h>
|
|
|
d873dd1 |
+#include <pk11func.h>
|
|
|
d873dd1 |
+#include <prerror.h>
|
|
|
d873dd1 |
+#include <secmod.h>
|
|
|
d873dd1 |
+#include <secerr.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#if defined (SC_SECURITY_TOKEN_ENABLE_TEST) || defined (SC_SECURITY_TOKEN_MONITOR_ENABLE_TEST)
|
|
|
d873dd1 |
+#define sc_debug(format, args...) g_printerr (format "\n", ##args)
|
|
|
d873dd1 |
+#define sc_warning(format, args...) g_printerr (format "\n", ##args)
|
|
|
d873dd1 |
+#else
|
|
|
d873dd1 |
+#define sc_debug(format, args...)
|
|
|
d873dd1 |
+#define sc_warning(format, args...)
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+struct _ScSecurityTokenPrivate {
|
|
|
d873dd1 |
+ SECMODModule *module;
|
|
|
d873dd1 |
+ ScSecurityTokenState state;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ CK_SLOT_ID slot_id;
|
|
|
d873dd1 |
+ gint slot_series;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ PK11SlotInfo *slot;
|
|
|
d873dd1 |
+ gchar *name;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ CERTCertificate *signing_certificate;
|
|
|
d873dd1 |
+ CERTCertificate *encryption_certificate;
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void sc_security_token_finalize (GObject *object);
|
|
|
d873dd1 |
+static void sc_security_token_class_install_signals (ScSecurityTokenClass *token_class);
|
|
|
d873dd1 |
+static void sc_security_token_class_install_properties (ScSecurityTokenClass *token_class);
|
|
|
d873dd1 |
+static void sc_security_token_set_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ const GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec);
|
|
|
d873dd1 |
+static void sc_security_token_get_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec);
|
|
|
d873dd1 |
+static void sc_security_token_set_name (ScSecurityToken *token, const gchar *name);
|
|
|
d873dd1 |
+static void sc_security_token_set_slot_id (ScSecurityToken *token,
|
|
|
d873dd1 |
+ gint slot_id);
|
|
|
d873dd1 |
+static void sc_security_token_set_slot_series (ScSecurityToken *token,
|
|
|
d873dd1 |
+ gint slot_series);
|
|
|
d873dd1 |
+static void sc_security_token_set_module (ScSecurityToken *token,
|
|
|
d873dd1 |
+ SECMODModule *module);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static PK11SlotInfo *sc_security_token_find_slot_from_id (ScSecurityToken *token,
|
|
|
d873dd1 |
+ gint slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static PK11SlotInfo *sc_security_token_find_slot_from_token_name (ScSecurityToken *token,
|
|
|
d873dd1 |
+ const gchar *token_name);
|
|
|
d873dd1 |
+static gboolean sc_security_token_fetch_certificates (ScSecurityToken *token);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_DEFAULT_SLOT_ID
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_DEFAULT_SLOT_ID ((gulong) -1)
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifndef SC_SECURITY_TOKEN_DEFAULT_SLOT_SERIES
|
|
|
d873dd1 |
+#define SC_SECURITY_TOKEN_DEFAULT_SLOT_SERIES -1
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum {
|
|
|
d873dd1 |
+ PROP_0 = 0,
|
|
|
d873dd1 |
+ PROP_NAME,
|
|
|
d873dd1 |
+ PROP_SLOT_ID,
|
|
|
d873dd1 |
+ PROP_SLOT_SERIES,
|
|
|
d873dd1 |
+ PROP_MODULE,
|
|
|
d873dd1 |
+ NUMBER_OF_PROPERTIES
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+enum {
|
|
|
d873dd1 |
+ INSERTED,
|
|
|
d873dd1 |
+ REMOVED,
|
|
|
d873dd1 |
+ NUMBER_OF_SIGNALS
|
|
|
d873dd1 |
+};
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static guint sc_security_token_signals[NUMBER_OF_SIGNALS];
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+G_DEFINE_TYPE (ScSecurityToken, sc_security_token, G_TYPE_OBJECT);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_class_init (ScSecurityTokenClass *token_class)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GObjectClass *gobject_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class = G_OBJECT_CLASS (token_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class->finalize = sc_security_token_finalize;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_class_install_signals (token_class);
|
|
|
d873dd1 |
+ sc_security_token_class_install_properties (token_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_type_class_add_private (token_class,
|
|
|
d873dd1 |
+ sizeof (ScSecurityTokenPrivate));
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_class_install_signals (ScSecurityTokenClass *token_class)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GObjectClass *object_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ object_class = G_OBJECT_CLASS (token_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_signals[INSERTED] =
|
|
|
d873dd1 |
+ g_signal_new ("inserted",
|
|
|
d873dd1 |
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
|
d873dd1 |
+ G_SIGNAL_RUN_LAST,
|
|
|
d873dd1 |
+ G_STRUCT_OFFSET (ScSecurityTokenClass,
|
|
|
d873dd1 |
+ inserted),
|
|
|
d873dd1 |
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
|
|
|
d873dd1 |
+ G_TYPE_NONE, 0);
|
|
|
d873dd1 |
+ token_class->inserted = NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_signals[REMOVED] =
|
|
|
d873dd1 |
+ g_signal_new ("removed",
|
|
|
d873dd1 |
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
|
d873dd1 |
+ G_SIGNAL_RUN_LAST,
|
|
|
d873dd1 |
+ G_STRUCT_OFFSET (ScSecurityTokenClass,
|
|
|
d873dd1 |
+ removed),
|
|
|
d873dd1 |
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
|
|
|
d873dd1 |
+ G_TYPE_NONE, 0);
|
|
|
d873dd1 |
+ token_class->removed = NULL;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_class_install_properties (ScSecurityTokenClass *token_class)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ GObjectClass *object_class;
|
|
|
d873dd1 |
+ GParamSpec *param_spec;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ object_class = G_OBJECT_CLASS (token_class);
|
|
|
d873dd1 |
+ object_class->set_property = sc_security_token_set_property;
|
|
|
d873dd1 |
+ object_class->get_property = sc_security_token_get_property;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ param_spec = g_param_spec_ulong ("slot-id", _("Slot ID"),
|
|
|
d873dd1 |
+ _("The slot the token is in"),
|
|
|
d873dd1 |
+ 1, G_MAXULONG,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_DEFAULT_SLOT_ID,
|
|
|
d873dd1 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
|
d873dd1 |
+ g_object_class_install_property (object_class, PROP_SLOT_ID, param_spec);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ param_spec = g_param_spec_int ("slot-series", _("Slot Series"),
|
|
|
d873dd1 |
+ _("per-slot token identifier"),
|
|
|
d873dd1 |
+ -1, G_MAXINT,
|
|
|
d873dd1 |
+ SC_SECURITY_TOKEN_DEFAULT_SLOT_SERIES,
|
|
|
d873dd1 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
|
d873dd1 |
+ g_object_class_install_property (object_class, PROP_SLOT_SERIES, param_spec);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ param_spec = g_param_spec_string ("name", _("name"),
|
|
|
d873dd1 |
+ _("name"), NULL,
|
|
|
d873dd1 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
|
d873dd1 |
+ g_object_class_install_property (object_class, PROP_NAME, param_spec);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ param_spec = g_param_spec_pointer ("module", _("Module"),
|
|
|
d873dd1 |
+ _("security token driver"),
|
|
|
d873dd1 |
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
|
|
d873dd1 |
+ g_object_class_install_property (object_class, PROP_MODULE, param_spec);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_set_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ const GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token = SC_SECURITY_TOKEN (object);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ switch (prop_id)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ case PROP_NAME:
|
|
|
d873dd1 |
+ sc_security_token_set_name (token, g_value_get_string (value));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ case PROP_SLOT_ID:
|
|
|
d873dd1 |
+ sc_security_token_set_slot_id (token,
|
|
|
d873dd1 |
+ g_value_get_ulong (value));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ case PROP_SLOT_SERIES:
|
|
|
d873dd1 |
+ sc_security_token_set_slot_series (token,
|
|
|
d873dd1 |
+ g_value_get_int (value));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ case PROP_MODULE:
|
|
|
d873dd1 |
+ sc_security_token_set_module (token,
|
|
|
d873dd1 |
+ (SECMODModule *)
|
|
|
d873dd1 |
+ g_value_get_pointer (value));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ default:
|
|
|
d873dd1 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+CK_SLOT_ID
|
|
|
d873dd1 |
+sc_security_token_get_slot_id (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ return token->priv->slot_id;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ScSecurityTokenState
|
|
|
d873dd1 |
+sc_security_token_get_state (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ return token->priv->state;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gchar *
|
|
|
d873dd1 |
+sc_security_token_get_name (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ return g_strdup (token->priv->name);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gboolean
|
|
|
d873dd1 |
+sc_security_token_is_login_token (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ const gchar *login_token_name;
|
|
|
d873dd1 |
+ login_token_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if ((login_token_name == NULL) || (token->priv->name == NULL))
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (strcmp (token->priv->name, login_token_name) == 0)
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_get_property (GObject *object,
|
|
|
d873dd1 |
+ guint prop_id,
|
|
|
d873dd1 |
+ GValue *value,
|
|
|
d873dd1 |
+ GParamSpec *pspec)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token = SC_SECURITY_TOKEN (object);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ switch (prop_id)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ case PROP_NAME:
|
|
|
d873dd1 |
+ g_value_take_string (value,
|
|
|
d873dd1 |
+ sc_security_token_get_name (token));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ case PROP_SLOT_ID:
|
|
|
d873dd1 |
+ g_value_set_ulong (value,
|
|
|
d873dd1 |
+ (gulong) sc_security_token_get_slot_id (token));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ case PROP_SLOT_SERIES:
|
|
|
d873dd1 |
+ g_value_set_int (value,
|
|
|
d873dd1 |
+ sc_security_token_get_slot_series (token));
|
|
|
d873dd1 |
+ break;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ default:
|
|
|
d873dd1 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_set_name (ScSecurityToken *token,
|
|
|
d873dd1 |
+ const gchar *name)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (name == NULL)
|
|
|
d873dd1 |
+ return;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if ((token->priv->name == NULL) ||
|
|
|
d873dd1 |
+ (strcmp (token->priv->name, name) != 0)) {
|
|
|
d873dd1 |
+ g_free (token->priv->name);
|
|
|
d873dd1 |
+ token->priv->name = g_strdup (name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->slot == NULL) {
|
|
|
d873dd1 |
+ token->priv->slot = sc_security_token_find_slot_from_token_name (token,
|
|
|
d873dd1 |
+ token->priv->name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->slot != NULL) {
|
|
|
d873dd1 |
+ gint slot_id, slot_series;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ slot_id = PK11_GetSlotID (token->priv->slot);
|
|
|
d873dd1 |
+ if (slot_id != token->priv->slot_id)
|
|
|
d873dd1 |
+ sc_security_token_set_slot_id (token, slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ slot_series = PK11_GetSlotSeries (token->priv->slot);
|
|
|
d873dd1 |
+ if (slot_series != token->priv->slot_series)
|
|
|
d873dd1 |
+ sc_security_token_set_slot_series (token, slot_series);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_INSERTED);
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_REMOVED);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_object_notify (G_OBJECT (token), "name");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_set_slot_id (ScSecurityToken *token,
|
|
|
d873dd1 |
+ gint slot_id)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (token->priv->slot_id != slot_id)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ token->priv->slot_id = slot_id;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->slot == NULL) {
|
|
|
d873dd1 |
+ token->priv->slot = sc_security_token_find_slot_from_id (token,
|
|
|
d873dd1 |
+ token->priv->slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->slot != NULL) {
|
|
|
d873dd1 |
+ const gchar *token_name;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token_name = PK11_GetTokenName (token->priv->slot);
|
|
|
d873dd1 |
+ if ((token->priv->name == NULL) ||
|
|
|
d873dd1 |
+ ((token_name != NULL) &&
|
|
|
d873dd1 |
+ (strcmp (token_name, token->priv->name) != 0)))
|
|
|
d873dd1 |
+ sc_security_token_set_name (token, token_name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_INSERTED);
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ _sc_security_token_set_state (token, SC_SECURITY_TOKEN_STATE_REMOVED);
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_object_notify (G_OBJECT (token), "slot-id");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_set_slot_series (ScSecurityToken *token,
|
|
|
d873dd1 |
+ gint slot_series)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (token->priv->slot_series != slot_series)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ token->priv->slot_series = slot_series;
|
|
|
d873dd1 |
+ g_object_notify (G_OBJECT (token), "slot-series");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_set_module (ScSecurityToken *token,
|
|
|
d873dd1 |
+ SECMODModule *module)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ gboolean should_notify;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->module != module)
|
|
|
d873dd1 |
+ should_notify = TRUE;
|
|
|
d873dd1 |
+ else
|
|
|
d873dd1 |
+ should_notify = FALSE;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->module != NULL) {
|
|
|
d873dd1 |
+ SECMOD_DestroyModule (token->priv->module);
|
|
|
d873dd1 |
+ token->priv->module = NULL;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (module != NULL)
|
|
|
d873dd1 |
+ token->priv->module = SECMOD_ReferenceModule (module);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (should_notify)
|
|
|
d873dd1 |
+ g_object_notify (G_OBJECT (token), "module");
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gint
|
|
|
d873dd1 |
+sc_security_token_get_slot_series (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ return token->priv->slot_series;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void
|
|
|
d873dd1 |
+sc_security_token_init (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("initializing security token ");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token->priv = G_TYPE_INSTANCE_GET_PRIVATE (token,
|
|
|
d873dd1 |
+ SC_TYPE_SECURITY_TOKEN,
|
|
|
d873dd1 |
+ ScSecurityTokenPrivate);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->slot != NULL)
|
|
|
d873dd1 |
+ token->priv->name = g_strdup (PK11_GetTokenName (token->priv->slot));
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static void sc_security_token_finalize (GObject *object)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+ GObjectClass *gobject_class;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = SC_SECURITY_TOKEN (object);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_free (token->priv->name);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_set_module (token, NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class =
|
|
|
d873dd1 |
+ G_OBJECT_CLASS (sc_security_token_parent_class);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ gobject_class->finalize (object);
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+GQuark sc_security_token_error_quark (void)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ static GQuark error_quark = 0;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (error_quark == 0)
|
|
|
d873dd1 |
+ error_quark = g_quark_from_static_string ("sc-security-token-error-quark");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return error_quark;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ScSecurityToken *
|
|
|
d873dd1 |
+_sc_security_token_new (SECMODModule *module,
|
|
|
d873dd1 |
+ CK_SLOT_ID slot_id,
|
|
|
d873dd1 |
+ gint slot_series)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_return_val_if_fail (module != NULL, NULL);
|
|
|
d873dd1 |
+ g_return_val_if_fail (slot_id >= 1, NULL);
|
|
|
d873dd1 |
+ g_return_val_if_fail (slot_series > 0, NULL);
|
|
|
d873dd1 |
+ g_return_val_if_fail (sizeof (gulong) == sizeof (slot_id), NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = SC_SECURITY_TOKEN (g_object_new (SC_TYPE_SECURITY_TOKEN,
|
|
|
d873dd1 |
+ "module", module,
|
|
|
d873dd1 |
+ "slot-id", (gulong) slot_id,
|
|
|
d873dd1 |
+ "slot-series", slot_series,
|
|
|
d873dd1 |
+ NULL));
|
|
|
d873dd1 |
+ return token;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ScSecurityToken *
|
|
|
d873dd1 |
+_sc_security_token_new_from_name (SECMODModule *module,
|
|
|
d873dd1 |
+ const gchar *name)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_return_val_if_fail (module != NULL, NULL);
|
|
|
d873dd1 |
+ g_return_val_if_fail (name != NULL, NULL);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ token = SC_SECURITY_TOKEN (g_object_new (SC_TYPE_SECURITY_TOKEN,
|
|
|
d873dd1 |
+ "module", module,
|
|
|
d873dd1 |
+ "name", name,
|
|
|
d873dd1 |
+ NULL));
|
|
|
d873dd1 |
+ return token;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+void
|
|
|
d873dd1 |
+_sc_security_token_set_state (ScSecurityToken *token,
|
|
|
d873dd1 |
+ ScSecurityTokenState state)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ /* sc_security_token_fetch_certificates (token); */
|
|
|
d873dd1 |
+ if (token->priv->state != state)
|
|
|
d873dd1 |
+ {
|
|
|
d873dd1 |
+ token->priv->state = state;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (state == SC_SECURITY_TOKEN_STATE_INSERTED) {
|
|
|
d873dd1 |
+ g_signal_emit (token, sc_security_token_signals[INSERTED], 0);
|
|
|
d873dd1 |
+ } else if (state == SC_SECURITY_TOKEN_STATE_REMOVED)
|
|
|
d873dd1 |
+ g_signal_emit (token, sc_security_token_signals[REMOVED], 0);
|
|
|
d873dd1 |
+ else
|
|
|
d873dd1 |
+ g_assert_not_reached ();
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+/* So we could conceivably make the closure data a pointer to the token
|
|
|
d873dd1 |
+ * or something similiar and then emit signals when we want passwords,
|
|
|
d873dd1 |
+ * but it's probably easier to just get the password up front and use
|
|
|
d873dd1 |
+ * it. So we just take the passed in g_malloc'd (well probably, who knows)
|
|
|
d873dd1 |
+ * and strdup it using NSPR's memory allocation routines.
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+static char *
|
|
|
d873dd1 |
+sc_security_token_password_handler (PK11SlotInfo *slot,
|
|
|
d873dd1 |
+ PRBool is_retrying,
|
|
|
d873dd1 |
+ const gchar *password)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ if (is_retrying)
|
|
|
d873dd1 |
+ return NULL;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return password != NULL? PL_strdup (password): NULL;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+gboolean
|
|
|
d873dd1 |
+sc_security_token_unlock (ScSecurityToken *token,
|
|
|
d873dd1 |
+ const gchar *password)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ SECStatus status;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ PK11_SetPasswordFunc ((PK11PasswordFunc) sc_security_token_password_handler);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ /* we pass PR_TRUE to load certificates
|
|
|
d873dd1 |
+ */
|
|
|
d873dd1 |
+ status = PK11_Authenticate (token->priv->slot, PR_TRUE, (gpointer) password);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (status != SECSuccess) {
|
|
|
d873dd1 |
+ sc_debug ("could not unlock token - %d", status);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static PK11SlotInfo *
|
|
|
d873dd1 |
+sc_security_token_find_slot_from_token_name (ScSecurityToken *token,
|
|
|
d873dd1 |
+ const gchar *token_name)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ int i;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (i = 0; i < token->priv->module->slotCount; i++) {
|
|
|
d873dd1 |
+ const gchar *slot_token_name;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ slot_token_name = PK11_GetTokenName (token->priv->module->slots[i]);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if ((slot_token_name != NULL) &&
|
|
|
d873dd1 |
+ (strcmp (slot_token_name, token_name) == 0))
|
|
|
d873dd1 |
+ return token->priv->module->slots[i];
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return NULL;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static PK11SlotInfo *
|
|
|
d873dd1 |
+sc_security_token_find_slot_from_id (ScSecurityToken *token,
|
|
|
d873dd1 |
+ gint slot_id)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ int i;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (i = 0; i < token->priv->module->slotCount; i++)
|
|
|
d873dd1 |
+ if (PK11_GetSlotID (token->priv->module->slots[i]) == slot_id)
|
|
|
d873dd1 |
+ return token->priv->module->slots[i];
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return NULL;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static gboolean
|
|
|
d873dd1 |
+sc_security_token_fetch_certificates (ScSecurityToken *token)
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ PK11SlotInfo *slot;
|
|
|
d873dd1 |
+ CERTCertList *certificates;
|
|
|
d873dd1 |
+ CERTCertListNode *node;
|
|
|
d873dd1 |
+ SECStatus status;
|
|
|
d873dd1 |
+ int i;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_security_token_unlock (token, "0000");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("fetching certificates for token in slot %lu",
|
|
|
d873dd1 |
+ token->priv->slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ slot = sc_security_token_find_slot_from_id (token,
|
|
|
d873dd1 |
+ token->priv->slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_assert (PK11_GetSlotID (slot) == token->priv->slot_id);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (i == token->priv->module->slotCount) {
|
|
|
d873dd1 |
+ sc_debug ("could not find slot %lu", token->priv->slot_id);
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ certificates = PK11_ListCertsInSlot (slot);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("filtering out non-user certificates");
|
|
|
d873dd1 |
+ if (CERT_FilterCertListForUserCerts (certificates) != SECSuccess) {
|
|
|
d873dd1 |
+ CERT_DestroyCertList (certificates);
|
|
|
d873dd1 |
+ sc_debug ("could not filter out non-user certificates");
|
|
|
d873dd1 |
+ return FALSE;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ for (node = CERT_LIST_HEAD (certificates);
|
|
|
d873dd1 |
+ !CERT_LIST_END (node, certificates);
|
|
|
d873dd1 |
+ node = CERT_LIST_NEXT(node)) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ SECCertificateUsage cert_usages;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("verifying certificate for use");
|
|
|
d873dd1 |
+ status = CERT_VerifyCertificateNow (NULL, node->cert, TRUE,
|
|
|
d873dd1 |
+ 0, NULL, &cert_usages);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (status != SECSuccess) {
|
|
|
d873dd1 |
+ sc_debug ("could not be verified, skipping...");
|
|
|
d873dd1 |
+ continue;
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("got cert with usages 0x%lx", (gulong) cert_usages);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->encryption_certificate == NULL) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("checking if certificate can be used for data "
|
|
|
d873dd1 |
+ "encryption");
|
|
|
d873dd1 |
+ status = CERT_CheckCertUsage (node->cert,
|
|
|
d873dd1 |
+ KU_DATA_ENCIPHERMENT);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (status == SECSuccess) {
|
|
|
d873dd1 |
+ token->priv->encryption_certificate =
|
|
|
d873dd1 |
+ CERT_DupCertificate (node->cert);
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ sc_debug ("certificate can not be used for encryption");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (token->priv->signing_certificate == NULL) {
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ sc_debug ("checking if certificate can be used for data "
|
|
|
d873dd1 |
+ "signing");
|
|
|
d873dd1 |
+ status = CERT_CheckCertUsage (node->cert,
|
|
|
d873dd1 |
+ KU_DIGITAL_SIGNATURE);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ if (status == SECSuccess) {
|
|
|
d873dd1 |
+ token->priv->signing_certificate =
|
|
|
d873dd1 |
+ CERT_DupCertificate (node->cert);
|
|
|
d873dd1 |
+ } else {
|
|
|
d873dd1 |
+ sc_debug ("certificate can not be used for signing things");
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ }
|
|
|
d873dd1 |
+ return TRUE;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+#ifdef SC_SECURITY_TOKEN_ENABLE_TEST
|
|
|
d873dd1 |
+#include <glib.h>
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+static GMainLoop *event_loop;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+int
|
|
|
d873dd1 |
+main (int argc,
|
|
|
d873dd1 |
+ char *argv[])
|
|
|
d873dd1 |
+{
|
|
|
d873dd1 |
+ ScSecurityToken *token;
|
|
|
d873dd1 |
+ GError *error;
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR
|
|
|
d873dd1 |
+ | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_type_init ();
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_message ("creating instance of 'security token' object...");
|
|
|
d873dd1 |
+ token = _sc_security_token_new (NULL, 1, 1);
|
|
|
d873dd1 |
+ g_message ("'security token' object created successfully");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ g_message ("destroying previously created 'security token' object...");
|
|
|
d873dd1 |
+ g_object_unref (token);
|
|
|
d873dd1 |
+ token = NULL;
|
|
|
d873dd1 |
+ g_message ("'security token' object destroyed successfully");
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+ return 0;
|
|
|
d873dd1 |
+}
|
|
|
d873dd1 |
+#endif
|
|
|
d873dd1 |
--- gnome-screensaver-2.18.0/src/Makefile.am.securitytoken 2007-03-12 13:07:47.000000000 -0400
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/src/Makefile.am 2007-03-14 10:56:44.000000000 -0400
|
|
|
d873dd1 |
@@ -50,6 +50,18 @@
|
|
|
d873dd1 |
test-window \
|
|
|
d873dd1 |
$(NULL)
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+noinst_LIBRARIES = libsecuritytoken.a
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+libsecuritytoken_a_SOURCES = \
|
|
|
d873dd1 |
+ securitytoken.h \
|
|
|
d873dd1 |
+ securitytoken.c \
|
|
|
d873dd1 |
+ securitytokenmonitor.h \
|
|
|
d873dd1 |
+ securitytokenmonitor.c
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+libsecuritytoken_a_CFLAGS = $(SECURITY_TOKEN_CFLAGS) \
|
|
|
d873dd1 |
+ -DLIBDIR=\""$(libdir)"\" \
|
|
|
d873dd1 |
+ -DSYSCONFDIR=\""$(sysconfdir)"\"
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
gnome_screensaver_command_SOURCES = \
|
|
|
d873dd1 |
gnome-screensaver-command.c
|
|
|
d873dd1 |
|
|
|
d873dd1 |
@@ -204,6 +216,7 @@
|
|
|
d873dd1 |
gnome_screensaver_LDADD = \
|
|
|
d873dd1 |
$(GNOME_SCREENSAVER_LIBS) \
|
|
|
d873dd1 |
$(SAVER_LIBS) \
|
|
|
d873dd1 |
+ $(top_builddir)/src/libsecuritytoken.a \
|
|
|
d873dd1 |
$(NULL)
|
|
|
d873dd1 |
|
|
|
d873dd1 |
gnome_screensaver_LDFLAGS = -export-dynamic
|
|
|
d873dd1 |
--- gnome-screensaver-2.18.0/configure.ac.securitytoken 2007-03-01 13:16:35.000000000 -0500
|
|
|
d873dd1 |
+++ gnome-screensaver-2.18.0/configure.ac 2007-03-14 10:55:13.000000000 -0400
|
|
|
d873dd1 |
@@ -44,6 +44,7 @@
|
|
|
d873dd1 |
LIBEXIF_REQUIRED_VERSION=0.6.12
|
|
|
d873dd1 |
GLIB_REQUIRED_VERSION=2.7.0
|
|
|
d873dd1 |
LIBGNOMEKBDUI_REQUIRED_VERSION=0.1
|
|
|
d873dd1 |
+NSS_REQUIRED_VERSION=3.11.2
|
|
|
d873dd1 |
|
|
|
d873dd1 |
AC_CHECK_HEADERS(unistd.h)
|
|
|
d873dd1 |
AC_CHECK_HEADERS(crypt.h sys/select.h)
|
|
|
d873dd1 |
@@ -57,7 +58,8 @@
|
|
|
d873dd1 |
gtk+-2.0 >= $GTK_REQUIRED_VERSION
|
|
|
d873dd1 |
dbus-glib-1 >= $DBUS_REQUIRED_VERSION
|
|
|
d873dd1 |
gconf-2.0 >= $GCONF_REQUIRED_VERSION
|
|
|
d873dd1 |
- libgnome-menu >= $LIBGNOME_MENU_REQUIRED_VERSION)
|
|
|
d873dd1 |
+ libgnome-menu >= $LIBGNOME_MENU_REQUIRED_VERSION
|
|
|
d873dd1 |
+ nss >= $NSS_REQUIRED_VERSION)
|
|
|
d873dd1 |
AC_SUBST(GNOME_SCREENSAVER_CFLAGS)
|
|
|
d873dd1 |
AC_SUBST(GNOME_SCREENSAVER_LIBS)
|
|
|
d873dd1 |
|
|
|
d873dd1 |
@@ -92,8 +94,6 @@
|
|
|
d873dd1 |
|
|
|
d873dd1 |
AM_GCONF_SOURCE_2
|
|
|
d873dd1 |
|
|
|
d873dd1 |
-GNOME_COMPILE_WARNINGS(yes)
|
|
|
d873dd1 |
-
|
|
|
d873dd1 |
# Solaris requires libresolv for daemon()
|
|
|
d873dd1 |
case "$host" in
|
|
|
d873dd1 |
*-*-solaris*)
|
|
|
d873dd1 |
@@ -227,6 +227,16 @@
|
|
|
d873dd1 |
AM_CONDITIONAL(HAVE_USER_SWITCHING, test x$enable_user_switching = xyes)
|
|
|
d873dd1 |
AC_SUBST(HAVE_USER_SWITCHING)
|
|
|
d873dd1 |
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+# security token support
|
|
|
d873dd1 |
+PKG_CHECK_MODULES(SECURITY_TOKEN,
|
|
|
d873dd1 |
+ gobject-2.0 >= $GLIB_REQUIRED_VERSION
|
|
|
d873dd1 |
+ nss >= $NSS_REQUIRED_VERSION)
|
|
|
d873dd1 |
+AC_SUBST(SECURITY_TOKEN_CFLAGS)
|
|
|
d873dd1 |
+AC_SUBST(SECURITY_TOKEN_LIBS)
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
+
|
|
|
d873dd1 |
dnl ---------------------------------------------------------------------------
|
|
|
d873dd1 |
dnl - Where should we put documentation ?
|
|
|
d873dd1 |
dnl ---------------------------------------------------------------------------
|