File gnome-screensaver-2.19.1.1-securitytoken.patch of Package gnome-screensaver
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gnome-screensaver-dialog.c gnome-screensaver-2.19.1.1/src/gnome-screensaver-dialog.c
--- gnome-screensaver-2.19.1.1.orig/src/gnome-screensaver-dialog.c 2007-04-23 15:29:13.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/gnome-screensaver-dialog.c 2007-07-26 13:45:13.000000000 -0400
@@ -47,6 +47,7 @@ static gboolean enable_logout = FALSE;
static gboolean enable_switch = FALSE;
static char *logout_command = NULL;
static char *away_message = NULL;
+static gboolean token = FALSE;
static GOptionEntry entries [] = {
{ "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose,
@@ -61,6 +62,8 @@ static GOptionEntry entries [] = {
N_("Show the switch user button"), NULL },
{ "away-message", 0, 0, G_OPTION_ARG_STRING, &away_message,
N_("Message to show in the dialog"), N_("MESSAGE") },
+ { "token", 0, 0, G_OPTION_ARG_NONE, &token,
+ N_("Authenticate using a smart card token"), NULL },
{ NULL }
};
@@ -288,7 +291,7 @@ do_auth_check (GSLockPlug *plug)
gs_lock_plug_disable_prompt (plug);
gs_lock_plug_set_busy (plug);
- res = gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), auth_message_handler, plug, &error);
+ res = gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), token, auth_message_handler, plug, &error);
gs_debug ("Verify user returned: %s", res ? "TRUE" : "FALSE");
if (! res) {
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-auth.h gnome-screensaver-2.19.1.1/src/gs-auth.h
--- gnome-screensaver-2.19.1.1.orig/src/gs-auth.h 2007-02-22 23:39:09.000000000 -0500
+++ gnome-screensaver-2.19.1.1/src/gs-auth.h 2007-07-26 13:45:13.000000000 -0400
@@ -56,6 +56,7 @@ gboolean gs_auth_priv_init (void);
gboolean gs_auth_init (void);
gboolean gs_auth_verify_user (const char *username,
const char *display,
+ gboolean token,
GSAuthMessageFunc func,
gpointer data,
GError **error);
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-auth-helper.c gnome-screensaver-2.19.1.1/src/gs-auth-helper.c
--- gnome-screensaver-2.19.1.1.orig/src/gs-auth-helper.c 2007-02-22 23:39:09.000000000 -0500
+++ gnome-screensaver-2.19.1.1/src/gs-auth-helper.c 2007-07-26 13:45:13.000000000 -0400
@@ -78,7 +78,8 @@ gs_auth_get_verbose (void)
static gboolean
ext_run (const char *user,
const char *typed_passwd,
- gboolean verbose)
+ gboolean verbose,
+ gboolean token)
{
int pfd[2], status;
pid_t pid;
@@ -107,7 +108,9 @@ ext_run (const char *user,
}
/* Helper is invoked as helper service-name [user] */
- execlp (PASSWD_HELPER_PROGRAM, PASSWD_HELPER_PROGRAM, "gnome-screensaver", user, NULL);
+ execlp (PASSWD_HELPER_PROGRAM, PASSWD_HELPER_PROGRAM,
+ token ? PAM_SERVICE_NAME"-smartcard" : PAM_SERVICE_NAME,
+ user, NULL);
if (verbose) {
g_message ("%s: %s", PASSWD_HELPER_PROGRAM, strerror (errno));
}
@@ -150,6 +153,7 @@ ext_run (const char *user,
gboolean
gs_auth_verify_user (const char *username,
const char *display,
+ gboolean token,
GSAuthMessageFunc func,
gpointer data,
GError **error)
@@ -162,7 +166,7 @@ gs_auth_verify_user (const char *u
/* ask for the password for user */
if (func != NULL) {
func (GS_AUTH_MESSAGE_PROMPT_ECHO_OFF,
- "Password: ",
+ token ? "PIN: " : "Password: ",
&password,
data);
}
@@ -171,7 +175,7 @@ gs_auth_verify_user (const char *u
return FALSE;
}
- res = ext_run (username, password, gs_auth_get_verbose ());
+ res = ext_run (username, password, gs_auth_get_verbose (), token);
return res;
}
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-auth-pam.c gnome-screensaver-2.19.1.1/src/gs-auth-pam.c
--- gnome-screensaver-2.19.1.1.orig/src/gs-auth-pam.c 2007-02-22 23:39:09.000000000 -0500
+++ gnome-screensaver-2.19.1.1/src/gs-auth-pam.c 2007-07-26 13:45:13.000000000 -0400
@@ -373,10 +373,11 @@ static gboolean
create_pam_handle (const char *username,
const char *display,
struct pam_conv *conv,
- int *status_code)
+ int *status_code,
+ gboolean token)
{
int status;
- const char *service = PAM_SERVICE_NAME;
+ const char *service = token ? PAM_SERVICE_NAME"-smartcard" : PAM_SERVICE_NAME;
char *disp;
gboolean ret;
@@ -668,6 +669,7 @@ gs_auth_pam_verify_user (pam_handle_t *h
gboolean
gs_auth_verify_user (const char *username,
const char *display,
+ gboolean token,
GSAuthMessageFunc func,
gpointer data,
GError **error)
@@ -690,7 +692,7 @@ gs_auth_verify_user (const char *u
conv.appdata_ptr = (void *) &c;
/* Initialize PAM. */
- create_pam_handle (username, display, &conv, &status);
+ create_pam_handle (username, display, &conv, &status, token);
if (status != PAM_SUCCESS) {
goto done;
}
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-auth-pwent.c gnome-screensaver-2.19.1.1/src/gs-auth-pwent.c
--- gnome-screensaver-2.19.1.1.orig/src/gs-auth-pwent.c 2007-02-22 23:39:09.000000000 -0500
+++ gnome-screensaver-2.19.1.1/src/gs-auth-pwent.c 2007-07-26 13:45:13.000000000 -0400
@@ -242,6 +242,7 @@ passwds_match (const char *cleartext,
gboolean
gs_auth_verify_user (const char *username,
const char *display,
+ gboolean token,
GSAuthMessageFunc func,
gpointer data,
GError **error)
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-manager.c gnome-screensaver-2.19.1.1/src/gs-manager.c
--- gnome-screensaver-2.19.1.1.orig/src/gs-manager.c 2007-04-23 15:29:13.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/gs-manager.c 2007-07-26 13:45:13.000000000 -0400
@@ -1284,7 +1284,7 @@ window_obscured_cb (GSWindow *window,
maybe_set_window_throttle (manager, window, obscured);
if (! obscured) {
- gs_manager_request_unlock (manager);
+ gs_manager_request_unlock (manager, FALSE);
}
}
@@ -1294,7 +1294,7 @@ window_activity_cb (GSWindow *window,
{
gboolean handled;
- handled = gs_manager_request_unlock (manager);
+ handled = gs_manager_request_unlock (manager, FALSE);
return handled;
}
@@ -1564,7 +1564,7 @@ gs_manager_get_active (GSManager *manage
}
gboolean
-gs_manager_request_unlock (GSManager *manager)
+gs_manager_request_unlock (GSManager *manager, gboolean token)
{
GSWindow *window;
@@ -1593,7 +1593,7 @@ gs_manager_request_unlock (GSManager *ma
/* Find the GSWindow that contains the pointer */
window = find_window_at_pointer (manager);
- gs_window_request_unlock (window);
+ gs_window_request_unlock (window, token);
return TRUE;
}
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-manager.h gnome-screensaver-2.19.1.1/src/gs-manager.h
--- gnome-screensaver-2.19.1.1.orig/src/gs-manager.h 2007-04-23 15:29:13.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/gs-manager.h 2007-07-26 13:45:13.000000000 -0400
@@ -95,7 +95,7 @@ void gs_manager_set_themes
GSList *themes);
void gs_manager_set_mode (GSManager *manager,
GSSaverMode mode);
-gboolean gs_manager_request_unlock (GSManager *manager);
+gboolean gs_manager_request_unlock (GSManager *manager, gboolean token);
void gs_manager_cancel_unlock_request (GSManager *manager);
G_END_DECLS
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-monitor.c gnome-screensaver-2.19.1.1/src/gs-monitor.c
--- gnome-screensaver-2.19.1.1.orig/src/gs-monitor.c 2007-04-23 15:29:13.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/gs-monitor.c 2007-07-26 13:45:13.000000000 -0400
@@ -29,6 +29,10 @@
#include <glib.h>
#include <glib-object.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
#include "gnome-screensaver.h"
#include "gs-manager.h"
@@ -41,6 +45,10 @@
#include "gs-prefs.h"
#include "gs-debug.h"
+#define PKCS11_MONITOR_SERVICE "com.novell.Pkcs11Monitor"
+#define PKCS11_MONITOR_PATH "/com/novell/Pkcs11Monitor"
+#define PKCS11_MONITOR_INTERFACE "com.novell.Pkcs11Monitor"
+
static void gs_monitor_class_init (GSMonitorClass *klass);
static void gs_monitor_init (GSMonitor *monitor);
static void gs_monitor_finalize (GObject *object);
@@ -56,6 +64,8 @@ struct GSMonitorPrivate
GSFade *fade;
GSGrab *grab;
+ DBusGProxy *security_token_monitor;
+
guint release_grab_id;
};
@@ -229,7 +239,7 @@ gs_monitor_lock_screen (GSMonitor *monit
}
static void
-gs_monitor_simulate_user_activity (GSMonitor *monitor)
+gs_monitor_simulate_user_activity (GSMonitor *monitor, gboolean token)
{
/* in case the screen isn't blanked reset the
idle watcher */
@@ -237,7 +247,7 @@ gs_monitor_simulate_user_activity (GSMon
/* request that the manager unlock -
will pop up a dialog if necessary */
- gs_manager_request_unlock (monitor->priv->manager);
+ gs_manager_request_unlock (monitor->priv->manager, token);
}
static void
@@ -306,7 +316,59 @@ static void
listener_simulate_user_activity_cb (GSListener *listener,
GSMonitor *monitor)
{
- gs_monitor_simulate_user_activity (monitor);
+ gs_monitor_simulate_user_activity (monitor, FALSE);
+}
+
+static void
+security_token_inserted_cb (DBusGProxy *proxy,
+ const char *token_name,
+ GSMonitor *monitor)
+{
+ gs_monitor_simulate_user_activity (monitor, TRUE);
+}
+
+static gboolean
+gs_monitor_should_lock_on_login_security_token_removal (void)
+{
+ /* FIXME: lame hack
+ */
+ // return system ("pkcs11_setup rm_action | grep -q lock") == 0;
+ return TRUE;
+}
+
+static gboolean
+gs_monitor_is_token_inserted (DBusGProxy *proxy, const char *token_name)
+{
+ gboolean is_inserted = FALSE;
+ if (!dbus_g_proxy_call (proxy, "IsTokenInserted", NULL,
+ G_TYPE_STRING, token_name, G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &is_inserted, G_TYPE_INVALID)) {
+ return FALSE;
+ }
+ return is_inserted;
+}
+
+static gboolean
+sc_security_token_is_login_token (const char *token_name)
+{
+ const char *env_token_name;
+
+ env_token_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME");
+ return env_token_name && !strcmp (token_name, env_token_name);
+}
+
+static void
+security_token_removed_cb (DBusGProxy *proxy,
+ const char *token_name,
+ GSMonitor *monitor)
+{
+ if (gs_monitor_should_lock_on_login_security_token_removal () &&
+ sc_security_token_is_login_token (token_name))
+ gs_monitor_lock_screen (monitor);
+
+ /* If we're already locked and the lock dialog is up, kill it.
+ */
+ gs_manager_cancel_unlock_request (monitor->priv->manager);
}
static void
@@ -425,6 +487,33 @@ connect_manager_signals (GSMonitor *moni
}
static void
+disconnect_security_token_monitor_signals (GSMonitor *monitor)
+{
+ dbus_g_proxy_disconnect_signal (monitor->priv->security_token_monitor,
+ "SecurityTokenInserted",
+ G_CALLBACK (security_token_inserted_cb), monitor);
+ dbus_g_proxy_disconnect_signal (monitor->priv->security_token_monitor,
+ "SecurityTokenRemoved",
+ G_CALLBACK (security_token_removed_cb), monitor);
+}
+
+static void
+connect_security_token_monitor_signals (GSMonitor *monitor)
+{
+ dbus_g_proxy_add_signal (monitor->priv->security_token_monitor,
+ "SecurityTokenInserted", G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (monitor->priv->security_token_monitor,
+ "SecurityTokenInserted",
+ G_CALLBACK (security_token_inserted_cb), monitor, NULL);
+
+ dbus_g_proxy_add_signal (monitor->priv->security_token_monitor,
+ "SecurityTokenRemoved", G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (monitor->priv->security_token_monitor,
+ "SecurityTokenRemoved",
+ G_CALLBACK (security_token_removed_cb), monitor, NULL);
+}
+
+static void
disconnect_prefs_signals (GSMonitor *monitor)
{
g_signal_handlers_disconnect_by_func (monitor->priv->prefs, _gs_monitor_update_from_prefs, monitor);
@@ -440,6 +529,8 @@ connect_prefs_signals (GSMonitor *monito
static void
gs_monitor_init (GSMonitor *monitor)
{
+ DBusGConnection *conn;
+ GError *err = NULL;
monitor->priv = GS_MONITOR_GET_PRIVATE (monitor);
@@ -458,6 +549,36 @@ gs_monitor_init (GSMonitor *monitor)
monitor->priv->manager = gs_manager_new ();
connect_manager_signals (monitor);
+ /* PKCS11_LOGIN_TOKEN_NAME is set if the user logged in with a
+ * security token.
+ */
+ conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (!conn) {
+ g_warning ("couldn't connect to system bus: %s\n", err->message);
+ g_error_free (err);
+ monitor->priv->security_token_monitor = NULL;
+ } else {
+ gchar *env_token_name;
+
+ monitor->priv->security_token_monitor = dbus_g_proxy_new_for_name (conn,
+ PKCS11_MONITOR_SERVICE,
+ PKCS11_MONITOR_PATH,
+ PKCS11_MONITOR_INTERFACE);
+ dbus_g_connection_unref (conn);
+
+ connect_security_token_monitor_signals (monitor);
+
+ env_token_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME");
+ /* if the user logged in with a security token but it's
+ * not currently inserted, then they must have yanked it
+ * before we started. lock the screen immediately
+ */
+ if (env_token_name && env_token_name[0] &&
+ gs_monitor_should_lock_on_login_security_token_removal () &&
+ !gs_monitor_is_token_inserted (monitor->priv->security_token_monitor, env_token_name))
+ gs_monitor_lock_screen (monitor);
+ }
+
_gs_monitor_update_from_prefs (monitor, monitor->priv->prefs);
}
@@ -473,6 +594,11 @@ gs_monitor_finalize (GObject *object)
g_return_if_fail (monitor->priv != NULL);
+ if (monitor->priv->security_token_monitor != NULL) {
+ disconnect_security_token_monitor_signals (monitor);
+ g_object_unref (monitor->priv->security_token_monitor);
+ }
+
disconnect_watcher_signals (monitor);
disconnect_listener_signals (monitor);
disconnect_manager_signals (monitor);
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-window.h gnome-screensaver-2.19.1.1/src/gs-window.h
--- gnome-screensaver-2.19.1.1.orig/src/gs-window.h 2007-04-23 15:29:13.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/gs-window.h 2007-07-26 13:45:13.000000000 -0400
@@ -82,7 +82,7 @@ void gs_window_set_logout_command
void gs_window_set_away_message (GSWindow *window,
const char *away_message);
-void gs_window_request_unlock (GSWindow *window);
+void gs_window_request_unlock (GSWindow *window, gboolean token);
void gs_window_cancel_unlock_request (GSWindow *window);
GSWindow * gs_window_new (GdkScreen *screen,
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/gs-window-x11.c gnome-screensaver-2.19.1.1/src/gs-window-x11.c
--- gnome-screensaver-2.19.1.1.orig/src/gs-window-x11.c 2007-07-26 13:44:40.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/gs-window-x11.c 2007-07-26 13:45:13.000000000 -0400
@@ -78,6 +78,7 @@ struct GSWindowPrivate
GtkWidget *keyboard_socket;
guint popup_dialog_idle_id;
+ gboolean popup_dialog_idle_token;
guint dialog_map_signal_id;
guint dialog_unmap_signal_id;
@@ -571,8 +572,9 @@ remove_popup_dialog_idle (GSWindow *wind
}
static void
-add_popup_dialog_idle (GSWindow *window)
+add_popup_dialog_idle (GSWindow *window, gboolean token)
{
+ window->priv->popup_dialog_idle_token = token;
window->priv->popup_dialog_idle_id = g_idle_add ((GSourceFunc)popup_dialog_idle, window);
}
@@ -1546,6 +1548,10 @@ popup_dialog_idle (GSWindow *window)
command = g_string_append (command, " --verbose");
}
+ if (window->priv->popup_dialog_idle_token) {
+ command = g_string_append (command, " --token");
+ }
+
gs_window_clear (window);
set_invisible_cursor (GTK_WIDGET (window)->window, FALSE);
@@ -1561,13 +1567,14 @@ popup_dialog_idle (GSWindow *window)
g_string_free (command, TRUE);
+ window->priv->popup_dialog_idle_token = FALSE;
window->priv->popup_dialog_idle_id = 0;
return FALSE;
}
void
-gs_window_request_unlock (GSWindow *window)
+gs_window_request_unlock (GSWindow *window, gboolean token)
{
g_return_if_fail (GS_IS_WINDOW (window));
@@ -1589,7 +1596,7 @@ gs_window_request_unlock (GSWindow *wind
}
if (window->priv->popup_dialog_idle_id == 0) {
- add_popup_dialog_idle (window);
+ add_popup_dialog_idle (window, token);
}
g_signal_emit (window, signals [DIALOG_UP], 0);
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/test-passwd.c gnome-screensaver-2.19.1.1/src/test-passwd.c
--- gnome-screensaver-2.19.1.1.orig/src/test-passwd.c 2007-02-22 23:39:09.000000000 -0500
+++ gnome-screensaver-2.19.1.1/src/test-passwd.c 2007-07-26 13:45:13.000000000 -0400
@@ -250,7 +250,7 @@ main (int argc,
again:
error = NULL;
- if (gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), auth_message_handler, NULL, &error)) {
+ if (gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), FALSE, auth_message_handler, NULL, &error)) {
printf ("Correct!\n");
} else {
if (error != NULL) {
diff -ruNp gnome-screensaver-2.19.1.1.orig/src/test-window.c gnome-screensaver-2.19.1.1/src/test-window.c
--- gnome-screensaver-2.19.1.1.orig/src/test-window.c 2007-03-17 16:28:22.000000000 -0400
+++ gnome-screensaver-2.19.1.1/src/test-window.c 2007-07-26 13:45:13.000000000 -0400
@@ -69,7 +69,7 @@ static gboolean
window_activity_cb (GSWindow *window,
gpointer data)
{
- gs_window_request_unlock (window);
+ gs_window_request_unlock (window, FALSE);
return TRUE;
}