1
/* gsd-smartcard-manager.c - object for monitoring smartcard insertion and
4
* Copyright (C) 2006, 2009 Red Hat, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2, or (at your option)
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
* Written By: Ray Strode
25
#include "gsd-smartcard-manager.h"
27
#define SMARTCARD_ENABLE_INTERNAL_API
28
#include "gsd-smartcard.h"
38
#include <sys/resource.h>
44
#include <glib/gi18n.h>
53
#ifndef GSD_SMARTCARD_MANAGER_DRIVER
54
#define GSD_SMARTCARD_MANAGER_DRIVER LIBDIR"/pkcs11/libcoolkeypk11.so"
57
#ifndef GSD_SMARTCARD_MANAGER_NSS_DB
58
#define GSD_SMARTCARD_MANAGER_NSS_DB SYSCONFDIR"/pki/nssdb"
61
#ifndef GSD_MAX_OPEN_FILE_DESCRIPTORS
62
#define GSD_MAX_OPEN_FILE_DESCRIPTORS 1024
65
#ifndef GSD_OPEN_FILE_DESCRIPTORS_DIR
66
#define GSD_OPEN_FILE_DESCRIPTORS_DIR "/proc/self/fd"
69
typedef enum _GsdSmartcardManagerState GsdSmartcardManagerState;
70
typedef struct _GsdSmartcardManagerWorker GsdSmartcardManagerWorker;
72
enum _GsdSmartcardManagerState {
73
GSD_SMARTCARD_MANAGER_STATE_STOPPED = 0,
74
GSD_SMARTCARD_MANAGER_STATE_STARTING,
75
GSD_SMARTCARD_MANAGER_STATE_STARTED,
76
GSD_SMARTCARD_MANAGER_STATE_STOPPING,
79
struct _GsdSmartcardManagerPrivate {
80
GsdSmartcardManagerState state;
86
GPid smartcard_event_watcher_pid;
87
GHashTable *smartcards;
89
guint poll_timeout_id;
91
guint32 is_unstoppable : 1;
92
guint32 nss_is_loaded : 1;
95
struct _GsdSmartcardManagerWorker {
96
GsdSmartcardManager *manager;
100
SECMODModule *module;
101
GHashTable *smartcards;
103
GSource *event_source;
105
guint32 nss_is_loaded : 1;
108
static void gsd_smartcard_manager_finalize (GObject *object);
109
static void gsd_smartcard_manager_class_install_signals (GsdSmartcardManagerClass *service_class);
110
static void gsd_smartcard_manager_class_install_properties (GsdSmartcardManagerClass *service_class);
111
static void gsd_smartcard_manager_set_property (GObject *object,
115
static void gsd_smartcard_manager_get_property (GObject *object,
119
static void gsd_smartcard_manager_set_module_path (GsdSmartcardManager *manager,
120
const char *module_path);
121
static void gsd_smartcard_manager_card_removed_handler (GsdSmartcardManager *manager,
123
static void gsd_smartcard_manager_card_inserted_handler (GsdSmartcardManager *manager_class,
125
static gboolean gsd_smartcard_manager_stop_now (GsdSmartcardManager *manager);
126
static void gsd_smartcard_manager_queue_stop (GsdSmartcardManager *manager);
128
static GsdSmartcardManagerWorker *gsd_smartcard_manager_create_worker (GsdSmartcardManager *manager,
129
SECMODModule *module);
131
static GsdSmartcardManagerWorker * gsd_smartcard_manager_worker_new (GsdSmartcardManager *manager,
134
SECMODModule *module);
135
static void gsd_smartcard_manager_worker_free (GsdSmartcardManagerWorker *worker);
136
static gboolean open_pipe (int *write_fd, int *read_fd);
137
static gboolean read_bytes (int fd, gpointer bytes, gsize num_bytes);
138
static gboolean write_bytes (int fd, gconstpointer bytes, gsize num_bytes);
139
static GsdSmartcard *read_smartcard (int fd, SECMODModule *module);
140
static gboolean write_smartcard (int fd, GsdSmartcard *card);
149
SMARTCARD_INSERTED = 0,
155
static guint gsd_smartcard_manager_signals[NUMBER_OF_SIGNALS];
157
G_DEFINE_TYPE (GsdSmartcardManager,
158
gsd_smartcard_manager,
162
gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *manager_class)
164
GObjectClass *gobject_class;
166
gobject_class = G_OBJECT_CLASS (manager_class);
168
gobject_class->finalize = gsd_smartcard_manager_finalize;
170
gsd_smartcard_manager_class_install_signals (manager_class);
171
gsd_smartcard_manager_class_install_properties (manager_class);
173
g_type_class_add_private (manager_class,
174
sizeof (GsdSmartcardManagerPrivate));
178
gsd_smartcard_manager_class_install_properties (GsdSmartcardManagerClass *card_class)
180
GObjectClass *object_class;
181
GParamSpec *param_spec;
183
object_class = G_OBJECT_CLASS (card_class);
184
object_class->set_property = gsd_smartcard_manager_set_property;
185
object_class->get_property = gsd_smartcard_manager_get_property;
187
param_spec = g_param_spec_string ("module-path", "Module Path",
188
"path to smartcard PKCS #11 driver",
189
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
190
g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec);
194
gsd_smartcard_manager_set_property (GObject *object,
199
GsdSmartcardManager *manager = GSD_SMARTCARD_MANAGER (object);
202
case PROP_MODULE_PATH:
203
gsd_smartcard_manager_set_module_path (manager,
204
g_value_get_string (value));
208
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
214
gsd_smartcard_manager_get_property (GObject *object,
219
GsdSmartcardManager *manager = GSD_SMARTCARD_MANAGER (object);
223
case PROP_MODULE_PATH:
224
module_path = gsd_smartcard_manager_get_module_path (manager);
225
g_value_set_string (value, module_path);
226
g_free (module_path);
230
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
236
gsd_smartcard_manager_get_module_path (GsdSmartcardManager *manager)
238
return manager->priv->module_path;
242
gsd_smartcard_manager_set_module_path (GsdSmartcardManager *manager,
243
const char *module_path)
245
if ((manager->priv->module_path == NULL) && (module_path == NULL)) {
249
if (((manager->priv->module_path == NULL) ||
250
(module_path == NULL) ||
251
(strcmp (manager->priv->module_path, module_path) != 0))) {
252
g_free (manager->priv->module_path);
253
manager->priv->module_path = g_strdup (module_path);
254
g_object_notify (G_OBJECT (manager), "module-path");
259
gsd_smartcard_manager_card_removed_handler (GsdSmartcardManager *manager,
262
g_debug ("informing smartcard of its removal");
263
_gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED);
268
gsd_smartcard_manager_card_inserted_handler (GsdSmartcardManager *manager,
271
g_debug ("informing smartcard of its insertion");
273
_gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED);
279
gsd_smartcard_manager_class_install_signals (GsdSmartcardManagerClass *manager_class)
281
GObjectClass *object_class;
283
object_class = G_OBJECT_CLASS (manager_class);
285
gsd_smartcard_manager_signals[SMARTCARD_INSERTED] =
286
g_signal_new ("smartcard-inserted",
287
G_OBJECT_CLASS_TYPE (object_class),
289
G_STRUCT_OFFSET (GsdSmartcardManagerClass,
291
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
292
G_TYPE_NONE, 1, G_TYPE_POINTER);
293
manager_class->smartcard_inserted = gsd_smartcard_manager_card_inserted_handler;
295
gsd_smartcard_manager_signals[SMARTCARD_REMOVED] =
296
g_signal_new ("smartcard-removed",
297
G_OBJECT_CLASS_TYPE (object_class),
299
G_STRUCT_OFFSET (GsdSmartcardManagerClass,
301
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
302
G_TYPE_NONE, 1, G_TYPE_POINTER);
303
manager_class->smartcard_removed = gsd_smartcard_manager_card_removed_handler;
305
gsd_smartcard_manager_signals[ERROR] =
306
g_signal_new ("error",
307
G_OBJECT_CLASS_TYPE (object_class),
309
G_STRUCT_OFFSET (GsdSmartcardManagerClass, error),
310
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
311
G_TYPE_NONE, 1, G_TYPE_POINTER);
312
manager_class->error = NULL;
316
slot_id_equal (CK_SLOT_ID *slot_id_1,
317
CK_SLOT_ID *slot_id_2)
319
g_assert (slot_id_1 != NULL);
320
g_assert (slot_id_2 != NULL);
322
return *slot_id_1 == *slot_id_2;
326
slot_id_hash (CK_SLOT_ID *slot_id)
328
guint32 upper_bits, lower_bits;
331
if (sizeof (CK_SLOT_ID) == sizeof (int)) {
332
return g_int_hash (slot_id);
335
upper_bits = ((*slot_id) >> 31) - 1;
336
lower_bits = (*slot_id) & 0xffffffff;
338
/* The upper bits are almost certainly always zero,
339
* so let's degenerate to g_int_hash for the
342
temp = lower_bits + upper_bits;
343
return upper_bits + g_int_hash (&temp);
347
gsd_smartcard_manager_init (GsdSmartcardManager *manager)
349
g_debug ("initializing smartcard manager");
351
manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
352
GSD_TYPE_SMARTCARD_MANAGER,
353
GsdSmartcardManagerPrivate);
354
manager->priv->poll_timeout_id = 0;
355
manager->priv->is_unstoppable = FALSE;
357
manager->priv->smartcards =
358
g_hash_table_new_full (g_str_hash,
360
(GDestroyNotify) g_free,
361
(GDestroyNotify) g_object_unref);
365
gsd_smartcard_manager_finalize (GObject *object)
367
GsdSmartcardManager *manager;
368
GObjectClass *gobject_class;
370
manager = GSD_SMARTCARD_MANAGER (object);
372
G_OBJECT_CLASS (gsd_smartcard_manager_parent_class);
374
gsd_smartcard_manager_stop_now (manager);
376
g_hash_table_destroy (manager->priv->smartcards);
377
manager->priv->smartcards = NULL;
379
gobject_class->finalize (object);
383
gsd_smartcard_manager_error_quark (void)
385
static GQuark error_quark = 0;
387
if (error_quark == 0) {
388
error_quark = g_quark_from_static_string ("gsd-smartcard-manager-error-quark");
394
GsdSmartcardManager *
395
gsd_smartcard_manager_new_default (void)
397
return gsd_smartcard_manager_new (NULL);
400
GsdSmartcardManager *
401
gsd_smartcard_manager_new (const char *module_path)
403
GsdSmartcardManager *instance;
405
instance = GSD_SMARTCARD_MANAGER (g_object_new (GSD_TYPE_SMARTCARD_MANAGER,
406
"module-path", module_path,
413
gsd_smartcard_manager_emit_error (GsdSmartcardManager *manager,
416
manager->priv->is_unstoppable = TRUE;
417
g_signal_emit (manager, gsd_smartcard_manager_signals[ERROR], 0,
419
manager->priv->is_unstoppable = FALSE;
423
gsd_smartcard_manager_emit_smartcard_inserted (GsdSmartcardManager *manager,
426
manager->priv->is_unstoppable = TRUE;
427
g_signal_emit (manager, gsd_smartcard_manager_signals[SMARTCARD_INSERTED], 0,
429
manager->priv->is_unstoppable = FALSE;
433
gsd_smartcard_manager_emit_smartcard_removed (GsdSmartcardManager *manager,
436
manager->priv->is_unstoppable = TRUE;
437
g_signal_emit (manager, gsd_smartcard_manager_signals[SMARTCARD_REMOVED], 0,
439
manager->priv->is_unstoppable = FALSE;
443
gsd_smartcard_manager_check_for_and_process_events (GIOChannel *io_channel,
444
GIOCondition condition,
445
GsdSmartcardManagerWorker *worker)
448
GsdSmartcardManager *manager;
449
gboolean should_stop;
454
manager = worker->manager;
458
should_stop = (condition & G_IO_HUP) || (condition & G_IO_ERR);
461
g_debug ("received %s on event socket, stopping "
463
(condition & G_IO_HUP) && (condition & G_IO_ERR)?
465
(condition & G_IO_HUP)?
469
if (!(condition & G_IO_IN)) {
470
g_debug ("nevermind outta here!");
474
fd = g_io_channel_unix_get_fd (io_channel);
477
if (!read_bytes (fd, &event_type, 1)) {
478
g_debug ("could not read event type, stopping");
483
card = read_smartcard (fd, worker->module);
486
g_debug ("could not read card, stopping");
491
card_name = gsd_smartcard_get_name (card);
492
g_debug ("card '%s' had event %c", card_name, event_type);
494
switch (event_type) {
496
g_hash_table_replace (manager->priv->smartcards,
500
gsd_smartcard_manager_emit_smartcard_inserted (manager, card);
505
gsd_smartcard_manager_emit_smartcard_removed (manager, card);
506
if (!g_hash_table_remove (manager->priv->smartcards, card_name)) {
507
g_debug ("got removal event of unknown card!");
517
g_object_unref (card);
527
error = g_error_new (GSD_SMARTCARD_MANAGER_ERROR,
528
GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS,
529
"%s", (condition & G_IO_IN) ? g_strerror (errno) : _("received error or hang up from event source"));
531
gsd_smartcard_manager_emit_error (manager, error);
532
g_error_free (error);
533
gsd_smartcard_manager_stop_now (manager);
541
stop_manager (GsdSmartcardManager *manager)
543
manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STOPPED;
545
if (manager->priv->nss_is_loaded) {
547
manager->priv->nss_is_loaded = FALSE;
549
g_debug ("smartcard manager stopped");
553
stop_worker (GsdSmartcardManagerWorker *worker)
555
GsdSmartcardManager *manager;
557
manager = worker->manager;
559
if (worker->event_source != NULL) {
560
g_source_destroy (worker->event_source);
561
worker->event_source = NULL;
564
if (worker->thread != NULL) {
565
SECMOD_CancelWait (worker->module);
566
worker->thread = NULL;
569
SECMOD_DestroyModule (worker->module);
570
manager->priv->workers = g_list_remove (manager->priv->workers, worker);
572
if (manager->priv->workers == NULL && manager->priv->state != GSD_SMARTCARD_MANAGER_STATE_STOPPED) {
573
stop_manager (manager);
578
gsd_smartcard_manager_event_processing_stopped_handler (GsdSmartcardManagerWorker *worker)
580
worker->event_source = NULL;
582
stop_worker (worker);
586
open_pipe (int *write_fd,
589
int pipe_fds[2] = { -1, -1 };
591
g_assert (write_fd != NULL);
592
g_assert (read_fd != NULL);
594
if (pipe (pipe_fds) < 0) {
598
if (fcntl (pipe_fds[0], F_SETFD, FD_CLOEXEC) < 0) {
604
if (fcntl (pipe_fds[1], F_SETFD, FD_CLOEXEC) < 0) {
610
*read_fd = pipe_fds[0];
611
*write_fd = pipe_fds[1];
617
gsd_smartcard_manager_stop_watching_for_events (GsdSmartcardManager *manager)
621
node = manager->priv->workers;
622
while (node != NULL) {
623
GsdSmartcardManagerWorker *worker;
626
worker = (GsdSmartcardManagerWorker *) node->data;
627
next_node = node->next;
629
stop_worker (worker);
636
load_nss (GError **error)
638
SECStatus status = SECSuccess;
639
static const guint32 flags =
641
NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT |
642
NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD;
644
g_debug ("attempting to load NSS database '%s'",
645
GSD_SMARTCARD_MANAGER_NSS_DB);
647
PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
649
status = NSS_Initialize (GSD_SMARTCARD_MANAGER_NSS_DB,
650
"", "", SECMOD_DB, flags);
652
if (status != SECSuccess) {
653
gsize error_message_size;
656
error_message_size = PR_GetErrorTextLength ();
658
if (error_message_size == 0) {
659
g_debug ("NSS security system could not be initialized");
661
GSD_SMARTCARD_MANAGER_ERROR,
662
GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
663
_("NSS security system could not be initialized"));
667
error_message = g_slice_alloc0 (error_message_size);
668
PR_GetErrorText (error_message);
671
GSD_SMARTCARD_MANAGER_ERROR,
672
GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
673
"%s", error_message);
674
g_debug ("NSS security system could not be initialized - %s",
677
g_slice_free1 (error_message_size, error_message);
682
g_debug ("NSS database sucessfully loaded");
686
g_debug ("NSS database couldn't be sucessfully loaded");
691
get_available_modules (GsdSmartcardManager *manager)
693
SECMODModuleList *module_list, *tmp;
696
g_debug ("Getting list of suitable modules");
698
module_list = SECMOD_GetDefaultModuleList ();
700
for (tmp = module_list; tmp != NULL; tmp = tmp->next) {
701
if (!SECMOD_HasRemovableSlots (tmp->module) ||
702
!tmp->module->loaded)
705
g_debug ("Using module '%s'", tmp->module->commonName);
707
modules = g_list_prepend (modules,
708
SECMOD_ReferenceModule (tmp->module));
715
load_driver (GsdSmartcardManager *manager,
721
gboolean module_explicitly_specified;
723
g_debug ("attempting to load driver...");
726
module_explicitly_specified = module_path != NULL;
727
if (module_explicitly_specified) {
728
SECMODModule *module;
730
module_spec = g_strdup_printf ("library=\"%s\"", module_path);
731
g_debug ("loading smartcard driver using spec '%s'",
734
module = SECMOD_LoadUserModule (module_spec,
736
FALSE /* recurse */);
737
g_free (module_spec);
740
if (SECMOD_HasRemovableSlots (module) &&
742
modules = g_list_prepend (modules, module);
744
g_debug ("fallback module found but not %s",
745
SECMOD_HasRemovableSlots (module)?
746
"removable" : "loaded");
747
SECMOD_DestroyModule (module);
751
SECMODListLock *lock;
753
lock = SECMOD_GetDefaultModuleListLock ();
756
SECMOD_GetReadLock (lock);
757
modules = get_available_modules (manager);
758
SECMOD_ReleaseReadLock (lock);
761
/* fallback to compiled in driver path
763
if (modules == NULL) {
764
SECMODModule *module;
765
module_path = GSD_SMARTCARD_MANAGER_DRIVER;
766
module_spec = g_strdup_printf ("library=\"%s\"", module_path);
767
g_debug ("loading smartcard driver using spec '%s'",
770
module = SECMOD_LoadUserModule (module_spec,
772
FALSE /* recurse */);
773
g_free (module_spec);
776
if (SECMOD_HasRemovableSlots (module) &&
778
modules = g_list_prepend (modules, module);
780
g_debug ("fallback module found but not loaded");
781
SECMOD_DestroyModule (module);
787
if (!module_explicitly_specified && modules == NULL) {
789
GSD_SMARTCARD_MANAGER_ERROR,
790
GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
791
_("no suitable smartcard driver could be found"));
792
} else if (modules == NULL) {
794
gsize error_message_size;
797
error_message_size = PR_GetErrorTextLength ();
799
if (error_message_size == 0) {
800
g_debug ("smartcard driver '%s' could not be loaded",
803
GSD_SMARTCARD_MANAGER_ERROR,
804
GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
805
_("smartcard driver '%s' could not be "
806
"loaded"), module_path);
810
error_message = g_slice_alloc0 (error_message_size);
811
PR_GetErrorText (error_message);
814
GSD_SMARTCARD_MANAGER_ERROR,
815
GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
816
"%s", error_message);
818
g_debug ("smartcard driver '%s' could not be loaded - %s",
819
module_path, error_message);
820
g_slice_free1 (error_message_size, error_message);
823
manager->priv->modules = modules;
825
return manager->priv->modules != NULL;
829
gsd_smartcard_manager_get_all_cards (GsdSmartcardManager *manager)
834
node = manager->priv->workers;
835
while (node != NULL) {
837
GsdSmartcardManagerWorker *worker;
839
worker = (GsdSmartcardManagerWorker *) node->data;
841
for (i = 0; i < worker->module->slotCount; i++) {
847
slot_id = PK11_GetSlotID (worker->module->slots[i]);
848
slot_series = PK11_GetSlotSeries (worker->module->slots[i]);
850
card = _gsd_smartcard_new (worker->module,
851
slot_id, slot_series);
853
card_name = gsd_smartcard_get_name (card);
855
g_hash_table_replace (manager->priv->smartcards,
862
static GsdSmartcardManagerWorker *
863
start_worker (GsdSmartcardManager *manager,
864
SECMODModule *module,
867
GIOChannel *io_channel;
869
GsdSmartcardManagerWorker *worker;
871
worker = gsd_smartcard_manager_create_worker (manager, module);
873
if (worker == NULL) {
875
GSD_SMARTCARD_MANAGER_ERROR,
876
GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS,
877
_("could not watch for incoming card events - %s"),
883
io_channel = g_io_channel_unix_new (worker->manager_fd);
885
source = g_io_create_watch (io_channel, G_IO_IN | G_IO_HUP);
886
g_io_channel_unref (io_channel);
889
worker->event_source = source;
891
g_source_set_callback (worker->event_source,
892
(GSourceFunc) (GIOFunc)
893
gsd_smartcard_manager_check_for_and_process_events,
896
gsd_smartcard_manager_event_processing_stopped_handler);
897
g_source_attach (worker->event_source, NULL);
898
g_source_unref (worker->event_source);
904
start_workers (GsdSmartcardManager *manager)
908
node = manager->priv->modules;
909
while (node != NULL) {
910
SECMODModule *module;
911
GsdSmartcardManagerWorker *worker;
914
module = (SECMODModule *) node->data;
917
worker = start_worker (manager, module, &error);
918
if (worker == NULL) {
919
g_warning ("%s", error->message);
920
g_error_free (error);
922
manager->priv->workers = g_list_prepend (manager->priv->workers,
930
gsd_smartcard_manager_start (GsdSmartcardManager *manager,
935
if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STARTED) {
936
g_debug ("smartcard manager already started");
940
manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STARTING;
943
if (!manager->priv->nss_is_loaded && !load_nss (&nss_error)) {
944
g_propagate_error (error, nss_error);
947
manager->priv->nss_is_loaded = TRUE;
949
if (manager->priv->modules == NULL) {
950
if (!load_driver (manager, manager->priv->module_path, &nss_error)) {
951
g_propagate_error (error, nss_error);
956
start_workers (manager);
958
/* populate the hash with cards that are already inserted
960
gsd_smartcard_manager_get_all_cards (manager);
962
manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STARTED;
965
/* don't leave it in a half started state
967
if (manager->priv->state != GSD_SMARTCARD_MANAGER_STATE_STARTED) {
968
g_debug ("smartcard manager could not be completely started");
969
gsd_smartcard_manager_stop (manager);
971
g_debug ("smartcard manager started");
974
return manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STARTED;
978
gsd_smartcard_manager_stop_now (GsdSmartcardManager *manager)
980
if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STOPPED) {
984
gsd_smartcard_manager_stop_watching_for_events (manager);
990
gsd_smartcard_manager_queue_stop (GsdSmartcardManager *manager)
993
manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STOPPING;
995
g_idle_add ((GSourceFunc) gsd_smartcard_manager_stop_now, manager);
999
gsd_smartcard_manager_stop (GsdSmartcardManager *manager)
1001
if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STOPPED) {
1005
if (manager->priv->is_unstoppable) {
1006
gsd_smartcard_manager_queue_stop (manager);
1010
gsd_smartcard_manager_stop_now (manager);
1014
gsd_smartcard_manager_check_for_login_card (CK_SLOT_ID slot_id,
1016
gboolean *is_inserted)
1018
g_assert (is_inserted != NULL);
1020
if (gsd_smartcard_is_login_card (card)) {
1021
*is_inserted = TRUE;
1027
gsd_smartcard_manager_login_card_is_inserted (GsdSmartcardManager *manager)
1030
gboolean is_inserted;
1032
is_inserted = FALSE;
1033
g_hash_table_foreach (manager->priv->smartcards,
1035
gsd_smartcard_manager_check_for_login_card,
1040
static GsdSmartcardManagerWorker *
1041
gsd_smartcard_manager_worker_new (GsdSmartcardManager *manager,
1044
SECMODModule *module)
1046
GsdSmartcardManagerWorker *worker;
1048
worker = g_slice_new0 (GsdSmartcardManagerWorker);
1049
worker->manager = manager;
1050
worker->fd = worker_fd;
1051
worker->manager_fd = manager_fd;
1052
worker->module = module;
1054
worker->smartcards =
1055
g_hash_table_new_full ((GHashFunc) slot_id_hash,
1056
(GEqualFunc) slot_id_equal,
1057
(GDestroyNotify) g_free,
1058
(GDestroyNotify) g_object_unref);
1064
gsd_smartcard_manager_worker_free (GsdSmartcardManagerWorker *worker)
1066
if (worker->smartcards != NULL) {
1067
g_hash_table_destroy (worker->smartcards);
1068
worker->smartcards = NULL;
1071
g_slice_free (GsdSmartcardManagerWorker, worker);
1080
size_t total_bytes_read;
1083
bytes_left = (size_t) num_bytes;
1084
total_bytes_read = 0;
1087
bytes_read = read (fd,
1088
(char *) bytes + total_bytes_read,
1090
g_assert (bytes_read <= (ssize_t) bytes_left);
1092
if (bytes_read <= 0) {
1093
if ((bytes_read < 0) && (errno == EINTR || errno == EAGAIN)) {
1099
bytes_left -= bytes_read;
1100
total_bytes_read += bytes_read;
1102
} while (bytes_left > 0);
1104
if (total_bytes_read < (size_t) num_bytes) {
1112
write_bytes (int fd,
1113
gconstpointer bytes,
1117
size_t total_bytes_written;
1118
ssize_t bytes_written;
1120
bytes_left = (size_t) num_bytes;
1121
total_bytes_written = 0;
1124
bytes_written = write (fd,
1125
(char *) bytes + total_bytes_written,
1127
g_assert (bytes_written <= (ssize_t) bytes_left);
1129
if (bytes_written <= 0) {
1130
if ((bytes_written < 0) && (errno == EINTR || errno == EAGAIN)) {
1136
bytes_left -= bytes_written;
1137
total_bytes_written += bytes_written;
1139
} while (bytes_left > 0);
1141
if (total_bytes_written < (size_t) num_bytes) {
1148
static GsdSmartcard *
1149
read_smartcard (int fd,
1150
SECMODModule *module)
1154
gsize card_name_size;
1157
if (!read_bytes (fd, &card_name_size, sizeof (card_name_size))) {
1161
card_name = g_slice_alloc0 (card_name_size);
1162
if (!read_bytes (fd, card_name, card_name_size)) {
1163
g_slice_free1 (card_name_size, card_name);
1166
card = _gsd_smartcard_new_from_name (module, card_name);
1167
g_slice_free1 (card_name_size, card_name);
1173
write_smartcard (int fd,
1176
gsize card_name_size;
1179
card_name = gsd_smartcard_get_name (card);
1180
card_name_size = strlen (card_name) + 1;
1182
if (!write_bytes (fd, &card_name_size, sizeof (card_name_size))) {
1187
if (!write_bytes (fd, card_name, card_name_size)) {
1197
gsd_smartcard_manager_worker_emit_smartcard_removed (GsdSmartcardManagerWorker *worker,
1201
g_debug ("card '%s' removed!", gsd_smartcard_get_name (card));
1203
if (!write_bytes (worker->fd, "R", 1)) {
1207
if (!write_smartcard (worker->fd, card)) {
1214
g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR,
1215
GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS,
1216
"%s", g_strerror (errno));
1221
gsd_smartcard_manager_worker_emit_smartcard_inserted (GsdSmartcardManagerWorker *worker,
1225
g_debug ("card '%s' inserted!", gsd_smartcard_get_name (card));
1226
if (!write_bytes (worker->fd, "I", 1)) {
1230
if (!write_smartcard (worker->fd, card)) {
1237
g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR,
1238
GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS,
1239
"%s", g_strerror (errno));
1244
gsd_smartcard_manager_worker_watch_for_and_process_event (GsdSmartcardManagerWorker *worker,
1248
CK_SLOT_ID slot_id, *key = NULL;
1249
int slot_series, card_slot_series;
1251
GError *processing_error;
1254
g_debug ("waiting for card event");
1257
slot = SECMOD_WaitForAnyTokenEvent (worker->module, 0, PR_SecondsToInterval (1));
1259
processing_error = NULL;
1264
error_code = PORT_GetError ();
1265
if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT)) {
1266
g_debug ("spurrious event occurred");
1270
/* FIXME: is there a function to convert from a PORT error
1271
* code to a translated string?
1273
g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR,
1274
GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
1275
_("encountered unexpected error while "
1276
"waiting for smartcard events"));
1280
/* the slot id and series together uniquely identify a card.
1281
* You can never have two cards with the same slot id at the
1282
* same time, however (I think), so we can key off of it.
1284
slot_id = PK11_GetSlotID (slot);
1285
slot_series = PK11_GetSlotSeries (slot);
1287
/* First check to see if there is a card that we're currently
1288
* tracking in the slot.
1290
key = g_new (CK_SLOT_ID, 1);
1292
card = g_hash_table_lookup (worker->smartcards, key);
1295
card_slot_series = gsd_smartcard_get_slot_series (card);
1297
card_slot_series = -1;
1300
if (PK11_IsPresent (slot)) {
1301
/* Now, check to see if their is a new card in the slot.
1302
* If there was a different card in the slot now than
1303
* there was before, then we need to emit a removed signal
1304
* for the old card (we don't want unpaired insertion events).
1306
if ((card != NULL) &&
1307
card_slot_series != slot_series) {
1308
if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) {
1309
g_propagate_error (error, processing_error);
1314
card = _gsd_smartcard_new (worker->module,
1315
slot_id, slot_series);
1317
g_hash_table_replace (worker->smartcards,
1321
if (!gsd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) {
1322
g_propagate_error (error, processing_error);
1326
/* if we aren't tracking the card, just discard the event.
1327
* We don't want unpaired remove events. Note on startup
1328
* NSS will generate an "insertion" event if a card is
1329
* already inserted in the slot.
1331
if ((card != NULL)) {
1332
/* FIXME: i'm not sure about this code. Maybe we
1333
* shouldn't do this at all, or maybe we should do it
1334
* n times (where n = slot_series - card_slot_series + 1)
1336
* Right now, i'm just doing it once.
1338
if ((slot_series - card_slot_series) > 1) {
1340
if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) {
1341
g_propagate_error (error, processing_error);
1344
g_hash_table_remove (worker->smartcards, key);
1346
card = _gsd_smartcard_new (worker->module,
1347
slot_id, slot_series);
1348
g_hash_table_replace (worker->smartcards,
1351
if (!gsd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) {
1352
g_propagate_error (error, processing_error);
1357
if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) {
1358
g_propagate_error (error, processing_error);
1362
g_hash_table_remove (worker->smartcards, key);
1365
g_debug ("got spurious remove event");
1373
PK11_FreeSlot (slot);
1379
gsd_smartcard_manager_worker_run (GsdSmartcardManagerWorker *worker)
1382
gboolean should_continue;
1387
should_continue = gsd_smartcard_manager_worker_watch_for_and_process_event (worker, &error);
1389
while (should_continue);
1391
if (error != NULL) {
1392
g_debug ("could not process card event - %s", error->message);
1393
g_error_free (error);
1396
gsd_smartcard_manager_worker_free (worker);
1399
static GsdSmartcardManagerWorker *
1400
gsd_smartcard_manager_create_worker (GsdSmartcardManager *manager,
1401
SECMODModule *module)
1403
GsdSmartcardManagerWorker *worker;
1404
int write_fd, read_fd;
1408
if (!open_pipe (&write_fd, &read_fd)) {
1412
worker = gsd_smartcard_manager_worker_new (manager,
1417
worker->thread = g_thread_create ((GThreadFunc)
1418
gsd_smartcard_manager_worker_run,
1419
worker, FALSE, NULL);
1421
if (worker->thread == NULL) {
1422
gsd_smartcard_manager_worker_free (worker);
1429
#ifdef GSD_SMARTCARD_MANAGER_ENABLE_TEST
1432
static GMainLoop *event_loop;
1433
static gboolean should_exit_on_next_remove = FALSE;
1436
on_timeout (GsdSmartcardManager *manager)
1439
g_print ("Re-enabling manager.\n");
1441
if (!gsd_smartcard_manager_start (manager, &error)) {
1442
g_warning ("could not start smartcard manager - %s",
1444
g_error_free (error);
1447
g_print ("Please re-insert smartcard\n");
1449
should_exit_on_next_remove = TRUE;
1455
on_device_inserted (GsdSmartcardManager *manager,
1458
g_print ("smartcard inserted!\n");
1459
g_print ("Please remove it.\n");
1463
on_device_removed (GsdSmartcardManager *manager,
1466
g_print ("smartcard removed!\n");
1468
if (should_exit_on_next_remove) {
1469
g_main_loop_quit (event_loop);
1471
g_print ("disabling manager for 2 seconds\n");
1472
gsd_smartcard_manager_stop (manager);
1473
g_timeout_add_seconds (2, (GSourceFunc) on_timeout, manager);
1481
GsdSmartcardManager *manager;
1484
g_log_set_always_fatal (G_LOG_LEVEL_ERROR
1485
| G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
1487
g_message ("creating instance of 'smartcard manager' object...");
1488
manager = gsd_smartcard_manager_new (NULL);
1489
g_message ("'smartcard manager' object created successfully");
1491
g_signal_connect (manager, "smartcard-inserted",
1492
G_CALLBACK (on_device_inserted), NULL);
1494
g_signal_connect (manager, "smartcard-removed",
1495
G_CALLBACK (on_device_removed), NULL);
1497
g_message ("starting listener...");
1500
if (!gsd_smartcard_manager_start (manager, &error)) {
1501
g_warning ("could not start smartcard manager - %s",
1503
g_error_free (error);
1507
event_loop = g_main_loop_new (NULL, FALSE);
1508
g_main_loop_run (event_loop);
1509
g_main_loop_unref (event_loop);
1512
g_message ("destroying previously created 'smartcard manager' object...");
1513
g_object_unref (manager);
1515
g_message ("'smartcard manager' object destroyed successfully");