/* * Find the Slot based on ID and the module. */ PK11SlotInfo * SECMOD_FindSlotByID(SECMODModule *module, CK_SLOT_ID slotID) { int i; PK11SlotInfo *slot = NULL; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return slot; } SECMOD_GetReadLock(moduleLock); for (i=0; i < module->slotCount; i++) { PK11SlotInfo *cSlot = module->slots[i]; if (cSlot->slotID == slotID) { slot = PK11_ReferenceSlot(cSlot); break; } } SECMOD_ReleaseReadLock(moduleLock); if (slot == NULL) { PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED); } return slot; }
/* nsIEnumerator listModules (); */ NS_IMETHODIMP nsPKCS11ModuleDB::ListModules(nsIEnumerator **_retval) { nsNSSShutDownPreventionLock locker; nsresult rv = NS_OK; /* get isupports array */ nsCOMPtr<nsISupportsArray> array; rv = NS_NewISupportsArray(getter_AddRefs(array)); if (NS_FAILED(rv)) return rv; /* get the default list of modules */ SECMODModuleList *list = SECMOD_GetDefaultModuleList(); /* lock down the list for reading */ SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); SECMOD_GetReadLock(lock); while (list) { nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module); array->AppendElement(module); list = list->next; } /* Get the modules in the database that didn't load */ list = SECMOD_GetDeadModuleList(); while (list) { nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module); array->AppendElement(module); list = list->next; } SECMOD_ReleaseReadLock(lock); rv = array->Enumerate(_retval); return rv; }
PK11SlotInfo * SECMOD_FindSlot(SECMODModule *module,const char *name) { int i; char *string; PK11SlotInfo *retSlot = NULL; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return retSlot; } SECMOD_GetReadLock(moduleLock); for (i=0; i < module->slotCount; i++) { PK11SlotInfo *slot = module->slots[i]; if (PK11_IsPresent(slot)) { string = PK11_GetTokenName(slot); } else { string = PK11_GetSlotName(slot); } if (PORT_Strcmp(name,string) == 0) { retSlot = PK11_ReferenceSlot(slot); break; } } SECMOD_ReleaseReadLock(moduleLock); if (retSlot == NULL) { PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED); } return retSlot; }
/* nsIEnumerator listSlots (); */ NS_IMETHODIMP nsPKCS11Module::ListSlots(nsIEnumerator **_retval) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; nsresult rv = NS_OK; int i; /* get isupports array */ nsCOMPtr<nsISupportsArray> array; rv = NS_NewISupportsArray(getter_AddRefs(array)); if (NS_FAILED(rv)) return rv; /* applications which allow new slot creation (which Firefox now does * since it uses the WaitForSlotEvent call) need to hold the * ModuleList Read lock to prevent the slot array from changing out * from under it. */ SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); SECMOD_GetReadLock(lock); for (i=0; i<mModule->slotCount; i++) { if (mModule->slots[i]) { nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(mModule->slots[i]); array->AppendElement(slot); } } SECMOD_ReleaseReadLock(lock); rv = array->Enumerate(_retval); return rv; }
PRBool IsP11KitEnabled(void) { SECMODListLock *lock; SECMODModuleList *mlp; PRBool found = PR_FALSE; lock = SECMOD_GetDefaultModuleListLock(); if (!lock) { PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]); return found; } SECMOD_GetReadLock(lock); mlp = SECMOD_GetDefaultModuleList(); for (; mlp != NULL; mlp = mlp->next) { if (IsP11KitProxyModule(mlp->module)) { found = PR_TRUE; break; } } SECMOD_ReleaseReadLock(lock); return found; }
/* * check to see if the module has removable slots that we may need to * watch for. */ PRBool SECMOD_HasRemovableSlots(SECMODModule *mod) { int i; PRBool ret = PR_FALSE; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return ret; } SECMOD_GetReadLock(moduleLock); for (i=0; i < mod->slotCount; i++) { PK11SlotInfo *slot = mod->slots[i]; /* perm modules are not inserted or removed */ if (slot->isPerm) { continue; } ret = PR_TRUE; break; } if (mod->slotCount == 0 ) { ret = PR_TRUE; } SECMOD_ReleaseReadLock(moduleLock); return ret; }
/* * find a module by name, and add a reference to it. * return that module. */ SECMODModule * SECMOD_FindModule(const char *name) { SECMODModuleList *mlp; SECMODModule *module = NULL; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return module; } SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL; mlp = mlp->next) { if (PORT_Strcmp(name,mlp->module->commonName) == 0) { module = mlp->module; SECMOD_ReferenceModule(module); break; } } if (module) { goto found; } for(mlp = modulesUnload; mlp != NULL; mlp = mlp->next) { if (PORT_Strcmp(name,mlp->module->commonName) == 0) { module = mlp->module; SECMOD_ReferenceModule(module); break; } } found: SECMOD_ReleaseReadLock(moduleLock); return module; }
/* installs the PKCS11 module & update registry */ SECStatus SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath, unsigned long defaultMechanismFlags, unsigned long cipherEnableFlags, char* modparms, char* nssparms) { SECMODModule *module; SECStatus result = SECFailure; int s,i; PK11SlotInfo* slot; PR_SetErrorText(0, NULL); if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return result; } module = SECMOD_CreateModule(dllPath, moduleName, modparms, nssparms); if (module == NULL) { return result; } if (module->dllName != NULL) { if (module->dllName[0] != 0) { result = SECMOD_AddModule(module); if (result == SECSuccess) { /* turn on SSL cipher enable flags */ module->ssl[0] = cipherEnableFlags; SECMOD_GetReadLock(moduleLock); /* check each slot to turn on appropriate mechanisms */ for (s = 0; s < module->slotCount; s++) { slot = (module->slots)[s]; /* for each possible mechanism */ for (i=0; i < num_pk11_default_mechanisms; i++) { /* we are told to turn it on by default ? */ PRBool add = (PK11_DefaultArray[i].flag & defaultMechanismFlags) ? PR_TRUE: PR_FALSE; result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), add); } /* for each mechanism */ /* disable each slot if the defaultFlags say so */ if (defaultMechanismFlags & PK11_DISABLE_FLAG) { PK11_UserDisableSlot(slot); } } /* for each slot of this module */ SECMOD_ReleaseReadLock(moduleLock); /* delete and re-add module in order to save changes * to the module */ result = SECMOD_UpdateModule(module); } } } SECMOD_DestroyModule(module); return result; }
NSS_IMPLEMENT PRStatus STAN_LoadDefaultNSS3TrustDomain ( void ) { NSSTrustDomain *td; SECMODModuleList *mlp; SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); int i; if (g_default_trust_domain || g_default_crypto_context) { /* Stan is already initialized or a previous shutdown failed. */ nss_SetError(NSS_ERROR_ALREADY_INITIALIZED); return PR_FAILURE; } td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL); if (!td) { return PR_FAILURE; } /* * Deadlock warning: we should never acquire the moduleLock while * we hold the tokensLock. We can use the NSSRWLock Rank feature to * guarrentee this. tokensLock have a higher rank than module lock. */ td->tokenList = nssList_Create(td->arena, PR_TRUE); if (!td->tokenList) { goto loser; } SECMOD_GetReadLock(moduleLock); NSSRWLock_LockWrite(td->tokensLock); for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]); } } td->tokens = nssList_CreateIterator(td->tokenList); NSSRWLock_UnlockWrite(td->tokensLock); SECMOD_ReleaseReadLock(moduleLock); if (!td->tokens) { goto loser; } g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL); if (!g_default_crypto_context) { goto loser; } g_default_trust_domain = td; return PR_SUCCESS; loser: NSSTrustDomain_Destroy(td); return PR_FAILURE; }
/************************************************************************ * * L i s t M o d u l e s * * Lists all the modules in the database, along with their slots and tokens. */ Error ListModules() { SECMODListLock *lock; SECMODModuleList *list; SECMODModuleList *deadlist; SECMODModuleList *mlp; Error ret=UNSPECIFIED_ERR; int count = 0; lock = SECMOD_GetDefaultModuleListLock(); if(!lock) { PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]); return NO_LIST_LOCK_ERR; } SECMOD_GetReadLock(lock); list = SECMOD_GetDefaultModuleList(); deadlist = SECMOD_GetDeadModuleList(); if (!list && !deadlist) { PR_fprintf(PR_STDERR, errStrings[NO_MODULE_LIST_ERR]); ret = NO_MODULE_LIST_ERR; goto loser; } PR_fprintf(PR_STDOUT, "\nListing of PKCS #11 Modules\n" "-----------------------------------------------------------\n"); for(mlp=list; mlp != NULL; mlp = mlp->next) { printModule(mlp->module, &count); } for (mlp=deadlist; mlp != NULL; mlp = mlp->next) { printModule(mlp->module, &count); } PR_fprintf(PR_STDOUT, "-----------------------------------------------------------\n"); ret = SUCCESS; loser: SECMOD_ReleaseReadLock(lock); return ret; }
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); try_to_complete_all_drivers_activation (task); }
static PRBool module_has_removable_hw_slots(SECMODModule *mod) { int i; PRBool ret = PR_FALSE; SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return ret; } SECMOD_GetReadLock(moduleLock); for (i = 0; i < mod->slotCount; i++) { PK11SlotInfo *slot = mod->slots[i]; if (PK11_IsRemovable(slot) && PK11_IsHW(slot)) { ret = PR_TRUE; break; } } SECMOD_ReleaseReadLock(moduleLock); return ret; }
/* Funtion reports true if module of modType is installed/configured */ PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags ) { PRBool result = PR_FALSE; SECMODModuleList *mods; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return result; } SECMOD_GetReadLock(moduleLock); mods = SECMOD_GetDefaultModuleList(); for ( ; mods != NULL; mods = mods->next) { if (mods->module->ssl[0] & SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) { result = PR_TRUE; } } SECMOD_ReleaseReadLock(moduleLock); return result; }
void PK11_LogoutAll(void) { SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); SECMODModuleList *modList = SECMOD_GetDefaultModuleList(); SECMODModuleList *mlp = NULL; int i; /* NSS is not initialized, there are not tokens to log out */ if (lock == NULL) { return; } SECMOD_GetReadLock(lock); /* find the number of entries */ for (mlp = modList; mlp != NULL; mlp = mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { PK11_Logout(mlp->module->slots[i]); } } SECMOD_ReleaseReadLock(lock); }
/* * find the function pointer. */ SECMODModule * secmod_FindModuleByFuncPtr(void *funcPtr) { SECMODModuleList *mlp; SECMODModule *module = NULL; SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL; mlp = mlp->next) { /* paranoia, shouldn't ever happen */ if (!mlp->module) { continue; } if (funcPtr == mlp->module->functionList) { module = mlp->module; SECMOD_ReferenceModule(module); break; } } SECMOD_ReleaseReadLock(moduleLock); if (module == NULL) { PORT_SetError(SEC_ERROR_NO_MODULE); } return module; }
/* * find a module by ID, and add a reference to it. * return that module. */ SECMODModule * SECMOD_FindModuleByID(SECMODModuleID id) { SECMODModuleList *mlp; SECMODModule *module = NULL; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return module; } SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL; mlp = mlp->next) { if (id == mlp->module->moduleID) { module = mlp->module; SECMOD_ReferenceModule(module); break; } } SECMOD_ReleaseReadLock(moduleLock); if (module == NULL) { PORT_SetError(SEC_ERROR_NO_MODULE); } return module; }
VCardEmulError vcard_emul_init(const VCardEmulOptions *options) { SECStatus rv; PRBool ret, has_readers = PR_FALSE; VReader *vreader; VReaderEmul *vreader_emul; SECMODListLock *module_lock; SECMODModuleList *module_list; SECMODModuleList *mlp; int i; if (vcard_emul_init_called) { return VCARD_EMUL_INIT_ALREADY_INITED; } vcard_emul_init_called = 1; vreader_init(); vevent_queue_init(); if (options == NULL) { options = &default_options; } /* first initialize NSS */ if (options->nss_db) { rv = NSS_Init(options->nss_db); } else { gchar *path; #ifndef _WIN32 path = g_strdup("/etc/pki/nssdb"); #else if (g_get_system_config_dirs() == NULL || g_get_system_config_dirs()[0] == NULL) { return VCARD_EMUL_FAIL; } path = g_build_filename( g_get_system_config_dirs()[0], "pki", "nssdb", NULL); #endif rv = NSS_Init(path); g_free(path); } if (rv != SECSuccess) { return VCARD_EMUL_FAIL; } /* Set password callback function */ PK11_SetPasswordFunc(vcard_emul_get_password); /* set up soft cards emulated by software certs rather than physical cards * */ for (i = 0; i < options->vreader_count; i++) { int j; int cert_count; unsigned char **certs; int *cert_len; VCardKey **keys; PK11SlotInfo *slot; slot = PK11_FindSlotByName(options->vreader[i].name); if (slot == NULL) { continue; } vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type, options->vreader[i].type_params); vreader = vreader_new(options->vreader[i].vname, vreader_emul, vreader_emul_delete); vreader_add_reader(vreader); cert_count = options->vreader[i].cert_count; ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, options->vreader[i].cert_count); if (ret == PR_FALSE) { continue; } cert_count = 0; for (j = 0; j < options->vreader[i].cert_count; j++) { /* we should have a better way of identifying certs than by * nickname here */ CERTCertificate *cert = PK11_FindCertFromNickname( options->vreader[i].cert_name[j], NULL); if (cert == NULL) { continue; } certs[cert_count] = cert->derCert.data; cert_len[cert_count] = cert->derCert.len; keys[cert_count] = vcard_emul_make_key(slot, cert); /* this is safe because the key is still holding a cert reference */ CERT_DestroyCertificate(cert); cert_count++; } if (cert_count) { VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len, keys, cert_count); vreader_insert_card(vreader, vcard); vcard_emul_init_series(vreader, vcard); /* allow insertion and removal of soft cards */ vreader_emul->saved_vcard = vcard_reference(vcard); vcard_free(vcard); vreader_free(vreader); has_readers = PR_TRUE; } g_free(certs); g_free(cert_len); g_free(keys); } /* if we aren't suppose to use hw, skip looking up hardware tokens */ if (!options->use_hw) { nss_emul_init = has_readers; return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL; } /* make sure we have some PKCS #11 module loaded */ module_lock = SECMOD_GetDefaultModuleListLock(); module_list = SECMOD_GetDefaultModuleList(); SECMOD_GetReadLock(module_lock); for (mlp = module_list; mlp; mlp = mlp->next) { SECMODModule *module = mlp->module; if (module_has_removable_hw_slots(module)) { break; } } SECMOD_ReleaseReadLock(module_lock); /* now examine all the slots, finding which should be readers */ /* We should control this with options. For now we mirror out any * removable hardware slot */ default_card_type = options->hw_card_type; default_type_params = g_strdup(options->hw_type_params); SECMOD_GetReadLock(module_lock); for (mlp = module_list; mlp; mlp = mlp->next) { SECMODModule *module = mlp->module; /* Ignore the internal module */ if (module == NULL || module == SECMOD_GetInternalModule()) { continue; } for (i = 0; i < module->slotCount; i++) { PK11SlotInfo *slot = module->slots[i]; /* only map removable HW slots */ if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) { continue; } if (strcmp("E-Gate 0 0", PK11_GetSlotName(slot)) == 0) { /* * coolkey <= 1.1.0-20 emulates this reader if it can't find * any hardware readers. This causes problems, warn user of * problems. */ fprintf(stderr, "known bad coolkey version - see " "https://bugzilla.redhat.com/show_bug.cgi?id=802435\n"); continue; } vreader_emul = vreader_emul_new(slot, options->hw_card_type, options->hw_type_params); vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul, vreader_emul_delete); vreader_add_reader(vreader); if (PK11_IsPresent(slot)) { VCard *vcard; vcard = vcard_emul_mirror_card(vreader); vreader_insert_card(vreader, vcard); vcard_emul_init_series(vreader, vcard); vcard_free(vcard); } } vcard_emul_new_event_thread(module); } SECMOD_ReleaseReadLock(module_lock); nss_emul_init = PR_TRUE; return VCARD_EMUL_OK; }
VCardEmulError vcard_emul_init(const VCardEmulOptions *options) { SECStatus rv; PRBool ret, has_readers = PR_FALSE, need_coolkey_module; VReader *vreader; VReaderEmul *vreader_emul; SECMODListLock *module_lock; SECMODModuleList *module_list; SECMODModuleList *mlp; int i; if (vcard_emul_init_called) { return VCARD_EMUL_INIT_ALREADY_INITED; } vcard_emul_init_called = 1; vreader_init(); vevent_queue_init(); if (options == NULL) { options = &default_options; } /* first initialize NSS */ if (options->nss_db) { rv = NSS_Init(options->nss_db); } else { rv = NSS_Init("sql:/etc/pki/nssdb"); } if (rv != SECSuccess) { return VCARD_EMUL_FAIL; } /* Set password callback function */ PK11_SetPasswordFunc(vcard_emul_get_password); /* set up soft cards emulated by software certs rather than physical cards * */ for (i = 0; i < options->vreader_count; i++) { int j; int cert_count; unsigned char **certs; int *cert_len; VCardKey **keys; PK11SlotInfo *slot; slot = PK11_FindSlotByName(options->vreader[i].name); if (slot == NULL) { continue; } vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type, options->vreader[i].type_params); vreader = vreader_new(options->vreader[i].vname, vreader_emul, vreader_emul_delete); vreader_add_reader(vreader); cert_count = options->vreader[i].cert_count; ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, options->vreader[i].cert_count); if (ret == PR_FALSE) { continue; } cert_count = 0; for (j = 0; j < options->vreader[i].cert_count; j++) { /* we should have a better way of identifying certs than by * nickname here */ CERTCertificate *cert = PK11_FindCertFromNickname( options->vreader[i].cert_name[j], NULL); if (cert == NULL) { continue; } certs[cert_count] = cert->derCert.data; cert_len[cert_count] = cert->derCert.len; keys[cert_count] = vcard_emul_make_key(slot, cert); /* this is safe because the key is still holding a cert reference */ CERT_DestroyCertificate(cert); cert_count++; } if (cert_count) { VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len, keys, cert_count); vreader_insert_card(vreader, vcard); vcard_emul_init_series(vreader, vcard); /* allow insertion and removal of soft cards */ vreader_emul->saved_vcard = vcard_reference(vcard); vcard_free(vcard); vreader_free(vreader); has_readers = PR_TRUE; } g_free(certs); g_free(cert_len); g_free(keys); } /* if we aren't suppose to use hw, skip looking up hardware tokens */ if (!options->use_hw) { nss_emul_init = has_readers; return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL; } /* make sure we have some PKCS #11 module loaded */ module_lock = SECMOD_GetDefaultModuleListLock(); module_list = SECMOD_GetDefaultModuleList(); need_coolkey_module = !has_readers; SECMOD_GetReadLock(module_lock); for (mlp = module_list; mlp; mlp = mlp->next) { SECMODModule *module = mlp->module; if (module_has_removable_hw_slots(module)) { need_coolkey_module = PR_FALSE; break; } } SECMOD_ReleaseReadLock(module_lock); if (need_coolkey_module) { SECMODModule *module; module = SECMOD_LoadUserModule( (char *)"library=libcoolkeypk11.so name=Coolkey", NULL, PR_FALSE); if (module == NULL) { return VCARD_EMUL_FAIL; } SECMOD_DestroyModule(module); /* free our reference, Module will still * be on the list. * until we destroy it */ } /* now examine all the slots, finding which should be readers */ /* We should control this with options. For now we mirror out any * removable hardware slot */ default_card_type = options->hw_card_type; default_type_params = strdup(options->hw_type_params); SECMOD_GetReadLock(module_lock); for (mlp = module_list; mlp; mlp = mlp->next) { SECMODModule *module = mlp->module; PRBool has_emul_slots = PR_FALSE; if (module == NULL) { continue; } for (i = 0; i < module->slotCount; i++) { PK11SlotInfo *slot = module->slots[i]; /* only map removable HW slots */ if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) { continue; } vreader_emul = vreader_emul_new(slot, options->hw_card_type, options->hw_type_params); vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul, vreader_emul_delete); vreader_add_reader(vreader); has_readers = PR_TRUE; has_emul_slots = PR_TRUE; if (PK11_IsPresent(slot)) { VCard *vcard; vcard = vcard_emul_mirror_card(vreader); vreader_insert_card(vreader, vcard); vcard_emul_init_series(vreader, vcard); vcard_free(vcard); } } if (has_emul_slots) { vcard_emul_new_event_thread(module); } } SECMOD_ReleaseReadLock(module_lock); nss_emul_init = has_readers; return VCARD_EMUL_OK; }
/* * this handles modules that do not support C_WaitForSlotEvent(). * The internal flags are stored. Note that C_WaitForSlotEvent() does not * have a timeout, so we don't have one for handleWaitForSlotEvent() either. */ PK11SlotInfo * secmod_HandleWaitForSlotEvent(SECMODModule *mod, unsigned long flags, PRIntervalTime latency) { PRBool removableSlotsFound = PR_FALSE; int i; int error = SEC_ERROR_NO_EVENT; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return NULL; } PZ_Lock(mod->refLock); if (mod->evControlMask & SECMOD_END_WAIT) { mod->evControlMask &= ~SECMOD_END_WAIT; PZ_Unlock(mod->refLock); PORT_SetError(SEC_ERROR_NO_EVENT); return NULL; } mod->evControlMask |= SECMOD_WAIT_SIMULATED_EVENT; while (mod->evControlMask & SECMOD_WAIT_SIMULATED_EVENT) { PZ_Unlock(mod->refLock); /* now is a good time to see if new slots have been added */ SECMOD_UpdateSlotList(mod); /* loop through all the slots on a module */ SECMOD_GetReadLock(moduleLock); for (i=0; i < mod->slotCount; i++) { PK11SlotInfo *slot = mod->slots[i]; PRUint16 series; PRBool present; /* perm modules do not change */ if (slot->isPerm) { continue; } removableSlotsFound = PR_TRUE; /* simulate the PKCS #11 module flags. are the flags different * from the last time we called? */ series = slot->series; present = PK11_IsPresent(slot); if ((slot->flagSeries != series) || (slot->flagState != present)) { slot->flagState = present; slot->flagSeries = series; SECMOD_ReleaseReadLock(moduleLock); PZ_Lock(mod->refLock); mod->evControlMask &= ~SECMOD_END_WAIT; PZ_Unlock(mod->refLock); return PK11_ReferenceSlot(slot); } } SECMOD_ReleaseReadLock(moduleLock); /* if everything was perm modules, don't lock up forever */ if ((mod->slotCount !=0) && !removableSlotsFound) { error =SEC_ERROR_NO_SLOT_SELECTED; PZ_Lock(mod->refLock); break; } if (flags & CKF_DONT_BLOCK) { PZ_Lock(mod->refLock); break; } PR_Sleep(latency); PZ_Lock(mod->refLock); } mod->evControlMask &= ~SECMOD_END_WAIT; PZ_Unlock(mod->refLock); PORT_SetError(error); return NULL; }