nss/sysinit.patch

1493 lines
46 KiB
Diff

Index: ./mozilla/security/nss/cmd/manifest.mn
===================================================================
RCS file: /cvsroot/mozilla/security/nss/cmd/manifest.mn,v
retrieving revision 1.27
diff -u -p -r1.27 manifest.mn
--- ./mozilla/security/nss/cmd/manifest.mn 4 Sep 2008 22:15:21 -0000 1.27
+++ ./mozilla/security/nss/cmd/manifest.mn 18 Sep 2009 23:38:36 -0000
@@ -75,6 +75,7 @@ DIRS = lib \
ssltap \
strsclnt \
symkeyutil \
+ sysinit \
tests \
tstclnt \
vfychain \
Index: mozilla/security/nss/cmd/sysinit/Makefile
===================================================================
RCS file: security/nss/cmd/sysinit/Makefile
diff -N security/nss/cmd/sysinit/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./mozilla/security/nss/cmd/sysinit/Makefile 18 Sep 2009 23:38:36 -0000
@@ -0,0 +1,80 @@
+#! gmake
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+#include ../platlibs.mk
+include config.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+#include ../platrules.mk
+
Index: mozilla/security/nss/cmd/sysinit/config.mk
===================================================================
RCS file: security/nss/cmd/sysinit/config.mk
diff -N security/nss/cmd/sysinit/config.mk
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./mozilla/security/nss/cmd/sysinit/config.mk 18 Sep 2009 23:38:36 -0000
@@ -0,0 +1,121 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+# can't do this in manifest.mn because OS_TARGET isn't defined there.
+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+
+# don't want the 32 in the shared library name
+SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
+
+RES = $(OBJDIR)/$(LIBRARY_NAME).res
+RESNAME = $(LIBRARY_NAME).rc
+
+ifdef NS_USE_GCC
+EXTRA_SHARED_LIBS += \
+ -L$(DIST)/lib \
+ -L$(NSSUTIL_LIB_DIR) \
+ -lnssutil3 \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4\
+ $(NULL)
+else # ! NS_USE_GCC
+EXTRA_SHARED_LIBS += \
+ $(DIST)/lib/nssutil3.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NULL)
+endif # NS_USE_GCC
+
+else
+
+# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
+# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
+EXTRA_SHARED_LIBS += \
+ -L$(DIST)/lib \
+ -L$(NSSUTIL_LIB_DIR) \
+ -lnssutil3 \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4 \
+ $(NULL)
+
+endif
+
+
+# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
+
+ifeq ($(OS_TARGET),SunOS)
+ifeq ($(BUILD_SUN_PKG), 1)
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+ifeq ($(USE_64), 1)
+MKSHLIB += -R '$$ORIGIN:/usr/lib/mps/secv1/64:/usr/lib/mps/64'
+else
+MKSHLIB += -R '$$ORIGIN:/usr/lib/mps/secv1:/usr/lib/mps'
+endif
+else
+MKSHLIB += -R '$$ORIGIN'
+endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+ifneq ($(OS_TEST), ia64)
+# pa-risc
+ifeq ($(USE_64), 1)
+MKSHLIB += +b '$$ORIGIN'
+endif
+endif
+endif
+
+ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
+ifndef NS_USE_GCC
+# Export 'mktemp' to be backward compatible with NSS 3.2.x and 3.3.x
+# but do not put it in the import library. See bug 142575.
+DEFINES += -DWIN32_NSS3_DLL_COMPAT
+DLLFLAGS += -EXPORT:mktemp=nss_mktemp,PRIVATE
+endif
+endif
Index: mozilla/security/nss/cmd/sysinit/manifest.mn
===================================================================
RCS file: security/nss/cmd/sysinit/manifest.mn
diff -N security/nss/cmd/sysinit/manifest.mn
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./mozilla/security/nss/cmd/sysinit/manifest.mn 18 Sep 2009 23:38:36 -0000
@@ -0,0 +1,50 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+CORE_DEPTH = ../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+DEFINES = -DNSPR20
+
+CSRCS = nsssysinit.c
+
+LIBRARY = nsssysinit
+LIBRARY_NAME = nsssysinit
+#LIBRARY_VERSION = 3
+
Index: mozilla/security/nss/cmd/sysinit/nsssysinit.c
===================================================================
RCS file: security/nss/cmd/sysinit/nsssysinit.c
diff -N security/nss/cmd/sysinit/nsssysinit.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./mozilla/security/nss/cmd/sysinit/nsssysinit.c 18 Sep 2009 23:38:36 -0000
@@ -0,0 +1,356 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "seccomon.h"
+#include "prio.h"
+#include "prprf.h"
+
+
+
+/*
+ * The following provides a default example for operating systems to set up
+ * and manage applications loading NSS on their OS globally.
+ *
+ * This code hooks in to the system pkcs11.txt, which controls all the loading
+ * of pkcs11 modules common to all applications.
+ */
+
+/*
+ * OS Specific function to get where the NSS user database should reside.
+ */
+
+#ifdef XP_UNIX
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int testdir(char *dir)
+{
+ struct stat buf;
+ memset(&buf, 0, sizeof(buf));
+
+ if (stat(dir,&buf) < 0) {
+ return 0;
+ }
+
+ return S_ISDIR(buf.st_mode);
+}
+
+#define NSS_USER_PATH1 "/.pki"
+#define NSS_USER_PATH2 "/nssdb"
+char *getUserDB(void)
+{
+ char *userdir = getenv("HOME");
+ char *nssdir = NULL;
+
+ if (userdir == NULL) {
+ return NULL;
+ }
+
+ nssdir = PORT_Alloc(strlen(userdir)
+ +sizeof(NSS_USER_PATH1)+sizeof(NSS_USER_PATH2));
+ if (nssdir == NULL) {
+ return NULL;
+ }
+ PORT_Memcpy(nssdir, userdir, strlen(userdir)+1);
+ /* verify it exists */
+ if (!testdir(nssdir)) {
+ PORT_Free(nssdir);
+ return NULL;
+ }
+ PORT_Strcat(nssdir, NSS_USER_PATH1);
+ if (!testdir(nssdir) && mkdir(nssdir, 0760)) {
+ PORT_Free(nssdir);
+ return NULL;
+ }
+ PORT_Strcat(nssdir, NSS_USER_PATH2);
+ if (!testdir(nssdir) && mkdir(nssdir, 0760)) {
+ PORT_Free(nssdir);
+ return NULL;
+ }
+ return nssdir;
+}
+
+#define NSS_DEFAULT_SYSTEM "/etc/pki/nssdb"
+char *getSystemDB(void) {
+ return PORT_Strdup(NSS_DEFAULT_SYSTEM);
+}
+
+#else
+#ifdef XP_WIN
+char *getUserDB(void)
+{
+ /* use the registry to find the user's NSS_DIR. if no entry exists, creaate
+ * one in the users Appdir location */
+}
+
+char *getSystemDB(void)
+{
+ /* use the registry to find the system's NSS_DIR. if no entry exists, creaate
+ * one based on the windows system data area */
+}
+
+#else
+#error "Need to write getUserDB and get SystemDB functions"
+#endif
+#endif
+
+static PRBool getFIPSEnv()
+{
+ char *fipsEnv = getenv("NSS_FIPS");
+ if (!fipsEnv) {
+ return 0;
+ }
+ if ((strcasecmp(fipsEnv,"fips") == 0) ||
+ (strcasecmp(fipsEnv,"true") == 0) ||
+ (strcasecmp(fipsEnv,"on") == 0) ||
+ (strcasecmp(fipsEnv,"1") == 0)) {
+ return 1;
+ }
+ return 0;
+}
+#ifdef XP_LINUX
+
+PRBool getFIPSMode()
+{
+ FILE *f;
+ char d;
+ size_t size;
+
+ f = fopen("/proc/sys/crypto/fips_enabled", "r");
+ if (!f) {
+ /* if we don't have a proc flag, fall back to the
+ * environment variable */
+ return getFIPSEnv();
+ }
+
+ size = fread(&d, 1, 1, f);
+ fclose(f);
+ if (size != 1)
+ return 0;
+ if (d != '1')
+ return 0;
+ return 1;
+}
+
+#else
+static PRBool getFIPSMode()
+{
+ return getFIPSEnv();
+}
+#endif
+
+
+#define NSS_DEFAULT_FLAGS "flags=readonly"
+
+/*
+ * This function builds the list of databases and modules to load, and sets
+ * their configuration. For the sample we have a fixed set.
+ * 1. We load the user's home nss database.
+ * 2. We load the user's custom PKCS #11 modules.
+ * 3. We load the system nss database readonly.
+ *
+ * Any space allocated in get_list must be freed in release_list.
+ * This function can use whatever information is available to the application.
+ * it is running in the process of the application for which it is making
+ * decisions, so it's possible to acquire the application name as part of
+ * the decision making process.
+ *
+ */
+static char **
+get_list(char *filename, char *stripped_parameters)
+{
+ char **module_list = PORT_ZNewArray(char *, 4);
+ char *userdb;
+ int next = 0;
+
+ /* can't get any space */
+ if (module_list == NULL) {
+ return NULL;
+ }
+
+ userdb = getUserDB();
+ if (userdb != NULL) {
+ /* return a list of databases to open. First the user Database */
+ module_list[next++] = PR_smprintf(
+ "library= "
+ "module=\"NSS User database\" "
+ "parameters=\"configdir='sql:%s' %s\" "
+ "NSS=\"flags=internal%s\"",
+ userdb, stripped_parameters, getFIPSMode() ? ",FIPS" : "");
+
+ /* now open the user's defined PKCS #11 modules */
+ /* skip the local user DB entry */
+ module_list[next++] = PR_smprintf(
+ "library= "
+ "module=\"NSS User database\" "
+ "parameters=\"configdir='sql:%s' %s\" "
+ "NSS=\"flags=internal,moduleDBOnly,defaultModDB,skipFirst\"",
+ userdb, stripped_parameters);
+ }
+
+ /* now the system database (always read only) */
+ module_list[next++] = PR_smprintf(
+ "library= "
+ "module=\"NSS system database\" "
+ "parameters=\"configdir='sql:%s' tokenDescription='NSS system database' flags=readonly\" "
+ "NSS=\"flags=internal,critical\"",filename);
+
+ /* that was the last module */
+ module_list[next] = 0;
+
+ PORT_Free(userdb);
+
+ return module_list;
+}
+
+static char **
+release_list(char **arg)
+{
+ static char *success = "Success";
+ int next;
+
+ for (next = 0; arg[next]; next++) {
+ free(arg[next]);
+ }
+ PORT_Free(arg);
+ return &success;
+}
+
+
+#include "pk11pars.h"
+
+#define TARGET_SPEC_COPY(new, start, end) \
+ if (end > start) { \
+ int _cnt = end - start; \
+ PORT_Memcpy(new, start, _cnt); \
+ new += _cnt; \
+ }
+
+static void
+safestrcpy(char *target, char *src)
+{
+ while (*src) {
+ *target++ = *src++;
+ }
+ *target = 0;
+}
+
+/* determine what options the user was trying to open this database with */
+/* filename is the directory pointed to by configdir= */
+/* stripped is the rest of the paramters with configdir= stripped out */
+static SECStatus
+parse_paramters(char *parameters, char **filename, char **stripped)
+{
+ char *sourcePrev;
+ char *sourceCurr;
+ char *targetCurr;
+ char *newStripped;
+ *filename = NULL;
+ *stripped = NULL;
+
+ newStripped = PORT_Alloc(PORT_Strlen(parameters)+2);
+ targetCurr = newStripped;
+ sourcePrev = parameters;
+ sourceCurr = secmod_argStrip(parameters);
+ TARGET_SPEC_COPY(targetCurr, sourcePrev, sourceCurr);
+
+ while (*sourceCurr) {
+ int next;
+ sourcePrev = sourceCurr;
+ SECMOD_HANDLE_STRING_ARG(sourceCurr, *filename, "configdir=",
+ sourcePrev = sourceCurr; )
+ SECMOD_HANDLE_FINAL_ARG(sourceCurr);
+ TARGET_SPEC_COPY(targetCurr, sourcePrev, sourceCurr);
+ }
+ *targetCurr = 0;
+ if (*filename == NULL) {
+ PORT_Free(newStripped);
+ return SECFailure;
+ }
+ /* strip off any directives from the filename */
+ if (strncmp("sql:", *filename, 4) == 0) {
+ safestrcpy(*filename, (*filename)+4);
+ } else if (strncmp("dbm:", *filename, 4) == 0) {
+ safestrcpy(*filename, (*filename)+4);
+ } else if (strncmp("extern:", *filename, 7) == 0) {
+ safestrcpy(*filename, (*filename)+7);
+ }
+ *stripped = newStripped;
+ return SECSuccess;
+}
+
+/* entry point */
+char **
+NSS_ReturnModuleSpecData(unsigned long function, char *parameters, void *args)
+{
+ char *filename = NULL;
+ char *stripped = NULL;
+ char **retString = NULL;
+ SECStatus rv;
+
+ rv = parse_paramters(parameters, &filename, &stripped);
+ if (rv != SECSuccess) {
+ /* use defaults */
+ filename = getSystemDB();
+ if (!filename) {
+ return NULL;
+ }
+ stripped = PORT_Strdup(NSS_DEFAULT_FLAGS);
+ if (!stripped) {
+ free(filename);
+ return NULL;
+ }
+ }
+ switch (function) {
+ case SECMOD_MODULE_DB_FUNCTION_FIND:
+ retString = get_list(filename, stripped);
+ break;
+ case SECMOD_MODULE_DB_FUNCTION_RELEASE:
+ retString = release_list((char **)args);
+ break;
+ /* can't add or delete from this module DB */
+ case SECMOD_MODULE_DB_FUNCTION_ADD:
+ case SECMOD_MODULE_DB_FUNCTION_DEL:
+ retString = NULL;
+ break;
+ default:
+ retString = NULL;
+ break;
+ }
+
+ if (filename) PORT_Free(filename);
+ if (stripped) PORT_Free(stripped);
+ return retString;
+}
Index: mozilla/security/nss/lib/pk11wrap/pk11load.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11load.c,v
retrieving revision 1.25
diff -u -p -r1.25 pk11load.c
--- ./mozilla/security/nss/lib/pk11wrap/pk11load.c 2 Oct 2008 00:56:15 -0000 1.25
+++ ./mozilla/security/nss/lib/pk11wrap/pk11load.c 1 Sep 2009 22:47:51 -0000
@@ -120,15 +120,83 @@ PRBool pk11_getFinalizeModulesOption(voi
}
/*
+ * 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, char *modulespec)
+{
+ PK11SlotInfo *slot;
+ char *newModuleSpec;
+ char **children;
+ CK_SLOT_ID *ids;
+ SECStatus rv;
+
+ /* first look for token= key words from the module spec */
+ newModuleSpec = secmod_ParseModuleSpecForTokens(modulespec,&children,&ids);
+ if (!newModuleSpec) {
+ return SECFailure;
+ }
+ slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec);
+ if (slot) {
+ int newID;
+ char **thisChild;
+ CK_SLOT_ID *thisID;
+ char *oldModuleSpec;
+
+ newID = slot->slotID;
+ PK11_FreeSlot(slot);
+ for (thisChild=children, thisID=ids; thisChild && *thisChild;
+ thisChild++,thisID++) {
+ 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;
+ }
+ secmod_FreeChildren(children, ids);
+ PORT_Free(newModuleSpec);
+ return rv;
+}
+
+/*
* collect the steps we need to initialize a module in a single function
*/
SECStatus
-secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded)
+secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
+ PRBool* alreadyLoaded)
{
CK_C_INITIALIZE_ARGS moduleArgs;
CK_VOID_PTR pInitArgs;
CK_RV crv;
+ if (reload) {
+ *reload = NULL;
+ }
+
if (!mod || !alreadyLoaded) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -144,10 +212,36 @@ secmod_ModuleInit(SECMODModule *mod, PRB
pInitArgs = &moduleArgs;
}
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
- if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
- (!enforceAlreadyInitializedError)) {
- *alreadyLoaded = PR_TRUE;
- return SECSuccess;
+ if (CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) {
+ SECMODModule *oldModule = NULL;
+
+ /* Library has already been loaded once, if caller expects it, and it
+ * has additional configuration, try reloading it as well. */
+ if (reload != NULL && mod->libraryParams) {
+ oldModule = secmod_findModuleByFuncPtr(mod->functionList);
+ }
+ /* Library has been loaded by NSS. It means it may be capable of
+ * reloading */
+ if (oldModule) {
+ SECStatus rv;
+ rv = secmod_HandleReload(oldModule, mod->libraryParams);
+ if (rv == SECSuccess) {
+ /* This module should go away soon, since we've
+ * simply expanded the slots on the old module.
+ * When it goes away, it should not Finalize since
+ * that will close our old module as well. Setting
+ * the function list to NULL will prevent that close */
+ mod->functionList = NULL;
+ *reload = oldModule;
+ return SECSuccess;
+ }
+ SECMOD_DestroyModule(oldModule);
+ }
+ /* reload not possible, fall back to old semantics */
+ if (!enforceAlreadyInitializedError) {
+ *alreadyLoaded = PR_TRUE;
+ return SECSuccess;
+ }
}
if (crv != CKR_OK) {
if (pInitArgs == NULL ||
@@ -258,7 +352,7 @@ softoken_LoadDSO( void )
* load a new module into our address space and initialize it.
*/
SECStatus
-SECMOD_LoadPKCS11Module(SECMODModule *mod) {
+secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
PRLibrary *library = NULL;
CK_C_GetFunctionList entry = NULL;
char * full_name;
@@ -271,7 +365,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mo
if (mod->loaded) return SECSuccess;
/* intenal modules get loaded from their internal list */
- if (mod->internal) {
+ if (mod->internal && (mod->dllName == NULL)) {
/*
* Loads softoken as a dynamic library,
* even though the rest of NSS assumes this as the "internal" module.
@@ -308,26 +402,14 @@ SECMOD_LoadPKCS11Module(SECMODModule *mo
return SECFailure;
}
-#ifdef notdef
- /* look up the library name */
- full_name = PR_GetLibraryName(PR_GetLibraryPath(),mod->dllName);
- if (full_name == NULL) {
- return SECFailure;
- }
-#else
full_name = PORT_Strdup(mod->dllName);
-#endif
/* load the library. If this succeeds, then we have to remember to
* unload the library if anything goes wrong from here on out...
*/
library = PR_LoadLibrary(full_name);
mod->library = (void *)library;
-#ifdef notdef
- PR_FreeLibraryName(full_name);
-#else
PORT_Free(full_name);
-#endif
if (library == NULL) {
return SECFailure;
@@ -375,11 +457,18 @@ SECMOD_LoadPKCS11Module(SECMODModule *mo
mod->isThreadSafe = PR_TRUE;
/* Now we initialize the module */
- rv = secmod_ModuleInit(mod, &alreadyLoaded);
+ rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
if (rv != SECSuccess) {
goto fail;
}
+ /* module has been reloaded, this module itself is done,
+ * return to the caller */
+ if (mod->functionList == NULL) {
+ mod->loaded = PR_TRUE; /* technically the module is loaded.. */
+ return SECSuccess;
+ }
+
/* check the version number */
if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
if (info.cryptokiVersion.major != 2) goto fail2;
@@ -460,7 +549,9 @@ SECMOD_UnloadModule(SECMODModule *mod) {
return SECFailure;
}
if (finalizeModules) {
- if (!mod->moduleDBOnly) PK11_GETTAB(mod)->C_Finalize(NULL);
+ if (mod->functionList &&!mod->moduleDBOnly) {
+ PK11_GETTAB(mod)->C_Finalize(NULL);
+ }
}
mod->moduleID = 0;
mod->loaded = PR_FALSE;
Index: mozilla/security/nss/lib/pk11wrap/pk11pars.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11pars.c,v
retrieving revision 1.22
diff -u -p -r1.22 pk11pars.c
--- ./mozilla/security/nss/lib/pk11wrap/pk11pars.c 1 Sep 2009 21:56:26 -0000 1.22
+++ ./mozilla/security/nss/lib/pk11wrap/pk11pars.c 1 Sep 2009 22:47:51 -0000
@@ -224,6 +224,389 @@ SECMOD_GetDefaultModDBFlag(SECMODModule
return (flags & SECMOD_FLAG_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
}
+/*
+ * Find any token= values in the module spec.
+ * Always return a new spec which does not have any token= arguments.
+ * If token= arguments are found, Split the the various tokens defined into
+ * an array of child specs to return.
+ *
+ * Caller is responsible for freeing the child spec and the new token
+ * spec.
+ */
+
+#define SECMOD_SPEC_COPY(new, start, end) \
+ if (end > start) { \
+ int _cnt = end - start; \
+ PORT_Memcpy(new, start, _cnt); \
+ new += _cnt; \
+ }
+
+char *
+secmod_ParseModuleSpecForTokens(char *moduleSpec, char ***children,
+ CK_SLOT_ID **ids)
+{
+ char *newSpec = PORT_Alloc(PORT_Strlen(moduleSpec)+2);
+ char *newSpecPtr = newSpec;
+ char *modulePrev = moduleSpec;
+ char *target = NULL;
+ char **childArray = NULL;
+ char *tokenIndex;
+ CK_SLOT_ID *idArray = NULL;
+ int tokenCount = 0;
+ int i;
+
+ if (newSpec == NULL) {
+ return NULL;
+ }
+
+ *children = NULL;
+ if (ids) {
+ *ids = NULL;
+ }
+ moduleSpec = secmod_argStrip(moduleSpec);
+ SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
+
+ /*
+ * walk down the list. if we find a tokens= argument, save it,
+ * otherise copy the argument.
+ */
+ while (*moduleSpec) {
+ int next;
+ modulePrev = moduleSpec;
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",
+ modulePrev = moduleSpec; /* skip copying */ )
+ SECMOD_HANDLE_FINAL_ARG(moduleSpec)
+ SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
+ }
+ *newSpecPtr = 0;
+
+ /* no target found, return the newSpec */
+ if (target == NULL) {
+ return newSpec;
+ }
+
+ /* now build the child array from target */
+ /*first count them */
+ for (tokenIndex = secmod_argStrip(target); *tokenIndex;
+ tokenIndex = secmod_argStrip(secmod_argSkipParameter(tokenIndex))) {
+ tokenCount++;
+ }
+
+ childArray = PORT_NewArray(char *, tokenCount+1);
+ if (childArray == NULL) {
+ /* just return the spec as is then */
+ PORT_Free(target);
+ return newSpec;
+ }
+ if (ids) {
+ idArray = PORT_NewArray(CK_SLOT_ID, tokenCount+1);
+ if (idArray == NULL) {
+ PORT_Free(childArray);
+ PORT_Free(target);
+ return newSpec;
+ }
+ }
+
+ /* now fill them in */
+ for (tokenIndex = secmod_argStrip(target), i=0 ;
+ *tokenIndex && (i < tokenCount);
+ tokenIndex=secmod_argStrip(tokenIndex)) {
+ int next;
+ char *name = secmod_argGetName(tokenIndex, &next);
+ tokenIndex += next;
+
+ if (idArray) {
+ idArray[i] = secmod_argDecodeNumber(name);
+ }
+
+ PORT_Free(name); /* drop the explicit number */
+
+ /* if anything is left, copy the args to the child array */
+ if (!secmod_argIsBlank(*tokenIndex)) {
+ childArray[i++] = secmod_argFetchValue(tokenIndex, &next);
+ tokenIndex += next;
+ }
+ }
+
+ PORT_Free(target);
+ childArray[i] = 0;
+ if (idArray) {
+ idArray[i] = 0;
+ }
+
+ /* return it */
+ *children = childArray;
+ if (ids) {
+ *ids = idArray;
+ }
+ return newSpec;
+}
+
+void
+secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
+{
+ char **thisChild = children;
+
+ if (!children) {
+ return;
+ }
+
+ for (thisChild = children; thisChild && *thisChild; thisChild++ ) {
+ PORT_Free(*thisChild);
+ }
+ PORT_Free(children);
+ if (ids) {
+ PORT_Free(ids);
+ }
+ return;
+}
+
+
+static int
+secmod_escapeSize(const char *string, char quote)
+{
+ int escapes = 0, size = 0;
+ const char *src;
+ for (src=string; *src ; src++) {
+ if ((*src == quote) || (*src == '\\')) escapes++;
+ size++;
+ }
+
+ return escapes+size+1;
+}
+
+
+/*
+ * add escapes to protect quote characters...
+ */
+static char *
+secmod_addEscape(const char *string, char quote)
+{
+ char *newString = 0;
+ int size = 0;
+ const char *src;
+ char *dest;
+
+
+ size = secmod_escapeSize(string,quote);
+ newString = PORT_ZAlloc(size);
+ if (newString == NULL) {
+ return NULL;
+ }
+
+ for (src=string, dest=newString; *src; src++,dest++) {
+ if ((*src == '\\') || (*src == quote)) {
+ *dest++ = '\\';
+ }
+ *dest = *src;
+ }
+
+ return newString;
+}
+
+static int
+secmod_doubleEscapeSize(const char *string, char quote1, char quote2)
+{
+ int escapes = 0, size = 0;
+ const char *src;
+ for (src=string; *src ; src++) {
+ if (*src == '\\') escapes+=3; /* \\\\ */
+ if (*src == quote1) escapes+=2; /* \\quote1 */
+ if (*src == quote2) escapes++; /* \quote2 */
+ size++;
+ }
+
+ return escapes+size+1;
+}
+
+char *
+secmod_doubleEscape(const char *string, char quote1, char quote2)
+{
+ char *round1 = NULL;
+ char *retValue = NULL;
+ if (string == NULL) {
+ goto done;
+ }
+ round1 = secmod_addEscape(string,quote1);
+ if (round1) {
+ retValue = secmod_addEscape(round1,quote2);
+ PORT_Free(round1);
+ }
+
+done:
+ if (retValue == NULL) {
+ retValue = PORT_Strdup("");
+ }
+ return retValue;
+}
+
+
+/*
+ * caclulate the length of each child record:
+ * " 0x{id}=<{escaped_child}>"
+ */
+static int
+secmod_getChildLength(char *child, CK_SLOT_ID id)
+{
+ int length = secmod_doubleEscapeSize(child, '>', ']');
+ if (id == 0) {
+ length++;
+ }
+ while (id) {
+ length++;
+ id = id >> 4;
+ }
+ length += 6; /* {sp}0x[id]=<{child}> */
+ return length;
+}
+
+/*
+ * Build a child record:
+ * " 0x{id}=<{escaped_child}>"
+ */
+SECStatus
+secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
+{
+ int len;
+ char *escSpec;
+
+ len = PR_snprintf(*next, *length, " 0x%x=<",id);
+ if (len < 0) {
+ return SECFailure;
+ }
+ *next += len;
+ *length -= len;
+ escSpec = secmod_doubleEscape(child, '>', ']');
+ if (escSpec == NULL) {
+ return SECFailure;
+ }
+ if (*child && (*escSpec == 0)) {
+ PORT_Free(escSpec);
+ return SECFailure;
+ }
+ len = strlen(escSpec);
+ if (len+1 > *length) {
+ PORT_Free(escSpec);
+ return SECFailure;
+ }
+ PORT_Memcpy(*next,escSpec, len);
+ *next += len;
+ *length -= len;
+ PORT_Free(escSpec);
+ **next = '>';
+ (*next)++;
+ (*length)--;
+ return SECSuccess;
+}
+
+#define TOKEN_STRING " tokens=["
+
+char *
+secmod_mkAppendTokensList(PRArenaPool *arena, char *oldParam, char *newToken,
+ CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
+{
+ char *rawParam = NULL; /* oldParam with tokens stripped off */
+ char *newParam = NULL; /* space for the return parameter */
+ char *nextParam = NULL; /* current end of the new parameter */
+ char **oldChildren = NULL;
+ CK_SLOT_ID *oldIds = NULL;
+ void *mark = NULL; /* mark the arena pool in case we need
+ * to release it */
+ int length, i, tmpLen;
+ SECStatus rv;
+
+ /* first strip out and save the old tokenlist */
+ rawParam = secmod_ParseModuleSpecForTokens(oldParam,&oldChildren,&oldIds);
+ if (!rawParam) {
+ goto loser;
+ }
+
+ /* now calculate the total length of the new buffer */
+ /* First the 'fixed stuff', length of rawparam (does not include a NULL),
+ * length of the token string (does include the NULL), closing bracket */
+ length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1;
+ /* now add then length of all the old children */
+ for (i=0; oldChildren && oldChildren[i]; i++) {
+ length += secmod_getChildLength(oldChildren[i], oldIds[i]);
+ }
+
+ /* add the new token */
+ length += secmod_getChildLength(newToken, newID);
+
+ /* and it's new children */
+ for (i=0; children && children[i]; i++) {
+ if (ids[i] == -1) {
+ continue;
+ }
+ length += secmod_getChildLength(children[i], ids[i]);
+ }
+
+ /* now allocate and build the string */
+ mark = PORT_ArenaMark(arena);
+ if (!mark) {
+ goto loser;
+ }
+ newParam = PORT_ArenaAlloc(arena,length);
+ if (!newParam) {
+ goto loser;
+ }
+
+ PORT_Strcpy(newParam, oldParam);
+ tmpLen = strlen(oldParam);
+ nextParam = newParam + tmpLen;
+ length -= tmpLen;
+ PORT_Memcpy(nextParam, TOKEN_STRING, sizeof(TOKEN_STRING)-1);
+ nextParam += sizeof(TOKEN_STRING)-1;
+ length -= sizeof(TOKEN_STRING)-1;
+
+ for (i=0; oldChildren && oldChildren[i]; i++) {
+ rv = secmod_mkTokenChild(&nextParam,&length,oldChildren[i],oldIds[i]);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ for (i=0; children && children[i]; i++) {
+ if (ids[i] == -1) {
+ continue;
+ }
+ rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ if (length < 2) {
+ goto loser;
+ }
+
+ *nextParam++ = ']';
+ *nextParam++ = 0;
+
+ /* we are going to return newParam now, don't release the mark */
+ PORT_ArenaUnmark(arena, mark);
+ mark = NULL;
+
+loser:
+ if (mark) {
+ PORT_ArenaRelease(arena, mark);
+ newParam = NULL; /* if the mark is still active,
+ * don't return the param */
+ }
+ if (rawParam) {
+ PORT_Free(rawParam);
+ }
+ if (oldChildren) {
+ secmod_FreeChildren(oldChildren, oldIds);
+ }
+ return newParam;
+}
+
static char *
secmod_mkModuleSpec(SECMODModule * module)
{
@@ -365,6 +748,7 @@ SECMOD_LoadModule(char *modulespec,SECMO
char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL;
SECStatus status;
SECMODModule *module = NULL;
+ SECMODModule *oldModule = NULL;
SECStatus rv;
/* initialize the underlying module structures */
@@ -389,11 +773,19 @@ SECMOD_LoadModule(char *modulespec,SECMO
}
/* load it */
- rv = SECMOD_LoadPKCS11Module(module);
+ rv = secmod_LoadPKCS11Module(module, &oldModule);
if (rv != SECSuccess) {
goto loser;
}
+ /* if we just reload an old module, no need to add it to any lists.
+ * we simple release all our references */
+ if (oldModule) {
+ SECMOD_DestroyModule(module);
+ SECMOD_DestroyModule(oldModule);
+ return SECSuccess;
+ }
+
if (recurse && module->isModuleDB) {
char ** moduleSpecList;
PORT_SetError(0);
Index: mozilla/security/nss/lib/pk11wrap/pk11util.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11util.c,v
retrieving revision 1.56
diff -u -p -r1.56 pk11util.c
--- ./mozilla/security/nss/lib/pk11wrap/pk11util.c 1 Sep 2009 21:56:26 -0000 1.56
+++ ./mozilla/security/nss/lib/pk11wrap/pk11util.c 1 Sep 2009 22:47:51 -0000
@@ -285,6 +285,30 @@ SECMOD_FindModuleByID(SECMODModuleID id)
}
/*
+ * 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) {
+ 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 the Slot based on ID and the module.
*/
PK11SlotInfo *
@@ -508,7 +532,7 @@ SECMOD_AddModule(SECMODModule *newModule
/* module already exists. */
}
- rv = SECMOD_LoadPKCS11Module(newModule);
+ rv = secmod_LoadPKCS11Module(newModule, NULL);
if (rv != SECSuccess) {
return rv;
}
@@ -1202,7 +1226,7 @@ SECMOD_CancelWait(SECMODModule *mod)
* we intend to use it again */
if (CKR_OK == crv) {
PRBool alreadyLoaded;
- secmod_ModuleInit(mod, &alreadyLoaded);
+ secmod_ModuleInit(mod, NULL, &alreadyLoaded);
} else {
/* Finalized failed for some reason, notify the application
* so maybe it has a prayer of recovering... */
@@ -1279,58 +1303,6 @@ secmod_UserDBOp(PK11SlotInfo *slot, CK_O
}
/*
- * add escapes to protect quote characters...
- */
-static char *
-nss_addEscape(const char *string, char quote)
-{
- char *newString = 0;
- int escapes = 0, size = 0;
- const char *src;
- char *dest;
-
- for (src=string; *src ; src++) {
- if ((*src == quote) || (*src == '\\')) escapes++;
- size++;
- }
-
- newString = PORT_ZAlloc(escapes+size+1);
- if (newString == NULL) {
- return NULL;
- }
-
- for (src=string, dest=newString; *src; src++,dest++) {
- if ((*src == '\\') || (*src == quote)) {
- *dest++ = '\\';
- }
- *dest = *src;
- }
-
- return newString;
-}
-
-static char *
-nss_doubleEscape(const char *string)
-{
- char *round1 = NULL;
- char *retValue = NULL;
- if (string == NULL) {
- goto done;
- }
- round1 = nss_addEscape(string,'>');
- if (round1) {
- retValue = nss_addEscape(round1,']');
- PORT_Free(round1);
- }
-
-done:
- if (retValue == NULL) {
- retValue = PORT_Strdup("");
- }
- return retValue;
-}
-
-/*
* return true if the selected slot ID is not present or doesn't exist
*/
static PRBool
@@ -1412,7 +1384,7 @@ SECMOD_OpenNewSlot(SECMODModule *mod, co
}
/* we've found the slot, now build the moduleSpec */
- escSpec = nss_doubleEscape(moduleSpec);
+ escSpec = secmod_doubleEscape(moduleSpec, '>', ']');
if (escSpec == NULL) {
PK11_FreeSlot(slot);
return NULL;
Index: mozilla/security/nss/lib/pk11wrap/secmodi.h
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/pk11wrap/secmodi.h,v
retrieving revision 1.31
diff -u -p -r1.31 secmodi.h
--- ./mozilla/security/nss/lib/pk11wrap/secmodi.h 2 Dec 2008 23:24:50 -0000 1.31
+++ ./mozilla/security/nss/lib/pk11wrap/secmodi.h 1 Sep 2009 22:47:51 -0000
@@ -58,7 +58,8 @@ void nss_DumpModuleLog(void);
extern int secmod_PrivateModuleCount;
extern void SECMOD_Init(void);
-SECStatus secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded);
+SECStatus secmod_ModuleInit(SECMODModule *mod, SECMODModule **oldModule,
+ PRBool* alreadyLoaded);
/* list managment */
extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule);
@@ -73,6 +74,7 @@ extern void SECMOD_ReleaseWriteLock(SECM
/* Operate on modules by name */
extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID);
+extern SECMODModule *secmod_findModuleByFuncPtr(void *funcPtr);
/* database/memory management */
extern SECMODModuleList *SECMOD_NewModuleListElement(void);
@@ -84,10 +86,25 @@ extern unsigned long SECMOD_InternaltoPu
extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags);
/* Library functions */
-SECStatus SECMOD_LoadPKCS11Module(SECMODModule *);
+SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
SECStatus SECMOD_UnloadModule(SECMODModule *);
void SECMOD_SetInternalModule(SECMODModule *);
+/* parsing parameters */
+/* returned char * must be freed by caller with PORT_Free */
+/* children and ids are null terminated arrays which must be freed with
+ * secmod_FreeChildren */
+char *secmod_ParseModuleSpecForTokens(char *moduleSpec,
+ char ***children,
+ CK_SLOT_ID **ids);
+void secmod_FreeChildren(char **children, CK_SLOT_ID *ids);
+char *secmod_mkAppendTokensList(PRArenaPool *arena, char *origModuleSpec,
+ char *newModuleSpec, CK_SLOT_ID newID,
+ char **children, CK_SLOT_ID *ids);
+char *secmod_doubleEscape(const char *string, char quote1, char quote2);
+
+
+
void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot);
CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
CK_VOID_PTR pdata);
Index: mozilla/security/nss/lib/pki/pki3hack.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/pki/pki3hack.c,v
retrieving revision 1.97
diff -u -p -r1.97 pki3hack.c
--- ./mozilla/security/nss/lib/pki/pki3hack.c 30 Jul 2009 22:43:32 -0000 1.97
+++ ./mozilla/security/nss/lib/pki/pki3hack.c 1 Sep 2009 22:47:51 -0000
@@ -101,6 +101,11 @@ STAN_InitTokenForSlotInfo(NSSTrustDomain
NSSToken *token;
if (!td) {
td = g_default_trust_domain;
+ if (!td) {
+ /* we're called while still initting. slot will get added
+ * appropriately through normal init processes */
+ return PR_SUCCESS;
+ }
}
token = nssToken_CreateFromPK11SlotInfo(td, slot);
PK11Slot_SetNSSToken(slot, token);
@@ -118,6 +123,11 @@ STAN_ResetTokenInterator(NSSTrustDomain
{
if (!td) {
td = g_default_trust_domain;
+ if (!td) {
+ /* we're called while still initting. slot will get added
+ * appropriately through normal init processes */
+ return PR_SUCCESS;
+ }
}
NSSRWLock_LockWrite(td->tokensLock);
nssListIterator_Destroy(td->tokens);