int find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h, const char *wanted_slot_label, const char *wanted_token_label, unsigned int *slot_num) { SECMODModule *module = h->module; PK11SlotInfo *slot; unsigned long i; int rv; if (slot_num == NULL || module == NULL) return (-1); if (wanted_token_label == NULL){ rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num); return (rv); } /* wanted_token_label != NULL */ if (strcmp(wanted_slot_label, "none") == 0) { for (i = 0; i < module->slotCount; i++) { if (module->slots[i] && PK11_IsPresent(module->slots[i])) { const char *token_label; slot = PK11_ReferenceSlot(module->slots[i]); token_label = PK11_GetTokenName(slot); if (memcmp_pad_max((void *) token_label, strlen(token_label), (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0) { h->slot = slot; *slot_num = PK11_GetSlotID(slot); return (0); } } } return (-1); } else { for (i = 0; i < module->slotCount; i++) { if (module->slots[i] && PK11_IsPresent(module->slots[i])) { const char *slot_label; const char *token_label; slot = PK11_ReferenceSlot(module->slots[i]); slot_label = PK11_GetSlotName(slot); token_label = PK11_GetTokenName(slot); if ((memcmp_pad_max((void *)slot_label, strlen(slot_label), (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) && (memcmp_pad_max((void *)token_label, strlen(token_label), (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0)) { h->slot = slot; *slot_num = PK11_GetSlotID(slot); return (0); } } } return (-1); } }
int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot_num) { /* NSS manages the sessions under the covers, use this function to * select a slot */ if (h->slot != NULL) { /* we've already selected the slot */ if (PK11_GetSlotID(h->slot) == slot_num) { return 0; } /* the slot we've selected isn't the one we want to open */ PK11_FreeSlot(h->slot); h->slot = NULL; } /* look the slot up */ h->slot = SECMOD_LookupSlot(h->module->moduleID, slot_num); if (h->slot == NULL) { return -1; } /* make sure it is present */ if (!PK11_IsPresent(h->slot)) { PK11_FreeSlot(h->slot); h->slot = NULL; return -1; } return 0; }
static void sync_initial_tokens_from_driver (GsdSmartcardManager *self, SECMODModule *driver, GHashTable *smartcards, GCancellable *cancellable) { GsdSmartcardManagerPrivate *priv = self->priv; int i; for (i = 0; i < driver->slotCount; i++) { PK11SlotInfo *card; card = driver->slots[i]; if (PK11_IsPresent (card)) { CK_SLOT_ID slot_id; slot_id = PK11_GetSlotID (card); g_debug ("Detected smartcard in slot %d at start up", (int) slot_id); g_hash_table_replace (smartcards, GINT_TO_POINTER ((int) slot_id), PK11_ReferenceSlot (card)); gsd_smartcard_service_sync_token (priv->service, card, cancellable); } } }
static PK11SlotInfo * msd_smartcard_find_slot_from_id (MsdSmartcard *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; }
/* * find a slot by it's slot number or label. If slot number is '0' any * slot is ok. */ int find_slot_by_number_and_label(pkcs11_handle_t *h, int wanted_slot_id, const char *wanted_token_label, unsigned int *slot_num) { int rv; const char *token_label = NULL; PK11SlotInfo *slot = NULL; /* we want a specific slot id, or we don't kare about the label */ if ((wanted_token_label == NULL) || (wanted_slot_id != 0)) { rv = find_slot_by_number(h, wanted_slot_id, slot_num); /* if we don't care about the label, or we failed, we're done */ if ((wanted_token_label == NULL) || (rv != 0)) { return rv; } /* verify it's the label we want */ token_label = PK11_GetTokenName(h->slot); if ((token_label != NULL) && (strcmp (wanted_token_label, token_label) == 0)) { return 0; } return -1; } /* we want a specific slot by label only */ slot = PK11_FindSlotByName(wanted_token_label); if (!slot) { return -1; } /* make sure it's in the right module */ if (h->module) { if (h->module != PK11_GetModule(slot)) { PK11_FreeSlot(slot); return -1; } } else { /* no module was specified, use the one slot came in */ h->module = SECMOD_ReferenceModule(PK11_GetModule(slot)); } h->slot = slot; /* Adopt the reference */ *slot_num = PK11_GetSlotID(h->slot); return 0; }
static void msd_smartcard_set_name (MsdSmartcard *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 = msd_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) { msd_smartcard_set_slot_id (card, slot_id); } slot_series = PK11_GetSlotSeries (card->priv->slot); if (slot_series != card->priv->slot_series) { msd_smartcard_set_slot_series (card, slot_series); } _msd_smartcard_set_state (card, MSD_SMARTCARD_STATE_INSERTED); } else { _msd_smartcard_set_state (card, MSD_SMARTCARD_STATE_REMOVED); } } g_object_notify (G_OBJECT (card), "name"); } }
/* * This function will search the slot list to find a slot based on the slot * label. If the wanted_slot_label is "none", then we will return the first * slot with the token presented. * * This function return 0 if it found a matching slot; otherwise, it returns * -1. */ int find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label, unsigned int *slotID) { SECMODModule *module = h->module; PK11SlotInfo *slot; int rv; int i; if (slotID == NULL || wanted_slot_label == NULL || strlen(wanted_slot_label) == 0 || module == NULL) return (-1); if (strcmp(wanted_slot_label, "none") == 0) { rv = find_slot_by_number(h, 0, slotID); return (rv); } else { /* wanted_slot_label is not "none" */ for (i = 0; i < module->slotCount; i++) { if (module->slots[i] && PK11_IsPresent(module->slots[i])) { const char *slot_label; slot = PK11_ReferenceSlot(module->slots[i]); slot_label = PK11_GetSlotName(slot); if (memcmp_pad_max((void *)slot_label, strlen(slot_label), (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) { h->slot = slot; *slotID = PK11_GetSlotID(slot); return 0; } } } } return (-1); }
int find_slot_by_number(pkcs11_handle_t *h, unsigned int slot_num, unsigned int *slotID) { SECMODModule *module = h->module; int i; /* if module is null, * any of the PKCS #11 modules specified in the system config * is available, find one */ if (module == NULL) { PK11SlotList *list; PK11SlotListElement *le; PK11SlotInfo *slot = NULL; /* find a slot, we haven't specifically selected a module, * so find an appropriate one. */ /* get them all */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL); if (list == NULL) { return -1; } for (le = list->head; le; le = le->next) { CK_SLOT_INFO slInfo; SECStatus rv; slInfo.flags = 0; rv = PK11_GetSlotInfo(le->slot, &slInfo); if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) { slot = PK11_ReferenceSlot(le->slot); module = SECMOD_ReferenceModule(PK11_GetModule(le->slot)); break; } } PK11_FreeSlotList(list); if (slot == NULL) { return -1; } h->slot = slot; h->module = module; *slotID = PK11_GetSlotID(slot); return 0; } /* * we're configured with a specific module, look for a present slot * on that module. */ if (slot_num == 0) { /* threaded applications should also acquire the * DefaultModuleListLock */ for (i=0; i < module->slotCount; i++) { if (module->slots[i] && PK11_IsPresent(module->slots[i])) { h->slot = PK11_ReferenceSlot(module->slots[i]); *slotID = PK11_GetSlotID(h->slot); return 0; } } } /* we're configured for a specific module and token, see if it's present */ slot_num--; if (slot_num < module->slotCount && module->slots && module->slots[slot_num] && PK11_IsPresent(module->slots[slot_num])) { h->slot = PK11_ReferenceSlot(module->slots[slot_num]); *slotID = PK11_GetSlotID(h->slot); return 0; } return -1; }
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 (g_cancellable_set_error_if_cancelled (cancellable, error)) { g_warning ("smartcard event function cancelled"); return FALSE; } if (card == NULL) { int error_code; error_code = PORT_GetError (); operation->number_of_consecutive_errors++; if (operation->number_of_consecutive_errors > 10) { g_warning ("Got %d consecutive smartcard errors, so giving up.", operation->number_of_consecutive_errors); g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, "encountered unexpected error while " "waiting for smartcard events (error %x)", error_code); return FALSE; } g_warning ("Got potentially spurious smartcard event error: %x.", error_code); g_usleep (0.5 * G_USEC_PER_SEC); return TRUE; } operation->number_of_consecutive_errors = 0; 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; }
// // This is the main loop. // void SmartCardMonitoringThread::Execute() { PK11SlotInfo *slot; const char *tokenName = nsnull; // // populate token names for already inserted tokens. // PK11SlotList *sl = PK11_FindSlotsByNames(mModule->dllName, nsnull, nsnull, true); PK11SlotListElement *sle; if (sl) { for (sle=PK11_GetFirstSafe(sl); sle; sle=PK11_GetNextSafe(sl,sle,false)) { SetTokenName(PK11_GetSlotID(sle->slot), PK11_GetTokenName(sle->slot), PK11_GetSlotSeries(sle->slot)); } PK11_FreeSlotList(sl); } // loop starts.. do { slot = SECMOD_WaitForAnyTokenEvent(mModule, 0, PR_SecondsToInterval(1) ); if (slot == nsnull) { break; } // now we have a potential insertion or removal event, see if the slot // is present to determine which it is... if (PK11_IsPresent(slot)) { // insertion CK_SLOT_ID slotID = PK11_GetSlotID(slot); PRUint32 series = PK11_GetSlotSeries(slot); // skip spurious insertion events... if (series != GetTokenSeries(slotID)) { // if there's a token name, then we have not yet issued a remove // event for the previous token, do so now... tokenName = GetTokenName(slotID); if (tokenName) { SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName); } tokenName = PK11_GetTokenName(slot); // save the token name and series SetTokenName(slotID, tokenName, series); SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_INSERT), tokenName); } } else { // retrieve token name CK_SLOT_ID slotID = PK11_GetSlotID(slot); tokenName = GetTokenName(slotID); // if there's not a token name, then the software isn't expecting // a (or another) remove event. if (tokenName) { SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName); // clear the token name (after we send it) SetTokenName(slotID, nsnull, 0); } } PK11_FreeSlot(slot); } while (1); }