From edfd786d01e59feba1f22381dc8b020abbb37f6e Mon Sep 17 00:00:00 2001 From: CentOS Buildsys Date: Nov 08 2013 11:01:57 +0000 Subject: import gnome-settings-daemon-3.8.6.1-2.el7.src.rpm --- diff --git a/.gnome-settings-daemon.metadata b/.gnome-settings-daemon.metadata new file mode 100644 index 0000000..dda3937 --- /dev/null +++ b/.gnome-settings-daemon.metadata @@ -0,0 +1 @@ +2e9abb80f7b25ec0fbc96d76434f3ce7af6a7390 SOURCES/gnome-settings-daemon-3.8.6.1.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/0001-keyboard-Stop-adding-locale-based-input-sources-from.patch b/SOURCES/0001-keyboard-Stop-adding-locale-based-input-sources-from.patch new file mode 100644 index 0000000..8dd93fc --- /dev/null +++ b/SOURCES/0001-keyboard-Stop-adding-locale-based-input-sources-from.patch @@ -0,0 +1,94 @@ +From 49d2e09887fc4bd1d12f11f5b49ec5f7e091d05c Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 4 Mar 2013 17:32:57 +0100 +Subject: [PATCH] keyboard: Stop adding locale based input sources from a + hardcoded list + +This was never meant to be the definite way to do it and we now have +gnome-initial-setup which is a better place to do this. + +https://bugzilla.gnome.org/show_bug.cgi?id=685567 +--- + plugins/keyboard/gsd-keyboard-manager.c | 58 +-------------------------------- + 1 file changed, 1 insertion(+), 57 deletions(-) + +diff --git a/plugins/keyboard/gsd-keyboard-manager.c b/plugins/keyboard/gsd-keyboard-manager.c +index ebfa7d8..b15d355 100644 +--- a/plugins/keyboard/gsd-keyboard-manager.c ++++ b/plugins/keyboard/gsd-keyboard-manager.c +@@ -468,58 +468,6 @@ out: + return (gchar **) g_ptr_array_free (opt_array, FALSE); + } + +-static const gchar * +-engine_from_locale (void) +-{ +- const gchar *locale; +- const gchar *locale_engine[][2] = { +- { "as_IN", "m17n:as:phonetic" }, +- { "bn_IN", "m17n:bn:inscript" }, +- { "gu_IN", "m17n:gu:inscript" }, +- { "hi_IN", "m17n:hi:inscript" }, +- { "ja_JP", "anthy" }, +- { "kn_IN", "m17n:kn:kgp" }, +- { "ko_KR", "hangul" }, +- { "mai_IN", "m17n:mai:inscript" }, +- { "ml_IN", "m17n:ml:inscript" }, +- { "mr_IN", "m17n:mr:inscript" }, +- { "or_IN", "m17n:or:inscript" }, +- { "pa_IN", "m17n:pa:inscript" }, +- { "sd_IN", "m17n:sd:inscript" }, +- { "ta_IN", "m17n:ta:tamil99" }, +- { "te_IN", "m17n:te:inscript" }, +- { "zh_CN", "pinyin" }, +- { "zh_HK", "cangjie3" }, +- { "zh_TW", "chewing" }, +- }; +- gint i; +- +- locale = setlocale (LC_CTYPE, NULL); +- if (!locale) +- return NULL; +- +- for (i = 0; i < G_N_ELEMENTS (locale_engine); ++i) +- if (g_str_has_prefix (locale, locale_engine[i][0])) +- return locale_engine[i][1]; +- +- return NULL; +-} +- +-static void +-add_ibus_sources_from_locale (GSettings *settings) +-{ +- const gchar *locale_engine; +- GVariantBuilder builder; +- +- locale_engine = engine_from_locale (); +- if (!locale_engine) +- return; +- +- init_builder_with_sources (&builder, settings); +- g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_IBUS, locale_engine); +- g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); +-} +- + static void + convert_ibus (GSettings *settings) + { +@@ -1465,12 +1413,8 @@ maybe_create_initial_settings (GsdKeyboardManager *manager) + + /* if we still don't have anything do some educated guesses */ + sources = g_settings_get_value (settings, KEY_INPUT_SOURCES); +- if (g_variant_n_children (sources) < 1) { ++ if (g_variant_n_children (sources) < 1) + get_sources_from_xkb_config (manager); +-#ifdef HAVE_IBUS +- add_ibus_sources_from_locale (settings); +-#endif +- } + g_variant_unref (sources); + + options = g_settings_get_strv (settings, KEY_KEYBOARD_OPTIONS); +-- +1.8.1.4 + diff --git a/SOURCES/0001-media-keys-Merge-power_action_-functions.patch b/SOURCES/0001-media-keys-Merge-power_action_-functions.patch new file mode 100644 index 0000000..eb25509 --- /dev/null +++ b/SOURCES/0001-media-keys-Merge-power_action_-functions.patch @@ -0,0 +1,60 @@ +From 6ffc07f87a09deeaa4bbd6156fc1dbd733d4ab27 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Sat, 19 Oct 2013 23:58:34 +0200 +Subject: [PATCH 1/3] media-keys: Merge power_action_* functions + +They only differed by a single line. +--- + plugins/media-keys/gsd-media-keys-manager.c | 21 +++++---------------- + 1 file changed, 5 insertions(+), 16 deletions(-) + +diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c +index 93cf14e..2c46d74 100644 +--- a/plugins/media-keys/gsd-media-keys-manager.c ++++ b/plugins/media-keys/gsd-media-keys-manager.c +@@ -1766,22 +1766,11 @@ do_toggle_contrast_action (GsdMediaKeysManager *manager) + } + + static void +-power_action_suspend (GsdMediaKeysManager *manager) ++power_action (GsdMediaKeysManager *manager, ++ const char *action) + { + g_dbus_proxy_call (manager->priv->logind_proxy, +- "Suspend", +- g_variant_new ("(b)", TRUE), +- G_DBUS_CALL_FLAGS_NONE, +- G_MAXINT, +- manager->priv->bus_cancellable, +- NULL, NULL); +-} +- +-static void +-power_action_hibernate (GsdMediaKeysManager *manager) +-{ +- g_dbus_proxy_call (manager->priv->logind_proxy, +- "Hibernate", ++ action, + g_variant_new ("(b)", TRUE), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, +@@ -1799,14 +1788,14 @@ do_config_power_action (GsdMediaKeysManager *manager, + config_key); + switch (action_type) { + case GSD_POWER_ACTION_SUSPEND: +- power_action_suspend (manager); ++ power_action (manager, "Suspend"); + break; + case GSD_POWER_ACTION_INTERACTIVE: + case GSD_POWER_ACTION_SHUTDOWN: + gnome_session_shutdown (manager); + break; + case GSD_POWER_ACTION_HIBERNATE: +- power_action_hibernate (manager); ++ power_action (manager, "Hibernate"); + break; + case GSD_POWER_ACTION_BLANK: + case GSD_POWER_ACTION_NOTHING: +-- +1.8.4.2 + diff --git a/SOURCES/0002-media-keys-Make-the-shutdown-action-not-be-interacti.patch b/SOURCES/0002-media-keys-Make-the-shutdown-action-not-be-interacti.patch new file mode 100644 index 0000000..1297abf --- /dev/null +++ b/SOURCES/0002-media-keys-Make-the-shutdown-action-not-be-interacti.patch @@ -0,0 +1,33 @@ +From fcea8bec0a73ce1f5803a8273f7865d8554bd033 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Sun, 20 Oct 2013 00:01:49 +0200 +Subject: [PATCH 2/3] media-keys: Make the "shutdown" action not be interactive + +Shutdown is supposed to shutdown without asking, as "interactive" +already should do what we need for interactive shutdowns. + +https://bugzilla.gnome.org/show_bug.cgi?id=698733 +--- + plugins/media-keys/gsd-media-keys-manager.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c +index 2c46d74..cab4aa2 100644 +--- a/plugins/media-keys/gsd-media-keys-manager.c ++++ b/plugins/media-keys/gsd-media-keys-manager.c +@@ -1791,9 +1791,11 @@ do_config_power_action (GsdMediaKeysManager *manager, + power_action (manager, "Suspend"); + break; + case GSD_POWER_ACTION_INTERACTIVE: +- case GSD_POWER_ACTION_SHUTDOWN: + gnome_session_shutdown (manager); + break; ++ case GSD_POWER_ACTION_SHUTDOWN: ++ power_action (manager, "PowerOff"); ++ break; + case GSD_POWER_ACTION_HIBERNATE: + power_action (manager, "Hibernate"); + break; +-- +1.8.4.2 + diff --git a/SOURCES/0003-media-keys-Allow-the-power-key-in-more-places.patch b/SOURCES/0003-media-keys-Allow-the-power-key-in-more-places.patch new file mode 100644 index 0000000..8224a73 --- /dev/null +++ b/SOURCES/0003-media-keys-Allow-the-power-key-in-more-places.patch @@ -0,0 +1,156 @@ +From f9c12c90d84a3b79321e983d90e40e01ce54e3fa Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 6 Nov 2013 17:54:53 +0100 +Subject: [PATCH 3/3] media-keys: Allow the power key in more places + +We allow using the power key pretty much everywhere now, but +we also ensure that we never show interactive dialogues on the +lock screen (something that was possible with other suspend/power +buttons already if more than more than one user was logged in, +or an interactive shutdown was configured). + +See https://bugzilla.redhat.com/show_bug.cgi?id=980692 + +https://bugzilla.gnome.org/show_bug.cgi?id=707095 +--- + plugins/media-keys/gsd-media-keys-manager.c | 37 ++++++++++++++++++++--------- + plugins/media-keys/shortcuts-list.h | 23 ++++++++++++++---- + 2 files changed, 45 insertions(+), 15 deletions(-) + +diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c +index cab4aa2..6609165 100644 +--- a/plugins/media-keys/gsd-media-keys-manager.c ++++ b/plugins/media-keys/gsd-media-keys-manager.c +@@ -1767,11 +1767,12 @@ do_toggle_contrast_action (GsdMediaKeysManager *manager) + + static void + power_action (GsdMediaKeysManager *manager, +- const char *action) ++ const char *action, ++ gboolean allow_interaction) + { + g_dbus_proxy_call (manager->priv->logind_proxy, + action, +- g_variant_new ("(b)", TRUE), ++ g_variant_new ("(b)", allow_interaction), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + manager->priv->bus_cancellable, +@@ -1780,7 +1781,8 @@ power_action (GsdMediaKeysManager *manager, + + static void + do_config_power_action (GsdMediaKeysManager *manager, +- const gchar *config_key) ++ const gchar *config_key, ++ gboolean in_lock_screen) + { + GsdPowerActionType action_type; + +@@ -1788,16 +1790,17 @@ do_config_power_action (GsdMediaKeysManager *manager, + config_key); + switch (action_type) { + case GSD_POWER_ACTION_SUSPEND: +- power_action (manager, "Suspend"); ++ power_action (manager, "Suspend", !in_lock_screen); + break; + case GSD_POWER_ACTION_INTERACTIVE: +- gnome_session_shutdown (manager); ++ if (!in_lock_screen) ++ gnome_session_shutdown (manager); + break; + case GSD_POWER_ACTION_SHUTDOWN: +- power_action (manager, "PowerOff"); ++ power_action (manager, "PowerOff", !in_lock_screen); + break; + case GSD_POWER_ACTION_HIBERNATE: +- power_action (manager, "Hibernate"); ++ power_action (manager, "Hibernate", !in_lock_screen); + break; + case GSD_POWER_ACTION_BLANK: + case GSD_POWER_ACTION_NOTHING: +@@ -2064,16 +2067,28 @@ do_action (GsdMediaKeysManager *manager, + do_toggle_contrast_action (manager); + break; + case POWER_KEY: +- do_config_power_action (manager, "button-power"); ++ do_config_power_action (manager, "button-power", FALSE); + break; + case SLEEP_KEY: +- do_config_power_action (manager, "button-sleep"); ++ do_config_power_action (manager, "button-sleep", FALSE); + break; + case SUSPEND_KEY: +- do_config_power_action (manager, "button-suspend"); ++ do_config_power_action (manager, "button-suspend", FALSE); + break; + case HIBERNATE_KEY: +- do_config_power_action (manager, "button-hibernate"); ++ do_config_power_action (manager, "button-hibernate", FALSE); ++ break; ++ case POWER_KEY_NO_DIALOG: ++ do_config_power_action (manager, "button-power", TRUE); ++ break; ++ case SLEEP_KEY_NO_DIALOG: ++ do_config_power_action (manager, "button-sleep", TRUE); ++ break; ++ case SUSPEND_KEY_NO_DIALOG: ++ do_config_power_action (manager, "button-suspend", TRUE); ++ break; ++ case HIBERNATE_KEY_NO_DIALOG: ++ do_config_power_action (manager, "button-hibernate", TRUE); + break; + case SCREEN_BRIGHTNESS_UP_KEY: + case SCREEN_BRIGHTNESS_DOWN_KEY: +diff --git a/plugins/media-keys/shortcuts-list.h b/plugins/media-keys/shortcuts-list.h +index 1ac0798..a2e6638 100644 +--- a/plugins/media-keys/shortcuts-list.h ++++ b/plugins/media-keys/shortcuts-list.h +@@ -75,6 +75,10 @@ typedef enum { + SLEEP_KEY, + SUSPEND_KEY, + HIBERNATE_KEY, ++ POWER_KEY_NO_DIALOG, ++ SLEEP_KEY_NO_DIALOG, ++ SUSPEND_KEY_NO_DIALOG, ++ HIBERNATE_KEY_NO_DIALOG, + SCREEN_BRIGHTNESS_UP_KEY, + SCREEN_BRIGHTNESS_DOWN_KEY, + KEYBOARD_BRIGHTNESS_UP_KEY, +@@ -88,6 +92,11 @@ typedef enum { + #define GSD_KEYBINDING_MODE_LAUNCHER (SHELL_KEYBINDING_MODE_NORMAL | \ + SHELL_KEYBINDING_MODE_OVERVIEW) + #define SCREENSAVER_MODE SHELL_KEYBINDING_MODE_ALL & ~SHELL_KEYBINDING_MODE_UNLOCK_SCREEN ++#define POWER_KEYS_MODE (SHELL_KEYBINDING_MODE_NORMAL | \ ++ SHELL_KEYBINDING_MODE_OVERVIEW | \ ++ SHELL_KEYBINDING_MODE_LOGIN_SCREEN) ++#define POWER_KEYS_MODE_NO_DIALOG (SHELL_KEYBINDING_MODE_LOCK_SCREEN | \ ++ SHELL_KEYBINDING_MODE_UNLOCK_SCREEN) + + static struct { + MediaKeyType key_type; +@@ -145,12 +154,18 @@ static struct { + { TOGGLE_CONTRAST_KEY, "toggle-contrast", NULL, NULL, SHELL_KEYBINDING_MODE_ALL }, + { MAGNIFIER_ZOOM_IN_KEY, "magnifier-zoom-in", NULL, NULL, SHELL_KEYBINDING_MODE_ALL }, + { MAGNIFIER_ZOOM_OUT_KEY, "magnifier-zoom-out", NULL, NULL, SHELL_KEYBINDING_MODE_ALL }, +- { POWER_KEY, NULL, N_("Power Off"), "XF86PowerOff", GSD_KEYBINDING_MODE_LAUNCHER }, ++ { POWER_KEY, NULL, N_("Power Off"), "XF86PowerOff", POWER_KEYS_MODE }, + /* the kernel / Xorg names really are like this... */ + /* translators: "Sleep" means putting the machine to sleep, either through hibernate or suspend */ +- { SLEEP_KEY, NULL, N_("Sleep"), "XF86Suspend", SHELL_KEYBINDING_MODE_ALL }, +- { SUSPEND_KEY, NULL, N_("Suspend"), "XF86Sleep", SHELL_KEYBINDING_MODE_ALL }, +- { HIBERNATE_KEY, NULL, N_("Hibernate"), "XF86Hibernate", SHELL_KEYBINDING_MODE_ALL }, ++ { SLEEP_KEY, NULL, N_("Sleep"), "XF86Suspend", POWER_KEYS_MODE }, ++ { SUSPEND_KEY, NULL, N_("Suspend"), "XF86Sleep", POWER_KEYS_MODE }, ++ { HIBERNATE_KEY, NULL, N_("Hibernate"), "XF86Hibernate", POWER_KEYS_MODE }, ++ { POWER_KEY_NO_DIALOG, NULL, N_("Power Off"), "XF86PowerOff", POWER_KEYS_MODE_NO_DIALOG }, ++ /* the kernel / Xorg names really are like this... */ ++ /* translators: "Sleep" means putting the machine to sleep, either through hibernate or suspend */ ++ { SLEEP_KEY_NO_DIALOG, NULL, N_("Sleep"), "XF86Suspend", POWER_KEYS_MODE_NO_DIALOG }, ++ { SUSPEND_KEY_NO_DIALOG, NULL, N_("Suspend"), "XF86Sleep", POWER_KEYS_MODE_NO_DIALOG }, ++ { HIBERNATE_KEY_NO_DIALOG, NULL, N_("Hibernate"), "XF86Hibernate", POWER_KEYS_MODE_NO_DIALOG }, + { SCREEN_BRIGHTNESS_UP_KEY, NULL, N_("Brightness Up"), "XF86MonBrightnessUp", SHELL_KEYBINDING_MODE_ALL }, + { SCREEN_BRIGHTNESS_DOWN_KEY, NULL, N_("Brightness Down"), "XF86MonBrightnessDown", SHELL_KEYBINDING_MODE_ALL }, + { KEYBOARD_BRIGHTNESS_UP_KEY, NULL, N_("Keyboard Brightness Up"), "XF86KbdBrightnessUp", SHELL_KEYBINDING_MODE_ALL }, +-- +1.8.4.2 + diff --git a/SOURCES/gnome-settings-daemon-3.5.4-ppc-no-wacom.patch b/SOURCES/gnome-settings-daemon-3.5.4-ppc-no-wacom.patch new file mode 100644 index 0000000..1e44929 --- /dev/null +++ b/SOURCES/gnome-settings-daemon-3.5.4-ppc-no-wacom.patch @@ -0,0 +1,18 @@ +diff -up gnome-settings-daemon-3.5.4/configure.ac.ppc-no-wacom gnome-settings-daemon-3.5.4/configure.ac +--- gnome-settings-daemon-3.5.4/configure.ac.ppc-no-wacom 2012-07-17 18:42:41.000000000 +0200 ++++ gnome-settings-daemon-3.5.4/configure.ac 2012-07-17 18:43:39.000000000 +0200 +@@ -222,12 +222,12 @@ dnl ------------------------------------ + PKG_CHECK_MODULES(COLOR, [colord >= 0.1.9 gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION libcanberra-gtk3]) + + dnl --------------------------------------------------------------------------- +-dnl - wacom (disabled for s390/s390x and non Linux platforms) ++dnl - wacom (disabled for s390/s390x, ppc/ppc64 and non Linux platforms) + dnl --------------------------------------------------------------------------- + + case $host_os in + linux*) +- if test "$host_cpu" = s390 -o "$host_cpu" = s390x; then ++ if test "$host_cpu" = s390 -o "$host_cpu" = s390x -o "$host_cpu" = powerpc -o "$host_cpu" = ppc -o "$host_cpu" = powerpc64 -o "$host_cpu" = ppc64 ; then + have_wacom=no + else + if test x$enable_gudev != xno; then diff --git a/SOURCES/smartcard-support.patch b/SOURCES/smartcard-support.patch new file mode 100644 index 0000000..fcfca97 --- /dev/null +++ b/SOURCES/smartcard-support.patch @@ -0,0 +1,7128 @@ +From 92b5f8d3ca7b83fa5f10c16b8e876cfde23e4377 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 28 May 2013 09:20:57 -0400 +Subject: [PATCH 1/9] smartcard: drop old implementation + +It's going to be substantially rewritten, so drop the old +code to avoid a confusing diff when the new stuff lands. + +https://bugzilla.gnome.org/show_bug.cgi?id=704890 +--- + plugins/smartcard/Makefile.am | 75 -- + plugins/smartcard/gsd-smartcard-manager.c | 1519 ----------------------------- + plugins/smartcard/gsd-smartcard-manager.h | 88 -- + plugins/smartcard/gsd-smartcard-plugin.c | 337 ------- + plugins/smartcard/gsd-smartcard-plugin.h | 59 -- + plugins/smartcard/gsd-smartcard.c | 556 ----------- + plugins/smartcard/gsd-smartcard.h | 94 -- + plugins/smartcard/test-smartcard.c | 7 - + 8 files changed, 2735 deletions(-) + delete mode 100644 plugins/smartcard/Makefile.am + delete mode 100644 plugins/smartcard/gsd-smartcard-manager.c + delete mode 100644 plugins/smartcard/gsd-smartcard-manager.h + delete mode 100644 plugins/smartcard/gsd-smartcard-plugin.c + delete mode 100644 plugins/smartcard/gsd-smartcard-plugin.h + delete mode 100644 plugins/smartcard/gsd-smartcard.c + delete mode 100644 plugins/smartcard/gsd-smartcard.h + delete mode 100644 plugins/smartcard/test-smartcard.c + +diff --git a/plugins/smartcard/Makefile.am b/plugins/smartcard/Makefile.am +deleted file mode 100644 +index e2a0add..0000000 +--- a/plugins/smartcard/Makefile.am ++++ /dev/null +@@ -1,75 +0,0 @@ +-plugin_name = smartcard +- +-libexec_PROGRAMS = gsd-test-smartcard +- +-gsd_test_smartcard_SOURCES = \ +- gsd-smartcard-manager.h \ +- gsd-smartcard-manager.c \ +- gsd-smartcard.h \ +- gsd-smartcard.c \ +- test-smartcard.c +- +-gsd_test_smartcard_CFLAGS = \ +- -I$(top_srcdir)/gnome-settings-daemon \ +- -I$(top_srcdir)/plugins/common \ +- -DSYSCONFDIR=\""$(sysconfdir)"\" \ +- -DLIBDIR=\""$(libdir)"\" \ +- -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ +- $(NSS_CFLAGS) \ +- $(PLUGIN_CFLAGS) \ +- $(SETTINGS_PLUGIN_CFLAGS) \ +- $(AM_CFLAGS) +- +-gsd_test_smartcard_LDADD = \ +- $(top_builddir)/gnome-settings-daemon/libgsd.la \ +- $(top_builddir)/plugins/common/libcommon.la \ +- $(NSS_LIBS) \ +- $(SETTINGS_PLUGIN_LIBS) +- +-plugin_LTLIBRARIES = \ +- libsmartcard.la +- +-libsmartcard_la_SOURCES = \ +- gsd-smartcard-plugin.h \ +- gsd-smartcard-plugin.c \ +- gsd-smartcard.h \ +- gsd-smartcard.c \ +- gsd-smartcard-manager.h \ +- gsd-smartcard-manager.c +- +-libsmartcard_la_CPPFLAGS = \ +- -I$(top_srcdir)/gnome-settings-daemon \ +- -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ +- -DSYSCONFDIR=\""$(sysconfdir)"\" \ +- -DLIBDIR=\""$(libdir)"\" \ +- -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ +- $(AM_CPPFLAGS) +- +-libsmartcard_la_CFLAGS = \ +- $(PLUGIN_CFLAGS) \ +- $(SETTINGS_PLUGIN_CFLAGS) \ +- $(NSS_CFLAGS) \ +- $(AM_CFLAGS) +- +-libsmartcard_la_LDFLAGS = \ +- $(GSD_PLUGIN_LDFLAGS) +- +-libsmartcard_la_LIBADD = \ +- $(SETTINGS_PLUGIN_LIBS) \ +- $(NSS_LIBS) +- +-@GSD_INTLTOOL_PLUGIN_RULE@ +- +-plugin_in_files = \ +- smartcard.gnome-settings-plugin.in +- +-plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin) +- +-EXTRA_DIST = \ +- $(plugin_in_files) +- +-CLEANFILES = \ +- $(plugin_DATA) +- +-DISTCLEANFILES = \ +- $(plugin_DATA) +diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c +deleted file mode 100644 +index 3acef0e..0000000 +--- a/plugins/smartcard/gsd-smartcard-manager.c ++++ /dev/null +@@ -1,1519 +0,0 @@ +-/* gsd-smartcard-manager.c - object for monitoring smartcard insertion and +- * removal events +- * +- * Copyright (C) 2006, 2009 Red Hat, Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +- * 02111-1307, USA. +- * +- * Written By: Ray Strode +- */ +-#include "config.h" +- +-#include "gsd-smartcard-manager.h" +- +-#define SMARTCARD_ENABLE_INTERNAL_API +-#include "gsd-smartcard.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#ifndef GSD_SMARTCARD_MANAGER_DRIVER +-#define GSD_SMARTCARD_MANAGER_DRIVER LIBDIR"/pkcs11/libcoolkeypk11.so" +-#endif +- +-#ifndef GSD_SMARTCARD_MANAGER_NSS_DB +-#define GSD_SMARTCARD_MANAGER_NSS_DB SYSCONFDIR"/pki/nssdb" +-#endif +- +-#ifndef GSD_MAX_OPEN_FILE_DESCRIPTORS +-#define GSD_MAX_OPEN_FILE_DESCRIPTORS 1024 +-#endif +- +-#ifndef GSD_OPEN_FILE_DESCRIPTORS_DIR +-#define GSD_OPEN_FILE_DESCRIPTORS_DIR "/proc/self/fd" +-#endif +- +-typedef enum _GsdSmartcardManagerState GsdSmartcardManagerState; +-typedef struct _GsdSmartcardManagerWorker GsdSmartcardManagerWorker; +- +-enum _GsdSmartcardManagerState { +- GSD_SMARTCARD_MANAGER_STATE_STOPPED = 0, +- GSD_SMARTCARD_MANAGER_STATE_STARTING, +- GSD_SMARTCARD_MANAGER_STATE_STARTED, +- GSD_SMARTCARD_MANAGER_STATE_STOPPING, +-}; +- +-struct _GsdSmartcardManagerPrivate { +- GsdSmartcardManagerState state; +- GList *modules; +- char *module_path; +- +- GList *workers; +- +- GPid smartcard_event_watcher_pid; +- GHashTable *smartcards; +- +- guint poll_timeout_id; +- +- guint32 is_unstoppable : 1; +- guint32 nss_is_loaded : 1; +-}; +- +-struct _GsdSmartcardManagerWorker { +- GsdSmartcardManager *manager; +- int manager_fd; +- +- GThread *thread; +- SECMODModule *module; +- GHashTable *smartcards; +- int fd; +- GSource *event_source; +- +- guint32 nss_is_loaded : 1; +-}; +- +-static void gsd_smartcard_manager_finalize (GObject *object); +-static void gsd_smartcard_manager_class_install_signals (GsdSmartcardManagerClass *service_class); +-static void gsd_smartcard_manager_class_install_properties (GsdSmartcardManagerClass *service_class); +-static void gsd_smartcard_manager_set_property (GObject *object, +- guint prop_id, +- const GValue *value, +- GParamSpec *pspec); +-static void gsd_smartcard_manager_get_property (GObject *object, +- guint prop_id, +- GValue *value, +- GParamSpec *pspec); +-static void gsd_smartcard_manager_set_module_path (GsdSmartcardManager *manager, +- const char *module_path); +-static void gsd_smartcard_manager_card_removed_handler (GsdSmartcardManager *manager, +- GsdSmartcard *card); +-static void gsd_smartcard_manager_card_inserted_handler (GsdSmartcardManager *manager_class, +- GsdSmartcard *card); +-static gboolean gsd_smartcard_manager_stop_now (GsdSmartcardManager *manager); +-static void gsd_smartcard_manager_queue_stop (GsdSmartcardManager *manager); +- +-static GsdSmartcardManagerWorker *gsd_smartcard_manager_create_worker (GsdSmartcardManager *manager, +- SECMODModule *module); +- +-static GsdSmartcardManagerWorker * gsd_smartcard_manager_worker_new (GsdSmartcardManager *manager, +- int worker_fd, +- int manager_fd, +- SECMODModule *module); +-static void gsd_smartcard_manager_worker_free (GsdSmartcardManagerWorker *worker); +-static gboolean open_pipe (int *write_fd, int *read_fd); +-static gboolean read_bytes (int fd, gpointer bytes, gsize num_bytes); +-static gboolean write_bytes (int fd, gconstpointer bytes, gsize num_bytes); +-static GsdSmartcard *read_smartcard (int fd, SECMODModule *module); +-static gboolean write_smartcard (int fd, GsdSmartcard *card); +- +-enum { +- PROP_0 = 0, +- PROP_MODULE_PATH, +- NUMBER_OF_PROPERTIES +-}; +- +-enum { +- SMARTCARD_INSERTED = 0, +- SMARTCARD_REMOVED, +- ERROR, +- NUMBER_OF_SIGNALS +-}; +- +-static guint gsd_smartcard_manager_signals[NUMBER_OF_SIGNALS]; +- +-G_DEFINE_TYPE (GsdSmartcardManager, +- gsd_smartcard_manager, +- G_TYPE_OBJECT); +- +-static void +-gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *manager_class) +-{ +- GObjectClass *gobject_class; +- +- gobject_class = G_OBJECT_CLASS (manager_class); +- +- gobject_class->finalize = gsd_smartcard_manager_finalize; +- +- gsd_smartcard_manager_class_install_signals (manager_class); +- gsd_smartcard_manager_class_install_properties (manager_class); +- +- g_type_class_add_private (manager_class, +- sizeof (GsdSmartcardManagerPrivate)); +-} +- +-static void +-gsd_smartcard_manager_class_install_properties (GsdSmartcardManagerClass *card_class) +-{ +- GObjectClass *object_class; +- GParamSpec *param_spec; +- +- object_class = G_OBJECT_CLASS (card_class); +- object_class->set_property = gsd_smartcard_manager_set_property; +- object_class->get_property = gsd_smartcard_manager_get_property; +- +- param_spec = g_param_spec_string ("module-path", "Module Path", +- "path to smartcard PKCS #11 driver", +- NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); +- g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec); +-} +- +-static void +-gsd_smartcard_manager_set_property (GObject *object, +- guint prop_id, +- const GValue *value, +- GParamSpec *pspec) +-{ +- GsdSmartcardManager *manager = GSD_SMARTCARD_MANAGER (object); +- +- switch (prop_id) { +- case PROP_MODULE_PATH: +- gsd_smartcard_manager_set_module_path (manager, +- g_value_get_string (value)); +- break; +- +- default: +- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +- break; +- } +-} +- +-static void +-gsd_smartcard_manager_get_property (GObject *object, +- guint prop_id, +- GValue *value, +- GParamSpec *pspec) +-{ +- GsdSmartcardManager *manager = GSD_SMARTCARD_MANAGER (object); +- char *module_path; +- +- switch (prop_id) { +- case PROP_MODULE_PATH: +- module_path = gsd_smartcard_manager_get_module_path (manager); +- g_value_set_string (value, module_path); +- g_free (module_path); +- break; +- +- default: +- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +- break; +- } +-} +- +-char * +-gsd_smartcard_manager_get_module_path (GsdSmartcardManager *manager) +-{ +- return manager->priv->module_path; +-} +- +-static void +-gsd_smartcard_manager_set_module_path (GsdSmartcardManager *manager, +- const char *module_path) +-{ +- if ((manager->priv->module_path == NULL) && (module_path == NULL)) { +- return; +- } +- +- if (((manager->priv->module_path == NULL) || +- (module_path == NULL) || +- (strcmp (manager->priv->module_path, module_path) != 0))) { +- g_free (manager->priv->module_path); +- manager->priv->module_path = g_strdup (module_path); +- g_object_notify (G_OBJECT (manager), "module-path"); +- } +-} +- +-static void +-gsd_smartcard_manager_card_removed_handler (GsdSmartcardManager *manager, +- GsdSmartcard *card) +-{ +- g_debug ("informing smartcard of its removal"); +- _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED); +- g_debug ("done"); +-} +- +-static void +-gsd_smartcard_manager_card_inserted_handler (GsdSmartcardManager *manager, +- GsdSmartcard *card) +-{ +- g_debug ("informing smartcard of its insertion"); +- +- _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED); +- g_debug ("done"); +- +-} +- +-static void +-gsd_smartcard_manager_class_install_signals (GsdSmartcardManagerClass *manager_class) +-{ +- GObjectClass *object_class; +- +- object_class = G_OBJECT_CLASS (manager_class); +- +- gsd_smartcard_manager_signals[SMARTCARD_INSERTED] = +- g_signal_new ("smartcard-inserted", +- G_OBJECT_CLASS_TYPE (object_class), +- G_SIGNAL_RUN_FIRST, +- G_STRUCT_OFFSET (GsdSmartcardManagerClass, +- smartcard_inserted), +- NULL, NULL, g_cclosure_marshal_VOID__POINTER, +- G_TYPE_NONE, 1, G_TYPE_POINTER); +- manager_class->smartcard_inserted = gsd_smartcard_manager_card_inserted_handler; +- +- gsd_smartcard_manager_signals[SMARTCARD_REMOVED] = +- g_signal_new ("smartcard-removed", +- G_OBJECT_CLASS_TYPE (object_class), +- G_SIGNAL_RUN_FIRST, +- G_STRUCT_OFFSET (GsdSmartcardManagerClass, +- smartcard_removed), +- NULL, NULL, g_cclosure_marshal_VOID__POINTER, +- G_TYPE_NONE, 1, G_TYPE_POINTER); +- manager_class->smartcard_removed = gsd_smartcard_manager_card_removed_handler; +- +- gsd_smartcard_manager_signals[ERROR] = +- g_signal_new ("error", +- G_OBJECT_CLASS_TYPE (object_class), +- G_SIGNAL_RUN_LAST, +- G_STRUCT_OFFSET (GsdSmartcardManagerClass, error), +- NULL, NULL, g_cclosure_marshal_VOID__POINTER, +- G_TYPE_NONE, 1, G_TYPE_POINTER); +- manager_class->error = NULL; +-} +- +-static gboolean +-slot_id_equal (CK_SLOT_ID *slot_id_1, +- CK_SLOT_ID *slot_id_2) +-{ +- g_assert (slot_id_1 != NULL); +- g_assert (slot_id_2 != NULL); +- +- return *slot_id_1 == *slot_id_2; +-} +- +-static gboolean +-slot_id_hash (CK_SLOT_ID *slot_id) +-{ +- guint32 upper_bits, lower_bits; +- int temp; +- +- if (sizeof (CK_SLOT_ID) == sizeof (int)) { +- return g_int_hash (slot_id); +- } +- +- upper_bits = ((*slot_id) >> 31) - 1; +- lower_bits = (*slot_id) & 0xffffffff; +- +- /* The upper bits are almost certainly always zero, +- * so let's degenerate to g_int_hash for the +- * (very) common case +- */ +- temp = lower_bits + upper_bits; +- return upper_bits + g_int_hash (&temp); +-} +- +-static void +-gsd_smartcard_manager_init (GsdSmartcardManager *manager) +-{ +- g_debug ("initializing smartcard manager"); +- +- manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, +- GSD_TYPE_SMARTCARD_MANAGER, +- GsdSmartcardManagerPrivate); +- manager->priv->poll_timeout_id = 0; +- manager->priv->is_unstoppable = FALSE; +- +- manager->priv->smartcards = +- g_hash_table_new_full (g_str_hash, +- g_str_equal, +- (GDestroyNotify) g_free, +- (GDestroyNotify) g_object_unref); +-} +- +-static void +-gsd_smartcard_manager_finalize (GObject *object) +-{ +- GsdSmartcardManager *manager; +- GObjectClass *gobject_class; +- +- manager = GSD_SMARTCARD_MANAGER (object); +- gobject_class = +- G_OBJECT_CLASS (gsd_smartcard_manager_parent_class); +- +- gsd_smartcard_manager_stop_now (manager); +- +- g_hash_table_destroy (manager->priv->smartcards); +- manager->priv->smartcards = NULL; +- +- gobject_class->finalize (object); +-} +- +-GQuark +-gsd_smartcard_manager_error_quark (void) +-{ +- static GQuark error_quark = 0; +- +- if (error_quark == 0) { +- error_quark = g_quark_from_static_string ("gsd-smartcard-manager-error-quark"); +- } +- +- return error_quark; +-} +- +-GsdSmartcardManager * +-gsd_smartcard_manager_new_default (void) +-{ +- return gsd_smartcard_manager_new (NULL); +-} +- +-GsdSmartcardManager * +-gsd_smartcard_manager_new (const char *module_path) +-{ +- GsdSmartcardManager *instance; +- +- instance = GSD_SMARTCARD_MANAGER (g_object_new (GSD_TYPE_SMARTCARD_MANAGER, +- "module-path", module_path, +- NULL)); +- +- return instance; +-} +- +-static void +-gsd_smartcard_manager_emit_error (GsdSmartcardManager *manager, +- GError *error) +-{ +- manager->priv->is_unstoppable = TRUE; +- g_signal_emit (manager, gsd_smartcard_manager_signals[ERROR], 0, +- error); +- manager->priv->is_unstoppable = FALSE; +-} +- +-static void +-gsd_smartcard_manager_emit_smartcard_inserted (GsdSmartcardManager *manager, +- GsdSmartcard *card) +-{ +- manager->priv->is_unstoppable = TRUE; +- g_signal_emit (manager, gsd_smartcard_manager_signals[SMARTCARD_INSERTED], 0, +- card); +- manager->priv->is_unstoppable = FALSE; +-} +- +-static void +-gsd_smartcard_manager_emit_smartcard_removed (GsdSmartcardManager *manager, +- GsdSmartcard *card) +-{ +- manager->priv->is_unstoppable = TRUE; +- g_signal_emit (manager, gsd_smartcard_manager_signals[SMARTCARD_REMOVED], 0, +- card); +- manager->priv->is_unstoppable = FALSE; +-} +- +-static gboolean +-gsd_smartcard_manager_check_for_and_process_events (GIOChannel *io_channel, +- GIOCondition condition, +- GsdSmartcardManagerWorker *worker) +-{ +- GsdSmartcard *card; +- GsdSmartcardManager *manager; +- gboolean should_stop; +- guchar event_type; +- char *card_name; +- int fd; +- +- manager = worker->manager; +- +- g_debug ("event!"); +- card = NULL; +- should_stop = (condition & G_IO_HUP) || (condition & G_IO_ERR); +- +- if (should_stop) { +- g_debug ("received %s on event socket, stopping " +- "manager...", +- (condition & G_IO_HUP) && (condition & G_IO_ERR)? +- "error and hangup" : +- (condition & G_IO_HUP)? +- "hangup" : "error"); +- } +- +- if (!(condition & G_IO_IN)) { +- g_debug ("nevermind outta here!"); +- goto out; +- } +- +- fd = g_io_channel_unix_get_fd (io_channel); +- +- event_type = '\0'; +- if (!read_bytes (fd, &event_type, 1)) { +- g_debug ("could not read event type, stopping"); +- should_stop = TRUE; +- goto out; +- } +- +- card = read_smartcard (fd, worker->module); +- +- if (card == NULL) { +- g_debug ("could not read card, stopping"); +- should_stop = TRUE; +- goto out; +- } +- +- card_name = gsd_smartcard_get_name (card); +- g_debug ("card '%s' had event %c", card_name, event_type); +- +- switch (event_type) { +- case 'I': +- g_hash_table_replace (manager->priv->smartcards, +- card_name, card); +- card_name = NULL; +- +- gsd_smartcard_manager_emit_smartcard_inserted (manager, card); +- card = NULL; +- break; +- +- case 'R': +- gsd_smartcard_manager_emit_smartcard_removed (manager, card); +- if (!g_hash_table_remove (manager->priv->smartcards, card_name)) { +- g_debug ("got removal event of unknown card!"); +- } +- g_free (card_name); +- card_name = NULL; +- card = NULL; +- break; +- +- default: +- g_free (card_name); +- card_name = NULL; +- g_object_unref (card); +- +- should_stop = TRUE; +- break; +- } +- +-out: +- if (should_stop) { +- GError *error; +- +- error = g_error_new (GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, +- "%s", (condition & G_IO_IN) ? g_strerror (errno) : _("received error or hang up from event source")); +- +- gsd_smartcard_manager_emit_error (manager, error); +- g_error_free (error); +- gsd_smartcard_manager_stop_now (manager); +- return FALSE; +- } +- +- return TRUE; +-} +- +-static void +-stop_manager (GsdSmartcardManager *manager) +-{ +- manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STOPPED; +- +- if (manager->priv->nss_is_loaded) { +- NSS_Shutdown (); +- manager->priv->nss_is_loaded = FALSE; +- } +- g_debug ("smartcard manager stopped"); +-} +- +-static void +-stop_worker (GsdSmartcardManagerWorker *worker) +-{ +- GsdSmartcardManager *manager; +- +- manager = worker->manager; +- +- if (worker->event_source != NULL) { +- g_source_destroy (worker->event_source); +- worker->event_source = NULL; +- } +- +- if (worker->thread != NULL) { +- SECMOD_CancelWait (worker->module); +- worker->thread = NULL; +- } +- +- SECMOD_DestroyModule (worker->module); +- manager->priv->workers = g_list_remove (manager->priv->workers, worker); +- +- if (manager->priv->workers == NULL && manager->priv->state != GSD_SMARTCARD_MANAGER_STATE_STOPPED) { +- stop_manager (manager); +- } +-} +- +-static void +-gsd_smartcard_manager_event_processing_stopped_handler (GsdSmartcardManagerWorker *worker) +-{ +- worker->event_source = NULL; +- +- stop_worker (worker); +-} +- +-static gboolean +-open_pipe (int *write_fd, +- int *read_fd) +-{ +- int pipe_fds[2] = { -1, -1 }; +- +- g_assert (write_fd != NULL); +- g_assert (read_fd != NULL); +- +- if (pipe (pipe_fds) < 0) { +- return FALSE; +- } +- +- if (fcntl (pipe_fds[0], F_SETFD, FD_CLOEXEC) < 0) { +- close (pipe_fds[0]); +- close (pipe_fds[1]); +- return FALSE; +- } +- +- if (fcntl (pipe_fds[1], F_SETFD, FD_CLOEXEC) < 0) { +- close (pipe_fds[0]); +- close (pipe_fds[1]); +- return FALSE; +- } +- +- *read_fd = pipe_fds[0]; +- *write_fd = pipe_fds[1]; +- +- return TRUE; +-} +- +-static void +-gsd_smartcard_manager_stop_watching_for_events (GsdSmartcardManager *manager) +-{ +- GList *node; +- +- node = manager->priv->workers; +- while (node != NULL) { +- GsdSmartcardManagerWorker *worker; +- GList *next_node; +- +- worker = (GsdSmartcardManagerWorker *) node->data; +- next_node = node->next; +- +- stop_worker (worker); +- +- node = next_node; +- } +-} +- +-static gboolean +-load_nss (GError **error) +-{ +- SECStatus status = SECSuccess; +- static const guint32 flags = +- NSS_INIT_READONLY | +- NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT | +- NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD; +- +- g_debug ("attempting to load NSS database '%s'", +- GSD_SMARTCARD_MANAGER_NSS_DB); +- +- PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); +- +- status = NSS_Initialize (GSD_SMARTCARD_MANAGER_NSS_DB, +- "", "", SECMOD_DB, flags); +- +- if (status != SECSuccess) { +- gsize error_message_size; +- char *error_message; +- +- error_message_size = PR_GetErrorTextLength (); +- +- if (error_message_size == 0) { +- g_debug ("NSS security system could not be initialized"); +- g_set_error (error, +- GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, +- _("NSS security system could not be initialized")); +- goto out; +- } +- +- error_message = g_slice_alloc0 (error_message_size); +- PR_GetErrorText (error_message); +- +- g_set_error (error, +- GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, +- "%s", error_message); +- g_debug ("NSS security system could not be initialized - %s", +- error_message); +- +- g_slice_free1 (error_message_size, error_message); +- +- goto out; +- } +- +- g_debug ("NSS database sucessfully loaded"); +- return TRUE; +- +-out: +- g_debug ("NSS database couldn't be sucessfully loaded"); +- return FALSE; +-} +- +-static GList * +-get_available_modules (GsdSmartcardManager *manager) +-{ +- SECMODModuleList *module_list, *tmp; +- GList *modules; +- +- g_debug ("Getting list of suitable modules"); +- +- module_list = SECMOD_GetDefaultModuleList (); +- modules = NULL; +- for (tmp = module_list; tmp != NULL; tmp = tmp->next) { +- if (!SECMOD_HasRemovableSlots (tmp->module) || +- !tmp->module->loaded) +- continue; +- +- g_debug ("Using module '%s'", tmp->module->commonName); +- +- modules = g_list_prepend (modules, +- SECMOD_ReferenceModule (tmp->module)); +- } +- +- return modules; +-} +- +-static gboolean +-load_driver (GsdSmartcardManager *manager, +- char *module_path, +- GError **error) +-{ +- GList *modules; +- char *module_spec; +- gboolean module_explicitly_specified; +- +- g_debug ("attempting to load driver..."); +- +- modules = NULL; +- module_explicitly_specified = module_path != NULL; +- if (module_explicitly_specified) { +- SECMODModule *module; +- +- module_spec = g_strdup_printf ("library=\"%s\"", module_path); +- g_debug ("loading smartcard driver using spec '%s'", +- module_spec); +- +- module = SECMOD_LoadUserModule (module_spec, +- NULL /* parent */, +- FALSE /* recurse */); +- g_free (module_spec); +- module_spec = NULL; +- +- if (SECMOD_HasRemovableSlots (module) && +- module->loaded) { +- modules = g_list_prepend (modules, module); +- } else { +- g_debug ("fallback module found but not %s", +- SECMOD_HasRemovableSlots (module)? +- "removable" : "loaded"); +- SECMOD_DestroyModule (module); +- } +- +- } else { +- SECMODListLock *lock; +- +- lock = SECMOD_GetDefaultModuleListLock (); +- +- if (lock != NULL) { +- SECMOD_GetReadLock (lock); +- modules = get_available_modules (manager); +- SECMOD_ReleaseReadLock (lock); +- } +- +- /* fallback to compiled in driver path +- */ +- if (modules == NULL) { +- SECMODModule *module; +- module_path = GSD_SMARTCARD_MANAGER_DRIVER; +- module_spec = g_strdup_printf ("library=\"%s\"", module_path); +- g_debug ("loading smartcard driver using spec '%s'", +- module_spec); +- +- module = SECMOD_LoadUserModule (module_spec, +- NULL /* parent */, +- FALSE /* recurse */); +- g_free (module_spec); +- module_spec = NULL; +- +- if (SECMOD_HasRemovableSlots (module) && +- module->loaded) { +- modules = g_list_prepend (modules, module); +- } else { +- g_debug ("fallback module found but not loaded"); +- SECMOD_DestroyModule (module); +- } +- } +- +- } +- +- if (!module_explicitly_specified && modules == NULL) { +- g_set_error (error, +- GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, +- _("no suitable smartcard driver could be found")); +- } else if (modules == NULL) { +- +- gsize error_message_size; +- char *error_message; +- +- error_message_size = PR_GetErrorTextLength (); +- +- if (error_message_size == 0) { +- g_debug ("smartcard driver '%s' could not be loaded", +- module_path); +- g_set_error (error, +- GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, +- _("smartcard driver '%s' could not be " +- "loaded"), module_path); +- goto out; +- } +- +- error_message = g_slice_alloc0 (error_message_size); +- PR_GetErrorText (error_message); +- +- g_set_error (error, +- GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, +- "%s", error_message); +- +- g_debug ("smartcard driver '%s' could not be loaded - %s", +- module_path, error_message); +- g_slice_free1 (error_message_size, error_message); +- } +- +- manager->priv->modules = modules; +-out: +- return manager->priv->modules != NULL; +-} +- +-static void +-gsd_smartcard_manager_get_all_cards (GsdSmartcardManager *manager) +-{ +- GList *node; +- int i; +- +- node = manager->priv->workers; +- while (node != NULL) { +- +- GsdSmartcardManagerWorker *worker; +- +- worker = (GsdSmartcardManagerWorker *) node->data; +- +- for (i = 0; i < worker->module->slotCount; i++) { +- GsdSmartcard *card; +- CK_SLOT_ID slot_id; +- int slot_series; +- char *card_name; +- +- slot_id = PK11_GetSlotID (worker->module->slots[i]); +- slot_series = PK11_GetSlotSeries (worker->module->slots[i]); +- +- card = _gsd_smartcard_new (worker->module, +- slot_id, slot_series); +- +- card_name = gsd_smartcard_get_name (card); +- +- g_hash_table_replace (manager->priv->smartcards, +- card_name, card); +- } +- node = node->next; +- } +-} +- +-static GsdSmartcardManagerWorker * +-start_worker (GsdSmartcardManager *manager, +- SECMODModule *module, +- GError **error) +-{ +- GIOChannel *io_channel; +- GSource *source; +- GsdSmartcardManagerWorker *worker; +- +- worker = gsd_smartcard_manager_create_worker (manager, module); +- +- if (worker == NULL) { +- g_set_error (error, +- GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, +- _("could not watch for incoming card events - %s"), +- g_strerror (errno)); +- +- goto out; +- } +- +- io_channel = g_io_channel_unix_new (worker->manager_fd); +- +- source = g_io_create_watch (io_channel, G_IO_IN | G_IO_HUP); +- g_io_channel_unref (io_channel); +- io_channel = NULL; +- +- worker->event_source = source; +- +- g_source_set_callback (worker->event_source, +- (GSourceFunc) (GIOFunc) +- gsd_smartcard_manager_check_for_and_process_events, +- worker, +- (GDestroyNotify) +- gsd_smartcard_manager_event_processing_stopped_handler); +- g_source_attach (worker->event_source, NULL); +- g_source_unref (worker->event_source); +-out: +- return worker; +-} +- +-static void +-start_workers (GsdSmartcardManager *manager) +-{ +- GList *node; +- +- node = manager->priv->modules; +- while (node != NULL) { +- SECMODModule *module; +- GsdSmartcardManagerWorker *worker; +- GError *error; +- +- module = (SECMODModule *) node->data; +- +- error = NULL; +- worker = start_worker (manager, module, &error); +- if (worker == NULL) { +- g_warning ("%s", error->message); +- g_error_free (error); +- } else { +- manager->priv->workers = g_list_prepend (manager->priv->workers, +- worker); +- } +- node = node->next; +- } +-} +- +-gboolean +-gsd_smartcard_manager_start (GsdSmartcardManager *manager, +- GError **error) +-{ +- GError *nss_error; +- +- if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STARTED) { +- g_debug ("smartcard manager already started"); +- return TRUE; +- } +- +- manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STARTING; +- +- nss_error = NULL; +- if (!manager->priv->nss_is_loaded && !load_nss (&nss_error)) { +- g_propagate_error (error, nss_error); +- goto out; +- } +- manager->priv->nss_is_loaded = TRUE; +- +- if (manager->priv->modules == NULL) { +- if (!load_driver (manager, manager->priv->module_path, &nss_error)) { +- g_propagate_error (error, nss_error); +- goto out; +- } +- } +- +- start_workers (manager); +- +- /* populate the hash with cards that are already inserted +- */ +- gsd_smartcard_manager_get_all_cards (manager); +- +- manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STARTED; +- +-out: +- /* don't leave it in a half started state +- */ +- if (manager->priv->state != GSD_SMARTCARD_MANAGER_STATE_STARTED) { +- g_debug ("smartcard manager could not be completely started"); +- gsd_smartcard_manager_stop (manager); +- } else { +- g_debug ("smartcard manager started"); +- } +- +- return manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STARTED; +-} +- +-static gboolean +-gsd_smartcard_manager_stop_now (GsdSmartcardManager *manager) +-{ +- if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STOPPED) { +- return FALSE; +- } +- +- gsd_smartcard_manager_stop_watching_for_events (manager); +- +- return FALSE; +-} +- +-static void +-gsd_smartcard_manager_queue_stop (GsdSmartcardManager *manager) +-{ +- +- manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STOPPING; +- +- g_idle_add ((GSourceFunc) gsd_smartcard_manager_stop_now, manager); +-} +- +-void +-gsd_smartcard_manager_stop (GsdSmartcardManager *manager) +-{ +- if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STOPPED) { +- return; +- } +- +- if (manager->priv->is_unstoppable) { +- gsd_smartcard_manager_queue_stop (manager); +- return; +- } +- +- gsd_smartcard_manager_stop_now (manager); +-} +- +-static void +-gsd_smartcard_manager_check_for_login_card (CK_SLOT_ID slot_id, +- GsdSmartcard *card, +- gboolean *is_inserted) +-{ +- g_assert (is_inserted != NULL); +- +- if (gsd_smartcard_is_login_card (card)) { +- *is_inserted = TRUE; +- } +- +-} +- +-gboolean +-gsd_smartcard_manager_login_card_is_inserted (GsdSmartcardManager *manager) +- +-{ +- gboolean is_inserted; +- +- is_inserted = FALSE; +- g_hash_table_foreach (manager->priv->smartcards, +- (GHFunc) +- gsd_smartcard_manager_check_for_login_card, +- &is_inserted); +- return is_inserted; +-} +- +-static GsdSmartcardManagerWorker * +-gsd_smartcard_manager_worker_new (GsdSmartcardManager *manager, +- int worker_fd, +- int manager_fd, +- SECMODModule *module) +-{ +- GsdSmartcardManagerWorker *worker; +- +- worker = g_slice_new0 (GsdSmartcardManagerWorker); +- worker->manager = manager; +- worker->fd = worker_fd; +- worker->manager_fd = manager_fd; +- worker->module = module; +- +- worker->smartcards = +- g_hash_table_new_full ((GHashFunc) slot_id_hash, +- (GEqualFunc) slot_id_equal, +- (GDestroyNotify) g_free, +- (GDestroyNotify) g_object_unref); +- +- return worker; +-} +- +-static void +-gsd_smartcard_manager_worker_free (GsdSmartcardManagerWorker *worker) +-{ +- if (worker->smartcards != NULL) { +- g_hash_table_destroy (worker->smartcards); +- worker->smartcards = NULL; +- } +- +- g_slice_free (GsdSmartcardManagerWorker, worker); +-} +- +-static gboolean +-read_bytes (int fd, +- gpointer bytes, +- gsize num_bytes) +-{ +- size_t bytes_left; +- size_t total_bytes_read; +- ssize_t bytes_read; +- +- bytes_left = (size_t) num_bytes; +- total_bytes_read = 0; +- +- do { +- bytes_read = read (fd, +- (char *) bytes + total_bytes_read, +- bytes_left); +- g_assert (bytes_read <= (ssize_t) bytes_left); +- +- if (bytes_read <= 0) { +- if ((bytes_read < 0) && (errno == EINTR || errno == EAGAIN)) { +- continue; +- } +- +- bytes_left = 0; +- } else { +- bytes_left -= bytes_read; +- total_bytes_read += bytes_read; +- } +- } while (bytes_left > 0); +- +- if (total_bytes_read < (size_t) num_bytes) { +- return FALSE; +- } +- +- return TRUE; +-} +- +-static gboolean +-write_bytes (int fd, +- gconstpointer bytes, +- gsize num_bytes) +-{ +- size_t bytes_left; +- size_t total_bytes_written; +- ssize_t bytes_written; +- +- bytes_left = (size_t) num_bytes; +- total_bytes_written = 0; +- +- do { +- bytes_written = write (fd, +- (char *) bytes + total_bytes_written, +- bytes_left); +- g_assert (bytes_written <= (ssize_t) bytes_left); +- +- if (bytes_written <= 0) { +- if ((bytes_written < 0) && (errno == EINTR || errno == EAGAIN)) { +- continue; +- } +- +- bytes_left = 0; +- } else { +- bytes_left -= bytes_written; +- total_bytes_written += bytes_written; +- } +- } while (bytes_left > 0); +- +- if (total_bytes_written < (size_t) num_bytes) { +- return FALSE; +- } +- +- return TRUE; +-} +- +-static GsdSmartcard * +-read_smartcard (int fd, +- SECMODModule *module) +-{ +- GsdSmartcard *card; +- char *card_name; +- gsize card_name_size; +- +- card_name_size = 0; +- if (!read_bytes (fd, &card_name_size, sizeof (card_name_size))) { +- return NULL; +- } +- +- card_name = g_slice_alloc0 (card_name_size); +- if (!read_bytes (fd, card_name, card_name_size)) { +- g_slice_free1 (card_name_size, card_name); +- return NULL; +- } +- card = _gsd_smartcard_new_from_name (module, card_name); +- g_slice_free1 (card_name_size, card_name); +- +- return card; +-} +- +-static gboolean +-write_smartcard (int fd, +- GsdSmartcard *card) +-{ +- gsize card_name_size; +- char *card_name; +- +- card_name = gsd_smartcard_get_name (card); +- card_name_size = strlen (card_name) + 1; +- +- if (!write_bytes (fd, &card_name_size, sizeof (card_name_size))) { +- g_free (card_name); +- return FALSE; +- } +- +- if (!write_bytes (fd, card_name, card_name_size)) { +- g_free (card_name); +- return FALSE; +- } +- g_free (card_name); +- +- return TRUE; +-} +- +-static gboolean +-gsd_smartcard_manager_worker_emit_smartcard_removed (GsdSmartcardManagerWorker *worker, +- GsdSmartcard *card, +- GError **error) +-{ +- g_debug ("card '%s' removed!", gsd_smartcard_get_name (card)); +- +- if (!write_bytes (worker->fd, "R", 1)) { +- goto error_out; +- } +- +- if (!write_smartcard (worker->fd, card)) { +- goto error_out; +- } +- +- return TRUE; +- +-error_out: +- g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, +- "%s", g_strerror (errno)); +- return FALSE; +-} +- +-static gboolean +-gsd_smartcard_manager_worker_emit_smartcard_inserted (GsdSmartcardManagerWorker *worker, +- GsdSmartcard *card, +- GError **error) +-{ +- g_debug ("card '%s' inserted!", gsd_smartcard_get_name (card)); +- if (!write_bytes (worker->fd, "I", 1)) { +- goto error_out; +- } +- +- if (!write_smartcard (worker->fd, card)) { +- goto error_out; +- } +- +- return TRUE; +- +-error_out: +- g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, +- "%s", g_strerror (errno)); +- return FALSE; +-} +- +-static gboolean +-gsd_smartcard_manager_worker_watch_for_and_process_event (GsdSmartcardManagerWorker *worker, +- GError **error) +-{ +- PK11SlotInfo *slot; +- CK_SLOT_ID slot_id, *key = NULL; +- int slot_series, card_slot_series; +- GsdSmartcard *card; +- GError *processing_error; +- gboolean ret; +- +- g_debug ("waiting for card event"); +- ret = FALSE; +- +- slot = SECMOD_WaitForAnyTokenEvent (worker->module, 0, PR_SecondsToInterval (1)); +- +- processing_error = NULL; +- +- if (slot == NULL) { +- int error_code; +- +- error_code = PORT_GetError (); +- if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT)) { +- g_debug ("spurrious event occurred"); +- return TRUE; +- } +- +- /* FIXME: is there a function to convert from a PORT error +- * code to a translated string? +- */ +- g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, +- GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, +- _("encountered unexpected error while " +- "waiting for smartcard events")); +- goto out; +- } +- +- /* the slot id and series together uniquely identify a card. +- * You can never have two cards with the same slot id at the +- * same time, however (I think), so we can key off of it. +- */ +- slot_id = PK11_GetSlotID (slot); +- slot_series = PK11_GetSlotSeries (slot); +- +- /* First check to see if there is a card that we're currently +- * tracking in the slot. +- */ +- key = g_new (CK_SLOT_ID, 1); +- *key = slot_id; +- card = g_hash_table_lookup (worker->smartcards, key); +- +- if (card != NULL) { +- card_slot_series = gsd_smartcard_get_slot_series (card); +- } else { +- card_slot_series = -1; +- } +- +- if (PK11_IsPresent (slot)) { +- /* Now, check to see if their is a new card in the slot. +- * If there was a different card in the slot now than +- * there was before, then we need to emit a removed signal +- * for the old card (we don't want unpaired insertion events). +- */ +- if ((card != NULL) && +- card_slot_series != slot_series) { +- if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { +- g_propagate_error (error, processing_error); +- goto out; +- } +- } +- +- card = _gsd_smartcard_new (worker->module, +- slot_id, slot_series); +- +- g_hash_table_replace (worker->smartcards, +- key, card); +- key = NULL; +- +- if (!gsd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) { +- g_propagate_error (error, processing_error); +- goto out; +- } +- } else { +- /* if we aren't tracking the card, just discard the event. +- * We don't want unpaired remove events. Note on startup +- * NSS will generate an "insertion" event if a card is +- * already inserted in the slot. +- */ +- if ((card != NULL)) { +- /* FIXME: i'm not sure about this code. Maybe we +- * shouldn't do this at all, or maybe we should do it +- * n times (where n = slot_series - card_slot_series + 1) +- * +- * Right now, i'm just doing it once. +- */ +- if ((slot_series - card_slot_series) > 1) { +- +- if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { +- g_propagate_error (error, processing_error); +- goto out; +- } +- g_hash_table_remove (worker->smartcards, key); +- +- card = _gsd_smartcard_new (worker->module, +- slot_id, slot_series); +- g_hash_table_replace (worker->smartcards, +- key, card); +- key = NULL; +- if (!gsd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) { +- g_propagate_error (error, processing_error); +- goto out; +- } +- } +- +- if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { +- g_propagate_error (error, processing_error); +- goto out; +- } +- +- g_hash_table_remove (worker->smartcards, key); +- card = NULL; +- } else { +- g_debug ("got spurious remove event"); +- } +- } +- +- ret = TRUE; +- +-out: +- g_free (key); +- PK11_FreeSlot (slot); +- +- return ret; +-} +- +-static void +-gsd_smartcard_manager_worker_run (GsdSmartcardManagerWorker *worker) +-{ +- GError *error; +- gboolean should_continue; +- +- do +- { +- error = NULL; +- should_continue = gsd_smartcard_manager_worker_watch_for_and_process_event (worker, &error); +- } +- while (should_continue); +- +- if (error != NULL) { +- g_debug ("could not process card event - %s", error->message); +- g_error_free (error); +- } +- +- gsd_smartcard_manager_worker_free (worker); +-} +- +-static GsdSmartcardManagerWorker * +-gsd_smartcard_manager_create_worker (GsdSmartcardManager *manager, +- SECMODModule *module) +-{ +- GsdSmartcardManagerWorker *worker; +- int write_fd, read_fd; +- +- write_fd = -1; +- read_fd = -1; +- if (!open_pipe (&write_fd, &read_fd)) { +- return NULL; +- } +- +- worker = gsd_smartcard_manager_worker_new (manager, +- write_fd, +- read_fd, +- module); +- +- worker->thread = g_thread_create ((GThreadFunc) +- gsd_smartcard_manager_worker_run, +- worker, FALSE, NULL); +- +- if (worker->thread == NULL) { +- gsd_smartcard_manager_worker_free (worker); +- return NULL; +- } +- +- return worker; +-} +- +-#ifdef GSD_SMARTCARD_MANAGER_ENABLE_TEST +-#include +- +-static GMainLoop *event_loop; +-static gboolean should_exit_on_next_remove = FALSE; +- +-static gboolean +-on_timeout (GsdSmartcardManager *manager) +-{ +- GError *error; +- g_print ("Re-enabling manager.\n"); +- +- if (!gsd_smartcard_manager_start (manager, &error)) { +- g_warning ("could not start smartcard manager - %s", +- error->message); +- g_error_free (error); +- return TRUE; +- } +- g_print ("Please re-insert smartcard\n"); +- +- should_exit_on_next_remove = TRUE; +- +- return FALSE; +-} +- +-static void +-on_device_inserted (GsdSmartcardManager *manager, +- GsdSmartcard *card) +-{ +- g_print ("smartcard inserted!\n"); +- g_print ("Please remove it.\n"); +-} +- +-static void +-on_device_removed (GsdSmartcardManager *manager, +- GsdSmartcard *card) +-{ +- g_print ("smartcard removed!\n"); +- +- if (should_exit_on_next_remove) { +- g_main_loop_quit (event_loop); +- } else { +- g_print ("disabling manager for 2 seconds\n"); +- gsd_smartcard_manager_stop (manager); +- g_timeout_add_seconds (2, (GSourceFunc) on_timeout, manager); +- } +-} +- +-int +-main (int argc, +- char *argv[]) +-{ +- GsdSmartcardManager *manager; +- GError *error; +- +- g_log_set_always_fatal (G_LOG_LEVEL_ERROR +- | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); +- +- g_message ("creating instance of 'smartcard manager' object..."); +- manager = gsd_smartcard_manager_new (NULL); +- g_message ("'smartcard manager' object created successfully"); +- +- g_signal_connect (manager, "smartcard-inserted", +- G_CALLBACK (on_device_inserted), NULL); +- +- g_signal_connect (manager, "smartcard-removed", +- G_CALLBACK (on_device_removed), NULL); +- +- g_message ("starting listener..."); +- +- error = NULL; +- if (!gsd_smartcard_manager_start (manager, &error)) { +- g_warning ("could not start smartcard manager - %s", +- error->message); +- g_error_free (error); +- return 1; +- } +- +- event_loop = g_main_loop_new (NULL, FALSE); +- g_main_loop_run (event_loop); +- g_main_loop_unref (event_loop); +- event_loop = NULL; +- +- g_message ("destroying previously created 'smartcard manager' object..."); +- g_object_unref (manager); +- manager = NULL; +- g_message ("'smartcard manager' object destroyed successfully"); +- +- return 0; +-} +-#endif +diff --git a/plugins/smartcard/gsd-smartcard-manager.h b/plugins/smartcard/gsd-smartcard-manager.h +deleted file mode 100644 +index 949f194..0000000 +--- a/plugins/smartcard/gsd-smartcard-manager.h ++++ /dev/null +@@ -1,88 +0,0 @@ +-/* gsd-smartcard-manager.h - object for monitoring smartcard insertion and +- * removal events +- * +- * Copyright (C) 2006, 2009 Red Hat, Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +- * 02111-1307, USA. +- * +- * Written by: Ray Strode +- */ +-#ifndef GSD_SMARTCARD_MANAGER_H +-#define GSD_SMARTCARD_MANAGER_H +- +-#define GSD_SMARTCARD_ENABLE_INTERNAL_API +-#include "gsd-smartcard.h" +- +-#include +-#include +- +-G_BEGIN_DECLS +-#define GSD_TYPE_SMARTCARD_MANAGER (gsd_smartcard_manager_get_type ()) +-#define GSD_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManager)) +-#define GSD_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerClass)) +-#define GSD_IS_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SMARTCARD_MANAGER)) +-#define GSD_IS_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SMARTCARD_MANAGER)) +-#define GSD_SMARTCARD_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerClass)) +-#define GSD_SMARTCARD_MANAGER_ERROR (gsd_smartcard_manager_error_quark ()) +-typedef struct _GsdSmartcardManager GsdSmartcardManager; +-typedef struct _GsdSmartcardManagerClass GsdSmartcardManagerClass; +-typedef struct _GsdSmartcardManagerPrivate GsdSmartcardManagerPrivate; +-typedef enum _GsdSmartcardManagerError GsdSmartcardManagerError; +- +-struct _GsdSmartcardManager { +- GObject parent; +- +- /*< private > */ +- GsdSmartcardManagerPrivate *priv; +-}; +- +-struct _GsdSmartcardManagerClass { +- GObjectClass parent_class; +- +- /* Signals */ +- void (*smartcard_inserted) (GsdSmartcardManager *manager, +- GsdSmartcard *token); +- void (*smartcard_removed) (GsdSmartcardManager *manager, +- GsdSmartcard *token); +- void (*error) (GsdSmartcardManager *manager, +- GError *error); +-}; +- +-enum _GsdSmartcardManagerError { +- GSD_SMARTCARD_MANAGER_ERROR_GENERIC = 0, +- GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, +- GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, +- GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, +- GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS +-}; +- +-GType gsd_smartcard_manager_get_type (void) G_GNUC_CONST; +-GQuark gsd_smartcard_manager_error_quark (void) G_GNUC_CONST; +- +-GsdSmartcardManager *gsd_smartcard_manager_new_default (void); +- +-GsdSmartcardManager *gsd_smartcard_manager_new (const char *module); +- +-gboolean gsd_smartcard_manager_start (GsdSmartcardManager *manager, +- GError **error); +- +-void gsd_smartcard_manager_stop (GsdSmartcardManager *manager); +- +-char *gsd_smartcard_manager_get_module_path (GsdSmartcardManager *manager); +-gboolean gsd_smartcard_manager_login_card_is_inserted (GsdSmartcardManager *manager); +- +-G_END_DECLS +-#endif /* GSD_SMARTCARD_MANAGER_H */ +diff --git a/plugins/smartcard/gsd-smartcard-plugin.c b/plugins/smartcard/gsd-smartcard-plugin.c +deleted file mode 100644 +index df1a8c8..0000000 +--- a/plugins/smartcard/gsd-smartcard-plugin.c ++++ /dev/null +@@ -1,337 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2010 Red Hat, Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- * +- */ +- +-#include "config.h" +- +-#include +-#include +- +-#include +-#include +-#include +- +-#include "gnome-settings-plugin.h" +-#include "gnome-settings-session.h" +-#include "gsd-smartcard-plugin.h" +-#include "gsd-smartcard-manager.h" +- +-struct GsdSmartcardPluginPrivate { +- GsdSmartcardManager *manager; +- GDBusConnection *bus_connection; +- +- guint32 is_active : 1; +-}; +- +-typedef enum +-{ +- GSD_SMARTCARD_REMOVE_ACTION_NONE, +- GSD_SMARTCARD_REMOVE_ACTION_LOCK_SCREEN, +- GSD_SMARTCARD_REMOVE_ACTION_FORCE_LOGOUT, +-} GsdSmartcardRemoveAction; +- +-#define SCREENSAVER_DBUS_NAME "org.gnome.ScreenSaver" +-#define SCREENSAVER_DBUS_PATH "/" +-#define SCREENSAVER_DBUS_INTERFACE "org.gnome.ScreenSaver" +- +-#define SM_LOGOUT_MODE_FORCE 2 +- +-#define KEY_REMOVE_ACTION "removal-action" +- +-#define GSD_SMARTCARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPluginPrivate)) +- +-GNOME_SETTINGS_PLUGIN_REGISTER (GsdSmartcardPlugin, gsd_smartcard_plugin); +- +-static void +-simulate_user_activity (GsdSmartcardPlugin *plugin) +-{ +- GDBusProxy *screensaver_proxy; +- +- g_debug ("GsdSmartcardPlugin telling screensaver about smart card insertion"); +- screensaver_proxy = g_dbus_proxy_new_sync (plugin->priv->bus_connection, +- 0, NULL, +- SCREENSAVER_DBUS_NAME, +- SCREENSAVER_DBUS_PATH, +- SCREENSAVER_DBUS_INTERFACE, +- NULL, NULL); +- +- g_dbus_proxy_call (screensaver_proxy, +- "SimulateUserActivity", +- NULL, G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, NULL, NULL); +- +- g_object_unref (screensaver_proxy); +-} +- +-static void +-lock_screen (GsdSmartcardPlugin *plugin) +-{ +- GDBusProxy *screensaver_proxy; +- +- g_debug ("GsdSmartcardPlugin telling screensaver to lock screen"); +- screensaver_proxy = g_dbus_proxy_new_sync (plugin->priv->bus_connection, +- 0, NULL, +- SCREENSAVER_DBUS_NAME, +- SCREENSAVER_DBUS_PATH, +- SCREENSAVER_DBUS_INTERFACE, +- NULL, NULL); +- +- g_dbus_proxy_call (screensaver_proxy, +- "Lock", +- NULL, G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, NULL, NULL); +- +- g_object_unref (screensaver_proxy); +-} +- +-static void +-force_logout (GsdSmartcardPlugin *plugin) +-{ +- GDBusProxy *sm_proxy; +- GError *error; +- GVariant *res; +- +- g_debug ("GsdSmartcardPlugin telling session manager to force logout"); +- sm_proxy = gnome_settings_session_get_session_proxy (); +- +- error = NULL; +- res = g_dbus_proxy_call_sync (sm_proxy, +- "Logout", +- g_variant_new ("(i)", SM_LOGOUT_MODE_FORCE), +- G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, &error); +- +- if (! res) { +- g_warning ("GsdSmartcardPlugin Unable to force logout: %s", error->message); +- g_error_free (error); +- } else +- g_variant_unref (res); +- +- g_object_unref (sm_proxy); +-} +- +-static void +-gsd_smartcard_plugin_init (GsdSmartcardPlugin *plugin) +-{ +- plugin->priv = GSD_SMARTCARD_PLUGIN_GET_PRIVATE (plugin); +- +- g_debug ("GsdSmartcardPlugin initializing"); +- +- plugin->priv->manager = gsd_smartcard_manager_new (NULL); +-} +- +-static void +-gsd_smartcard_plugin_finalize (GObject *object) +-{ +- GsdSmartcardPlugin *plugin; +- +- g_return_if_fail (object != NULL); +- g_return_if_fail (GSD_IS_SMARTCARD_PLUGIN (object)); +- +- g_debug ("GsdSmartcardPlugin finalizing"); +- +- plugin = GSD_SMARTCARD_PLUGIN (object); +- +- g_return_if_fail (plugin->priv != NULL); +- +- if (plugin->priv->manager != NULL) { +- g_object_unref (plugin->priv->manager); +- } +- +- G_OBJECT_CLASS (gsd_smartcard_plugin_parent_class)->finalize (object); +-} +- +-static void +-smartcard_inserted_cb (GsdSmartcardManager *card_monitor, +- GsdSmartcard *card, +- GsdSmartcardPlugin *plugin) +-{ +- char *name; +- +- name = gsd_smartcard_get_name (card); +- g_debug ("GsdSmartcardPlugin smart card '%s' inserted", name); +- g_free (name); +- +- simulate_user_activity (plugin); +-} +- +-static gboolean +-user_logged_in_with_smartcard (void) +-{ +- return g_getenv ("PKCS11_LOGIN_TOKEN_NAME") != NULL; +-} +- +-static GsdSmartcardRemoveAction +-get_configured_remove_action (GsdSmartcardPlugin *plugin) +-{ +- GSettings *settings; +- char *remove_action_string; +- GsdSmartcardRemoveAction remove_action; +- +- settings = g_settings_new ("org.gnome.settings-daemon.peripherals.smartcard"); +- remove_action_string = g_settings_get_string (settings, KEY_REMOVE_ACTION); +- +- if (remove_action_string == NULL) { +- g_warning ("GsdSmartcardPlugin unable to get smartcard remove action"); +- remove_action = GSD_SMARTCARD_REMOVE_ACTION_NONE; +- } else if (strcmp (remove_action_string, "none") == 0) { +- remove_action = GSD_SMARTCARD_REMOVE_ACTION_NONE; +- } else if (strcmp (remove_action_string, "lock_screen") == 0) { +- remove_action = GSD_SMARTCARD_REMOVE_ACTION_LOCK_SCREEN; +- } else if (strcmp (remove_action_string, "force_logout") == 0) { +- remove_action = GSD_SMARTCARD_REMOVE_ACTION_FORCE_LOGOUT; +- } else { +- g_warning ("GsdSmartcardPlugin unknown smartcard remove action"); +- remove_action = GSD_SMARTCARD_REMOVE_ACTION_NONE; +- } +- +- g_object_unref (settings); +- +- return remove_action; +-} +- +-static void +-process_smartcard_removal (GsdSmartcardPlugin *plugin) +-{ +- GsdSmartcardRemoveAction remove_action; +- +- g_debug ("GsdSmartcardPlugin processing smartcard removal"); +- remove_action = get_configured_remove_action (plugin); +- +- switch (remove_action) +- { +- case GSD_SMARTCARD_REMOVE_ACTION_NONE: +- return; +- case GSD_SMARTCARD_REMOVE_ACTION_LOCK_SCREEN: +- lock_screen (plugin); +- break; +- case GSD_SMARTCARD_REMOVE_ACTION_FORCE_LOGOUT: +- force_logout (plugin); +- break; +- } +-} +- +-static void +-smartcard_removed_cb (GsdSmartcardManager *card_monitor, +- GsdSmartcard *card, +- GsdSmartcardPlugin *plugin) +-{ +- +- char *name; +- +- name = gsd_smartcard_get_name (card); +- g_debug ("GsdSmartcardPlugin smart card '%s' removed", name); +- g_free (name); +- +- if (!gsd_smartcard_is_login_card (card)) { +- g_debug ("GsdSmartcardPlugin removed smart card was not used to login"); +- return; +- } +- +- process_smartcard_removal (plugin); +-} +- +-static void +-impl_activate (GnomeSettingsPlugin *plugin) +-{ +- GError *error; +- GsdSmartcardPlugin *smartcard_plugin = GSD_SMARTCARD_PLUGIN (plugin); +- +- if (smartcard_plugin->priv->is_active) { +- g_debug ("GsdSmartcardPlugin Not activating smartcard plugin, because it's " +- "already active"); +- return; +- } +- +- if (!user_logged_in_with_smartcard ()) { +- g_debug ("GsdSmartcardPlugin Not activating smartcard plugin, because user didn't use " +- " smartcard to log in"); +- smartcard_plugin->priv->is_active = FALSE; +- return; +- } +- +- g_debug ("GsdSmartcardPlugin Activating smartcard plugin"); +- +- error = NULL; +- smartcard_plugin->priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); +- +- if (smartcard_plugin->priv->bus_connection == NULL) { +- g_warning ("GsdSmartcardPlugin Unable to connect to session bus: %s", error->message); +- return; +- } +- +- if (!gsd_smartcard_manager_start (smartcard_plugin->priv->manager, &error)) { +- g_warning ("GsdSmartcardPlugin Unable to start smartcard manager: %s", error->message); +- g_error_free (error); +- } +- +- g_signal_connect (smartcard_plugin->priv->manager, +- "smartcard-removed", +- G_CALLBACK (smartcard_removed_cb), smartcard_plugin); +- +- g_signal_connect (smartcard_plugin->priv->manager, +- "smartcard-inserted", +- G_CALLBACK (smartcard_inserted_cb), smartcard_plugin); +- +- if (!gsd_smartcard_manager_login_card_is_inserted (smartcard_plugin->priv->manager)) { +- g_debug ("GsdSmartcardPlugin processing smartcard removal immediately user logged in with smartcard " +- "and it's not inserted"); +- process_smartcard_removal (smartcard_plugin); +- } +- +- smartcard_plugin->priv->is_active = TRUE; +-} +- +-static void +-impl_deactivate (GnomeSettingsPlugin *plugin) +-{ +- GsdSmartcardPlugin *smartcard_plugin = GSD_SMARTCARD_PLUGIN (plugin); +- +- if (!smartcard_plugin->priv->is_active) { +- g_debug ("GsdSmartcardPlugin Not deactivating smartcard plugin, " +- "because it's already inactive"); +- return; +- } +- +- g_debug ("GsdSmartcardPlugin Deactivating smartcard plugin"); +- +- gsd_smartcard_manager_stop (smartcard_plugin->priv->manager); +- +- g_signal_handlers_disconnect_by_func (smartcard_plugin->priv->manager, +- smartcard_removed_cb, smartcard_plugin); +- +- g_signal_handlers_disconnect_by_func (smartcard_plugin->priv->manager, +- smartcard_inserted_cb, smartcard_plugin); +- smartcard_plugin->priv->bus_connection = NULL; +- smartcard_plugin->priv->is_active = FALSE; +-} +- +-static void +-gsd_smartcard_plugin_class_init (GsdSmartcardPluginClass *klass) +-{ +- GObjectClass *object_class = G_OBJECT_CLASS (klass); +- GnomeSettingsPluginClass *plugin_class = GNOME_SETTINGS_PLUGIN_CLASS (klass); +- +- object_class->finalize = gsd_smartcard_plugin_finalize; +- +- plugin_class->activate = impl_activate; +- plugin_class->deactivate = impl_deactivate; +- +- g_type_class_add_private (klass, sizeof (GsdSmartcardPluginPrivate)); +-} +diff --git a/plugins/smartcard/gsd-smartcard-plugin.h b/plugins/smartcard/gsd-smartcard-plugin.h +deleted file mode 100644 +index f1458d1..0000000 +--- a/plugins/smartcard/gsd-smartcard-plugin.h ++++ /dev/null +@@ -1,59 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2010 Red Hat, Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- * +- */ +- +-#ifndef __GSD_SMARTCARD_PLUGIN_H__ +-#define __GSD_SMARTCARD_PLUGIN_H__ +- +-#include +-#include +-#include +- +-#include "gnome-settings-plugin.h" +- +-G_BEGIN_DECLS +- +-#define GSD_TYPE_SMARTCARD_PLUGIN (gsd_smartcard_plugin_get_type ()) +-#define GSD_SMARTCARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPlugin)) +-#define GSD_SMARTCARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPluginClass)) +-#define GSD_IS_SMARTCARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SMARTCARD_PLUGIN)) +-#define GSD_IS_SMARTCARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SMARTCARD_PLUGIN)) +-#define GSD_SMARTCARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPluginClass)) +- +-typedef struct GsdSmartcardPluginPrivate GsdSmartcardPluginPrivate; +- +-typedef struct +-{ +- GnomeSettingsPlugin parent; +- GsdSmartcardPluginPrivate *priv; +-} GsdSmartcardPlugin; +- +-typedef struct +-{ +- GnomeSettingsPluginClass parent_class; +-} GsdSmartcardPluginClass; +- +-GType gsd_smartcard_plugin_get_type (void) G_GNUC_CONST; +- +-/* All the plugins must implement this function */ +-G_MODULE_EXPORT GType register_gnome_settings_plugin (GTypeModule *module); +- +-G_END_DECLS +- +-#endif /* __GSD_SMARTCARD_PLUGIN_H__ */ +diff --git a/plugins/smartcard/gsd-smartcard.c b/plugins/smartcard/gsd-smartcard.c +deleted file mode 100644 +index a926df1..0000000 +--- a/plugins/smartcard/gsd-smartcard.c ++++ /dev/null +@@ -1,556 +0,0 @@ +-/* gsd-smartcard.c - smartcard object +- * +- * Copyright (C) 2006 Ray Strode +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +- * 02111-1307, USA. +- */ +- +-#include "config.h" +- +-#define GSD_SMARTCARD_ENABLE_INTERNAL_API +-#include "gsd-smartcard.h" +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-struct _GsdSmartcardPrivate { +- SECMODModule *module; +- GsdSmartcardState state; +- +- CK_SLOT_ID slot_id; +- int slot_series; +- +- PK11SlotInfo *slot; +- char *name; +- +- CERTCertificate *signing_certificate; +- CERTCertificate *encryption_certificate; +-}; +- +-static void gsd_smartcard_finalize (GObject *object); +-static void gsd_smartcard_class_install_signals (GsdSmartcardClass *card_class); +-static void gsd_smartcard_class_install_properties (GsdSmartcardClass *card_class); +-static void gsd_smartcard_set_property (GObject *object, +- guint prop_id, +- const GValue *value, +- GParamSpec *pspec); +-static void gsd_smartcard_get_property (GObject *object, +- guint prop_id, +- GValue *value, +- GParamSpec *pspec); +-static void gsd_smartcard_set_name (GsdSmartcard *card, const char *name); +-static void gsd_smartcard_set_slot_id (GsdSmartcard *card, +- int slot_id); +-static void gsd_smartcard_set_slot_series (GsdSmartcard *card, +- int slot_series); +-static void gsd_smartcard_set_module (GsdSmartcard *card, +- SECMODModule *module); +- +-static PK11SlotInfo *gsd_smartcard_find_slot_from_id (GsdSmartcard *card, +- int slot_id); +- +-static PK11SlotInfo *gsd_smartcard_find_slot_from_card_name (GsdSmartcard *card, +- const char *card_name); +- +-#ifndef GSD_SMARTCARD_DEFAULT_SLOT_ID +-#define GSD_SMARTCARD_DEFAULT_SLOT_ID ((gulong) -1) +-#endif +- +-#ifndef GSD_SMARTCARD_DEFAULT_SLOT_SERIES +-#define GSD_SMARTCARD_DEFAULT_SLOT_SERIES -1 +-#endif +- +-enum { +- PROP_0 = 0, +- PROP_NAME, +- PROP_SLOT_ID, +- PROP_SLOT_SERIES, +- PROP_MODULE, +- NUMBER_OF_PROPERTIES +-}; +- +-enum { +- INSERTED, +- REMOVED, +- NUMBER_OF_SIGNALS +-}; +- +-static guint gsd_smartcard_signals[NUMBER_OF_SIGNALS]; +- +-G_DEFINE_TYPE (GsdSmartcard, gsd_smartcard, G_TYPE_OBJECT); +- +-static void +-gsd_smartcard_class_init (GsdSmartcardClass *card_class) +-{ +- GObjectClass *gobject_class; +- +- gobject_class = G_OBJECT_CLASS (card_class); +- +- gobject_class->finalize = gsd_smartcard_finalize; +- +- gsd_smartcard_class_install_signals (card_class); +- gsd_smartcard_class_install_properties (card_class); +- +- g_type_class_add_private (card_class, +- sizeof (GsdSmartcardPrivate)); +-} +- +-static void +-gsd_smartcard_class_install_signals (GsdSmartcardClass *card_class) +-{ +- GObjectClass *object_class; +- +- object_class = G_OBJECT_CLASS (card_class); +- +- gsd_smartcard_signals[INSERTED] = +- g_signal_new ("inserted", +- G_OBJECT_CLASS_TYPE (object_class), +- G_SIGNAL_RUN_LAST, +- G_STRUCT_OFFSET (GsdSmartcardClass, +- inserted), +- NULL, NULL, g_cclosure_marshal_VOID__VOID, +- G_TYPE_NONE, 0); +- +- gsd_smartcard_signals[REMOVED] = +- g_signal_new ("removed", +- G_OBJECT_CLASS_TYPE (object_class), +- G_SIGNAL_RUN_LAST, +- G_STRUCT_OFFSET (GsdSmartcardClass, +- removed), +- NULL, NULL, g_cclosure_marshal_VOID__VOID, +- G_TYPE_NONE, 0); +-} +- +-static void +-gsd_smartcard_class_install_properties (GsdSmartcardClass *card_class) +-{ +- GObjectClass *object_class; +- GParamSpec *param_spec; +- +- object_class = G_OBJECT_CLASS (card_class); +- object_class->set_property = gsd_smartcard_set_property; +- object_class->get_property = gsd_smartcard_get_property; +- +- param_spec = g_param_spec_ulong ("slot-id", "Slot ID", +- "The slot the card is in", +- 1, G_MAXULONG, +- GSD_SMARTCARD_DEFAULT_SLOT_ID, +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); +- g_object_class_install_property (object_class, PROP_SLOT_ID, param_spec); +- +- param_spec = g_param_spec_int ("slot-series", "Slot Series", +- "per-slot card identifier", +- -1, G_MAXINT, +- GSD_SMARTCARD_DEFAULT_SLOT_SERIES, +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); +- g_object_class_install_property (object_class, PROP_SLOT_SERIES, param_spec); +- +- param_spec = g_param_spec_string ("name", "name", +- "name", NULL, +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); +- g_object_class_install_property (object_class, PROP_NAME, param_spec); +- +- param_spec = g_param_spec_pointer ("module", "Module", +- "smartcard driver", +- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); +- g_object_class_install_property (object_class, PROP_MODULE, param_spec); +-} +- +-static void +-gsd_smartcard_set_property (GObject *object, +- guint prop_id, +- const GValue *value, +- GParamSpec *pspec) +-{ +- GsdSmartcard *card = GSD_SMARTCARD (object); +- +- switch (prop_id) { +- case PROP_NAME: +- gsd_smartcard_set_name (card, g_value_get_string (value)); +- break; +- +- case PROP_SLOT_ID: +- gsd_smartcard_set_slot_id (card, +- g_value_get_ulong (value)); +- break; +- +- case PROP_SLOT_SERIES: +- gsd_smartcard_set_slot_series (card, +- g_value_get_int (value)); +- break; +- +- case PROP_MODULE: +- gsd_smartcard_set_module (card, +- (SECMODModule *) +- g_value_get_pointer (value)); +- break; +- +- default: +- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +- } +-} +- +-CK_SLOT_ID +-gsd_smartcard_get_slot_id (GsdSmartcard *card) +-{ +- return card->priv->slot_id; +-} +- +-GsdSmartcardState +-gsd_smartcard_get_state (GsdSmartcard *card) +-{ +- return card->priv->state; +-} +- +-char * +-gsd_smartcard_get_name (GsdSmartcard *card) +-{ +- return g_strdup (card->priv->name); +-} +- +-gboolean +-gsd_smartcard_is_login_card (GsdSmartcard *card) +-{ +- const char *login_card_name; +- login_card_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME"); +- +- if ((login_card_name == NULL) || (card->priv->name == NULL)) { +- return FALSE; +- } +- +- if (strcmp (card->priv->name, login_card_name) == 0) { +- return TRUE; +- } +- +- return FALSE; +-} +- +-static void +-gsd_smartcard_get_property (GObject *object, +- guint prop_id, +- GValue *value, +- GParamSpec *pspec) +-{ +- GsdSmartcard *card = GSD_SMARTCARD (object); +- +- switch (prop_id) { +- case PROP_NAME: +- g_value_take_string (value, +- gsd_smartcard_get_name (card)); +- break; +- +- case PROP_SLOT_ID: +- g_value_set_ulong (value, +- (gulong) gsd_smartcard_get_slot_id (card)); +- break; +- +- case PROP_SLOT_SERIES: +- g_value_set_int (value, +- gsd_smartcard_get_slot_series (card)); +- break; +- +- default: +- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +- } +-} +- +-static void +-gsd_smartcard_set_name (GsdSmartcard *card, +- const char *name) +-{ +- if (name == NULL) { +- return; +- } +- +- if ((card->priv->name == NULL) || +- (strcmp (card->priv->name, name) != 0)) { +- g_free (card->priv->name); +- card->priv->name = g_strdup (name); +- +- if (card->priv->slot == NULL) { +- card->priv->slot = gsd_smartcard_find_slot_from_card_name (card, +- card->priv->name); +- +- if (card->priv->slot != NULL) { +- int slot_id, slot_series; +- +- slot_id = PK11_GetSlotID (card->priv->slot); +- if (slot_id != card->priv->slot_id) { +- gsd_smartcard_set_slot_id (card, slot_id); +- } +- +- slot_series = PK11_GetSlotSeries (card->priv->slot); +- if (slot_series != card->priv->slot_series) { +- gsd_smartcard_set_slot_series (card, slot_series); +- } +- +- _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED); +- } else { +- _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED); +- } +- } +- +- g_object_notify (G_OBJECT (card), "name"); +- } +-} +- +-static void +-gsd_smartcard_set_slot_id (GsdSmartcard *card, +- int slot_id) +-{ +- if (card->priv->slot_id != slot_id) { +- card->priv->slot_id = slot_id; +- +- if (card->priv->slot == NULL) { +- card->priv->slot = gsd_smartcard_find_slot_from_id (card, +- card->priv->slot_id); +- +- if (card->priv->slot != NULL) { +- const char *card_name; +- +- card_name = PK11_GetTokenName (card->priv->slot); +- if ((card->priv->name == NULL) || +- ((card_name != NULL) && +- (strcmp (card_name, card->priv->name) != 0))) { +- gsd_smartcard_set_name (card, card_name); +- } +- +- _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED); +- } else { +- _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED); +- } +- } +- +- g_object_notify (G_OBJECT (card), "slot-id"); +- } +-} +- +-static void +-gsd_smartcard_set_slot_series (GsdSmartcard *card, +- int slot_series) +-{ +- if (card->priv->slot_series != slot_series) { +- card->priv->slot_series = slot_series; +- g_object_notify (G_OBJECT (card), "slot-series"); +- } +-} +- +-static void +-gsd_smartcard_set_module (GsdSmartcard *card, +- SECMODModule *module) +-{ +- gboolean should_notify; +- +- if (card->priv->module != module) { +- should_notify = TRUE; +- } else { +- should_notify = FALSE; +- } +- +- if (card->priv->module != NULL) { +- SECMOD_DestroyModule (card->priv->module); +- card->priv->module = NULL; +- } +- +- if (module != NULL) { +- card->priv->module = SECMOD_ReferenceModule (module); +- } +- +- if (should_notify) { +- g_object_notify (G_OBJECT (card), "module"); +- } +-} +- +-int +-gsd_smartcard_get_slot_series (GsdSmartcard *card) +-{ +- return card->priv->slot_series; +-} +- +-static void +-gsd_smartcard_init (GsdSmartcard *card) +-{ +- +- g_debug ("initializing smartcard "); +- +- card->priv = G_TYPE_INSTANCE_GET_PRIVATE (card, +- GSD_TYPE_SMARTCARD, +- GsdSmartcardPrivate); +-} +- +-static void gsd_smartcard_finalize (GObject *object) +-{ +- GsdSmartcard *card; +- GObjectClass *gobject_class; +- +- card = GSD_SMARTCARD (object); +- +- g_free (card->priv->name); +- +- gsd_smartcard_set_module (card, NULL); +- +- gobject_class = G_OBJECT_CLASS (gsd_smartcard_parent_class); +- +- gobject_class->finalize (object); +-} +- +-GQuark gsd_smartcard_error_quark (void) +-{ +- static GQuark error_quark = 0; +- +- if (error_quark == 0) { +- error_quark = g_quark_from_static_string ("gsd-smartcard-error-quark"); +- } +- +- return error_quark; +-} +- +-GsdSmartcard * +-_gsd_smartcard_new (SECMODModule *module, +- CK_SLOT_ID slot_id, +- int slot_series) +-{ +- GsdSmartcard *card; +- +- g_return_val_if_fail (module != NULL, NULL); +- g_return_val_if_fail (slot_id >= 1, NULL); +- g_return_val_if_fail (slot_series > 0, NULL); +- g_return_val_if_fail (sizeof (gulong) == sizeof (slot_id), NULL); +- +- card = GSD_SMARTCARD (g_object_new (GSD_TYPE_SMARTCARD, +- "module", module, +- "slot-id", (gulong) slot_id, +- "slot-series", slot_series, +- NULL)); +- return card; +-} +- +-GsdSmartcard * +-_gsd_smartcard_new_from_name (SECMODModule *module, +- const char *name) +-{ +- GsdSmartcard *card; +- +- g_return_val_if_fail (module != NULL, NULL); +- g_return_val_if_fail (name != NULL, NULL); +- +- card = GSD_SMARTCARD (g_object_new (GSD_TYPE_SMARTCARD, +- "module", module, +- "name", name, +- NULL)); +- return card; +-} +- +-void +-_gsd_smartcard_set_state (GsdSmartcard *card, +- GsdSmartcardState state) +-{ +- /* gsd_smartcard_fetch_certificates (card); */ +- if (card->priv->state != state) { +- card->priv->state = state; +- +- if (state == GSD_SMARTCARD_STATE_INSERTED) { +- g_signal_emit (card, gsd_smartcard_signals[INSERTED], 0); +- } else if (state == GSD_SMARTCARD_STATE_REMOVED) { +- g_signal_emit (card, gsd_smartcard_signals[REMOVED], 0); +- } else { +- g_assert_not_reached (); +- } +- } +-} +- +-/* So we could conceivably make the closure data a pointer to the card +- * or something similiar and then emit signals when we want passwords, +- * but it's probably easier to just get the password up front and use +- * it. So we just take the passed in g_malloc'd (well probably, who knows) +- * and strdup it using NSPR's memory allocation routines. +- */ +-static char * +-gsd_smartcard_password_handler (PK11SlotInfo *slot, +- PRBool is_retrying, +- const char *password) +-{ +- if (is_retrying) { +- return NULL; +- } +- +- return password != NULL? PL_strdup (password): NULL; +-} +- +-gboolean +-gsd_smartcard_unlock (GsdSmartcard *card, +- const char *password) +-{ +- SECStatus status; +- +- PK11_SetPasswordFunc ((PK11PasswordFunc) gsd_smartcard_password_handler); +- +- /* we pass PR_TRUE to load certificates +- */ +- status = PK11_Authenticate (card->priv->slot, PR_TRUE, (gpointer) password); +- +- if (status != SECSuccess) { +- g_debug ("could not unlock card - %d", status); +- return FALSE; +- } +- return TRUE; +-} +- +-static PK11SlotInfo * +-gsd_smartcard_find_slot_from_card_name (GsdSmartcard *card, +- const char *card_name) +-{ +- int i; +- +- for (i = 0; i < card->priv->module->slotCount; i++) { +- const char *slot_card_name; +- +- slot_card_name = PK11_GetTokenName (card->priv->module->slots[i]); +- +- if ((slot_card_name != NULL) && +- (strcmp (slot_card_name, card_name) == 0)) { +- return card->priv->module->slots[i]; +- } +- } +- +- return NULL; +-} +- +-static PK11SlotInfo * +-gsd_smartcard_find_slot_from_id (GsdSmartcard *card, +- int slot_id) +-{ +- int i; +- +- for (i = 0; i < card->priv->module->slotCount; i++) { +- if (PK11_GetSlotID (card->priv->module->slots[i]) == slot_id) { +- return card->priv->module->slots[i]; +- } +- } +- +- return NULL; +-} +diff --git a/plugins/smartcard/gsd-smartcard.h b/plugins/smartcard/gsd-smartcard.h +deleted file mode 100644 +index c99b5fa..0000000 +--- a/plugins/smartcard/gsd-smartcard.h ++++ /dev/null +@@ -1,94 +0,0 @@ +-/* securitycard.h - api for reading and writing data to a security card +- * +- * Copyright (C) 2006 Ray Strode +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +- * 02111-1307, USA. +- */ +-#ifndef GSD_SMARTCARD_H +-#define GSD_SMARTCARD_H +- +-#include +-#include +- +-#include +- +-G_BEGIN_DECLS +-#define GSD_TYPE_SMARTCARD (gsd_smartcard_get_type ()) +-#define GSD_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_SMARTCARD, GsdSmartcard)) +-#define GSD_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_SMARTCARD, GsdSmartcardClass)) +-#define GSD_IS_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_SMARTCARD)) +-#define GSD_IS_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_SMARTCARD)) +-#define GSD_SMARTCARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_SMARTCARD, GsdSmartcardClass)) +-#define GSD_SMARTCARD_ERROR (gsd_smartcard_error_quark ()) +-typedef struct _GsdSmartcardClass GsdSmartcardClass; +-typedef struct _GsdSmartcard GsdSmartcard; +-typedef struct _GsdSmartcardPrivate GsdSmartcardPrivate; +-typedef enum _GsdSmartcardError GsdSmartcardError; +-typedef enum _GsdSmartcardState GsdSmartcardState; +- +-typedef struct _GsdSmartcardRequest GsdSmartcardRequest; +- +-struct _GsdSmartcard { +- GObject parent; +- +- /*< private > */ +- GsdSmartcardPrivate *priv; +-}; +- +-struct _GsdSmartcardClass { +- GObjectClass parent_class; +- +- void (* inserted) (GsdSmartcard *card); +- void (* removed) (GsdSmartcard *card); +-}; +- +-enum _GsdSmartcardError { +- GSD_SMARTCARD_ERROR_GENERIC = 0, +-}; +- +-enum _GsdSmartcardState { +- GSD_SMARTCARD_STATE_INSERTED = 0, +- GSD_SMARTCARD_STATE_REMOVED, +-}; +- +-GType gsd_smartcard_get_type (void) G_GNUC_CONST; +-GQuark gsd_smartcard_error_quark (void) G_GNUC_CONST; +- +-CK_SLOT_ID gsd_smartcard_get_slot_id (GsdSmartcard *card); +-gint gsd_smartcard_get_slot_series (GsdSmartcard *card); +-GsdSmartcardState gsd_smartcard_get_state (GsdSmartcard *card); +- +-char *gsd_smartcard_get_name (GsdSmartcard *card); +-gboolean gsd_smartcard_is_login_card (GsdSmartcard *card); +- +-gboolean gsd_smartcard_unlock (GsdSmartcard *card, +- const char *password); +- +-/* don't under any circumstances call these functions */ +-#ifdef GSD_SMARTCARD_ENABLE_INTERNAL_API +- +-GsdSmartcard *_gsd_smartcard_new (SECMODModule *module, +- CK_SLOT_ID slot_id, +- gint slot_series); +-GsdSmartcard *_gsd_smartcard_new_from_name (SECMODModule *module, +- const char *name); +- +-void _gsd_smartcard_set_state (GsdSmartcard *card, +- GsdSmartcardState state); +-#endif +- +-G_END_DECLS +-#endif /* GSD_SMARTCARD_H */ +diff --git a/plugins/smartcard/test-smartcard.c b/plugins/smartcard/test-smartcard.c +deleted file mode 100644 +index b57d908..0000000 +--- a/plugins/smartcard/test-smartcard.c ++++ /dev/null +@@ -1,7 +0,0 @@ +-#define NEW gsd_smartcard_manager_new_default +-#define START gsd_smartcard_manager_start +-#define STOP gsd_smartcard_manager_stop +-#define MANAGER GsdSmartcardManager +-#include "gsd-smartcard-manager.h" +- +-#include "test-plugin.h" +-- +1.8.3.1 + + +From f2afbc595d58cd54a586a1145879051161adb10c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 28 May 2013 09:22:39 -0400 +Subject: [PATCH 2/9] smartcard: add back smartcard support + +This commit lands a rewrite of the smartcard plugin. It makes use +of the DBus ObjectManager interface to export tokens over the bus, +as they're inserted and removed. + +https://bugzilla.gnome.org/show_bug.cgi?id=704890 +--- + plugins/smartcard/Makefile.am | 105 +++ + plugins/smartcard/gsd-smartcard-enum-types.c.in | 42 + + plugins/smartcard/gsd-smartcard-enum-types.h.in | 24 + + plugins/smartcard/gsd-smartcard-manager.c | 870 +++++++++++++++++++++ + plugins/smartcard/gsd-smartcard-manager.h | 82 ++ + plugins/smartcard/gsd-smartcard-plugin.c | 30 + + plugins/smartcard/gsd-smartcard-service.c | 773 ++++++++++++++++++ + plugins/smartcard/gsd-smartcard-service.h | 81 ++ + plugins/smartcard/gsd-smartcard-utils.c | 191 +++++ + plugins/smartcard/gsd-smartcard-utils.h | 38 + + .../org.gnome.SettingsDaemon.Smartcard.xml | 91 +++ + plugins/smartcard/test-smartcard.c | 7 + + 13 files changed, 2340 insertions(+) + create mode 100644 plugins/smartcard/Makefile.am + create mode 100644 plugins/smartcard/gsd-smartcard-enum-types.c.in + create mode 100644 plugins/smartcard/gsd-smartcard-enum-types.h.in + create mode 100644 plugins/smartcard/gsd-smartcard-manager.c + create mode 100644 plugins/smartcard/gsd-smartcard-manager.h + create mode 100644 plugins/smartcard/gsd-smartcard-plugin.c + create mode 100644 plugins/smartcard/gsd-smartcard-service.c + create mode 100644 plugins/smartcard/gsd-smartcard-service.h + create mode 100644 plugins/smartcard/gsd-smartcard-utils.c + create mode 100644 plugins/smartcard/gsd-smartcard-utils.h + create mode 100644 plugins/smartcard/org.gnome.SettingsDaemon.Smartcard.xml + create mode 100644 plugins/smartcard/test-smartcard.c + +diff --git a/plugins/smartcard/Makefile.am b/plugins/smartcard/Makefile.am +new file mode 100644 +index 0000000..2d27d1c +--- /dev/null ++++ b/plugins/smartcard/Makefile.am +@@ -0,0 +1,105 @@ ++plugin_name = smartcard ++libsmartcard_headers = gsd-smartcard-manager.h \ ++ gsd-smartcard-utils.h ++dbus_built_sources = org.gnome.SettingsDaemon.Smartcard.c org.gnome.SettingsDaemon.Smartcard.h ++enum_built_sources = gsd-smartcard-enum-types.h gsd-smartcard-enum-types.c ++BUILT_SOURCES = $(dbus_built_sources) $(enum_built_sources) ++ ++libexec_PROGRAMS = gsd-test-smartcard ++ ++plugin_LTLIBRARIES = \ ++ libsmartcard.la ++ ++$(dbus_built_sources) : Makefile.am org.gnome.SettingsDaemon.Smartcard.xml ++ $(AM_V_GEN) gdbus-codegen \ ++ --interface-prefix org.gnome.SettingsDaemon.Smartcard. \ ++ --c-namespace GsdSmartcardService \ ++ --c-generate-object-manager \ ++ --generate-c-code org.gnome.SettingsDaemon.Smartcard \ ++ org.gnome.SettingsDaemon.Smartcard.xml ++ ++gsd-smartcard-enum-types.h: gsd-smartcard-enum-types.h.in $(libsmartcard_headers) ++ $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ ++ ++gsd-smartcard-enum-types.c: gsd-smartcard-enum-types.c.in $(libsmartcard_headers) ++ $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ ++ ++gsd_test_smartcard_SOURCES = \ ++ $(dbus_built_sources) \ ++ $(enum_built_sources) \ ++ gsd-smartcard-service.c \ ++ gsd-smartcard-manager.c \ ++ gsd-smartcard-utils.c \ ++ test-smartcard.c ++ ++gsd_test_smartcard_CPPFLAGS = \ ++ -I$(top_srcdir)/data/ \ ++ -I$(top_srcdir)/gnome-settings-daemon \ ++ -I$(top_srcdir)/plugins/common \ ++ -DSYSCONFDIR=\""$(sysconfdir)"\" \ ++ -DLIBDIR=\""$(libdir)"\" \ ++ -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ ++ -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ ++ $(AM_CPPFLAGS) ++ ++gsd_test_smartcard_CFLAGS = \ ++ $(PLUGIN_CFLAGS) \ ++ $(SETTINGS_PLUGIN_CFLAGS) \ ++ $(MEDIA_KEYS_CFLAGS) \ ++ $(NSS_CFLAGS) \ ++ $(AM_CFLAGS) ++ ++gsd_test_smartcard_LDADD = \ ++ $(top_builddir)/gnome-settings-daemon/libgsd.la \ ++ $(top_builddir)/plugins/common/libcommon.la \ ++ $(NSS_LIBS) \ ++ $(SETTINGS_DAEMON_LIBS) \ ++ $(SETTINGS_PLUGIN_LIBS) ++ ++ ++libsmartcard_la_SOURCES = \ ++ $(libsmartcard_headers) \ ++ $(dbus_built_sources) \ ++ $(enum_built_sources) \ ++ gsd-smartcard-manager.c \ ++ gsd-smartcard-plugin.c \ ++ gsd-smartcard-service.c \ ++ gsd-smartcard-utils.c ++ ++libsmartcard_la_CPPFLAGS = \ ++ -I$(top_srcdir)/gnome-settings-daemon \ ++ -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ ++ -I$(top_srcdir)/plugins/common \ ++ -DSYSCONFDIR=\""$(sysconfdir)"\" \ ++ -DLIBDIR=\""$(libdir)"\" \ ++ -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ ++ $(AM_CPPFLAGS) ++ ++libsmartcard_la_CFLAGS = \ ++ $(PLUGIN_CFLAGS) \ ++ $(SETTINGS_PLUGIN_CFLAGS) \ ++ $(NSS_CFLAGS) \ ++ $(AM_CFLAGS) ++ ++libsmartcard_la_LDFLAGS = \ ++ $(GSD_PLUGIN_LDFLAGS) ++ ++libsmartcard_la_LIBADD = \ ++ $(SETTINGS_PLUGIN_LIBS) \ ++ $(NSS_LIBS) ++ ++@GSD_INTLTOOL_PLUGIN_RULE@ ++ ++plugin_in_files = \ ++ smartcard.gnome-settings-plugin.in ++ ++plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin) ++ ++EXTRA_DIST = \ ++ $(plugin_in_files) ++ ++CLEANFILES = \ ++ $(plugin_DATA) ++ ++DISTCLEANFILES = \ ++ $(plugin_DATA) +diff --git a/plugins/smartcard/gsd-smartcard-enum-types.c.in b/plugins/smartcard/gsd-smartcard-enum-types.c.in +new file mode 100644 +index 0000000..f281cf4 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-enum-types.c.in +@@ -0,0 +1,42 @@ ++/*** BEGIN file-header ***/ ++ ++#include ++ ++/*** END file-header ***/ ++ ++/*** BEGIN file-production ***/ ++#include "@filename@" ++/* enumerations from "@filename@" */ ++/*** END file-production ***/ ++ ++/*** BEGIN value-header ***/ ++GType @enum_name@_get_type (void) G_GNUC_CONST; ++ ++GType ++@enum_name@_get_type (void) ++{ ++ static GType etype = 0; ++ ++ if (G_UNLIKELY(etype == 0)) { ++ static const G@Type@Value values[] = { ++/*** END value-header ***/ ++ ++/*** BEGIN value-production ***/ ++ { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, ++/*** END value-production ***/ ++ ++/*** BEGIN value-tail ***/ ++ { 0, NULL, NULL } ++ }; ++ ++ etype = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); ++ } ++ ++ return etype; ++} ++ ++/*** END value-tail ***/ ++ ++/*** BEGIN file-tail ***/ ++ /**/ ++/*** END file-tail ***/ +diff --git a/plugins/smartcard/gsd-smartcard-enum-types.h.in b/plugins/smartcard/gsd-smartcard-enum-types.h.in +new file mode 100644 +index 0000000..79dcc3d +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-enum-types.h.in +@@ -0,0 +1,24 @@ ++/*** BEGIN file-header ***/ ++#ifndef GSD_IDENTITY_ENUM_TYPES_H ++#define GSD_IDENTITY_ENUM_TYPES_H ++ ++#include ++ ++G_BEGIN_DECLS ++/*** END file-header ***/ ++ ++/*** BEGIN file-production ***/ ++ ++/* enumerations from "@filename@" */ ++/*** END file-production ***/ ++ ++/*** BEGIN value-header ***/ ++GType @enum_name@_get_type (void) G_GNUC_CONST; ++#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) ++/*** END value-header ***/ ++ ++/*** BEGIN file-tail ***/ ++G_END_DECLS ++ ++#endif /* GSD_IDENTITY_ENUM_TYPES_H */ ++/*** END file-tail ***/ +diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c +new file mode 100644 +index 0000000..05f77f8 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-manager.c +@@ -0,0 +1,870 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 William Jon McCann ++ * Copyright (C) 2010,2011 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include "gnome-settings-plugin.h" ++#include "gnome-settings-profile.h" ++#include "gsd-smartcard-manager.h" ++#include "gsd-smartcard-service.h" ++#include "gsd-smartcard-enum-types.h" ++#include "gsd-smartcard-utils.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define GSD_SMARTCARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerPrivate)) ++ ++struct GsdSmartcardManagerPrivate ++{ ++ guint start_idle_id; ++ GsdSmartcardService *service; ++ GList *smartcards_watch_tasks; ++ GCancellable *cancellable; ++ ++ GSettings *settings; ++ ++ guint32 nss_is_loaded : 1; ++}; ++ ++#define CONF_SCHEMA "org.gnome.settings-daemon.peripherals.smartcard" ++ ++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); ++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); ++ ++static gpointer manager_object = NULL; ++ ++static void ++gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *klass) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ ++ object_class->finalize = gsd_smartcard_manager_finalize; ++ ++ gsd_smartcard_utils_register_error_domain (GSD_SMARTCARD_MANAGER_ERROR, ++ GSD_TYPE_SMARTCARD_MANAGER_ERROR); ++ g_type_class_add_private (klass, sizeof (GsdSmartcardManagerPrivate)); ++} ++ ++static void ++gsd_smartcard_manager_init (GsdSmartcardManager *self) ++{ ++ self->priv = GSD_SMARTCARD_MANAGER_GET_PRIVATE (self); ++} ++ ++static void ++load_nss (GsdSmartcardManager *self) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ SECStatus status = SECSuccess; ++ static const guint32 flags = NSS_INIT_READONLY ++ | NSS_INIT_FORCEOPEN ++ | NSS_INIT_NOROOTINIT ++ | NSS_INIT_OPTIMIZESPACE ++ | NSS_INIT_PK11RELOAD; ++ ++ g_debug ("attempting to load NSS database '%s'", ++ GSD_SMARTCARD_MANAGER_NSS_DB); ++ ++ PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); ++ ++ status = NSS_Initialize (GSD_SMARTCARD_MANAGER_NSS_DB, ++ "", "", SECMOD_DB, flags); ++ ++ if (status != SECSuccess) { ++ gsize error_message_size; ++ char *error_message; ++ ++ error_message_size = PR_GetErrorTextLength (); ++ ++ if (error_message_size == 0) { ++ g_debug ("NSS security system could not be initialized"); ++ } else { ++ error_message = g_alloca (error_message_size); ++ PR_GetErrorText (error_message); ++ ++ g_debug ("NSS security system could not be initialized - %s", ++ error_message); ++ } ++ priv->nss_is_loaded = FALSE; ++ return; ++ ++ } ++ ++ g_debug ("NSS database '%s' loaded", GSD_SMARTCARD_MANAGER_NSS_DB); ++ priv->nss_is_loaded = TRUE; ++} ++ ++static void ++unload_nss (GsdSmartcardManager *self) ++{ ++ g_debug ("attempting to unload NSS security system with database '%s'", ++ GSD_SMARTCARD_MANAGER_NSS_DB); ++ ++ if (self->priv->nss_is_loaded) { ++ NSS_Shutdown (); ++ self->priv->nss_is_loaded = FALSE; ++ g_debug ("NSS database '%s' unloaded", GSD_SMARTCARD_MANAGER_NSS_DB); ++ } else { ++ g_debug ("NSS database '%s' already not loaded", GSD_SMARTCARD_MANAGER_NSS_DB); ++ } ++} ++ ++typedef struct ++{ ++ SECMODModule *driver; ++ GHashTable *smartcards; ++} WatchSmartcardsOperation; ++ ++static void ++on_watch_cancelled (GCancellable *cancellable, ++ WatchSmartcardsOperation *operation) ++{ ++ SECMOD_CancelWait (operation->driver); ++} ++ ++static gboolean ++watch_one_event_from_driver (GsdSmartcardManager *self, ++ WatchSmartcardsOperation *operation, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ PK11SlotInfo *card, *old_card; ++ CK_SLOT_ID slot_id; ++ gulong handler_id; ++ int old_slot_series = -1, slot_series; ++ ++ handler_id = g_cancellable_connect (cancellable, ++ G_CALLBACK (on_watch_cancelled), ++ operation, ++ NULL); ++ ++ card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1)); ++ ++ g_cancellable_disconnect (cancellable, handler_id); ++ ++ if (card == NULL) { ++ int error_code; ++ ++ error_code = PORT_GetError (); ++ ++ g_warning ("smartcard event function failed."); ++ ++ g_set_error (error, ++ GSD_SMARTCARD_MANAGER_ERROR, ++ GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, ++ "encountered unexpected error while " ++ "waiting for smartcard events (error %d)", ++ error_code); ++ return FALSE; ++ } ++ ++ slot_id = PK11_GetSlotID (card); ++ slot_series = PK11_GetSlotSeries (card); ++ ++ old_card = g_hash_table_lookup (operation->smartcards, GINT_TO_POINTER ((int) slot_id)); ++ ++ /* If there is a different card in the slot now than ++ * there was before, then we need to emit a removed signal ++ * for the old card ++ */ ++ if (old_card != NULL) { ++ old_slot_series = PK11_GetSlotSeries (old_card); ++ ++ if (old_slot_series != slot_series) { ++ /* Card registered with slot previously is ++ * different than this card, so update its ++ * exported state to track the implicit missed ++ * removal ++ */ ++ gsd_smartcard_service_sync_token (priv->service, old_card, cancellable); ++ } ++ ++ g_hash_table_remove (operation->smartcards, GINT_TO_POINTER ((int) slot_id)); ++ } ++ ++ if (PK11_IsPresent (card)) { ++ g_debug ("Detected smartcard insertion event in slot %d", (int) slot_id); ++ ++ g_hash_table_replace (operation->smartcards, ++ GINT_TO_POINTER ((int) slot_id), ++ 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 ++ * event for slots that are empty at startup ++ */ ++ g_debug ("Detected slot %d is empty in reader", (int) slot_id); ++ } else { ++ g_debug ("Detected smartcard removal event in slot %d", (int) slot_id); ++ ++ /* If the just removed smartcard is known to us then ++ * we need to update its exported state to reflect the ++ * removal ++ */ ++ if (old_slot_series == slot_series) ++ gsd_smartcard_service_sync_token (priv->service, card, cancellable); ++ } ++ ++ PK11_FreeSlot (card); ++ ++ return TRUE; ++} ++ ++static void ++watch_smartcards_from_driver (GTask *task, ++ GsdSmartcardManager *self, ++ WatchSmartcardsOperation *operation, ++ GCancellable *cancellable) ++{ ++ g_debug ("watching for smartcard events"); ++ while (!g_cancellable_is_cancelled (cancellable)) { ++ gboolean watch_succeeded; ++ GError *error = NULL; ++ ++ watch_succeeded = watch_one_event_from_driver (self, operation, cancellable, &error); ++ ++ if (!watch_succeeded) { ++ g_task_return_error (task, error); ++ break; ++ } ++ } ++} ++ ++static void ++destroy_watch_smartcards_operation (WatchSmartcardsOperation *operation) ++{ ++ SECMOD_DestroyModule (operation->driver); ++ g_hash_table_unref (operation->smartcards); ++ g_free (operation); ++} ++ ++static void ++on_smartcards_watch_task_destroyed (GsdSmartcardManager *self, ++ GTask *freed_task) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ ++ G_LOCK (gsd_smartcards_watch_tasks); ++ priv->smartcards_watch_tasks = g_list_remove (priv->smartcards_watch_tasks, ++ freed_task); ++ G_UNLOCK (gsd_smartcards_watch_tasks); ++} ++ ++static void ++watch_smartcards_from_driver_async (GsdSmartcardManager *self, ++ SECMODModule *driver, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ GTask *task; ++ WatchSmartcardsOperation *operation; ++ ++ operation = g_new0 (WatchSmartcardsOperation, 1); ++ operation->driver = SECMOD_ReferenceModule (driver); ++ operation->smartcards = g_hash_table_new_full (g_direct_hash, ++ g_direct_equal, ++ NULL, ++ (GDestroyNotify) PK11_FreeSlot); ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ ++ g_task_set_task_data (task, ++ operation, ++ (GDestroyNotify) destroy_watch_smartcards_operation); ++ ++ G_LOCK (gsd_smartcards_watch_tasks); ++ priv->smartcards_watch_tasks = g_list_prepend (priv->smartcards_watch_tasks, ++ task); ++ g_object_weak_ref (G_OBJECT (task), ++ (GWeakNotify) on_smartcards_watch_task_destroyed, ++ self); ++ G_UNLOCK (gsd_smartcards_watch_tasks); ++ ++ g_task_run_in_thread (task, (GTaskThreadFunc) watch_smartcards_from_driver); ++ ++ g_object_unref (task); ++} ++ ++typedef struct ++{ ++ guint driver_registered : 1; ++ guint smartcards_watched : 1; ++} ActivateDriverOperation; ++ ++static void ++try_to_complete_driver_activation (GTask *task) ++{ ++ ActivateDriverOperation *operation; ++ ++ operation = g_task_get_task_data (task); ++ ++ if (!operation->driver_registered) ++ return; ++ ++ if (!operation->smartcards_watched) ++ return; ++ ++ g_task_return_boolean (task, TRUE); ++} ++ ++static gboolean ++register_driver_finish (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); ++} ++ ++static void ++on_driver_registered (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GTask *task) ++{ ++ ActivateDriverOperation *operation; ++ GError *error = NULL; ++ ++ if (!register_driver_finish (self, result, &error)) { ++ g_task_return_error (task, error); ++ g_object_unref (task); ++ return; ++ } ++ ++ operation = g_task_get_task_data (task); ++ operation->driver_registered = TRUE; ++ ++ try_to_complete_driver_activation (task); ++} ++ ++static void ++on_smartcards_from_driver_watched (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GTask *task) ++{ ++ ActivateDriverOperation *operation; ++ ++ operation = g_task_get_task_data (task); ++ operation->smartcards_watched = TRUE; ++ ++ try_to_complete_driver_activation (task); ++} ++ ++typedef struct { ++ SECMODModule *driver; ++ guint idle_id; ++ GError *error; ++} DriverRegistrationOperation; ++ ++static void ++destroy_driver_registration_operation (DriverRegistrationOperation *operation) ++{ ++ SECMOD_DestroyModule (operation->driver); ++ g_free (operation); ++} ++ ++static gboolean ++on_task_thread_to_complete_driver_registration (GTask *task) ++{ ++ DriverRegistrationOperation *operation; ++ operation = g_task_get_task_data (task); ++ ++ if (operation->error != NULL) ++ g_task_return_error (task, operation->error); ++ else ++ g_task_return_boolean (task, TRUE); ++ ++ return G_SOURCE_REMOVE; ++} ++ ++static gboolean ++on_main_thread_to_register_driver (GTask *task) ++{ ++ GsdSmartcardManager *self; ++ GsdSmartcardManagerPrivate *priv; ++ DriverRegistrationOperation *operation; ++ GSource *source; ++ ++ self = g_task_get_source_object (task); ++ priv = self->priv; ++ operation = g_task_get_task_data (task); ++ ++ gsd_smartcard_service_register_driver (priv->service, ++ operation->driver); ++ ++ source = g_idle_source_new (); ++ g_task_attach_source (task, ++ source, ++ (GSourceFunc) on_task_thread_to_complete_driver_registration); ++ g_source_unref (source); ++ ++ return G_SOURCE_REMOVE; ++} ++ ++static void ++register_driver (GsdSmartcardManager *self, ++ SECMODModule *driver, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GTask *task; ++ DriverRegistrationOperation *operation; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ operation = g_new0 (DriverRegistrationOperation, 1); ++ operation->driver = SECMOD_ReferenceModule (driver); ++ g_task_set_task_data (task, ++ operation, ++ (GDestroyNotify) destroy_driver_registration_operation); ++ ++ operation->idle_id = g_idle_add ((GSourceFunc) on_main_thread_to_register_driver, task); ++} ++ ++static void ++activate_driver (GsdSmartcardManager *self, ++ SECMODModule *driver, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ ActivateDriverOperation *operation; ++ GTask *task; ++ ++ g_debug ("Activating driver '%s'", driver->commonName); ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ operation = g_new0 (ActivateDriverOperation, 1); ++ g_task_set_task_data (task, operation, (GDestroyNotify) g_free); ++ ++ register_driver (self, ++ driver, ++ cancellable, ++ (GAsyncReadyCallback) on_driver_registered, ++ task); ++ watch_smartcards_from_driver_async (self, ++ driver, ++ cancellable, ++ (GAsyncReadyCallback) on_smartcards_from_driver_watched, ++ task); ++} ++ ++typedef struct ++{ ++ int pending_drivers_count; ++ int activated_drivers_count; ++} ActivateAllDriversOperation; ++ ++static gboolean ++activate_driver_async_finish (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); ++} ++ ++static void ++try_to_complete_all_drivers_activation (GTask *task) ++{ ++ ActivateAllDriversOperation *operation; ++ ++ operation = g_task_get_task_data (task); ++ ++ if (operation->pending_drivers_count >= 0) ++ return; ++ ++ if (operation->activated_drivers_count > 0) ++ g_task_return_boolean (task, TRUE); ++ else ++ g_task_return_boolean (task, FALSE); ++ ++ g_object_unref (task); ++} ++ ++static void ++on_driver_activated (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GTask *task) ++{ ++ GError *error = NULL; ++ gboolean driver_activated; ++ ActivateAllDriversOperation *operation; ++ ++ driver_activated = activate_driver_async_finish (self, result, &error); ++ ++ operation = g_task_get_task_data (task); ++ ++ if (driver_activated) ++ operation->activated_drivers_count++; ++ ++ operation->pending_drivers_count--; ++ ++ try_to_complete_all_drivers_activation (task); ++} ++ ++static void ++activate_all_drivers_async (GsdSmartcardManager *self, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GTask *task; ++ SECMODListLock *lock; ++ SECMODModuleList *driver_list, *node; ++ ActivateAllDriversOperation *operation; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ operation = g_new0 (ActivateAllDriversOperation, 1); ++ g_task_set_task_data (task, operation, (GDestroyNotify) g_free); ++ ++ lock = SECMOD_GetDefaultModuleListLock (); ++ ++ g_assert (lock != NULL); ++ ++ SECMOD_GetReadLock (lock); ++ driver_list = SECMOD_GetDefaultModuleList (); ++ for (node = driver_list; node != NULL; node = node->next) { ++ if (!node->module->loaded) ++ continue; ++ ++ if (!SECMOD_HasRemovableSlots (node->module)) ++ continue; ++ ++ operation->pending_drivers_count++; ++ ++ activate_driver (self, node->module, ++ cancellable, ++ (GAsyncReadyCallback) on_driver_activated, ++ task); ++ ++ } ++ SECMOD_ReleaseReadLock (lock); ++} ++ ++static gboolean ++activate_all_drivers_async_finish (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); ++} ++ ++static void ++on_all_drivers_activated (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GTask *task) ++{ ++ GError *error = NULL; ++ gboolean driver_activated; ++ ++ driver_activated = activate_all_drivers_async_finish (self, result, &error); ++ ++ if (!driver_activated) { ++ g_task_return_error (task, error); ++ return; ++ } ++ ++ g_task_return_boolean (task, TRUE); ++} ++ ++static void ++watch_smartcards (GTask *task, ++ GsdSmartcardManager *self, ++ gpointer data, ++ GCancellable *cancellable) ++{ ++ GMainContext *context; ++ GMainLoop *loop; ++ ++ g_debug ("Getting list of suitable drivers"); ++ context = g_main_context_new (); ++ g_main_context_push_thread_default (context); ++ ++ activate_all_drivers_async (self, ++ cancellable, ++ (GAsyncReadyCallback) on_all_drivers_activated, ++ task); ++ ++ loop = g_main_loop_new (context, FALSE); ++ g_main_loop_run (loop); ++ g_main_loop_unref (loop); ++ ++ g_main_context_pop_thread_default (context); ++ g_main_context_unref (context); ++} ++ ++static void ++watch_smartcards_async (GsdSmartcardManager *self, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GTask *task; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ ++ g_task_run_in_thread (task, (GTaskThreadFunc) watch_smartcards); ++ ++ g_object_unref (task); ++} ++ ++static gboolean ++watch_smartcards_async_finish (GsdSmartcardManager *self, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); ++} ++ ++static void ++on_smartcards_watched (GsdSmartcardManager *self, ++ GAsyncResult *result) ++{ ++ GError *error = NULL; ++ ++ if (!watch_smartcards_async_finish (self, result, &error)) { ++ g_debug ("Error watching smartcards: %s", error->message); ++ g_error_free (error); ++ } ++} ++ ++static void ++on_service_created (GObject *source_object, ++ GAsyncResult *result, ++ GsdSmartcardManager *self) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ GsdSmartcardService *service; ++ GError *error = NULL; ++ ++ service = gsd_smartcard_service_new_finish (result, &error); ++ ++ if (service == NULL) { ++ g_warning("Couldn't create session bus service: %s", error->message); ++ g_error_free (error); ++ return; ++ } ++ ++ priv->service = service; ++ ++ watch_smartcards_async (self, ++ priv->cancellable, ++ (GAsyncReadyCallback) on_smartcards_watched, ++ NULL); ++ ++} ++ ++static gboolean ++gsd_smartcard_manager_idle_cb (GsdSmartcardManager *self) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ ++ gnome_settings_profile_start (NULL); ++ ++ priv->cancellable = g_cancellable_new(); ++ priv->settings = g_settings_new (CONF_SCHEMA); ++ ++ load_nss (self); ++ ++ gsd_smartcard_service_new_async (self, ++ priv->cancellable, ++ (GAsyncReadyCallback) on_service_created, ++ self); ++ ++ gnome_settings_profile_end (NULL); ++ ++ priv->start_idle_id = 0; ++ return FALSE; ++} ++ ++gboolean ++gsd_smartcard_manager_start (GsdSmartcardManager *self, ++ GError **error) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ ++ gnome_settings_profile_start (NULL); ++ ++ priv->start_idle_id = g_idle_add ((GSourceFunc) gsd_smartcard_manager_idle_cb, self); ++ ++ gnome_settings_profile_end (NULL); ++ ++ return TRUE; ++} ++ ++void ++gsd_smartcard_manager_stop (GsdSmartcardManager *self) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ ++ g_debug ("Stopping smartcard manager"); ++ ++ unload_nss (self); ++ ++ g_clear_object (&priv->settings); ++ g_clear_object (&priv->cancellable); ++} ++ ++static PK11SlotInfo * ++get_login_token_for_operation (GsdSmartcardManager *self, ++ WatchSmartcardsOperation *operation) ++{ ++ GHashTableIter iter; ++ gpointer key, value; ++ ++ g_hash_table_iter_init (&iter, operation->smartcards); ++ while (g_hash_table_iter_next (&iter, &key, &value)) { ++ PK11SlotInfo *card_slot; ++ const char *token_name; ++ ++ card_slot = (PK11SlotInfo *) value; ++ token_name = PK11_GetTokenName (card_slot); ++ ++ if (g_strcmp0 (g_getenv ("PKCS11_LOGIN_TOKEN_NAME"), token_name) == 0) ++ return card_slot; ++ } ++ ++ return NULL; ++} ++ ++PK11SlotInfo * ++gsd_smartcard_manager_get_login_token (GsdSmartcardManager *self) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ GList *node; ++ ++ G_LOCK (gsd_smartcards_watch_tasks); ++ node = priv->smartcards_watch_tasks; ++ while (node != NULL) { ++ PK11SlotInfo *card_slot; ++ ++ GTask *task = node->data; ++ WatchSmartcardsOperation *operation = g_task_get_task_data (task); ++ ++ card_slot = get_login_token_for_operation (self, operation); ++ ++ if (card_slot != NULL) ++ return card_slot; ++ ++ node = node->next; ++ } ++ G_UNLOCK (gsd_smartcards_watch_tasks); ++ ++ return NULL; ++} ++ ++static GList * ++get_inserted_tokens_for_operation (GsdSmartcardManager *self, ++ WatchSmartcardsOperation *operation) ++{ ++ GList *inserted_tokens = NULL; ++ GHashTableIter iter; ++ gpointer key, value; ++ ++ g_hash_table_iter_init (&iter, operation->smartcards); ++ while (g_hash_table_iter_next (&iter, &key, &value)) { ++ PK11SlotInfo *card_slot; ++ ++ card_slot = (PK11SlotInfo *) value; ++ ++ if (PK11_IsPresent (card_slot)) ++ inserted_tokens = g_list_prepend (inserted_tokens, card_slot); ++ } ++ ++ return inserted_tokens; ++} ++ ++GList * ++gsd_smartcard_manager_get_inserted_tokens (GsdSmartcardManager *self, ++ gsize *num_tokens) ++{ ++ GsdSmartcardManagerPrivate *priv = self->priv; ++ GList *inserted_tokens = NULL, *node; ++ ++ G_LOCK (gsd_smartcards_watch_tasks); ++ for (node = priv->smartcards_watch_tasks; node != NULL; node = node->next) { ++ GTask *task = node->data; ++ WatchSmartcardsOperation *operation = g_task_get_task_data (task); ++ GList *operation_inserted_tokens; ++ ++ operation_inserted_tokens = get_inserted_tokens_for_operation (self, operation); ++ ++ inserted_tokens = g_list_concat (inserted_tokens, operation_inserted_tokens); ++ } ++ G_UNLOCK (gsd_smartcards_watch_tasks); ++ ++ if (num_tokens != NULL) ++ *num_tokens = g_list_length (inserted_tokens); ++ ++ return inserted_tokens; ++} ++ ++static void ++gsd_smartcard_manager_finalize (GObject *object) ++{ ++ GsdSmartcardManager *self; ++ GsdSmartcardManagerPrivate *priv; ++ ++ g_return_if_fail (object != NULL); ++ g_return_if_fail (GSD_IS_SMARTCARD_MANAGER (object)); ++ ++ self = GSD_SMARTCARD_MANAGER (object); ++ priv = self->priv; ++ ++ g_return_if_fail (self->priv != NULL); ++ ++ if (priv->start_idle_id != 0) ++ g_source_remove (priv->start_idle_id); ++ ++ gsd_smartcard_manager_stop (self); ++ ++ G_OBJECT_CLASS (gsd_smartcard_manager_parent_class)->finalize (object); ++} ++ ++GsdSmartcardManager * ++gsd_smartcard_manager_new (void) ++{ ++ if (manager_object != NULL) { ++ g_object_ref (manager_object); ++ } else { ++ manager_object = g_object_new (GSD_TYPE_SMARTCARD_MANAGER, NULL); ++ g_object_add_weak_pointer (manager_object, ++ (gpointer *) &manager_object); ++ } ++ ++ return GSD_SMARTCARD_MANAGER (manager_object); ++} +diff --git a/plugins/smartcard/gsd-smartcard-manager.h b/plugins/smartcard/gsd-smartcard-manager.h +new file mode 100644 +index 0000000..9d3a2ce +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-manager.h +@@ -0,0 +1,82 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 William Jon McCann ++ * Copyright (C) 2010 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++#ifndef __GSD_SMARTCARD_MANAGER_H ++#define __GSD_SMARTCARD_MANAGER_H ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++G_BEGIN_DECLS ++ ++#define GSD_TYPE_SMARTCARD_MANAGER (gsd_smartcard_manager_get_type ()) ++#define GSD_SMARTCARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManager)) ++#define GSD_SMARTCARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerClass)) ++#define GSD_IS_SMARTCARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SMARTCARD_MANAGER)) ++#define GSD_IS_SMARTCARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SMARTCARD_MANAGER)) ++#define GSD_SMARTCARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerClass)) ++#define GSD_SMARTCARD_MANAGER_ERROR (gsd_smartcard_manager_error_quark ()) ++ ++typedef struct GsdSmartcardManagerPrivate GsdSmartcardManagerPrivate; ++ ++typedef struct ++{ ++ GObject parent; ++ GsdSmartcardManagerPrivate *priv; ++} GsdSmartcardManager; ++ ++typedef struct ++{ ++ GObjectClass parent_class; ++} GsdSmartcardManagerClass; ++ ++typedef enum ++{ ++ GSD_SMARTCARD_MANAGER_ERROR_GENERIC = 0, ++ GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, ++ GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, ++ GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, ++ GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, ++ GSD_SMARTCARD_MANAGER_ERROR_FINDING_SMARTCARD ++} GsdSmartcardManagerError; ++ ++GType gsd_smartcard_manager_get_type (void); ++GQuark gsd_smartcard_manager_error_quark (void); ++ ++ ++GsdSmartcardManager * gsd_smartcard_manager_new (void); ++gboolean gsd_smartcard_manager_start (GsdSmartcardManager *manager, ++ GError **error); ++void gsd_smartcard_manager_stop (GsdSmartcardManager *manager); ++ ++PK11SlotInfo * gsd_smartcard_manager_get_login_token (GsdSmartcardManager *manager); ++GList * gsd_smartcard_manager_get_inserted_tokens (GsdSmartcardManager *manager, ++ gsize *num_tokens); ++ ++G_END_DECLS ++ ++#endif /* __GSD_SMARTCARD_MANAGER_H */ +diff --git a/plugins/smartcard/gsd-smartcard-plugin.c b/plugins/smartcard/gsd-smartcard-plugin.c +new file mode 100644 +index 0000000..ea78f85 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-plugin.c +@@ -0,0 +1,30 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 William Jon McCann ++ * Copyright (C) 2010 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include "gnome-settings-plugin.h" ++#include "gsd-smartcard-manager.h" ++ ++GNOME_SETTINGS_PLUGIN_REGISTER (GsdSmartcard, gsd_smartcard) +diff --git a/plugins/smartcard/gsd-smartcard-service.c b/plugins/smartcard/gsd-smartcard-service.c +new file mode 100644 +index 0000000..40350d0 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-service.c +@@ -0,0 +1,773 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2012 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++ * 02111-1307, USA. ++ * ++ * Authors: Ray Strode ++ */ ++ ++#include "config.h" ++ ++#include "gsd-smartcard-service.h" ++#include "org.gnome.SettingsDaemon.Smartcard.h" ++#include "gsd-smartcard-manager.h" ++#include "gsd-smartcard-enum-types.h" ++#include "gsd-smartcard-utils.h" ++ ++#include "gnome-settings-plugin.h" ++ ++#include ++#include ++#include ++ ++struct _GsdSmartcardServicePrivate ++{ ++ GDBusConnection *bus_connection; ++ GDBusObjectManagerServer *object_manager_server; ++ GsdSmartcardManager *smartcard_manager; ++ GCancellable *cancellable; ++ GHashTable *tokens; ++ ++ guint name_id; ++}; ++ ++#define GSD_SMARTCARD_DBUS_NAME GSD_DBUS_NAME ".Smartcard" ++#define GSD_SMARTCARD_DBUS_PATH GSD_DBUS_PATH "/Smartcard" ++#define GSD_SMARTCARD_MANAGER_DBUS_PATH GSD_SMARTCARD_DBUS_PATH "/Manager" ++#define GSD_SMARTCARD_MANAGER_DRIVERS_DBUS_PATH GSD_SMARTCARD_MANAGER_DBUS_PATH "/Drivers" ++#define GSD_SMARTCARD_MANAGER_TOKENS_DBUS_PATH GSD_SMARTCARD_MANAGER_DBUS_PATH "/Tokens" ++ ++enum { ++ PROP_0, ++ PROP_MANAGER, ++ PROP_BUS_CONNECTION ++}; ++ ++static void gsd_smartcard_service_set_property (GObject *object, ++ guint property_id, ++ const GValue *value, ++ GParamSpec *param_spec); ++static void gsd_smartcard_service_get_property (GObject *object, ++ guint property_id, ++ GValue *value, ++ GParamSpec *param_spec); ++static void async_initable_interface_init (GAsyncInitableIface *interface); ++static void smartcard_service_manager_interface_init (GsdSmartcardServiceManagerIface *interface); ++ ++G_LOCK_DEFINE_STATIC (gsd_smartcard_tokens); ++ ++G_DEFINE_TYPE_WITH_CODE (GsdSmartcardService, ++ gsd_smartcard_service, ++ GSD_SMARTCARD_SERVICE_TYPE_MANAGER_SKELETON, ++ G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, ++ async_initable_interface_init) ++ G_IMPLEMENT_INTERFACE (GSD_SMARTCARD_SERVICE_TYPE_MANAGER, ++ smartcard_service_manager_interface_init)); ++ ++static void ++set_bus_connection (GsdSmartcardService *self, ++ GDBusConnection *connection) ++{ ++ GsdSmartcardServicePrivate *priv = self->priv; ++ ++ if (priv->bus_connection != connection) { ++ g_clear_object (&priv->bus_connection); ++ priv->bus_connection = g_object_ref (connection); ++ g_object_notify (G_OBJECT (self), "bus-connection"); ++ } ++} ++ ++static void ++register_object_manager (GsdSmartcardService *self) ++{ ++ GsdSmartcardServiceObjectSkeleton *object; ++ ++ self->priv->object_manager_server = g_dbus_object_manager_server_new (GSD_SMARTCARD_DBUS_PATH); ++ ++ object = gsd_smartcard_service_object_skeleton_new (GSD_SMARTCARD_MANAGER_DBUS_PATH); ++ gsd_smartcard_service_object_skeleton_set_manager (object, ++ GSD_SMARTCARD_SERVICE_MANAGER (self)); ++ ++ g_dbus_object_manager_server_export (self->priv->object_manager_server, ++ G_DBUS_OBJECT_SKELETON (object)); ++ g_object_unref (object); ++ ++ g_dbus_object_manager_server_set_connection (self->priv->object_manager_server, ++ self->priv->bus_connection); ++} ++ ++static void ++on_bus_gotten (GObject *source_object, ++ GAsyncResult *result, ++ GTask *task) ++{ ++ GsdSmartcardService *self; ++ GsdSmartcardServicePrivate *priv; ++ GDBusConnection *connection; ++ GError *error = NULL; ++ ++ connection = g_bus_get_finish (result, &error); ++ if (connection == NULL) { ++ g_task_return_error (task, error); ++ goto out; ++ } ++ ++ g_debug ("taking name %s on session bus", GSD_SMARTCARD_DBUS_NAME); ++ ++ self = g_task_get_source_object (task); ++ priv = self->priv; ++ ++ set_bus_connection (self, connection); ++ ++ register_object_manager (self); ++ priv->name_id = g_bus_own_name_on_connection (connection, ++ GSD_SMARTCARD_DBUS_NAME, ++ G_BUS_NAME_OWNER_FLAGS_NONE, ++ NULL, ++ NULL, ++ NULL, ++ NULL); ++ g_task_return_boolean (task, TRUE); ++ ++out: ++ g_object_unref (task); ++ return; ++} ++ ++static gboolean ++gsd_smartcard_service_initable_init_finish (GAsyncInitable *initable, ++ GAsyncResult *result, ++ GError **error) ++{ ++ GTask *task; ++ ++ task = G_TASK (result); ++ ++ return g_task_propagate_boolean (task, error); ++} ++ ++static void ++gsd_smartcard_service_initable_init_async (GAsyncInitable *initable, ++ int io_priority, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (initable); ++ GTask *task; ++ ++ task = g_task_new (G_OBJECT (self), cancellable, callback, user_data); ++ g_task_set_priority (task, io_priority); ++ ++ g_bus_get (G_BUS_TYPE_SESSION, cancellable, (GAsyncReadyCallback) on_bus_gotten, task); ++} ++ ++static void ++async_initable_interface_init (GAsyncInitableIface *interface) ++{ ++ interface->init_async = gsd_smartcard_service_initable_init_async; ++ interface->init_finish = gsd_smartcard_service_initable_init_finish; ++} ++ ++static char * ++get_object_path_for_token (GsdSmartcardService *self, ++ PK11SlotInfo *card_slot) ++{ ++ char *object_path; ++ char *escaped_library_path; ++ SECMODModule *driver; ++ CK_SLOT_ID slot_id; ++ ++ driver = PK11_GetModule (card_slot); ++ slot_id = PK11_GetSlotID (card_slot); ++ ++ escaped_library_path = gsd_smartcard_utils_escape_object_path (driver->dllName); ++ ++ object_path = g_strdup_printf ("%s/token_from_%s_slot_%lu", ++ GSD_SMARTCARD_MANAGER_TOKENS_DBUS_PATH, ++ escaped_library_path, ++ (gulong) slot_id); ++ g_free (escaped_library_path); ++ ++ return object_path; ++} ++ ++static gboolean ++gsd_smartcard_service_handle_get_login_token (GsdSmartcardServiceManager *manager, ++ GDBusMethodInvocation *invocation) ++{ ++ GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (manager); ++ GsdSmartcardServicePrivate *priv = self->priv; ++ PK11SlotInfo *card_slot; ++ char *object_path; ++ ++ card_slot = gsd_smartcard_manager_get_login_token (priv->smartcard_manager); ++ ++ if (card_slot == NULL) { ++ g_dbus_method_invocation_return_error (invocation, ++ GSD_SMARTCARD_MANAGER_ERROR, ++ GSD_SMARTCARD_MANAGER_ERROR_FINDING_SMARTCARD, ++ _("User was not logged in with smartcard.")); ++ ++ return TRUE; ++ } ++ ++ object_path = get_object_path_for_token (self, card_slot); ++ gsd_smartcard_service_manager_complete_get_login_token (manager, ++ invocation, ++ object_path); ++ g_free (object_path); ++ ++ return TRUE; ++} ++ ++static gboolean ++gsd_smartcard_service_handle_get_inserted_tokens (GsdSmartcardServiceManager *manager, ++ GDBusMethodInvocation *invocation) ++{ ++ GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (manager); ++ GsdSmartcardServicePrivate *priv = self->priv; ++ GList *inserted_tokens, *node; ++ GPtrArray *object_paths; ++ ++ inserted_tokens = gsd_smartcard_manager_get_inserted_tokens (priv->smartcard_manager, ++ NULL); ++ ++ object_paths = g_ptr_array_new (); ++ for (node = inserted_tokens; node != NULL; node = node->next) { ++ PK11SlotInfo *card_slot = node->data; ++ char *object_path; ++ ++ object_path = get_object_path_for_token (self, card_slot); ++ g_ptr_array_add (object_paths, object_path); ++ } ++ g_ptr_array_add (object_paths, NULL); ++ g_list_free (inserted_tokens); ++ ++ gsd_smartcard_service_manager_complete_get_inserted_tokens (manager, ++ invocation, ++ (const char * const *) object_paths->pdata); ++ ++ g_ptr_array_free (object_paths, TRUE); ++ ++ return TRUE; ++} ++ ++static void ++smartcard_service_manager_interface_init (GsdSmartcardServiceManagerIface *interface) ++{ ++ interface->handle_get_login_token = gsd_smartcard_service_handle_get_login_token; ++ interface->handle_get_inserted_tokens = gsd_smartcard_service_handle_get_inserted_tokens; ++} ++ ++static void ++gsd_smartcard_service_init (GsdSmartcardService *self) ++{ ++ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ++ GSD_TYPE_SMARTCARD_SERVICE, ++ GsdSmartcardServicePrivate); ++ self->priv->tokens = g_hash_table_new_full (g_str_hash, ++ g_str_equal, ++ (GDestroyNotify) g_free, ++ NULL); ++} ++ ++static void ++gsd_smartcard_service_dispose (GObject *object) ++{ ++ GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (object); ++ ++ g_clear_object (&self->priv->bus_connection); ++ g_clear_object (&self->priv->object_manager_server); ++ g_clear_object (&self->priv->smartcard_manager); ++ ++ g_cancellable_cancel (self->priv->cancellable); ++ g_clear_object (&self->priv->cancellable); ++ g_clear_pointer (&self->priv->tokens, g_hash_table_unref); ++ ++ G_OBJECT_CLASS (gsd_smartcard_service_parent_class)->dispose (object); ++} ++ ++static void ++gsd_smartcard_service_set_property (GObject *object, ++ guint property_id, ++ const GValue *value, ++ GParamSpec *param_spec) ++{ ++ GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (object); ++ GsdSmartcardServicePrivate *priv = self->priv; ++ ++ switch (property_id) { ++ case PROP_MANAGER: ++ priv->smartcard_manager = g_value_dup_object (value); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec); ++ break; ++ } ++} ++ ++static void ++gsd_smartcard_service_get_property (GObject *object, ++ guint property_id, ++ GValue *value, ++ GParamSpec *param_spec) ++{ ++ GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (object); ++ GsdSmartcardServicePrivate *priv = self->priv; ++ ++ switch (property_id) { ++ case PROP_MANAGER: ++ g_value_set_object (value, priv->smartcard_manager); ++ break; ++ case PROP_BUS_CONNECTION: ++ g_value_set_object (value, priv->bus_connection); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec); ++ break; ++ } ++} ++ ++static void ++gsd_smartcard_service_class_init (GsdSmartcardServiceClass *service_class) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (service_class); ++ GParamSpec *param_spec; ++ ++ object_class->dispose = gsd_smartcard_service_dispose; ++ object_class->set_property = gsd_smartcard_service_set_property; ++ object_class->get_property = gsd_smartcard_service_get_property; ++ ++ param_spec = g_param_spec_object ("manager", ++ "Smartcard Manager", ++ "Smartcard Manager", ++ GSD_TYPE_SMARTCARD_MANAGER, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); ++ g_object_class_install_property (object_class, PROP_MANAGER, param_spec); ++ param_spec = g_param_spec_object ("bus-connection", ++ "Bus Connection", ++ "bus connection", ++ G_TYPE_DBUS_CONNECTION, ++ G_PARAM_READABLE); ++ g_object_class_install_property (object_class, PROP_BUS_CONNECTION, param_spec); ++ ++ g_type_class_add_private (service_class, sizeof (GsdSmartcardServicePrivate)); ++} ++ ++static void ++on_new_async_finished (GObject *source_object, ++ GAsyncResult *result, ++ GTask *task) ++{ ++ GError *error = NULL; ++ GObject *object; ++ ++ object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), ++ result, ++ &error); ++ ++ if (object == NULL) { ++ g_task_return_error (task, error); ++ goto out; ++ } ++ ++ g_assert (GSD_IS_SMARTCARD_SERVICE (object)); ++ ++ g_task_return_pointer (task, object, g_object_unref); ++out: ++ g_object_unref (task); ++ return; ++} ++ ++void ++gsd_smartcard_service_new_async (GsdSmartcardManager *manager, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GTask *task; ++ ++ task = g_task_new (NULL, cancellable, callback, user_data); ++ ++ g_async_initable_new_async (GSD_TYPE_SMARTCARD_SERVICE, ++ G_PRIORITY_DEFAULT, ++ cancellable, ++ (GAsyncReadyCallback) on_new_async_finished, ++ task, ++ "manager", manager, ++ NULL); ++} ++ ++GsdSmartcardService * ++gsd_smartcard_service_new_finish (GAsyncResult *result, ++ GError **error) ++{ ++ GTask *task; ++ GsdSmartcardService *self = NULL; ++ ++ task = G_TASK (result); ++ ++ self = g_task_propagate_pointer (task, error); ++ ++ if (self == NULL) ++ return self; ++ ++ return g_object_ref (self); ++} ++ ++static char * ++get_object_path_for_driver (GsdSmartcardService *self, ++ SECMODModule *driver) ++{ ++ char *object_path; ++ char *escaped_library_path; ++ ++ escaped_library_path = gsd_smartcard_utils_escape_object_path (driver->dllName); ++ ++ object_path = g_build_path ("/", ++ GSD_SMARTCARD_MANAGER_DRIVERS_DBUS_PATH, ++ escaped_library_path, NULL); ++ g_free (escaped_library_path); ++ ++ return object_path; ++} ++ ++void ++gsd_smartcard_service_register_driver (GsdSmartcardService *self, ++ SECMODModule *driver) ++{ ++ char *object_path; ++ GDBusObjectSkeleton *object; ++ GDBusInterfaceSkeleton *interface; ++ ++ object_path = get_object_path_for_driver (self, driver); ++ object = G_DBUS_OBJECT_SKELETON (gsd_smartcard_service_object_skeleton_new (object_path)); ++ g_free (object_path); ++ ++ interface = G_DBUS_INTERFACE_SKELETON (gsd_smartcard_service_driver_skeleton_new ()); ++ g_dbus_object_skeleton_add_interface (object, interface); ++ g_object_unref (interface); ++ ++ g_object_set (G_OBJECT (interface), ++ "library", driver->dllName, ++ "description", driver->commonName, ++ NULL); ++ g_dbus_object_manager_server_export (self->priv->object_manager_server, ++ object); ++ g_object_unref (object); ++} ++ ++static void ++synchronize_token_now (GsdSmartcardService *self, ++ PK11SlotInfo *card_slot) ++{ ++ GsdSmartcardServicePrivate *priv = self->priv; ++ GDBusInterfaceSkeleton *interface; ++ char *object_path; ++ const char *token_name; ++ gboolean is_present, is_login_card; ++ ++ object_path = get_object_path_for_token (self, card_slot); ++ ++ G_LOCK (gsd_smartcard_tokens); ++ interface = g_hash_table_lookup (priv->tokens, object_path); ++ g_free (object_path); ++ ++ if (interface == NULL) ++ goto out; ++ ++ token_name = PK11_GetTokenName (card_slot); ++ is_present = PK11_IsPresent (card_slot); ++ ++ if (g_strcmp0 (g_getenv ("PKCS11_LOGIN_TOKEN_NAME"), token_name) == 0) ++ is_login_card = TRUE; ++ else ++ is_login_card = FALSE; ++ ++ g_debug ("==============================="); ++ g_debug (" Token '%s'", token_name); ++ g_debug (" Inserted: %s", is_present? "yes" : "no"); ++ g_debug (" Previously used to login: %s", is_login_card? "yes" : "no"); ++ g_debug ("===============================\n"); ++ ++ g_object_set (G_OBJECT (interface), ++ "used-to-login", is_login_card, ++ "is-inserted", is_present, ++ NULL); ++ g_object_get (G_OBJECT (interface), ++ "used-to-login", &is_login_card, ++ "is-inserted", &is_present, ++ NULL); ++ ++out: ++ G_UNLOCK (gsd_smartcard_tokens); ++} ++ ++typedef struct ++{ ++ PK11SlotInfo *card_slot; ++ char *object_path; ++ GSource *main_thread_source; ++} RegisterNewTokenOperation; ++ ++static void ++destroy_register_new_token_operation (RegisterNewTokenOperation *operation) ++{ ++ g_clear_pointer (&operation->main_thread_source, ++ (GDestroyNotify) g_source_destroy); ++ PK11_FreeSlot (operation->card_slot); ++ g_free (operation->object_path); ++ g_free (operation); ++} ++ ++static gboolean ++on_main_thread_to_register_new_token (GTask *task) ++{ ++ GsdSmartcardService *self; ++ GsdSmartcardServicePrivate *priv; ++ GDBusObjectSkeleton *object; ++ GDBusInterfaceSkeleton *interface; ++ RegisterNewTokenOperation *operation; ++ SECMODModule *driver; ++ char *driver_object_path; ++ const char *token_name; ++ ++ self = g_task_get_source_object (task); ++ priv = self->priv; ++ ++ operation = g_task_get_task_data (task); ++ operation->main_thread_source = NULL; ++ ++ object = G_DBUS_OBJECT_SKELETON (gsd_smartcard_service_object_skeleton_new (operation->object_path)); ++ interface = G_DBUS_INTERFACE_SKELETON (gsd_smartcard_service_token_skeleton_new ()); ++ ++ g_dbus_object_skeleton_add_interface (object, interface); ++ g_object_unref (interface); ++ ++ driver = PK11_GetModule (operation->card_slot); ++ driver_object_path = get_object_path_for_driver (self, driver); ++ ++ token_name = PK11_GetTokenName (operation->card_slot); ++ ++ g_object_set (G_OBJECT (interface), ++ "driver", driver_object_path, ++ "name", token_name, ++ NULL); ++ g_free (driver_object_path); ++ ++ g_dbus_object_manager_server_export (self->priv->object_manager_server, ++ object); ++ ++ G_LOCK (gsd_smartcard_tokens); ++ g_hash_table_insert (priv->tokens, g_strdup (operation->object_path), interface); ++ G_UNLOCK (gsd_smartcard_tokens); ++ ++ g_task_return_boolean (task, TRUE); ++ ++ return G_SOURCE_REMOVE; ++} ++ ++static void ++create_main_thread_source (GSourceFunc callback, ++ gpointer user_data, ++ GSource **source_out) ++{ ++ GSource *source; ++ ++ source = g_idle_source_new (); ++ g_source_set_callback (source, callback, user_data, NULL); ++ ++ *source_out = source; ++ g_source_attach (source, NULL); ++ g_source_unref (source); ++} ++ ++static void ++register_new_token_in_main_thread (GsdSmartcardService *self, ++ PK11SlotInfo *card_slot, ++ char *object_path, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ RegisterNewTokenOperation *operation; ++ GTask *task; ++ ++ operation = g_new0 (RegisterNewTokenOperation, 1); ++ operation->card_slot = PK11_ReferenceSlot (card_slot); ++ operation->object_path = g_strdup (object_path); ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ ++ g_task_set_task_data (task, ++ operation, ++ (GDestroyNotify) destroy_register_new_token_operation); ++ ++ create_main_thread_source ((GSourceFunc) on_main_thread_to_register_new_token, ++ task, ++ &operation->main_thread_source); ++} ++ ++static gboolean ++register_new_token_in_main_thread_finish (GsdSmartcardService *self, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); ++} ++ ++static void ++on_token_registered (GsdSmartcardService *self, ++ GAsyncResult *result, ++ PK11SlotInfo *card_slot) ++{ ++ gboolean registered; ++ GError *error = NULL; ++ ++ registered = register_new_token_in_main_thread_finish (self, result, &error); ++ ++ if (!registered) { ++ g_debug ("Couldn't register token: %s", ++ error->message); ++ goto out; ++ } ++ ++ synchronize_token_now (self, card_slot); ++ ++out: ++ PK11_FreeSlot (card_slot); ++} ++ ++typedef struct ++{ ++ PK11SlotInfo *card_slot; ++ GSource *main_thread_source; ++} SynchronizeTokenOperation; ++ ++static void ++destroy_synchronize_token_operation (SynchronizeTokenOperation *operation) ++{ ++ g_clear_pointer (&operation->main_thread_source, ++ (GDestroyNotify) ++ g_source_destroy); ++ PK11_FreeSlot (operation->card_slot); ++ g_free (operation); ++} ++ ++static gboolean ++on_main_thread_to_synchronize_token (GTask *task) ++{ ++ GsdSmartcardService *self; ++ SynchronizeTokenOperation *operation; ++ ++ self = g_task_get_source_object (task); ++ ++ operation = g_task_get_task_data (task); ++ operation->main_thread_source = NULL; ++ ++ synchronize_token_now (self, operation->card_slot); ++ ++ g_task_return_boolean (task, TRUE); ++ ++ return G_SOURCE_REMOVE; ++} ++ ++static gboolean ++synchronize_token_in_main_thread_finish (GsdSmartcardService *self, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); ++} ++ ++static void ++synchronize_token_in_main_thread (GsdSmartcardService *self, ++ PK11SlotInfo *card_slot, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ SynchronizeTokenOperation *operation; ++ GTask *task; ++ ++ operation = g_new0 (SynchronizeTokenOperation, 1); ++ operation->card_slot = PK11_ReferenceSlot (card_slot); ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ ++ g_task_set_task_data (task, ++ operation, ++ (GDestroyNotify) ++ destroy_synchronize_token_operation); ++ ++ create_main_thread_source ((GSourceFunc) ++ on_main_thread_to_synchronize_token, ++ task, ++ &operation->main_thread_source); ++} ++ ++static void ++on_token_synchronized (GsdSmartcardService *self, ++ GAsyncResult *result, ++ PK11SlotInfo *card_slot) ++{ ++ gboolean synchronized; ++ GError *error = NULL; ++ ++ synchronized = synchronize_token_in_main_thread_finish (self, result, &error); ++ ++ if (!synchronized) ++ g_debug ("Couldn't synchronize token: %s", error->message); ++ ++ PK11_FreeSlot (card_slot); ++} ++ ++void ++gsd_smartcard_service_sync_token (GsdSmartcardService *self, ++ PK11SlotInfo *card_slot, ++ GCancellable *cancellable) ++{ ++ GsdSmartcardServicePrivate *priv = self->priv; ++ char *object_path; ++ GDBusInterfaceSkeleton *interface; ++ ++ object_path = get_object_path_for_token (self, card_slot); ++ ++ G_LOCK (gsd_smartcard_tokens); ++ interface = g_hash_table_lookup (priv->tokens, object_path); ++ G_UNLOCK (gsd_smartcard_tokens); ++ ++ if (interface == NULL) ++ register_new_token_in_main_thread (self, ++ card_slot, ++ object_path, ++ cancellable, ++ (GAsyncReadyCallback) ++ on_token_registered, ++ PK11_ReferenceSlot (card_slot)); ++ ++ else ++ synchronize_token_in_main_thread (self, ++ card_slot, ++ cancellable, ++ (GAsyncReadyCallback) ++ on_token_synchronized, ++ PK11_ReferenceSlot (card_slot)); ++ ++ g_free (object_path); ++} +diff --git a/plugins/smartcard/gsd-smartcard-service.h b/plugins/smartcard/gsd-smartcard-service.h +new file mode 100644 +index 0000000..2e48001 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-service.h +@@ -0,0 +1,81 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2012 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++ * 02111-1307, USA. ++ * ++ * Authors: Ray Strode ++ */ ++ ++#ifndef __GSD_SMARTCARD_SERVICE_H__ ++#define __GSD_SMARTCARD_SERVICE_H__ ++ ++#include ++#include ++#include ++#include "gsd-smartcard-manager.h" ++ ++#include "org.gnome.SettingsDaemon.Smartcard.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++G_BEGIN_DECLS ++ ++#define GSD_TYPE_SMARTCARD_SERVICE (gsd_smartcard_service_get_type ()) ++#define GSD_SMARTCARD_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GSD_TYPE_SMARTCARD_SERVICE, GsdSmartcardService)) ++#define GSD_SMARTCARD_SERVICE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GSD_TYPE_SMARTCARD_SERVICE, GsdSmartcardServiceClass)) ++#define GSD_IS_SMARTCARD_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GSD_TYPE_SMARTCARD_SERVICE)) ++#define GSD_IS_SMARTCARD_SERVICE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GSD_TYPE_SMARTCARD_SERVICE)) ++#define GSD_SMARTCARD_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_SMARTCARD_SERVICE, GsdSmartcardServiceClass)) ++ ++typedef struct _GsdSmartcardService GsdSmartcardService; ++typedef struct _GsdSmartcardServiceClass GsdSmartcardServiceClass; ++typedef struct _GsdSmartcardServicePrivate GsdSmartcardServicePrivate; ++ ++struct _GsdSmartcardService ++{ ++ GsdSmartcardServiceManagerSkeleton parent_instance; ++ GsdSmartcardServicePrivate *priv; ++}; ++ ++struct _GsdSmartcardServiceClass ++{ ++ GsdSmartcardServiceManagerSkeletonClass parent_class; ++}; ++ ++GType gsd_smartcard_service_get_type (void); ++void gsd_smartcard_service_new_async (GsdSmartcardManager *manager, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++GsdSmartcardService *gsd_smartcard_service_new_finish (GAsyncResult *result, ++ GError **error); ++ ++void gsd_smartcard_service_register_driver (GsdSmartcardService *service, ++ SECMODModule *driver); ++void gsd_smartcard_service_sync_token (GsdSmartcardService *service, ++ PK11SlotInfo *slot_info, ++ GCancellable *cancellable); ++ ++ ++G_END_DECLS ++ ++#endif /* __GSD_SMARTCARD_SERVICE_H__ */ +diff --git a/plugins/smartcard/gsd-smartcard-utils.c b/plugins/smartcard/gsd-smartcard-utils.c +new file mode 100644 +index 0000000..a2511a5 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-utils.c +@@ -0,0 +1,191 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2013 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++#include "config.h" ++#include "gsd-smartcard-utils.h" ++ ++#include ++ ++#include ++#include ++ ++static char * ++dashed_string_to_studly_caps (const char *dashed_string) ++{ ++ char *studly_string; ++ size_t studly_string_length; ++ size_t i; ++ ++ i = 0; ++ ++ studly_string = g_strdup (dashed_string); ++ studly_string_length = strlen (studly_string); ++ ++ studly_string[i] = g_ascii_toupper (studly_string[i]); ++ i++; ++ ++ while (i < studly_string_length) { ++ if (studly_string[i] == '-' || studly_string[i] == '_') { ++ memmove (studly_string + i, ++ studly_string + i + 1, ++ studly_string_length - i - 1); ++ studly_string_length--; ++ if (g_ascii_isalpha (studly_string[i])) { ++ studly_string[i] = g_ascii_toupper (studly_string[i]); ++ } ++ } ++ i++; ++ } ++ studly_string[studly_string_length] = '\0'; ++ ++ return studly_string; ++} ++ ++static char * ++dashed_string_to_dbus_error_string (const char *dashed_string, ++ const char *old_prefix, ++ const char *new_prefix, ++ const char *suffix) ++{ ++ char *studly_suffix; ++ char *dbus_error_string; ++ size_t dbus_error_string_length; ++ size_t i; ++ ++ i = 0; ++ ++ if (g_str_has_prefix (dashed_string, old_prefix) && ++ (dashed_string[strlen(old_prefix)] == '-' || ++ dashed_string[strlen(old_prefix)] == '_')) { ++ dashed_string += strlen (old_prefix) + 1; ++ } ++ ++ studly_suffix = dashed_string_to_studly_caps (suffix); ++ dbus_error_string = g_strdup_printf ("%s.%s.%s", new_prefix, dashed_string, studly_suffix); ++ g_free (studly_suffix); ++ i += strlen (new_prefix) + 1; ++ ++ dbus_error_string_length = strlen (dbus_error_string); ++ ++ dbus_error_string[i] = g_ascii_toupper (dbus_error_string[i]); ++ i++; ++ ++ while (i < dbus_error_string_length) { ++ if (dbus_error_string[i] == '_' || dbus_error_string[i] == '-') { ++ dbus_error_string[i] = '.'; ++ ++ if (g_ascii_isalpha (dbus_error_string[i + 1])) { ++ dbus_error_string[i + 1] = g_ascii_toupper (dbus_error_string[i + 1]); ++ } ++ } ++ ++ i++; ++ } ++ ++ return dbus_error_string; ++} ++ ++void ++gsd_smartcard_utils_register_error_domain (GQuark error_domain, ++ GType error_enum) ++{ ++ const char *error_domain_string; ++ char *type_name; ++ GType type; ++ GTypeClass *type_class; ++ GEnumClass *enum_class; ++ guint i; ++ ++ error_domain_string = g_quark_to_string (error_domain); ++ type_name = dashed_string_to_studly_caps (error_domain_string); ++ type = g_type_from_name (type_name); ++ type_class = g_type_class_ref (type); ++ enum_class = G_ENUM_CLASS (type_class); ++ ++ for (i = 0; i < enum_class->n_values; i++) { ++ char *dbus_error_string; ++ ++ dbus_error_string = dashed_string_to_dbus_error_string (error_domain_string, ++ "gsd", ++ "org.gnome.SettingsDaemon", ++ enum_class->values[i].value_nick); ++ ++ g_debug ("%s: Registering dbus error %s", type_name, dbus_error_string); ++ g_dbus_error_register_error (error_domain, ++ enum_class->values[i].value, ++ dbus_error_string); ++ g_free (dbus_error_string); ++ } ++ ++ g_type_class_unref (type_class); ++} ++ ++char * ++gsd_smartcard_utils_escape_object_path (const char *unescaped_string) ++{ ++ const char *p; ++ char *object_path; ++ GString *string; ++ ++ g_return_val_if_fail (unescaped_string != NULL, NULL); ++ ++ string = g_string_new (""); ++ ++ for (p = unescaped_string; *p != '\0'; p++) ++ { ++ guchar character; ++ ++ character = (guchar) * p; ++ ++ if (((character >= ((guchar) 'a')) && ++ (character <= ((guchar) 'z'))) || ++ ((character >= ((guchar) 'A')) && ++ (character <= ((guchar) 'Z'))) || ++ ((character >= ((guchar) '0')) && (character <= ((guchar) '9')))) ++ { ++ g_string_append_c (string, (char) character); ++ continue; ++ } ++ ++ g_string_append_printf (string, "_%x_", character); ++ } ++ ++ object_path = string->str; ++ ++ g_string_free (string, FALSE); ++ ++ return object_path; ++} ++ ++gboolean ++gsd_smartcard_utils_finish_boolean_task (GObject *object, ++ GAsyncResult *result, ++ GError **error) ++{ ++ gboolean return_value; ++ ++ g_return_val_if_fail (g_task_is_valid (result, object), FALSE); ++ ++ return_value = g_task_propagate_boolean (G_TASK (result), error); ++ ++ g_object_unref (G_OBJECT (result)); ++ ++ return return_value; ++} +diff --git a/plugins/smartcard/gsd-smartcard-utils.h b/plugins/smartcard/gsd-smartcard-utils.h +new file mode 100644 +index 0000000..c39b076 +--- /dev/null ++++ b/plugins/smartcard/gsd-smartcard-utils.h +@@ -0,0 +1,38 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2013 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++#ifndef __GSD_SMARTCARD_UTILS_H ++#define __GSD_SMARTCARD_UTILS_H ++ ++#include ++#include ++ ++G_BEGIN_DECLS ++void gsd_smartcard_utils_register_error_domain (GQuark error_domain, ++ GType error_enum); ++char * gsd_smartcard_utils_escape_object_path (const char *unescaped_string); ++ ++gboolean gsd_smartcard_utils_finish_boolean_task (GObject *object, ++ GAsyncResult *result, ++ GError **error); ++ ++G_END_DECLS ++ ++#endif /* __GSD_SMARTCARD_MANAGER_H */ +diff --git a/plugins/smartcard/org.gnome.SettingsDaemon.Smartcard.xml b/plugins/smartcard/org.gnome.SettingsDaemon.Smartcard.xml +new file mode 100644 +index 0000000..3daade9 +--- /dev/null ++++ b/plugins/smartcard/org.gnome.SettingsDaemon.Smartcard.xml +@@ -0,0 +1,91 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/smartcard/test-smartcard.c b/plugins/smartcard/test-smartcard.c +new file mode 100644 +index 0000000..b5ee3d5 +--- /dev/null ++++ b/plugins/smartcard/test-smartcard.c +@@ -0,0 +1,7 @@ ++#define NEW gsd_smartcard_manager_new ++#define START gsd_smartcard_manager_start ++#define STOP gsd_smartcard_manager_stop ++#define MANAGER GsdSmartcardManager ++#include "gsd-smartcard-manager.h" ++ ++#include "test-plugin.h" +-- +1.8.3.1 + + +From 7ad29294bcc95806b36bee3639c51901f44f8fc8 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sat, 27 Jul 2013 10:35:55 -0400 +Subject: [PATCH 3/9] Revert "build: Disable smartcard plugin for now" + +This reverts commit e2998b46a9d5eaa9ec2812867efac1eff8b3937f. + +Now that smartcard plugin is freshly revamped we can revert +the commit that disables it. + +https://bugzilla.gnome.org/show_bug.cgi?id=704890 +--- + configure.ac | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d7a9ead..c8a35f0 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -278,64 +278,63 @@ AC_ARG_ENABLE(packagekit, + yes) WANT_PACKAGEKIT=yes ;; + no) WANT_PACKAGEKIT=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-packagekit) ;; + esac], + [WANT_PACKAGEKIT=yes]) dnl Default value + + if test x$WANT_PACKAGEKIT = xyes ; then + PK_REQUIRED_VERSION=0.7.4 + PKG_CHECK_MODULES(PACKAGEKIT, glib-2.0 packagekit-glib2 >= $PK_REQUIRED_VERSION upower-glib >= $UPOWER_REQUIRED_VERSION gudev-1.0 libnotify >= $LIBNOTIFY_REQUIRED_VERSION, + [have_packagekit=true + AC_DEFINE(HAVE_PACKAGEKIT, 1, [Define if PackageKit should be used])], + [have_packagekit=false]) + fi + AM_CONDITIONAL(HAVE_PACKAGEKIT, test "x$have_packagekit" = "xtrue") + + AC_SUBST(PACKAGEKIT_CFLAGS) + AC_SUBST(PACKAGEKIT_LIBS) + + dnl ============================================== + dnl smartcard section + dnl ============================================== + have_smartcard_support=false + AC_ARG_ENABLE(smartcard-support, + AC_HELP_STRING([--disable-smartcard-support], + [turn off smartcard support]), + [case "${enableval}" in + yes) WANT_SMARTCARD_SUPPORT=yes ;; + no) WANT_SMARTCARD_SUPPORT=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-smartcard-support) ;; + esac], +- [WANT_SMARTCARD_SUPPORT=no]) ++ [WANT_SMARTCARD_SUPPORT=yes]) + + if test x$WANT_SMARTCARD_SUPPORT = xyes ; then +- AC_MSG_ERROR(Smartcard support is broken in this version) + NSS_REQUIRED_VERSION=3.11.2 + PKG_CHECK_MODULES(NSS, nss >= $NSS_REQUIRED_VERSION, + [have_smartcard_support=true + AC_DEFINE(SMARTCARD_SUPPORT, 1, [Define if smartcard support should be enabled])], + [have_smartcard_support=false]) + fi + AM_CONDITIONAL(SMARTCARD_SUPPORT, test "x$have_smartcard_support" = "xtrue") + + AC_SUBST(NSS_CFLAGS) + AC_SUBST(NSS_LIBS) + + AC_ARG_WITH(nssdb, + AC_HELP_STRING([--with-nssdb], + [where system NSS database is])) + + NSS_DATABASE="" + if test "x$have_smartcard_support" = "xtrue"; then + if ! test -z "$with_nssdb" ; then + NSS_DATABASE="$with_nssdb" + else + NSS_DATABASE="${sysconfdir}/pki/nssdb" + fi + else + if ! test -z "$with_nssdb" ; then + AC_MSG_WARN([nssdb specified when smartcard support is disabled]) + fi + fi + + AC_SUBST(NSS_DATABASE) + +-- +1.8.3.1 + + +From 667d9edf568556d9e840245ceed1a3723e8d352c Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Sat, 27 Jul 2013 13:46:29 -0400 +Subject: [PATCH 4/9] build: Fix smartcard plugin with srcdir != builddir + +--- + plugins/smartcard/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/smartcard/Makefile.am b/plugins/smartcard/Makefile.am +index 2d27d1c..3ba5abd 100644 +--- a/plugins/smartcard/Makefile.am ++++ b/plugins/smartcard/Makefile.am +@@ -1,49 +1,49 @@ + plugin_name = smartcard + libsmartcard_headers = gsd-smartcard-manager.h \ + gsd-smartcard-utils.h + dbus_built_sources = org.gnome.SettingsDaemon.Smartcard.c org.gnome.SettingsDaemon.Smartcard.h + enum_built_sources = gsd-smartcard-enum-types.h gsd-smartcard-enum-types.c + BUILT_SOURCES = $(dbus_built_sources) $(enum_built_sources) + + libexec_PROGRAMS = gsd-test-smartcard + + plugin_LTLIBRARIES = \ + libsmartcard.la + + $(dbus_built_sources) : Makefile.am org.gnome.SettingsDaemon.Smartcard.xml + $(AM_V_GEN) gdbus-codegen \ + --interface-prefix org.gnome.SettingsDaemon.Smartcard. \ + --c-namespace GsdSmartcardService \ + --c-generate-object-manager \ + --generate-c-code org.gnome.SettingsDaemon.Smartcard \ +- org.gnome.SettingsDaemon.Smartcard.xml ++ $(srcdir)/org.gnome.SettingsDaemon.Smartcard.xml + + gsd-smartcard-enum-types.h: gsd-smartcard-enum-types.h.in $(libsmartcard_headers) + $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ + + gsd-smartcard-enum-types.c: gsd-smartcard-enum-types.c.in $(libsmartcard_headers) + $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ + + gsd_test_smartcard_SOURCES = \ + $(dbus_built_sources) \ + $(enum_built_sources) \ + gsd-smartcard-service.c \ + gsd-smartcard-manager.c \ + gsd-smartcard-utils.c \ + test-smartcard.c + + gsd_test_smartcard_CPPFLAGS = \ + -I$(top_srcdir)/data/ \ + -I$(top_srcdir)/gnome-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + + gsd_test_smartcard_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MEDIA_KEYS_CFLAGS) \ + $(NSS_CFLAGS) \ +-- +1.8.3.1 + + +From bbf3aa7fbc268fff449d4cf0c2f3ee7f9bf791c0 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 28 Jul 2013 23:54:59 -0400 +Subject: [PATCH 5/9] smartcard: fix driver activation notification + +g-s-d fails to notice when it's finished loading all +the smartcard drivers. This is because the code was +waiting for the driver worker threads to finish instead +of to start (and also a fault >= instead > 0 check for +pending drivers) + +The commit fixes that. +--- + plugins/smartcard/gsd-smartcard-manager.c | 40 +++---------------------------- + 1 file changed, 3 insertions(+), 37 deletions(-) + +diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c +index 05f77f8..14c2f71 100644 +--- a/plugins/smartcard/gsd-smartcard-manager.c ++++ b/plugins/smartcard/gsd-smartcard-manager.c +@@ -294,121 +294,90 @@ watch_smartcards_from_driver_async (GsdSmartcardManager *self, + GsdSmartcardManagerPrivate *priv = self->priv; + GTask *task; + WatchSmartcardsOperation *operation; + + operation = g_new0 (WatchSmartcardsOperation, 1); + operation->driver = SECMOD_ReferenceModule (driver); + operation->smartcards = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) PK11_FreeSlot); + + task = g_task_new (self, cancellable, callback, user_data); + + g_task_set_task_data (task, + operation, + (GDestroyNotify) destroy_watch_smartcards_operation); + + G_LOCK (gsd_smartcards_watch_tasks); + priv->smartcards_watch_tasks = g_list_prepend (priv->smartcards_watch_tasks, + task); + g_object_weak_ref (G_OBJECT (task), + (GWeakNotify) on_smartcards_watch_task_destroyed, + self); + G_UNLOCK (gsd_smartcards_watch_tasks); + + g_task_run_in_thread (task, (GTaskThreadFunc) watch_smartcards_from_driver); + + g_object_unref (task); + } + +-typedef struct +-{ +- guint driver_registered : 1; +- guint smartcards_watched : 1; +-} ActivateDriverOperation; +- +-static void +-try_to_complete_driver_activation (GTask *task) +-{ +- ActivateDriverOperation *operation; +- +- operation = g_task_get_task_data (task); +- +- if (!operation->driver_registered) +- return; +- +- if (!operation->smartcards_watched) +- return; +- +- g_task_return_boolean (task, TRUE); +-} +- + static gboolean + register_driver_finish (GsdSmartcardManager *self, + GAsyncResult *result, + GError **error) + { + return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); + } + + static void + on_driver_registered (GsdSmartcardManager *self, + GAsyncResult *result, + GTask *task) + { +- ActivateDriverOperation *operation; + GError *error = NULL; + + if (!register_driver_finish (self, result, &error)) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + +- operation = g_task_get_task_data (task); +- operation->driver_registered = TRUE; +- +- try_to_complete_driver_activation (task); ++ g_task_return_boolean (task, TRUE); + } + + static void + on_smartcards_from_driver_watched (GsdSmartcardManager *self, + GAsyncResult *result, + GTask *task) + { +- ActivateDriverOperation *operation; +- +- operation = g_task_get_task_data (task); +- operation->smartcards_watched = TRUE; +- +- try_to_complete_driver_activation (task); ++ g_debug ("Done watching smartcards from driver"); + } + + typedef struct { + SECMODModule *driver; + guint idle_id; + GError *error; + } DriverRegistrationOperation; + + static void + destroy_driver_registration_operation (DriverRegistrationOperation *operation) + { + SECMOD_DestroyModule (operation->driver); + g_free (operation); + } + + static gboolean + on_task_thread_to_complete_driver_registration (GTask *task) + { + DriverRegistrationOperation *operation; + operation = g_task_get_task_data (task); + + if (operation->error != NULL) + g_task_return_error (task, operation->error); + else + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; + } + + static gboolean +@@ -435,103 +404,100 @@ on_main_thread_to_register_driver (GTask *task) + return G_SOURCE_REMOVE; + } + + static void + register_driver (GsdSmartcardManager *self, + SECMODModule *driver, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) + { + GTask *task; + DriverRegistrationOperation *operation; + + task = g_task_new (self, cancellable, callback, user_data); + operation = g_new0 (DriverRegistrationOperation, 1); + operation->driver = SECMOD_ReferenceModule (driver); + g_task_set_task_data (task, + operation, + (GDestroyNotify) destroy_driver_registration_operation); + + operation->idle_id = g_idle_add ((GSourceFunc) on_main_thread_to_register_driver, task); + } + + static void + activate_driver (GsdSmartcardManager *self, + SECMODModule *driver, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) + { +- ActivateDriverOperation *operation; + GTask *task; + + g_debug ("Activating driver '%s'", driver->commonName); + + task = g_task_new (self, cancellable, callback, user_data); +- operation = g_new0 (ActivateDriverOperation, 1); +- g_task_set_task_data (task, operation, (GDestroyNotify) g_free); + + register_driver (self, + driver, + cancellable, + (GAsyncReadyCallback) on_driver_registered, + task); + watch_smartcards_from_driver_async (self, + driver, + cancellable, + (GAsyncReadyCallback) on_smartcards_from_driver_watched, + task); + } + + typedef struct + { + int pending_drivers_count; + int activated_drivers_count; + } ActivateAllDriversOperation; + + static gboolean + activate_driver_async_finish (GsdSmartcardManager *self, + GAsyncResult *result, + GError **error) + { + return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); + } + + static void + try_to_complete_all_drivers_activation (GTask *task) + { + ActivateAllDriversOperation *operation; + + operation = g_task_get_task_data (task); + +- if (operation->pending_drivers_count >= 0) ++ if (operation->pending_drivers_count > 0) + return; + + if (operation->activated_drivers_count > 0) + g_task_return_boolean (task, TRUE); + else + g_task_return_boolean (task, FALSE); + + g_object_unref (task); + } + + static void + on_driver_activated (GsdSmartcardManager *self, + GAsyncResult *result, + GTask *task) + { + GError *error = NULL; + gboolean driver_activated; + ActivateAllDriversOperation *operation; + + driver_activated = activate_driver_async_finish (self, result, &error); + + operation = g_task_get_task_data (task); + + if (driver_activated) + operation->activated_drivers_count++; + + operation->pending_drivers_count--; + + try_to_complete_all_drivers_activation (task); + } +-- +1.8.3.1 + + +From 94f03e52bd1863d16e1df9a4a5634235f7532dff Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 28 Jul 2013 22:19:18 -0400 +Subject: [PATCH 6/9] smartcard: add screensaver proxy + +We're going to need to be able to lock the screen in some +cases when a user removes their smartcard. + +This commit adds the goo needed to get access to the lock +screen. +--- + plugins/smartcard/Makefile.am | 14 ++++++++- + plugins/smartcard/org.gnome.ScreenSaver.xml | 45 +++++++++++++++++++++++++++++ + 2 files changed, 58 insertions(+), 1 deletion(-) + create mode 100644 plugins/smartcard/org.gnome.ScreenSaver.xml + +diff --git a/plugins/smartcard/Makefile.am b/plugins/smartcard/Makefile.am +index 3ba5abd..62f85e7 100644 +--- a/plugins/smartcard/Makefile.am ++++ b/plugins/smartcard/Makefile.am +@@ -1,92 +1,104 @@ + plugin_name = smartcard + libsmartcard_headers = gsd-smartcard-manager.h \ + gsd-smartcard-utils.h + dbus_built_sources = org.gnome.SettingsDaemon.Smartcard.c org.gnome.SettingsDaemon.Smartcard.h ++screensaver_dbus_built_sources = org.gnome.ScreenSaver.c org.gnome.ScreenSaver.h + enum_built_sources = gsd-smartcard-enum-types.h gsd-smartcard-enum-types.c +-BUILT_SOURCES = $(dbus_built_sources) $(enum_built_sources) ++BUILT_SOURCES = $(dbus_built_sources) $(screensaver_dbus_built_sources) $(enum_built_sourcs) + + libexec_PROGRAMS = gsd-test-smartcard + + plugin_LTLIBRARIES = \ + libsmartcard.la + + $(dbus_built_sources) : Makefile.am org.gnome.SettingsDaemon.Smartcard.xml + $(AM_V_GEN) gdbus-codegen \ + --interface-prefix org.gnome.SettingsDaemon.Smartcard. \ + --c-namespace GsdSmartcardService \ + --c-generate-object-manager \ + --generate-c-code org.gnome.SettingsDaemon.Smartcard \ + $(srcdir)/org.gnome.SettingsDaemon.Smartcard.xml + ++$(screensaver_dbus_built_sources) : Makefile.am org.gnome.ScreenSaver.xml ++ gdbus-codegen \ ++ --interface-prefix org.gnome.ScreenSaver. \ ++ --generate-c-code org.gnome.ScreenSaver \ ++ --c-namespace Gsd \ ++ --annotate "org.gnome.ScreenSaver" \ ++ "org.gtk.GDBus.C.Name" ScreenSaver \ ++ $(srcdir)/org.gnome.ScreenSaver.xml ++ + gsd-smartcard-enum-types.h: gsd-smartcard-enum-types.h.in $(libsmartcard_headers) + $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ + + gsd-smartcard-enum-types.c: gsd-smartcard-enum-types.c.in $(libsmartcard_headers) + $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ + + gsd_test_smartcard_SOURCES = \ + $(dbus_built_sources) \ ++ $(screensaver_dbus_built_sources) \ + $(enum_built_sources) \ + gsd-smartcard-service.c \ + gsd-smartcard-manager.c \ + gsd-smartcard-utils.c \ + test-smartcard.c + + gsd_test_smartcard_CPPFLAGS = \ + -I$(top_srcdir)/data/ \ + -I$(top_srcdir)/gnome-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + + gsd_test_smartcard_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MEDIA_KEYS_CFLAGS) \ + $(NSS_CFLAGS) \ + $(AM_CFLAGS) + + gsd_test_smartcard_LDADD = \ + $(top_builddir)/gnome-settings-daemon/libgsd.la \ + $(top_builddir)/plugins/common/libcommon.la \ + $(NSS_LIBS) \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) + + + libsmartcard_la_SOURCES = \ + $(libsmartcard_headers) \ + $(dbus_built_sources) \ ++ $(screensaver_dbus_built_sources) \ + $(enum_built_sources) \ + gsd-smartcard-manager.c \ + gsd-smartcard-plugin.c \ + gsd-smartcard-service.c \ + gsd-smartcard-utils.c + + libsmartcard_la_CPPFLAGS = \ + -I$(top_srcdir)/gnome-settings-daemon \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -I$(top_srcdir)/plugins/common \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + + libsmartcard_la_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(NSS_CFLAGS) \ + $(AM_CFLAGS) + + libsmartcard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + + libsmartcard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NSS_LIBS) + + @GSD_INTLTOOL_PLUGIN_RULE@ + +diff --git a/plugins/smartcard/org.gnome.ScreenSaver.xml b/plugins/smartcard/org.gnome.ScreenSaver.xml +new file mode 100644 +index 0000000..7a6cf86 +--- /dev/null ++++ b/plugins/smartcard/org.gnome.ScreenSaver.xml +@@ -0,0 +1,45 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + + +From 6ac958091b6f2742bcc504f29b716028fe0cb37b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 28 Jul 2013 22:19:18 -0400 +Subject: [PATCH 7/9] smartcard: add session manager proxy + +We're going to need to be able to log the user out in some +cases when they remove their smartcard. + +This commit adds the makefile goo and the xml file stolen from +gnome-session source tree to get access to the session +manager to log out. +--- + plugins/smartcard/Makefile.am | 14 +- + plugins/smartcard/org.gnome.SessionManager.xml | 451 +++++++++++++++++++++++++ + 2 files changed, 464 insertions(+), 1 deletion(-) + create mode 100644 plugins/smartcard/org.gnome.SessionManager.xml + +diff --git a/plugins/smartcard/Makefile.am b/plugins/smartcard/Makefile.am +index 62f85e7..098bb47 100644 +--- a/plugins/smartcard/Makefile.am ++++ b/plugins/smartcard/Makefile.am +@@ -1,104 +1,116 @@ + plugin_name = smartcard + libsmartcard_headers = gsd-smartcard-manager.h \ + gsd-smartcard-utils.h + dbus_built_sources = org.gnome.SettingsDaemon.Smartcard.c org.gnome.SettingsDaemon.Smartcard.h + screensaver_dbus_built_sources = org.gnome.ScreenSaver.c org.gnome.ScreenSaver.h ++session_manager_dbus_built_sources = org.gnome.SessionManager.c org.gnome.SessionManager.h + enum_built_sources = gsd-smartcard-enum-types.h gsd-smartcard-enum-types.c +-BUILT_SOURCES = $(dbus_built_sources) $(screensaver_dbus_built_sources) $(enum_built_sourcs) ++BUILT_SOURCES = $(dbus_built_sources) $(screensaver_dbus_built_sources) $(session_manager_dbus_built_sources) $(enum_built_sources) + + libexec_PROGRAMS = gsd-test-smartcard + + plugin_LTLIBRARIES = \ + libsmartcard.la + + $(dbus_built_sources) : Makefile.am org.gnome.SettingsDaemon.Smartcard.xml + $(AM_V_GEN) gdbus-codegen \ + --interface-prefix org.gnome.SettingsDaemon.Smartcard. \ + --c-namespace GsdSmartcardService \ + --c-generate-object-manager \ + --generate-c-code org.gnome.SettingsDaemon.Smartcard \ + $(srcdir)/org.gnome.SettingsDaemon.Smartcard.xml + + $(screensaver_dbus_built_sources) : Makefile.am org.gnome.ScreenSaver.xml + gdbus-codegen \ + --interface-prefix org.gnome.ScreenSaver. \ + --generate-c-code org.gnome.ScreenSaver \ + --c-namespace Gsd \ + --annotate "org.gnome.ScreenSaver" \ + "org.gtk.GDBus.C.Name" ScreenSaver \ + $(srcdir)/org.gnome.ScreenSaver.xml + ++$(session_manager_dbus_built_sources) : Makefile.am org.gnome.SessionManager.xml ++ gdbus-codegen \ ++ --interface-prefix org.gnome.SessionManager. \ ++ --generate-c-code org.gnome.SessionManager \ ++ --c-namespace Gsd \ ++ --annotate "org.gnome.SessionManager" \ ++ "org.gtk.GDBus.C.Name" SessionManager \ ++ $(srcdir)/org.gnome.SessionManager.xml ++ + gsd-smartcard-enum-types.h: gsd-smartcard-enum-types.h.in $(libsmartcard_headers) + $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ + + gsd-smartcard-enum-types.c: gsd-smartcard-enum-types.c.in $(libsmartcard_headers) + $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@ + + gsd_test_smartcard_SOURCES = \ + $(dbus_built_sources) \ + $(screensaver_dbus_built_sources) \ ++ $(session_manager_dbus_built_sources) \ + $(enum_built_sources) \ + gsd-smartcard-service.c \ + gsd-smartcard-manager.c \ + gsd-smartcard-utils.c \ + test-smartcard.c + + gsd_test_smartcard_CPPFLAGS = \ + -I$(top_srcdir)/data/ \ + -I$(top_srcdir)/gnome-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + + gsd_test_smartcard_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MEDIA_KEYS_CFLAGS) \ + $(NSS_CFLAGS) \ + $(AM_CFLAGS) + + gsd_test_smartcard_LDADD = \ + $(top_builddir)/gnome-settings-daemon/libgsd.la \ + $(top_builddir)/plugins/common/libcommon.la \ + $(NSS_LIBS) \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) + + + libsmartcard_la_SOURCES = \ + $(libsmartcard_headers) \ + $(dbus_built_sources) \ + $(screensaver_dbus_built_sources) \ ++ $(session_manager_dbus_built_sources) \ + $(enum_built_sources) \ + gsd-smartcard-manager.c \ + gsd-smartcard-plugin.c \ + gsd-smartcard-service.c \ + gsd-smartcard-utils.c + + libsmartcard_la_CPPFLAGS = \ + -I$(top_srcdir)/gnome-settings-daemon \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -I$(top_srcdir)/plugins/common \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + + libsmartcard_la_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(NSS_CFLAGS) \ + $(AM_CFLAGS) + + libsmartcard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + + libsmartcard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NSS_LIBS) + + @GSD_INTLTOOL_PLUGIN_RULE@ + +diff --git a/plugins/smartcard/org.gnome.SessionManager.xml b/plugins/smartcard/org.gnome.SessionManager.xml +new file mode 100644 +index 0000000..eb69180 +--- /dev/null ++++ b/plugins/smartcard/org.gnome.SessionManager.xml +@@ -0,0 +1,451 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The variable name ++ ++ ++ ++ ++ The value ++ ++ ++ ++ ++ Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase. ++ ++ ++ ++ ++ ++ ++ ++ The locale category ++ ++ ++ ++ ++ The value ++ ++ ++ ++ ++ Reads the current state of the specific locale category. ++ ++ ++ ++ ++ ++ ++ ++ The error message ++ ++ ++ ++ ++ Whether the error should be treated as fatal ++ ++ ++ ++ ++ May be used by applications launched during the Session Manager initialization phase to indicate there was a problem. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The application identifier ++ ++ ++ ++ ++ Client startup identifier ++ ++ ++ ++ ++ The object path of the newly registered client ++ ++ ++ ++ ++ Register the caller as a Session Management client. ++ ++ ++ ++ ++ ++ ++ ++ ++ The object path of the client ++ ++ ++ ++ ++ Unregister the specified client from Session Management. ++ ++ ++ ++ ++ ++ ++ ++ ++ The application identifier ++ ++ ++ ++ ++ The toplevel X window identifier ++ ++ ++ ++ ++ The reason for the inhibit ++ ++ ++ ++ ++ Flags that specify what should be inhibited ++ ++ ++ ++ ++ The cookie ++ ++ ++ ++ ++ Proactively indicates that the calling application is performing an action that should not be interrupted and sets a reason to be displayed to the user when an interruption is about to take placea. ++ ++ ++ Applications should invoke this method when they begin an operation that ++ should not be interrupted, such as creating a CD or DVD. The types of actions ++ that may be blocked are specified by the flags parameter. When the application ++ completes the operation it should call Uninhibit() ++ or disconnect from the session bus. ++ ++ ++ Applications should not expect that they will always be able to block the ++ action. In most cases, users will be given the option to force the action ++ to take place. ++ ++ ++ Reasons should be short and to the point. ++ ++ ++ The flags parameter must include at least one of the following: ++ ++ ++ 1 ++ Inhibit logging out ++ ++ ++ 2 ++ Inhibit user switching ++ ++ ++ 4 ++ Inhibit suspending the session or computer ++ ++ ++ 8 ++ Inhibit the session being marked as idle ++ ++ ++ 16 ++ Inhibit auto-mounting removable media for the session ++ ++ ++ Values for flags may be bitwise or'ed together. ++ ++ ++ The returned cookie is used to uniquely identify this request. It should be used ++ as an argument to Uninhibit() in ++ order to remove the request. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The cookie ++ ++ ++ ++ ++ Cancel a previous call to Inhibit() identified by the cookie. ++ ++ ++ ++ ++ ++ ++ ++ Flags that spefify what should be inhibited ++ ++ ++ ++ ++ Returns TRUE if any of the operations in the bitfield flags are inhibited ++ ++ ++ ++ ++ Determine if operation(s) specified by the flags ++ are currently inhibited. Flags are same as those accepted ++ by the ++ Inhibit() ++ method. ++ ++ ++ ++ ++ ++ ++ ++ an array of client IDs ++ ++ ++ ++ ++ This gets a list of all the Clients ++ that are currently known to the session manager. ++ Each Client ID is an D-Bus object path for the object that implements the ++ Client interface. ++ ++ org.gnome.SessionManager.Client ++ ++ ++ ++ ++ ++ ++ an array of inhibitor IDs ++ ++ ++ ++ ++ This gets a list of all the Inhibitors ++ that are currently known to the session manager. ++ Each Inhibitor ID is an D-Bus object path for the object that implements the ++ Inhibitor interface. ++ ++ org.gnome.SessionManager.Inhibitor ++ ++ ++ ++ ++ ++ ++ ++ The autostart condition string ++ ++ ++ ++ ++ True if condition is handled, false otherwise ++ ++ ++ ++ ++ Allows the caller to determine whether the session manager is ++ handling changes to the specified autostart condition. ++ ++ ++ ++ ++ ++ ++ ++ Request a shutdown dialog. ++ ++ ++ ++ ++ ++ ++ ++ Request a reboot dialog. ++ ++ ++ ++ ++ ++ ++ ++ True if shutdown is available to the user, false otherwise ++ ++ ++ ++ ++ Allows the caller to determine whether or not it's okay to show ++ a shutdown option in the UI ++ ++ ++ ++ ++ ++ ++ ++ The type of logout that is being requested ++ ++ ++ ++ ++ Request a logout dialog ++ ++ Allowed values for the mode parameter are: ++ ++ ++ 0 ++ Normal. ++ ++ ++ 1 ++ No confirmation inferface should be shown. ++ ++ ++ 2 ++ Forcefully logout. No confirmation will be shown and any inhibitors will be ignored. ++ ++ ++ Values for flags may be bitwise or'ed together. ++ ++ ++ ++ ++ ++ ++ ++ ++ True if the session has entered the Running phase, false otherwise ++ ++ ++ ++ ++ Allows the caller to determine whether the session manager ++ has entered the Running phase, in case the client missed the ++ SessionRunning signal. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The object path for the added client ++ ++ ++ ++ ++ Emitted when a client has been added to the session manager. ++ ++ ++ ++ ++ ++ ++ ++ The object path for the removed client ++ ++ ++ ++ ++ Emitted when a client has been removed from the session manager. ++ ++ ++ ++ ++ ++ ++ ++ ++ The object path for the added inhibitor ++ ++ ++ ++ ++ Emitted when an inhibitor has been added to the session manager. ++ ++ ++ ++ ++ ++ ++ ++ The object path for the removed inhibitor ++ ++ ++ ++ ++ Emitted when an inhibitor has been removed from the session manager. ++ ++ ++ ++ ++ ++ ++ ++ ++ Indicates the session has entered the Running phase. ++ ++ ++ ++ ++ ++ ++ ++ Indicates the session is about to end. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The name of the session that has been loaded. ++ ++ ++ ++ ++ ++ ++ ++ If true, the session is currently in the ++ foreground and available for user input. ++ ++ ++ ++ ++ ++ ++ ++ A bitmask of flags to indicate which actions ++ are inhibited. See the Inhibit() function's description ++ for a list of possible values. ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + + +From 69d86f2acb2a5cd632fc2c6b4e6beff431e06846 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 29 Jul 2013 00:02:04 -0400 +Subject: [PATCH 8/9] 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. +--- + plugins/smartcard/gsd-smartcard-manager.c | 170 +++++++++++++++++++++++++++++- + plugins/smartcard/gsd-smartcard-manager.h | 1 + + plugins/smartcard/gsd-smartcard-service.c | 11 ++ + 3 files changed, 181 insertions(+), 1 deletion(-) + +diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c +index 14c2f71..4ac31ae 100644 +--- a/plugins/smartcard/gsd-smartcard-manager.c ++++ b/plugins/smartcard/gsd-smartcard-manager.c +@@ -4,86 +4,97 @@ + * Copyright (C) 2010,2011 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + #include "config.h" + + #include + #include + + #include "gnome-settings-plugin.h" + #include "gnome-settings-profile.h" + #include "gsd-smartcard-manager.h" + #include "gsd-smartcard-service.h" + #include "gsd-smartcard-enum-types.h" + #include "gsd-smartcard-utils.h" + ++#include "org.gnome.ScreenSaver.h" ++#include "org.gnome.SessionManager.h" ++ + #include + #include + #include + #include + #include + #include + + #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; + GsdSmartcardService *service; + 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); + + static gpointer manager_object = NULL; + + static void + gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gsd_smartcard_manager_finalize; + + gsd_smartcard_utils_register_error_domain (GSD_SMARTCARD_MANAGER_ERROR, + GSD_TYPE_SMARTCARD_MANAGER_ERROR); + g_type_class_add_private (klass, sizeof (GsdSmartcardManagerPrivate)); + } + + static void + gsd_smartcard_manager_init (GsdSmartcardManager *self) + { + self->priv = GSD_SMARTCARD_MANAGER_GET_PRIVATE (self); + } + + static void + load_nss (GsdSmartcardManager *self) + { + GsdSmartcardManagerPrivate *priv = self->priv; + SECStatus status = SECSuccess; + static const guint32 flags = NSS_INIT_READONLY +@@ -194,61 +205,60 @@ watch_one_event_from_driver (GsdSmartcardManager *self, + + old_card = g_hash_table_lookup (operation->smartcards, GINT_TO_POINTER ((int) slot_id)); + + /* If there is a different card in the slot now than + * there was before, then we need to emit a removed signal + * for the old card + */ + if (old_card != NULL) { + old_slot_series = PK11_GetSlotSeries (old_card); + + if (old_slot_series != slot_series) { + /* Card registered with slot previously is + * different than this card, so update its + * exported state to track the implicit missed + * removal + */ + gsd_smartcard_service_sync_token (priv->service, old_card, cancellable); + } + + g_hash_table_remove (operation->smartcards, GINT_TO_POINTER ((int) slot_id)); + } + + if (PK11_IsPresent (card)) { + g_debug ("Detected smartcard insertion event in slot %d", (int) slot_id); + + g_hash_table_replace (operation->smartcards, + GINT_TO_POINTER ((int) slot_id), + 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 + * event for slots that are empty at startup + */ + g_debug ("Detected slot %d is empty in reader", (int) slot_id); + } else { + g_debug ("Detected smartcard removal event in slot %d", (int) slot_id); + + /* If the just removed smartcard is known to us then + * we need to update its exported state to reflect the + * removal + */ + if (old_slot_series == slot_series) + gsd_smartcard_service_sync_token (priv->service, card, cancellable); + } + + PK11_FreeSlot (card); + + return TRUE; + } + + static void + watch_smartcards_from_driver (GTask *task, + GsdSmartcardManager *self, + WatchSmartcardsOperation *operation, + GCancellable *cancellable) + { + g_debug ("watching for smartcard events"); + while (!g_cancellable_is_cancelled (cancellable)) { +@@ -529,68 +539,79 @@ activate_all_drivers_async (GsdSmartcardManager *self, + + if (!SECMOD_HasRemovableSlots (node->module)) + continue; + + operation->pending_drivers_count++; + + activate_driver (self, node->module, + cancellable, + (GAsyncReadyCallback) on_driver_activated, + task); + + } + SECMOD_ReleaseReadLock (lock); + } + + static gboolean + activate_all_drivers_async_finish (GsdSmartcardManager *self, + GAsyncResult *result, + GError **error) + { + return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); + } + + static void + on_all_drivers_activated (GsdSmartcardManager *self, + GAsyncResult *result, + GTask *task) + { + GError *error = NULL; + gboolean driver_activated; ++ PK11SlotInfo *login_token; + + driver_activated = activate_all_drivers_async_finish (self, result, &error); + + if (!driver_activated) { + g_task_return_error (task, error); + 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); + } + + static void + watch_smartcards (GTask *task, + GsdSmartcardManager *self, + gpointer data, + GCancellable *cancellable) + { + GMainContext *context; + GMainLoop *loop; + + g_debug ("Getting list of suitable drivers"); + context = g_main_context_new (); + g_main_context_push_thread_default (context); + + activate_all_drivers_async (self, + cancellable, + (GAsyncReadyCallback) on_all_drivers_activated, + task); + + loop = g_main_loop_new (context, FALSE); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + } + + static void +@@ -676,60 +697,207 @@ gsd_smartcard_manager_idle_cb (GsdSmartcardManager *self) + priv->start_idle_id = 0; + return FALSE; + } + + gboolean + gsd_smartcard_manager_start (GsdSmartcardManager *self, + GError **error) + { + GsdSmartcardManagerPrivate *priv = self->priv; + + gnome_settings_profile_start (NULL); + + priv->start_idle_id = g_idle_add ((GSourceFunc) gsd_smartcard_manager_idle_cb, self); + + gnome_settings_profile_end (NULL); + + return TRUE; + } + + void + gsd_smartcard_manager_stop (GsdSmartcardManager *self) + { + GsdSmartcardManagerPrivate *priv = self->priv; + + g_debug ("Stopping smartcard manager"); + + unload_nss (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 * + get_login_token_for_operation (GsdSmartcardManager *self, + WatchSmartcardsOperation *operation) + { + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, operation->smartcards); + while (g_hash_table_iter_next (&iter, &key, &value)) { + PK11SlotInfo *card_slot; + const char *token_name; + + card_slot = (PK11SlotInfo *) value; + token_name = PK11_GetTokenName (card_slot); + + if (g_strcmp0 (g_getenv ("PKCS11_LOGIN_TOKEN_NAME"), token_name) == 0) + return card_slot; + } + + return NULL; + } + + PK11SlotInfo * + gsd_smartcard_manager_get_login_token (GsdSmartcardManager *self) + { + GsdSmartcardManagerPrivate *priv = self->priv; + GList *node; + +diff --git a/plugins/smartcard/gsd-smartcard-manager.h b/plugins/smartcard/gsd-smartcard-manager.h +index 9d3a2ce..7876fc1 100644 +--- a/plugins/smartcard/gsd-smartcard-manager.h ++++ b/plugins/smartcard/gsd-smartcard-manager.h +@@ -49,34 +49,35 @@ typedef struct + GsdSmartcardManagerPrivate *priv; + } GsdSmartcardManager; + + typedef struct + { + GObjectClass parent_class; + } GsdSmartcardManagerClass; + + typedef enum + { + GSD_SMARTCARD_MANAGER_ERROR_GENERIC = 0, + GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, + GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, + GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, + GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, + GSD_SMARTCARD_MANAGER_ERROR_FINDING_SMARTCARD + } GsdSmartcardManagerError; + + GType gsd_smartcard_manager_get_type (void); + GQuark gsd_smartcard_manager_error_quark (void); + + + GsdSmartcardManager * gsd_smartcard_manager_new (void); + gboolean gsd_smartcard_manager_start (GsdSmartcardManager *manager, + GError **error); + void gsd_smartcard_manager_stop (GsdSmartcardManager *manager); + + 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 + + #endif /* __GSD_SMARTCARD_MANAGER_H */ +diff --git a/plugins/smartcard/gsd-smartcard-service.c b/plugins/smartcard/gsd-smartcard-service.c +index 40350d0..cc20f4c 100644 +--- a/plugins/smartcard/gsd-smartcard-service.c ++++ b/plugins/smartcard/gsd-smartcard-service.c +@@ -478,60 +478,71 @@ synchronize_token_now (GsdSmartcardService *self, + { + GsdSmartcardServicePrivate *priv = self->priv; + GDBusInterfaceSkeleton *interface; + char *object_path; + const char *token_name; + gboolean is_present, is_login_card; + + object_path = get_object_path_for_token (self, card_slot); + + G_LOCK (gsd_smartcard_tokens); + interface = g_hash_table_lookup (priv->tokens, object_path); + g_free (object_path); + + if (interface == NULL) + goto out; + + token_name = PK11_GetTokenName (card_slot); + is_present = PK11_IsPresent (card_slot); + + if (g_strcmp0 (g_getenv ("PKCS11_LOGIN_TOKEN_NAME"), token_name) == 0) + is_login_card = TRUE; + else + is_login_card = FALSE; + + g_debug ("==============================="); + g_debug (" Token '%s'", token_name); + g_debug (" Inserted: %s", is_present? "yes" : "no"); + 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, + NULL); + g_object_get (G_OBJECT (interface), + "used-to-login", &is_login_card, + "is-inserted", &is_present, + NULL); + + out: + G_UNLOCK (gsd_smartcard_tokens); + } + + typedef struct + { + PK11SlotInfo *card_slot; + char *object_path; + GSource *main_thread_source; + } RegisterNewTokenOperation; + + static void + destroy_register_new_token_operation (RegisterNewTokenOperation *operation) + { + g_clear_pointer (&operation->main_thread_source, + (GDestroyNotify) g_source_destroy); + PK11_FreeSlot (operation->card_slot); + g_free (operation->object_path); + g_free (operation); + } + +-- +1.8.3.1 + + +From 73526df53a92aa2829e7043f7dec0e51cf7b0dee Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 22 Aug 2013 17:52:35 -0400 +Subject: [PATCH 9/9] smartcard: ignore softtoken + +For some reason that I haven't fully fleshed out, sometimes +the soft token gets into the "will load list" and then havoc +ensues. + +This commit fixes that by explicitly ignoring built-in modules. + +https://bugzilla.gnome.org/show_bug.cgi?id=706620 +--- + plugins/smartcard/gsd-smartcard-manager.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c +index 4ac31ae..eb22cb2 100644 +--- a/plugins/smartcard/gsd-smartcard-manager.c ++++ b/plugins/smartcard/gsd-smartcard-manager.c +@@ -513,60 +513,63 @@ on_driver_activated (GsdSmartcardManager *self, + } + + static void + activate_all_drivers_async (GsdSmartcardManager *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) + { + GTask *task; + SECMODListLock *lock; + SECMODModuleList *driver_list, *node; + ActivateAllDriversOperation *operation; + + task = g_task_new (self, cancellable, callback, user_data); + operation = g_new0 (ActivateAllDriversOperation, 1); + g_task_set_task_data (task, operation, (GDestroyNotify) g_free); + + lock = SECMOD_GetDefaultModuleListLock (); + + g_assert (lock != NULL); + + SECMOD_GetReadLock (lock); + driver_list = SECMOD_GetDefaultModuleList (); + for (node = driver_list; node != NULL; node = node->next) { + if (!node->module->loaded) + continue; + + if (!SECMOD_HasRemovableSlots (node->module)) + continue; + ++ if (node->module->dllName == NULL) ++ continue; ++ + operation->pending_drivers_count++; + + activate_driver (self, node->module, + cancellable, + (GAsyncReadyCallback) on_driver_activated, + task); + + } + SECMOD_ReleaseReadLock (lock); + } + + static gboolean + activate_all_drivers_async_finish (GsdSmartcardManager *self, + GAsyncResult *result, + GError **error) + { + return gsd_smartcard_utils_finish_boolean_task (G_OBJECT (self), result, error); + } + + static void + on_all_drivers_activated (GsdSmartcardManager *self, + GAsyncResult *result, + GTask *task) + { + GError *error = NULL; + gboolean driver_activated; + PK11SlotInfo *login_token; + + driver_activated = activate_all_drivers_async_finish (self, result, &error); + +-- +1.8.3.1 + diff --git a/SPECS/gnome-settings-daemon.spec b/SPECS/gnome-settings-daemon.spec new file mode 100644 index 0000000..9403322 --- /dev/null +++ b/SPECS/gnome-settings-daemon.spec @@ -0,0 +1,1123 @@ +Name: gnome-settings-daemon +Version: 3.8.6.1 +Release: 2%{?dist} +Summary: The daemon sharing settings from GNOME to GTK+/KDE applications + +Group: System Environment/Daemons +License: GPLv2+ +URL: http://download.gnome.org/sources/%{name} +#VCS: git:git://git.gnome.org/gnome-settings-daemon +Source: http://download.gnome.org/sources/%{name}/3.8/%{name}-%{version}.tar.xz +# disable wacom for ppc/ppc64 (used on RHEL) +Patch0: %{name}-3.5.4-ppc-no-wacom.patch +# g-i-s takes this role now +Patch1: 0001-keyboard-Stop-adding-locale-based-input-sources-from.patch +# backport of smartcard support from gnome 3.9 +Patch2: smartcard-support.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=980692 +Patch3: 0001-media-keys-Merge-power_action_-functions.patch +Patch4: 0002-media-keys-Make-the-shutdown-action-not-be-interacti.patch +Patch5: 0003-media-keys-Allow-the-power-key-in-more-places.patch + +Requires: control-center-filesystem +Requires: colord + +BuildRequires: dbus-glib-devel +BuildRequires: gtk3-devel >= 3.7.8 +BuildRequires: gnome-desktop3-devel >= 3.1.4 +BuildRequires: xorg-x11-proto-devel libXxf86misc-devel +BuildRequires: pulseaudio-libs-devel +BuildRequires: libgnomekbd-devel +BuildRequires: libnotify-devel +BuildRequires: gettext intltool +BuildRequires: fontconfig-devel +BuildRequires: libcanberra-devel +BuildRequires: polkit-devel +BuildRequires: autoconf automake libtool +BuildRequires: libxklavier-devel +BuildRequires: gsettings-desktop-schemas-devel >= 0.1.7 +BuildRequires: PackageKit-glib-devel +BuildRequires: cups-devel +BuildRequires: upower-devel +BuildRequires: libgudev1-devel +BuildRequires: librsvg2-devel +BuildRequires: nss-devel +BuildRequires: colord-devel >= 0.1.12 +BuildRequires: lcms2-devel >= 2.2 +BuildRequires: libXi-devel libXfixes-devel +BuildRequires: systemd-devel +BuildRequires: libXtst-devel +BuildRequires: libxkbfile-devel +BuildRequires: ibus-devel +BuildRequires: libxslt +BuildRequires: docbook-style-xsl +%ifnarch s390 s390x %{?rhel:ppc ppc64} +BuildRequires: libwacom-devel >= 0.7 +BuildRequires: xorg-x11-drv-wacom-devel +%endif + +%description +A daemon to share settings from GNOME to other applications. It also +handles global keybindings, as well as a number of desktop-wide settings. + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: dbus-glib-devel + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + +%package updates +Summary: updates plugin for %{name} +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description updates +The %{name}-updates package contains the updates plugin for %{name} + +%prep +%setup -q +%if 0%{?rhel} +%patch0 -p1 -b .ppc-no-wacom +%endif +%patch1 -p1 -b .stop-adding-input-sources +%patch2 -p1 -b .smartcard +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 + +autoreconf -i -f + +%build +%configure --disable-static \ + --enable-profiling \ + --enable-packagekit \ + --enable-systemd +make %{?_smp_mflags} + + +%install +make install DESTDIR=$RPM_BUILD_ROOT +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + +%find_lang %{name} --with-gnome + +mkdir $RPM_BUILD_ROOT%{_libdir}/gnome-settings-daemon-3.0/gtk-modules + +%post +touch --no-create %{_datadir}/icons/hicolor >&/dev/null || : + +%postun +if [ $1 -eq 0 ]; then + touch --no-create %{_datadir}/icons/hicolor >&/dev/null || : + gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : + glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : +fi + +%posttrans +gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : +glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : + +%postun updates +if [ $1 -eq 0 ]; then + glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : +fi + +%posttrans updates +glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : + +%files -f %{name}.lang +%doc AUTHORS COPYING NEWS +%dir %{_sysconfdir}/gnome-settings-daemon +%dir %{_sysconfdir}/gnome-settings-daemon/xrandr + +# list plugins explicitly, so we notice if one goes missing +# some of these don't have a separate gschema +%{_libdir}/gnome-settings-daemon-3.0/a11y-keyboard.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/liba11y-keyboard.so + +%{_libdir}/gnome-settings-daemon-3.0/clipboard.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libclipboard.so + +%{_libdir}/gnome-settings-daemon-3.0/housekeeping.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libhousekeeping.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/keyboard.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libkeyboard.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.keyboard.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/media-keys.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libmedia-keys.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.media-keys.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/mouse.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libmouse.so + +%{_libexecdir}/gsd-backlight-helper +%{_datadir}/polkit-1/actions/org.gnome.settings-daemon.plugins.power.policy +%{_libdir}/gnome-settings-daemon-3.0/power.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libpower.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.power.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/print-notifications.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libprint-notifications.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/remote-display.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libremote-display.so + +%{_libdir}/gnome-settings-daemon-3.0/screensaver-proxy.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libscreensaver-proxy.so + +%{_libdir}/gnome-settings-daemon-3.0/smartcard.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libsmartcard.so + +%{_libdir}/gnome-settings-daemon-3.0/sound.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libsound.so + +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.peripherals.gschema.xml +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.peripherals.wacom.gschema.xml + +%ifnarch s390 s390x %{?rhel:ppc ppc64} +%{_libdir}/gnome-settings-daemon-3.0/wacom.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libgsdwacom.so +%{_libexecdir}/gsd-wacom-led-helper +%{_datadir}/polkit-1/actions/org.gnome.settings-daemon.plugins.wacom.policy +%endif + +%{_libdir}/gnome-settings-daemon-3.0/xrandr.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libxrandr.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.xrandr.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/xsettings.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libxsettings.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.xsettings.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/a11y-settings.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/liba11y-settings.so + +%{_libdir}/gnome-settings-daemon-3.0/color.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libcolor.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.color.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/liborientation.so +%{_libdir}/gnome-settings-daemon-3.0/orientation.gnome-settings-plugin +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.orientation.gschema.xml + +%{_libdir}/gnome-settings-daemon-3.0/libcursor.so +%{_libdir}/gnome-settings-daemon-3.0/cursor.gnome-settings-plugin + +%{_libdir}/gnome-settings-daemon-3.0/libgsd.so + +%{_libexecdir}/gnome-settings-daemon +%{_libexecdir}/gnome-settings-daemon-localeexec +%{_libexecdir}/gsd-locate-pointer +%{_libexecdir}/gsd-printer + +%{_datadir}/gnome-settings-daemon/ +%{_sysconfdir}/xdg/autostart/gnome-settings-daemon.desktop +%{_datadir}/icons/hicolor/*/apps/gsd-xrandr.* +%{_datadir}/GConf/gsettings/gnome-settings-daemon.convert + +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.enums.xml +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.gschema.xml + +%{_datadir}/dbus-1/services/org.freedesktop.IBus.service + +%{_datadir}/man/man1/gnome-settings-daemon.1.gz + + +%files devel +%{_includedir}/gnome-settings-daemon-3.0 +%{_libdir}/pkgconfig/gnome-settings-daemon.pc +%dir %{_datadir}/gnome-settings-daemon-3.0 +%{_datadir}/gnome-settings-daemon-3.0/input-device-example.sh +%ifnarch s390 s390x %{?rhel:ppc ppc64} +%{_libexecdir}/gsd-list-wacom +%{_libexecdir}/gsd-test-wacom +%{_libexecdir}/gsd-test-wacom-osd +%endif +%{_libexecdir}/gsd-test-a11y-keyboard +%{_libexecdir}/gsd-test-a11y-settings +%{_libexecdir}/gsd-test-cursor +%{_libexecdir}/gsd-test-housekeeping +%{_libexecdir}/gsd-test-input-helper +%{_libexecdir}/gsd-test-keyboard +%{_libexecdir}/gsd-test-media-keys +%{_libexecdir}/gsd-test-mouse +%{_libexecdir}/gsd-test-orientation +%{_libexecdir}/gsd-test-print-notifications +%{_libexecdir}/gsd-test-remote-display +%{_libexecdir}/gsd-test-screensaver-proxy +%{_libexecdir}/gsd-test-smartcard +%{_libexecdir}/gsd-test-sound +%{_libexecdir}/gsd-test-xrandr +%{_libexecdir}/gsd-test-xsettings + +%files updates +%{_libdir}/gnome-settings-daemon-3.0/updates.gnome-settings-plugin +%{_libdir}/gnome-settings-daemon-3.0/libupdates.so +%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.updates.gschema.xml + +%changelog +* Fri Nov 08 2013 Bastien Nocera 3.8.6.1-2 +- Make the power button work in gdm +Resolves: #980692 + +* Thu Oct 31 2013 Bastien Nocera 3.8.6.1-1 +- Update to 3.8.6.1 to fix build failures +Resolves: #1016206 + +* Wed Oct 30 2013 Bastien Nocera 3.8.6-1 +- Update to 3.8.6 +Resolves: #1016206 + +* Fri Sep 6 2013 Rui Matos - 3.8.5-1 +- Update to 3.8.5 +- Drop upstreamed patches + +* Thu Aug 22 2013 Ray Strode 3.8.4-3 +- Ignore soft tokens + Related: #854724 + Resolves: #991835 + +* Tue Jul 30 2013 Ray Strode 3.8.4-2 +- Add back in smartcard support + Related: #854724 + +* Tue Jul 30 2013 Ray Strode 3.8.4-1 +- Update to 3.8.4 + +* Mon Jul 22 2013 Bastien Nocera 3.8.3-4 +- Remove obsolete GStreamer 0.10 BRs + +* Sun Jun 16 2013 Kalev Lember - 3.8.3-3 +- Backport more upstream fixes for the localeexec helper (#974778) + +* Mon Jun 10 2013 Matthias Clasen - 3.8.3-2 +- Avoid calling setenv after threads are initialized (#919855) + +* Fri Jun 7 2013 Rui Matos - 3.8.3-1 +- Update to 3.8.3 + +* Fri May 17 2013 Rui Matos +- Add a patch to stop adding input sources automatically based on + locale since that's now gnome-initial-setup's job + +* Tue May 14 2013 Richard Hughes - 3.8.2-1 +- Update to 3.8.2 + +* Thu May 9 2013 Jens Petersen - 3.8.1-2 +- default ibus engine in Fedora is now kkc for Japanese + and libpinyin for Chinese (#948117) + +* Tue Apr 16 2013 Richard Hughes - 3.8.1-1 +- Update to 3.8.1 + +* Tue Mar 26 2013 Richard Hughes - 3.8.0-1 +- Update to 3.8.0 + +* Tue Mar 19 2013 Matthias Clasen - 3.7.92-1 +- Update to 3.7.92 + +* Tue Mar 5 2013 Matthias Clasen - 3.7.91-1 +- Update to 3.7.91 + +* Wed Feb 20 2013 Richard Hughes - 3.7.90-1 +- Update to 3.7.90 + +* Thu Feb 07 2013 Richard Hughes - 3.7.5.1-1 +- Update to 3.7.5.1 + +* Wed Feb 06 2013 Debarshi Ray - 3.7.5-2 +- Bump the gtk3 BuildRequires + +* Tue Feb 05 2013 Richard Hughes - 3.7.5-1 +- Update to 3.7.5 + +* Wed Jan 16 2013 Richard Hughes - 3.7.4-1 +- Update to 3.7.4 + +* Mon Dec 31 2012 Dan Horák - 3.7.3-2 +- fix filelist for s390(x) (and ppc/ppc64 in RHEL) + +* Thu Dec 20 2012 Kalev Lember - 3.7.3-1 +- Update to 3.7.3 +- Adjust the spec file for the (temporarly) disabled smartcard plugin + +* Tue Nov 20 2012 Richard Hughes - 3.7.1-1 +- Update to 3.7.1 +- Remove upstreamed patches + +* Wed Nov 14 2012 Kalev Lember - 3.6.3-1 +- Update to 3.6.3 +- Drop the static man page patch and BR docbook-style-xsl instead + +* Thu Nov 08 2012 Bastien Nocera 3.6.2-1 +- Update to 3.6.2 + +* Thu Oct 18 2012 Matthias Clasen - 3.6.1-3 +- Fix a typo in the suspend patch (#858259) + +* Mon Oct 08 2012 Dan Horák - 3.6.1-2 +- fix build on s390(x) + +* Mon Oct 08 2012 Bastien Nocera 3.6.1-1 +- Update to 3.6.1 + +* Fri Oct 5 2012 Olivier Fourdan - 3.6.0-5 +- Adds Wacom OSD window from upstream bug #679062 + +* Wed Oct 3 2012 Matthias Clasen - 3.6.0-4 +- Fix an inhibitor leak in the previous patch + +* Tue Oct 2 2012 Matthias Clasen - 3.6.0-3 +- Fix lid close handling with new systemd + +* Fri Sep 28 2012 Peter Robinson - 3.6.0-2 +- Split out PackageKit into a sub package. Fixes #699348 + +* Tue Sep 25 2012 Richard Hughes - 3.6.0-1 +- Update to 3.6.0 + +* Wed Sep 19 2012 Richard Hughes - 3.5.92-1 +- Update to 3.5.92 + +* Wed Sep 05 2012 Cosimo Cecchi - 3.5.91-1 +- Update to 3.5.91 + +* Wed Aug 22 2012 Richard Hughes - 3.5.90-1 +- Update to 3.5.90 + +* Tue Aug 21 2012 Richard Hughes - 3.5.6-1 +- Update to 3.5.6 + +* Fri Jul 27 2012 Fedora Release Engineering - 3.5.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 24 2012 Dan Horák - 3.5.5-3 +- fix build without wacom + +* Thu Jul 19 2012 Matthias Clasen - 3.5.5-2 +- Fix the updates plugin to load + +* Thu Jul 19 2012 Matthias Clasen - 3.5.5-1 +- Update to 3.5.5 + +* Tue Jul 17 2012 Dan Horák - 3.5.4-3 +- fix build on s390(x) - cherry-picked from f17 branch +- allow build without wacom on ppc/ppc64 + +* Tue Jul 17 2012 Matthias Clasen - 3.5.4-2 +- Rebuild against new PackageKit + +* Wed Jun 27 2012 Richard Hughes - 3.5.4-1 +- Update to 3.5.4 + +* Tue Jun 26 2012 Richard Hughes - 3.5.3-1 +- Update to 3.5.3 + +* Thu Jun 14 2012 Matthias Clasen - 3.5.2-4 +- Drop calculator patch, no longer needed + +* Thu Jun 07 2012 Matthias Clasen - 3.5.2-3 +- Fix file lists + +* Thu Jun 07 2012 Richard Hughes - 3.5.2-2 +- Add missing BR + +* Wed Jun 06 2012 Richard Hughes - 3.5.2-1 +- Update to 3.5.2 + +* Fri May 18 2012 Richard Hughes - 3.4.2-1 +- Update to 3.4.2 + +* Mon Apr 16 2012 Richard Hughes - 3.4.1-1 +- Update to 3.4.1 + +* Mon Mar 26 2012 Richard Hughes - 3.4.0-1 +- New upstream version. + +* Tue Mar 20 2012 Richard Hughes 3.3.92-1 +- Update to 3.3.92 + +* Mon Mar 05 2012 Bastien Nocera 3.3.91-1 +- Update to 3.3.91 + +* Wed Feb 22 2012 Bastien Nocera 3.3.90.1-1 +- Update to 3.3.90.1 + +* Thu Feb 9 2012 Matthias Clasen 3.3.5-2 +- Use systemd for session tracking + +* Tue Feb 7 2012 Matthias Clasen 3.3.5-1 +- Update to 3.3.5 + +* Fri Jan 20 2012 Matthias Clasen 3.3.4-2 +- Some crash fixes + +* Tue Jan 17 2012 Bastien Nocera 3.3.4-1 +- Update to 3.3.4 + +* Fri Jan 13 2012 Fedora Release Engineering - 3.3.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Dec 27 2011 Matthias Clasen - 3.3.3.1-2 +- Fix a path problem in the gnome-settings-daemon autostart file + +* Fri Dec 23 2011 Matthias Clasen - 3.3.3.1-1 +- Update to 3.3.3.1 + +* Wed Dec 21 2011 Matthias Clasen - 3.3.3-1 +- Update to 3.3.3 + +* Wed Nov 23 2011 Matthias Clasen - 3.3.2-1 +- Update to 3.3.2 + +* Fri Nov 11 2011 Bastien Nocera 3.2.2-1 +- Update to 3.2.2 + +* Wed Oct 26 2011 Fedora Release Engineering - 3.2.1-4 +- Rebuilt for glibc bug#747377 + +* Tue Oct 25 2011 Marek Kasik - 3.2.1-3 +- Fix a typo in registration of an object on DBus (#747318) + +* Mon Oct 24 2011 Matthias Clasen - 3.2.1-2 +- Fix calculator keybinding (#745367) + +* Mon Oct 17 2011 Bastien Nocera 3.2.1-1 +- Update to 3.2.1 + +* Wed Oct 12 2011 Adam Williamson - 3.2.0-2 +- backport some greatest hits from git to stop the same bugs being + reported over and over (all will be in 3.2.1) + +* Tue Sep 27 2011 Ray - 3.2.0-1 +- Update to 3.2.0 + +* Tue Sep 20 2011 Matthias Clasen - 3.1.92-1 +- Update to 3.1.92 + +* Tue Sep 6 2011 Matthias Clasen - 3.1.91-1 +- Update to 3.1.91 + +* Tue Jul 26 2011 Cosimo Cecchi - 3.1.4-2 +- Add a patch to make the fallback mounter to build correctly +- Include the new power plugin + +* Mon Jul 25 2011 Matthias Clasen - 3.1.4-1 +- Update to 3.1.4 + +* Fri Jul 22 2011 Tomas Bzatek - 3.1.3-2 +- Add support for chrony (#723212) + +* Mon Jul 04 2011 Bastien Nocera 3.1.3-1 +- Update to 3.1.3 + +* Tue Jun 21 2011 Tomas Bzatek - 3.1.2-2 +- Fix fortify fail in gsd-color-manager.c (#714625) + +* Wed Jun 15 2011 Tomas Bzatek - 3.1.2-1 +- Update to 3.1.2 + +* Wed Jun 15 2011 Bastien Nocera 3.1.1-3 +- Rebuild for new gnome-desktop3 libs + +* Mon Jun 13 2011 Marek Kasik 3.1.1-2 +- Remove requirement of system-config-printer-udev (#704381) + +* Wed May 11 2011 Tomas Bzatek - 3.1.1-1 +- Update to 3.1.1 + +* Sat May 07 2011 Christopher Aillon - 3.0.1-5 +- Update gsettings schema scriptlet + +* Mon May 2 2011 Matthias Clasen 3.0.1-4 +- Try to fix a crash (#698533) + +* Thu Apr 28 2011 Bastien Nocera 3.0.1-2 +- Fix setting ntpd usage with SystemD + +* Tue Apr 26 2011 Bastien Nocera 3.0.1-1 +- Update to 3.0.1 + +* Wed Apr 06 2011 Bastien Nocera 3.0.0.1-1 +- Update to 3.0.0.1 + +* Mon Apr 04 2011 Bastien Nocera 3.0.0-1 +- Update to 3.0.0 + +* Wed Mar 30 2011 Marek Kasik 2.91.93-2 +- Make CUPS' subscriptions expirable + +* Fri Mar 25 2011 Bastien Nocera 2.91.93-1 +- Update to 2.91.93 + +* Mon Mar 21 2011 Matthias Clasen 2.91.92-1 +- Update 2.91.92 + +* Wed Mar 16 2011 Richard Hughes 2.91.91-3 +- Add a patch from upstream to fix the updates plugin. + +* Fri Mar 11 2011 Bastien Nocera 2.91.91-2 +- Add libXxf86misc-devel requires so that key repeat/delay works + +* Tue Mar 08 2011 Bastien Nocera 2.91.91-1 +- Update to 2.91.91 + +* Fri Feb 25 2011 Matthias Clasen - 2.91.90-4 +- Fix undefined symbols in the updates plugin + +* Wed Feb 23 2011 Matthias Clasen - 2.91.90-3 +- BR PackageKit and cups +- Explicitly list plugins so we notice if they go missing + +* Wed Feb 23 2011 Cosimo Cecchi - 2.91.90-2 +- Include an upstream patch to fix a possible crasher + +* Tue Feb 22 2011 Matthias Clasen 2.91.90-1 +- Update to 2.91.90 + +* Wed Feb 16 2011 Bastien Nocera 2.91.9-6 +- Fix crasher when media keys GSettings value changes + +* Sun Feb 13 2011 Christopher Aillon - 2.91.9-5 +- Rebuild for new libxklavier + +* Fri Feb 11 2011 Matthias Clasen 2.91.9-4 +- Rebuild against newer gtk + +* Tue Feb 08 2011 Fedora Release Engineering - 2.91.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Feb 08 2011 Bastien Nocera 2.91.9-2 +- Fix setting timezones in the date & time panel (#674999) + +* Wed Feb 2 2011 Matthias Clasen 2.91.9-1 +- 2.91.9 + +* Tue Jan 11 2011 Matthias Clasen 2.91.8-1 +- 2.91.8 + +* Tue Jan 11 2011 Matthias Clasen 2.91.7-2 +- Own %%{_libdir}/gnome-settings-daemon-3.0/gtk-modules + +* Mon Jan 10 2011 Matthias Clasen 2.91.7-1 +- Update to 2.91.7 + +* Sat Jan 8 2011 Matthias Clasen 2.91.6.2-1 +- Update to 2.91.6.2 + +* Fri Dec 3 2010 Matthias Clasen 2.91.5.1-1 +- Update to 2.91.5.1 + +* Thu Dec 2 2010 Dan Williams - 2.91.5-4 +- Re-add patch handling org.gnome.media-handling gsettings schema rename + +* Wed Dec 1 2010 Dan Williams - 2.91.5-3 +- Fix various cases of forgetting to draw the background + +* Tue Nov 30 2010 Owen Taylor - 2.91.5-2 +- Add a patch handling org.gnome.media-handling gsettings schema rename + +* Tue Nov 30 2010 Tomas Bzatek 2.91.5-1 +- Update to 2.91.5 + +* Fri Nov 26 2010 Bastien Nocera 2.91.4-2 +- Fix crasher on startup + +* Thu Nov 25 2010 Bastien Nocera 2.91.4-1 +- Update to 2.91.4 + +* Wed Nov 17 2010 Richard Hughes 2.91.3-1 +- Update to 2.91.3 + +* Wed Nov 10 2010 Bastien Nocera 2.91.2.1-0.4. +- Update to 2.91.2.1 + +* Wed Nov 3 2010 Matthias Clasen 2.91.2-0.4.20101102 +- Rebuild against new libnotify + +* Tue Nov 2 2010 Matthias Clasen 2.91.2-0.3.20101102 +- Make theme changing work + +* Tue Nov 02 2010 Richard Hughes 2.91.2-0.2.20101102 +- Add BR gsettings-desktop-schemas-devel + +* Tue Nov 02 2010 Richard Hughes 2.91.2-0.1.20101102 +- Update to a git snapshot to fix rawhide. + +* Wed Oct 06 2010 Richard Hughes 2.91.0-3 +- Fix the pkgconfig file manually + +* Wed Oct 06 2010 Richard Hughes 2.91.0-2 +- Rebuild against the new libgnomekbd library + +* Mon Oct 4 2010 Matthias Clasen - 2.91.0-1 +- Update to 2.91.0 + +* Wed Sep 29 2010 jkeating - 2.90.1-2 +- Rebuilt for gcc bug 634757 + +* Wed Sep 22 2010 Bastien Nocera 2.90.1-1 +- Update to 2.90.1 + +* Tue Aug 31 2010 Matthias Clasen 2.31.91-1 +- Update to 2.31.91 + +* Fri Aug 27 2010 Matthias Clasen 2.31.6-2 +- Fix a problem with warning bubbles in virtual machines (#624624) + +* Tue Aug 3 2010 Matthias Clasen 2.31.6-1 +- Update to 2.31.6 + +* Tue Jul 13 2010 Matthias Clasen 2.31.5.1-1 +- Update to 2.31.5.1 + +* Mon Jul 12 2010 Matthias Clasen 2.31.5-1 +- Update to 2.31.5 + +* Wed Jun 30 2010 Matthias Clasen 2.31.4.2-1 +- Update to 2.31.4.2 + +* Tue Jun 29 2010 Matthias Clasen 2.31.4.1-1 +- Update to 2.31.4.1 + +* Tue Jun 29 2010 Matthias Clasen 2.31.4-1 +- Update to 2.31.4 + +* Mon Jun 28 2010 Bastien Nocera 2.31.3-3 +- Don't remove the sound plugin if we want the caches to be + updated + +* Tue Jun 8 2010 Matthias Clasen 2.31.3-1 +- Update to 2.31.3 + +* Thu May 27 2010 Matthias Clasen 2.31.2-1 +- Update to 2.31.2 + +* Sun May 16 2010 Matthias Clasen 2.31.1-1 +- Update to 2.31.1 + +* Fri Apr 30 2010 Matthias Clasen 2.30.1-4 +- Waah, one more mistake in these macros + +* Tue Apr 27 2010 Matthias Clasen 2.30.1-3 +- Nobody understands macro processors... + +* Tue Apr 27 2010 Matthias Clasen 2.30.1-2 +- Fix a typo + +* Mon Apr 26 2010 Matthias Clasen 2.30.1-1 +- Update to 2.30.1 +- Spec file cleanups + +* Mon Mar 29 2010 Matthias Clasen 2.30.0-1 +- Update to 2.30.0 + +* Mon Mar 22 2010 Bastien Nocera 2.29.92-3 +- Disable the font plugin by default + +* Wed Mar 10 2010 Bastien Nocera 2.29.92-2 +- Remove unneeded icons, already upstream + +* Tue Mar 09 2010 Bastien Nocera 2.29.92-1 +- Update to 2.29.92 + +* Sat Feb 27 2010 Matthias Clasen 2.29.91.1-2 +- Fix Fn-F8 OSD icon +- Modernize scriptlets + +* Wed Feb 24 2010 Matthias Clasen 2.29.91.1-1 +- Update to 2.29.91.1 + +* Wed Feb 17 2010 Matthias Clasen 2.29.90-2 +- Set a name for the keyboard statusicon + +* Wed Feb 10 2010 Tomas Bzatek 2.29.90-1 +- Update to 2.29.90 + +* Tue Jan 26 2010 Matthias Clasen 2.29.6-1 +- Update to 2.29.6 + +* Fri Dec 18 2009 Matthias Clasen 2.28.1-10 +- Avoid warning messages from the OSD code + +* Tue Dec 15 2009 Matthias Clasen 2.28.1-9 +- Survive when running without XKB (#547780) + +* Thu Nov 12 2009 Matthias Clasen 2.28.1-8 +- Avoid a 'whitespace leak' around the display statusicon (gnome #601696) + +* Mon Nov 9 2009 Matthias Clasen 2.28.1-7 +- React to screen changes when showing the background (gnome #601203) + +* Thu Nov 05 2009 Bastien Nocera 2.28.1-6 +- Fix the volume going over 100% in the OSD + +* Wed Oct 28 2009 Bastien Nocera 2.28.1-5 +- Update OSD code again + +* Tue Oct 27 2009 Bastien Nocera 2.28.1-4 +- Fix bluriness in OSD + +* Mon Oct 26 2009 Matthias Clasen - 2.28.1-3 +- Change default font rendering to use slight hinting + +* Mon Oct 26 2009 Peter Hutterer 2.28.1-2 +- left-handed-touchpad.patch: change physical touchpad buttons to + left-handed, not tapping though (#498249) + +* Mon Oct 19 2009 Matthias Clasen - 2.28.1-1 +- Update to 2.28.1 + +* Thu Oct 1 2009 Matthias Clasen - 2.28.0-4 +- Fix keyboard variant handling + +* Fri Sep 25 2009 Matthias Clasen - 2.28.0-3 +- Align the OSD visuals with the notification theme + +* Tue Sep 22 2009 Adam Jackson 2.28.0-2 +- BuildRequires: libcanberra-devel + +* Mon Sep 21 2009 Matthias Clasen - 2.28.0-1 +- Update to 2.28.0 + +* Wed Sep 09 2009 Bastien Nocera 2.27.92-2 +- Update left-hand touchpad patch + +* Mon Sep 7 2009 Matthias Clasen - 2.27.92-1 +- Update to 2.27.92 + +* Sun Aug 30 2009 Matthias Clasen - 2.27.91-3 +- Make 'Locate Pointer' work with metacity again + +* Wed Aug 26 2009 Peter Hutterer 2.27.91-2 +- buttonmapping.patch: Don't check for IsXExtensionDevice, only skip button + mappings for core devices instead (#502129). + +* Mon Aug 24 2009 Bastien Nocera 2.27.91-1 +- Update to 2.27.91 + +* Fri Aug 14 2009 Bastien Nocera 2.27.90-2 +- Update gnome-volume-control code + +* Fri Aug 14 2009 Bastien Nocera 2.27.90-1 +- Update to 2.27.90 + +* Tue Jul 28 2009 Matthias Clasen 2.27.5-1 +- Update to 2.27.5 + +* Fri Jul 24 2009 Fedora Release Engineering - 2.27.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 21 2009 Matthias Clasen 2.27.4-3 +- Make locate-pointer not interfere with media keys + +* Wed Jul 15 2009 Matthias Clasen 2.27.4-2 +- Rebuild against new libgnomekbd + +* Tue Jul 14 2009 Matthias Clasen 2.27.4-1 +- Update ot 2.27.4 + +* Tue Jun 30 2009 Matthias Clasen 2.27.3-2 +- Rebuild against new libxklavier + +* Tue Jun 16 2009 Matthias Clasen 2.27.3-1 +- Update to 2.27.3 + +* Mon Jun 8 2009 Matthias Clasen 2.27.1-2 +- Make the 'locate pointer' effect cope with changing compositing + managers + +* Sat May 16 2009 Matthias Clasen 2.27.1-1 +- Update to 2.27.1 + +* Fri May 08 2009 Bastien Nocera 2.26.1-4 +- Remove useless patch, see: +http://bugzilla.gnome.org/show_bug.cgi?id=580761 for details + +* Wed Apr 29 2009 Bastien Nocera 2.26.1-3 +- Don't set touchpads to be left-handed, otherwise the tap + behaves like the 2nd mouse button (#483639) + +* Mon Apr 27 2009 Matthias Clasen - 2.26.1-2 +- Don't drop schemas translations from po files + +* Tue Apr 14 2009 Matthias Clasen - 2.26.1-1 +- Update to 2.26.1 + +* Wed Apr 8 2009 Matthias Clasen - 2.26.0-2 +- Support touchpads + +* Mon Mar 16 2009 Matthias Clasen - 2.26.0-1 +- Update to 2.26.0 + +* Mon Mar 2 2009 Matthias Clasen - 2.25.92-1 +- Update to 2.25.92 + +* Tue Feb 24 2009 Fedora Release Engineering - 2.25.90-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 5 2009 Matthias Clasen - 2.25.90-2 +- Fix a warning (#484132) + +* Wed Feb 4 2009 Matthias Clasen - 2.25.90-1 +- Update to 2.25.90 + +* Mon Jan 19 2009 - Ray Strode - 2.25.3-4 +- Update fade patch for new gnome-desktop release + +* Thu Dec 18 2008 - Bastien Nocera - 2.25.3-3 +- Rebuild + +* Thu Dec 18 2008 - Ray Strode - 2.25.3-2 +- Drop touchpad patch for now + +* Thu Dec 18 2008 - Bastien Nocera - 2.25.3-1 +- Update to 2.25.3 + +* Thu Dec 18 2008 - Bastien Nocera - 2.25.2-11 +- Fix touchpad patches + +* Wed Dec 17 2008 Matthias Clasen - 2.25.2-10 +- Rebuild against new gnome-desktop + +* Wed Dec 10 2008 Ray Strode - 2.25.2-9 +- Don't call SetPointerMapping when using Xinput since + it duplicates effort but gets touchpads wrong (bug 324721) + +* Wed Dec 10 2008 Ray Strode - 2.25.2-8 +- Shutdown cleanly when bus goes away (bug 445898 again) + +* Wed Dec 10 2008 Ray Strode - 2.25.2-7 +- Don't map touch pad tap to right-click for left-handed + users (bug 324721) + +* Wed Dec 10 2008 Ray Strode - 2.25.2-6 +- Listen for DeviceAdded signals when configuring mouse + (in addition to DeviceEnabled). This may help with + bug 474758. + +* Tue Dec 9 2008 Ray Strode - 2.25.2-5 +- Shutdown cleanly on TERM signal (bug 445898) + +* Sun Dec 7 2008 Behdad Esfahbod - 2.25.2-4 +- Add gnome-settings-daemon-2.24.1-umask.patch + +* Thu Dec 4 2008 Ray Strode - 2.25.2-2 +- Rebase fade patch to apply with Behdad's updates to + g-s-d + +* Wed Dec 3 2008 Matthias Clasen - 2.25.2-1 +- Ypdate to 2.25.2 + +* Thu Nov 13 2008 Matthias Clasen - 2.25.1-4 +- Rebuild + +* Wed Nov 12 2008 Matthias Clasen - 2.25.1-2 +- Update to 2.25.1 + +* Fri Oct 24 2008 Ray Strode - 2.24.0-14 +- At fontconfig-devel buildrequires (bug 468304) + +* Wed Oct 15 2008 Matthias Clasen - 2.24.0-13 +- Save some space + +* Tue Oct 14 2008 Ray Strode - 2.24.0-12 +- Hold off on settings-daemon fade if nautilus is going to do + it anyway. + +* Tue Oct 14 2008 Matthias Clasen - 2.24.0-11 +- Show the shutdown dialog when the power button is pressed + +* Tue Oct 14 2008 Matthias Clasen - 2.24.0-9 +- Drop a patch that is no longer needed with the evdev ruleset + in xkeyboard-config + +* Sun Oct 12 2008 Matthias Clasen - 2.24.0-7 +- Try harder not to override peoples configured keyboard layouts + +* Sun Oct 12 2008 Ray Strode - 2.24.0-6 +- Update fade patch to skip crossfade when changing frames in + slideshow background. + +* Fri Oct 10 2008 Matthias Clasen - 2.24.0-5 +- Fix the picking up of the gdm keyboard layout even more + +* Tue Sep 30 2008 Matthias Clasen - 2.24.0-3 +- Fix the picking up of the gdm keyboard layout + +* Sun Sep 28 2008 Ray Strode - 2.24.0-2 +- Don't draw background twice at startup + +* Tue Sep 23 2008 Matthias Clasen - 2.24.0-1 +- Update to 2.24.0 + +* Thu Sep 18 2008 Ray Strode - 2.23.92-3 +- When switching desktop backgrounds fade between them + +* Thu Sep 11 2008 Soren Sandmann - 2.23.92-2 +- Fix various bugs in the fn-F7 support + +* Mon Sep 8 2008 Matthias Clasen - 2.23.92-1 +- Update to 2.23.92 + +* Fri Sep 5 2008 Matthias Clasen - 2.23.91-5 +- Try harder to use the keyboard layout that gdm tells us + +* Thu Sep 04 2008 Soren Sandmann - 2.23.91-4 +- Use the fn-F7 key, not the F7 key. + +* Wed Sep 03 2008 Soren Sandmann - 2.23.91-3 +- Bump gnome-desktop requirement + +* Wed Sep 03 2008 Soren Sandmann - 2.23.91-2 +- Add patch to do fn-f7 cycling + +* Mon Sep 01 2008 - Bastien Nocera - 2.23.91-1 +- Update to 2.23.91 + +* Thu Aug 28 2008 Jon McCann - 2.23.91-0.2008.08.28.2 +- BuildRequires libnotify-devel + +* Thu Aug 28 2008 Jon McCann - 2.23.91-0.2008.08.28.1 +- Update to snapshot + +* Fri Aug 22 2008 Matthias Clasen - 2.23.90-1 +- Update to 2.23.90 + +* Thu Aug 14 2008 Lennart Poettering - 2.23.6-3 +- Rerun autotools after patching configure.ac + +* Thu Aug 14 2008 Lennart Poettering - 2.23.6-2 +- Apply patch from gnome bug 545386. This hasn't been accepted in this form yet + by upstream, will however very likely be merged in a similar form. +- Disable esd/sounds module since we don't need it to start PA anymore + +* Tue Aug 5 2008 Matthias Clasen - 2.23.6-1 +- Update to 2.23.6 + +* Fri Jul 25 2008 Matthias Clasen - 2.23.5-3 +- Use standard icon names in the volume OSD + +* Fri Jul 25 2008 - Bastien Nocera - 2.23.5-2 +- Fix build, call gtk-update-icon-cache as required + +* Thu Jul 24 2008 Soren Sandmann - 2.23.5-1 +- Update to 2.23.5 + +* Wed Jun 18 2008 Matthias Clasen - 2.23.4-1 +- Update to 2.23.4 + +* Tue Jun 17 2008 Colin Walters - 2.23.3-2 +- Add (now upstreamed) patch to legacy ESD preference; see + http://bugzilla.gnome.org/show_bug.cgi?id=533198 + https://bugzilla.redhat.com/show_bug.cgi?id=430624 + +* Wed Jun 4 2008 Matthias Clasen - 2.23.3-1 +- Update to 2.23.3 + +* Wed May 14 2008 Matthias Clasen - 2.23.2-0.2008.05.14.2 +- Fix BuildRequires + +* Wed May 14 2008 Jon McCann - 2.23.2-0.2008.05.14.1 +- Build snapshot + +* Tue May 13 2008 Matthias Clasen - 2.23.1-1-5 +- Rebuild + +* Mon May 5 2008 Matthias Clasen - 2.23.1-1-4 +- Pick up the keyboard layout from the login screen + +* Mon May 5 2008 Matthias Clasen - 2.23.1-1-3 +- Fix background drawing without nautilus + +* Tue Apr 29 2008 - Bastien Nocera - 2.23.1.1-2 +- Add patch from upstream to avoid the Stop button triggering an Eject (#346201) + +* Fri Apr 25 2008 Matthias Clasen - 2.23.1.1-1 +- Update to 2.23.1.1 + +* Tue Apr 22 2008 Matthias Clasen - 2.22.1-2008.03.26.6 +- Make the xrandr plugin survive the absence of Xrandr + +* Sat Apr 5 2008 - Soren Sandmann - 2.22.1-2008.03.26.5 +- Update randr plugin + +* Mon Mar 31 2008 - Ray Strode - 2.22.1-0.2008.03.26.4 +- Over the releases we've accumulated default.png, default-wide.png default-5_4.png + and default.jpg. We haven't been able to drop them because it would leave some + users with white backgrounds on upgrade. This patch just falls back to the + default image if the user's background doesn't exist. + +* Wed Mar 26 2008 - Bastien Nocera - 2.22.1-0.2008.03.26.3 +- Add patch for the mouse plugin not to eat multimedia key events (#438942) + +* Wed Mar 26 2008 Jon McCann - 2.22.1-0.2008.03.26.2 +- Rebuild + +* Wed Mar 26 2008 Jon McCann - 2.22.1-0.2008.03.26.1 +- Update to snapshot +- Enable profiling + +* Wed Mar 26 2008 - Bastien Nocera - 2.22.0-3 +- apps_gnome_settings_daemon_default_editor.schemas is obsolete (#438937) + +* Thu Mar 20 2008 Matthias Clasen 2.22.0-2 +- Fix interaction between "Locate Pointer" and volume keys + +* Mon Mar 10 2008 Matthias Clasen 2.22.0-1 +- Update to 2.22.0 + +* Sun Mar 9 2008 Ray Strode - 2.21.92-3 +- Don't set keyboard model on startup from gconf if evdev is being used. + Evdev needs to use its own keyboard model to work right. + +* Sun Mar 2 2008 Soren Sandmann - 2.21.92-2 +- Update randr patch to handle video key + +* Fri Feb 29 2008 Jon McCann - 2.21.92-1 +- Update to 2.21.92 + +* Tue Feb 12 2008 Soren Sandmann - 2.21.91-3 +- Add patch to make the xrandr plugin listen for client messages from + the control panel and reread the configuration file. + +* Mon Feb 11 2008 Matthias Clasen - 2.21.91-2 +- Remove obsolete control-center translations + +* Mon Feb 11 2008 - Bastien Nocera - 2.21.91-1 +- Update to 2.21.91 +- Remove obsolete patches + +* Thu Feb 7 2008 Matthias Clasen - 2.21.90.1-3 +- Load xkb settings initially + +* Thu Jan 31 2008 - Bastien Nocera - 2.21.90.1-2 +- Fix the path for g-s-d, from upstream patch + +* Tue Jan 29 2008 - Bastien Nocera - 2.21.90.1-1 +- Update to 2.21.90.1 + +* Tue Jan 29 2008 - Bastien Nocera - 2.21.90-1 +- Update to 2.21.90 + +* Tue Jan 15 2008 Matthias Clasen - 2.21.5.2-2 +- Incorporate review feedback (#428833) + +* Tue Jan 15 2008 Matthias Clasen - 2.21.5.2-1 +- Update to 2.21.5.2 + +* Tue Jan 15 2008 Matthias Clasen - 2.21.5.1-1 +- Update to 2.21.5.1 +- Fix up BuildRequires + +* Thu Dec 06 2007 - Bastien Nocera - 2.21.5-1 +- First package +