1493 lines
46 KiB
Diff
1493 lines
46 KiB
Diff
Index: ./mozilla/security/nss/lib/manifest.mn
|
|
===================================================================
|
|
RCS file: /cvsroot/mozilla/security/nss/lib/manifest.mn,v
|
|
retrieving revision 1.19
|
|
diff -u -p -r1.19 manifest.mn
|
|
--- ./mozilla/security/nss/lib/manifest.mn 16 Nov 2007 05:29:23 -0000 1.19
|
|
+++ ./mozilla/security/nss/lib/manifest.mn 27 Sep 2009 16:38:49 -0000
|
|
@@ -56,6 +56,7 @@ DIRS = util freebl softoken \
|
|
pkcs12 pkcs7 smime \
|
|
crmf jar \
|
|
ckfw \
|
|
+ sysinit \
|
|
$(NULL)
|
|
|
|
# fortcrypt is no longer built
|
|
Index: ./mozilla/security/nss/lib/sysinit/Makefile
|
|
===================================================================
|
|
RCS file: ./mozilla/security/nss/lib/sysinit/Makefile
|
|
diff -N ./mozilla/security/nss/lib/sysinit/Makefile
|
|
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
|
+++ ./mozilla/security/nss/lib/sysinit/Makefile 27 Sep 2009 16:38:50 -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/lib/sysinit/config.mk
|
|
===================================================================
|
|
RCS file: ./mozilla/security/nss/lib/sysinit/config.mk
|
|
diff -N ./mozilla/security/nss/lib/sysinit/config.mk
|
|
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
|
+++ ./mozilla/security/nss/lib/sysinit/config.mk 27 Sep 2009 16:38:50 -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/lib/sysinit/manifest.mn
|
|
===================================================================
|
|
RCS file: ./mozilla/security/nss/lib/sysinit/manifest.mn
|
|
diff -N ./mozilla/security/nss/lib/sysinit/manifest.mn
|
|
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
|
+++ ./mozilla/security/nss/lib/sysinit/manifest.mn 27 Sep 2009 16:38:50 -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/lib/sysinit/nsssysinit.c
|
|
===================================================================
|
|
RCS file: ./mozilla/security/nss/lib/sysinit/nsssysinit.c
|
|
diff -N ./mozilla/security/nss/lib/sysinit/nsssysinit.c
|
|
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
|
+++ ./mozilla/security/nss/lib/sysinit/nsssysinit.c 27 Sep 2009 16:38:50 -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);
|