/* Re-insert of a card that has been removed by force removal */ VCardEmulError vcard_emul_force_card_insert(VReader *vreader) { VReaderEmul *vreader_emul; VCard *vcard; if (!nss_emul_init || (vreader_card_is_present(vreader) == VREADER_OK)) { return VCARD_EMUL_FAIL; /* card is already removed */ } vreader_emul = vreader_get_private(vreader); /* if it's a softcard, get the saved vcard from the reader emul structure */ if (vreader_emul->saved_vcard) { vcard = vcard_reference(vreader_emul->saved_vcard); } else { /* it must be a physical card, rebuild it */ if (!PK11_IsPresent(vreader_emul->slot)) { /* physical card has been removed, not way to reinsert it */ return VCARD_EMUL_FAIL; } vcard = vcard_emul_mirror_card(vreader); } vreader_insert_card(vreader, vcard); vcard_free(vcard); return VCARD_EMUL_OK; }
/* pull the slot out of the reader private data */ static PK11SlotInfo * vcard_emul_reader_get_slot(VReader *vreader) { VReaderEmul *vreader_emul = vreader_get_private(vreader); if (vreader_emul == NULL) { return NULL; } return vreader_emul->slot; }
/* * This thread looks for card and reader insertions and puts events on the * event queue */ static void vcard_emul_event_thread(void *arg) { PK11SlotInfo *slot; VReader *vreader; VReaderEmul *vreader_emul; VCard *vcard; SECMODModule *module = (SECMODModule *)arg; do { slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500); if (slot == NULL) { break; } vreader = vcard_emul_find_vreader_from_slot(slot); if (vreader == NULL) { /* new vreader */ vreader_emul = vreader_emul_new(slot, default_card_type, default_type_params); vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul, vreader_emul_delete); PK11_FreeSlot(slot); slot = NULL; vreader_add_reader(vreader); vreader_free(vreader); continue; } /* card remove/insert */ vreader_emul = vreader_get_private(vreader); if (PK11_IsPresent(slot)) { int series = PK11_GetSlotSeries(slot); if (series != vreader_emul->series) { if (vreader_emul->present) { vreader_insert_card(vreader, NULL); } vcard = vcard_emul_mirror_card(vreader); vreader_insert_card(vreader, vcard); vcard_free(vcard); } vreader_emul->series = series; vreader_emul->present = 1; vreader_free(vreader); PK11_FreeSlot(slot); continue; } if (vreader_emul->present) { vreader_insert_card(vreader, NULL); } vreader_emul->series = 0; vreader_emul->present = 0; PK11_FreeSlot(slot); vreader_free(vreader); } while (1); }
/* if the card is inserted when we start up, make sure our state is correct */ static void vcard_emul_init_series(VReader *vreader, VCard *vcard) { VReaderEmul *vreader_emul = vreader_get_private(vreader); PK11SlotInfo *slot = vreader_emul->slot; vreader_emul->present = PK11_IsPresent(slot); vreader_emul->series = PK11_GetSlotSeries(slot); if (vreader_emul->present == 0) { vreader_insert_card(vreader, NULL); } }
/* * TODO: move this to emulater non-specific file */ static const char * vcard_emul_get_type_params(VReader *vreader) { VReaderEmul *vreader_emul; vreader_emul = vreader_get_private(vreader); if (vreader_emul && vreader_emul->type_params) { return vreader_emul->type_params; } return ""; }
/* * TODO: move this to emulater non-specific file */ static VCardEmulType vcard_emul_get_type(VReader *vreader) { VReaderEmul *vreader_emul; vreader_emul = vreader_get_private(vreader); if (vreader_emul && vreader_emul->default_type != VCARD_EMUL_NONE) { return vreader_emul->default_type; } return vcard_emul_type_select(vreader); }
static VReader * vcard_emul_find_vreader_from_slot(PK11SlotInfo *slot) { VReaderList *reader_list = vreader_get_reader_list(); VReaderListEntry *current_entry = NULL; if (reader_list == NULL) { return NULL; } for (current_entry = vreader_list_get_first(reader_list); current_entry; current_entry = vreader_list_get_next(current_entry)) { VReader *reader = vreader_list_get_reader(current_entry); VReaderEmul *reader_emul = vreader_get_private(reader); if (reader_emul->slot == slot) { return reader; } vreader_free(reader); } return NULL; }
/* * This thread looks for card and reader insertions and puts events on the * event queue */ static void vcard_emul_event_thread(void *arg) { PK11SlotInfo *slot; VReader *vreader; VReaderEmul *vreader_emul; VCard *vcard; SECMODModule *module = (SECMODModule *)arg; do { /* * XXX - the latency value doesn't matter one bit. you only get no * blocking (flags |= CKF_DONT_BLOCK) or PKCS11_WAIT_LATENCY (==500), * hard coded in coolkey. And it isn't coolkey's fault - the timeout * value we pass get's dropped on the floor before C_WaitForSlotEvent * is called. */ slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500); if (slot == NULL) { /* this could be just a no event indication */ if (PORT_GetError() == SEC_ERROR_NO_EVENT) { continue; } break; } vreader = vcard_emul_find_vreader_from_slot(slot); if (vreader == NULL) { /* new vreader */ vreader_emul = vreader_emul_new(slot, default_card_type, default_type_params); vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul, vreader_emul_delete); PK11_FreeSlot(slot); slot = NULL; vreader_add_reader(vreader); vreader_free(vreader); continue; } /* card remove/insert */ vreader_emul = vreader_get_private(vreader); if (PK11_IsPresent(slot)) { int series = PK11_GetSlotSeries(slot); if (series != vreader_emul->series) { if (vreader_emul->present) { vreader_insert_card(vreader, NULL); } vcard = vcard_emul_mirror_card(vreader); vreader_insert_card(vreader, vcard); vcard_free(vcard); } vreader_emul->series = series; vreader_emul->present = 1; vreader_free(vreader); PK11_FreeSlot(slot); continue; } if (vreader_emul->present) { vreader_insert_card(vreader, NULL); } vreader_emul->series = 0; vreader_emul->present = 0; PK11_FreeSlot(slot); vreader_free(vreader); } while (1); }