Esempio n. 1
0
/*
 * find a module by name and delete it off the module list
 */
SECStatus
SECMOD_DeleteInternalModule(const char *name) 
{
    SECMODModuleList *mlp;
    SECMODModuleList **mlpp;
    SECStatus rv = SECFailure;

    if (pendingModule) {
	PORT_SetError(SEC_ERROR_MODULE_STUCK);
	return rv;
    }
    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return rv;
    }

    SECMOD_GetWriteLock(moduleLock);
    for(mlpp = &modules,mlp = modules; 
				mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
	if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
	    /* don't delete the internal module */
	    if (mlp->module->internal) {
		SECMOD_RemoveList(mlpp,mlp);
		rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module);
	    } 
	    break;
	}
    }
    SECMOD_ReleaseWriteLock(moduleLock);

    if (rv == SECSuccess) {
	SECMODModule *newModule,*oldModule;

	if (mlp->module->isFIPS) {
    	    newModule = SECMOD_CreateModule(NULL, SECMOD_INT_NAME,
				NULL, SECMOD_INT_FLAGS);
	} else {
    	    newModule = SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME,
				NULL, SECMOD_FIPS_FLAGS);
	}
	if (newModule) {
	    PK11SlotInfo *slot;
	    newModule->libraryParams = 
	     PORT_ArenaStrdup(newModule->arena,mlp->module->libraryParams);
	    /* if an explicit internal key slot has been set, reset it */
	    slot = pk11_SwapInternalKeySlot(NULL);
	    if (slot) {
		secmod_SetInternalKeySlotFlag(newModule, PR_TRUE);
	    }
	    rv = SECMOD_AddModule(newModule);
	    if (rv != SECSuccess) {
		/* load failed, restore the internal key slot */
		pk11_SetInternalKeySlot(slot);
		SECMOD_DestroyModule(newModule);
		newModule = NULL;
	    }
	    /* free the old explicit internal key slot, we now have a new one */
	    if (slot) {
		PK11_FreeSlot(slot);
	    }
	}
	if (newModule == NULL) {
	    SECMODModuleList *last = NULL,*mlp2;
	   /* we're in pretty deep trouble if this happens...Security
	    * not going to work well... try to put the old module back on
	    * the list */
	   SECMOD_GetWriteLock(moduleLock);
	   for(mlp2 = modules; mlp2 != NULL; mlp2 = mlp->next) {
		last = mlp2;
	   }

	   if (last == NULL) {
		modules = mlp;
	   } else {
		SECMOD_AddList(last,mlp,NULL);
	   }
	   SECMOD_ReleaseWriteLock(moduleLock);
	   return SECFailure; 
	}
	pendingModule = oldModule = internalModule;
	internalModule = NULL;
	SECMOD_DestroyModule(oldModule);
 	SECMOD_DeletePermDB(mlp->module);
	SECMOD_DestroyModuleListElement(mlp);
	internalModule = newModule; /* adopt the module */
    }
    return rv;
}
Esempio n. 2
0
/*
 * Allow specification loading the same module more than once at init time.
 * This enables 2 things.
 *
 *    1) we can load additional databases by manipulating secmod.db/pkcs11.txt.
 *    2) we can handle the case where some library has already initialized NSS
 *    before the main application.
 *
 * oldModule is the module we have already initialized.
 * char *modulespec is the full module spec for the library we want to
 * initialize.
 */
static SECStatus
secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule)
{
    PK11SlotInfo *slot;
    char *modulespec;
    char *newModuleSpec;
    char **children;
    CK_SLOT_ID *ids;
    SECMODConfigList *conflist = NULL;
    SECStatus         rv       = SECFailure;
    int               count    = 0;

    /* first look for tokens= key words from the module spec */
    modulespec = newModule->libraryParams;
    newModuleSpec = secmod_ParseModuleSpecForTokens(PR_TRUE,
				newModule->isFIPS, modulespec, &children, &ids);
    if (!newModuleSpec) {
	return SECFailure;
    }

    /* 
     * We are now trying to open a new slot on an already loaded module.
     * If that slot represents a cert/key database, we don't want to open
     * multiple copies of that same database. Unfortunately we understand
     * the softoken flags well enough to be able to do this, so we can only get
     * the list of already loaded databases if we are trying to open another
     * internal module. 
     */
    if (oldModule->internal) {
	conflist = secmod_GetConfigList(oldModule->isFIPS, 
					oldModule->libraryParams, &count);
    }


    /* don't open multiple of the same db */
    if (conflist && secmod_MatchConfigList(newModuleSpec, conflist, count)) { 
	rv = SECSuccess;
	goto loser;
    }
    slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec);
    if (slot) {
	int newID;
	char **thisChild;
	CK_SLOT_ID *thisID;
	char *oldModuleSpec;

	if (secmod_IsInternalKeySlot(newModule)) {
	    pk11_SetInternalKeySlot(slot);
	}
	newID = slot->slotID;
	PK11_FreeSlot(slot);
	for (thisChild=children, thisID=ids; thisChild && *thisChild; 
						thisChild++,thisID++) {
	    if (conflist &&
		       secmod_MatchConfigList(*thisChild, conflist, count)) {
		*thisID = (CK_SLOT_ID) -1;
		continue;
	    }
	    slot = SECMOD_OpenNewSlot(oldModule, *thisChild);
	    if (slot) {
		*thisID = slot->slotID;
		PK11_FreeSlot(slot);
	    } else {
		*thisID = (CK_SLOT_ID) -1;
	    }
	}

	/* update the old module initialization string in case we need to
	 * shutdown and reinit the whole mess (this is rare, but can happen
	 * when trying to stop smart card insertion/removal threads)... */
	oldModuleSpec = secmod_MkAppendTokensList(oldModule->arena, 
		oldModule->libraryParams, newModuleSpec, newID, 
		children, ids);
	if (oldModuleSpec) {
	    oldModule->libraryParams = oldModuleSpec;
	}
	
	rv = SECSuccess;
    }

loser:
    secmod_FreeChildren(children, ids);
    PORT_Free(newModuleSpec);
    if (conflist) {
	secmod_FreeConfigList(conflist, count);
    }
    return rv;
}