summaryrefslogtreecommitdiff
path: root/plugins/smartcard
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2013-07-29 00:02:04 -0400
committerRay Strode <rstrode@redhat.com>2013-07-29 00:08:22 -0400
commit92460adeaaa9707958e972b9f6b2cfefe7a50f71 (patch)
treea0605832674d39664bd133aa5b3494c40ddaf9d0 /plugins/smartcard
parent8d6732952787ac20e8eefec15b6d645b2d9c3087 (diff)
downloadgnome-settings-daemon-92460adeaaa9707958e972b9f6b2cfefe7a50f71.tar.gz
smartcard: support old card removal actions
The old smartcard plugin supported a feature where the screen would lock or the session would get logged out if a user yanked their login token. This commit adds that feature back.
Diffstat (limited to 'plugins/smartcard')
-rw-r--r--plugins/smartcard/gsd-smartcard-manager.c170
-rw-r--r--plugins/smartcard/gsd-smartcard-manager.h1
-rw-r--r--plugins/smartcard/gsd-smartcard-service.c11
3 files changed, 181 insertions, 1 deletions
diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c
index 14c2f717..4ac31ae9 100644
--- a/plugins/smartcard/gsd-smartcard-manager.c
+++ b/plugins/smartcard/gsd-smartcard-manager.c
@@ -31,6 +31,9 @@
#include "gsd-smartcard-enum-types.h"
#include "gsd-smartcard-utils.h"
+#include "org.gnome.ScreenSaver.h"
+#include "org.gnome.SessionManager.h"
+
#include <prerror.h>
#include <prinit.h>
#include <nss.h>
@@ -40,6 +43,8 @@
#define GSD_SMARTCARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerPrivate))
+#define GSD_SESSION_MANAGER_LOGOUT_MODE_FORCE 2
+
struct GsdSmartcardManagerPrivate
{
guint start_idle_id;
@@ -47,16 +52,22 @@ struct GsdSmartcardManagerPrivate
GList *smartcards_watch_tasks;
GCancellable *cancellable;
+ GsdSessionManager *session_manager;
+ GsdScreenSaver *screen_saver;
+
GSettings *settings;
guint32 nss_is_loaded : 1;
};
#define CONF_SCHEMA "org.gnome.settings-daemon.peripherals.smartcard"
+#define KEY_REMOVE_ACTION "removal-action"
static void gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *klass);
static void gsd_smartcard_manager_init (GsdSmartcardManager *self);
static void gsd_smartcard_manager_finalize (GObject *object);
+static void lock_screen (GsdSmartcardManager *self);
+static void log_out (GsdSmartcardManager *self);
G_DEFINE_TYPE (GsdSmartcardManager, gsd_smartcard_manager, G_TYPE_OBJECT)
G_DEFINE_QUARK (gsd-smartcard-manager-error, gsd_smartcard_manager_error)
G_LOCK_DEFINE_STATIC (gsd_smartcards_watch_tasks);
@@ -221,7 +232,6 @@ watch_one_event_from_driver (GsdSmartcardManager *self,
PK11_ReferenceSlot (card));
gsd_smartcard_service_sync_token (priv->service, card, cancellable);
-
} else if (old_card == NULL) {
/* If the just removed smartcard is not known to us then
* ignore the removal event. NSS sends a synthentic removal
@@ -556,6 +566,7 @@ on_all_drivers_activated (GsdSmartcardManager *self,
{
GError *error = NULL;
gboolean driver_activated;
+ PK11SlotInfo *login_token;
driver_activated = activate_all_drivers_async_finish (self, result, &error);
@@ -564,6 +575,16 @@ on_all_drivers_activated (GsdSmartcardManager *self,
return;
}
+ login_token = gsd_smartcard_manager_get_login_token (self);
+
+ if (login_token || g_getenv ("PKCS11_LOGIN_TOKEN_NAME") != NULL) {
+ /* The card used to log in was removed before login completed.
+ * Do removal action immediately
+ */
+ if (!login_token || !PK11_IsPresent (login_token))
+ gsd_smartcard_manager_do_remove_action (self);
+ }
+
g_task_return_boolean (task, TRUE);
}
@@ -703,6 +724,153 @@ gsd_smartcard_manager_stop (GsdSmartcardManager *self)
g_clear_object (&priv->settings);
g_clear_object (&priv->cancellable);
+ g_clear_object (&priv->session_manager);
+ g_clear_object (&priv->screen_saver);
+}
+
+static void
+on_got_screen_saver_to_lock_screen (GObject *object,
+ GAsyncResult *result,
+ GsdSmartcardManager *self)
+{
+ GsdSmartcardManagerPrivate *priv = self->priv;
+ GsdScreenSaver *screen_saver;
+ GError *error = NULL;
+
+ screen_saver = gsd_screen_saver_proxy_new_for_bus_finish (result, &error);
+
+ if (screen_saver == NULL) {
+ g_warning ("Couldn't find screen saver service to lock screen: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (priv->screen_saver != NULL)
+ g_object_unref (screen_saver);
+
+ priv->screen_saver = screen_saver;
+
+ lock_screen (self);
+}
+
+static void
+on_screen_locked (GsdScreenSaver *screen_saver,
+ GAsyncResult *result,
+ GsdSmartcardManager *self)
+{
+ gboolean is_locked;
+ GError *error = NULL;
+
+ is_locked = gsd_screen_saver_call_lock_finish (screen_saver, result, &error);
+
+ if (!is_locked) {
+ g_warning ("Couldn't lock screen: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+}
+
+static void
+lock_screen (GsdSmartcardManager *self)
+{
+ GsdSmartcardManagerPrivate *priv = self->priv;
+
+ if (priv->screen_saver == NULL) {
+ gsd_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.gnome.ScreenSaver",
+ "/org/gnome/ScreenSaver",
+ priv->cancellable,
+ (GAsyncReadyCallback) on_got_screen_saver_to_lock_screen,
+ self);
+ return;
+ }
+
+ gsd_screen_saver_call_lock (priv->screen_saver,
+ priv->cancellable,
+ (GAsyncReadyCallback) on_screen_locked,
+ self);
+}
+
+static void
+on_got_session_manager_to_log_out (GObject *object,
+ GAsyncResult *result,
+ GsdSmartcardManager *self)
+{
+ GsdSmartcardManagerPrivate *priv = self->priv;
+ GsdSessionManager *session_manager;
+ GError *error = NULL;
+
+ session_manager = gsd_session_manager_proxy_new_for_bus_finish (result, &error);
+
+ if (session_manager == NULL) {
+ g_warning ("Couldn't find session manager service to log out: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (priv->session_manager != NULL)
+ g_object_unref (session_manager);
+
+ priv->session_manager = session_manager;
+
+ log_out (self);
+}
+
+static void
+on_logged_out (GsdSessionManager *session_manager,
+ GAsyncResult *result,
+ GsdSmartcardManager *self)
+{
+ gboolean is_logged_out;
+ GError *error = NULL;
+
+ is_logged_out = gsd_session_manager_call_logout_finish (session_manager, result, &error);
+
+ if (!is_logged_out) {
+ g_warning ("Couldn't log out: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+}
+
+static void
+log_out (GsdSmartcardManager *self)
+{
+ GsdSmartcardManagerPrivate *priv = self->priv;
+
+ if (priv->session_manager == NULL) {
+ gsd_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager",
+ priv->cancellable,
+ (GAsyncReadyCallback) on_got_session_manager_to_log_out,
+ self);
+ return;
+ }
+
+ gsd_session_manager_call_logout (priv->session_manager,
+ GSD_SESSION_MANAGER_LOGOUT_MODE_FORCE,
+ priv->cancellable,
+ (GAsyncReadyCallback) on_logged_out,
+ self);
+}
+
+void
+gsd_smartcard_manager_do_remove_action (GsdSmartcardManager *self)
+{
+ GsdSmartcardManagerPrivate *priv = self->priv;
+ char *remove_action;
+
+ remove_action = g_settings_get_string (priv->settings, KEY_REMOVE_ACTION);
+
+ if (strcmp (remove_action, "lock-screen") == 0)
+ lock_screen (self);
+ else if (strcmp (remove_action, "force-logout") == 0)
+ log_out (self);
}
static PK11SlotInfo *
diff --git a/plugins/smartcard/gsd-smartcard-manager.h b/plugins/smartcard/gsd-smartcard-manager.h
index 9d3a2ce8..7876fc1c 100644
--- a/plugins/smartcard/gsd-smartcard-manager.h
+++ b/plugins/smartcard/gsd-smartcard-manager.h
@@ -76,6 +76,7 @@ void gsd_smartcard_manager_stop (GsdSmartcardManager
PK11SlotInfo * gsd_smartcard_manager_get_login_token (GsdSmartcardManager *manager);
GList * gsd_smartcard_manager_get_inserted_tokens (GsdSmartcardManager *manager,
gsize *num_tokens);
+void gsd_smartcard_manager_do_remove_action (GsdSmartcardManager *manager);
G_END_DECLS
diff --git a/plugins/smartcard/gsd-smartcard-service.c b/plugins/smartcard/gsd-smartcard-service.c
index 40350d06..cc20f4c2 100644
--- a/plugins/smartcard/gsd-smartcard-service.c
+++ b/plugins/smartcard/gsd-smartcard-service.c
@@ -505,6 +505,17 @@ synchronize_token_now (GsdSmartcardService *self,
g_debug (" Previously used to login: %s", is_login_card? "yes" : "no");
g_debug ("===============================\n");
+ if (!is_present && is_login_card) {
+ gboolean was_present;
+
+ g_object_get (G_OBJECT (interface),
+ "is-inserted", &was_present,
+ NULL);
+
+ if (was_present)
+ gsd_smartcard_manager_do_remove_action (priv->smartcard_manager);
+ }
+
g_object_set (G_OBJECT (interface),
"used-to-login", is_login_card,
"is-inserted", is_present,