]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
nss: use NSS_InitContext() to initialize NSS if available
authorKamil Dudka <kdudka@redhat.com>
Tue, 10 Apr 2012 13:42:34 +0000 (15:42 +0200)
committerKamil Dudka <kdudka@redhat.com>
Fri, 13 Apr 2012 10:19:36 +0000 (12:19 +0200)
NSS_InitContext() was introduced in NSS 3.12.5 and helps to prevent
collisions on NSS initialization/shutdown with other libraries.

Bug: https://bugzilla.redhat.com/738456

RELEASE-NOTES
configure.ac
lib/nss.c

index 58a4cbd6595b3358c4f4bfd4b2add9ce3b19ed4d..15b1d0a2ae9a1c42dd4b98af9b2925ac769455cc 100644 (file)
@@ -14,6 +14,7 @@ This release includes the following changes:
 
 This release includes the following bugfixes:
 
+ o nss: libcurl now uses NSS_InitContext() to prevent collisions if available [1]
  o 
 
 This release includes the following known bugs:
@@ -29,4 +30,5 @@ advice from friends like these:
 
 References to bug reports and discussions on issues:
 
+ [1] = https://bugzilla.redhat.com/738456
  
index 541c74f3d2724fd8e94131cd110866bf73d9b1ab..89f26f47a3f29a51eb346eb0d4f0b62b7ded0f32 100644 (file)
@@ -2118,6 +2118,14 @@ if test "$OPENSSL_ENABLED" != "1" -a "$GNUTLS_ENABLED" != "1"; then
       if test "x$USE_NSS" = "xyes"; then
         AC_MSG_NOTICE([detected NSS version $version])
 
+        dnl NSS_InitContext() was introduced in NSS 3.12.5 and helps to prevent
+        dnl collisions on NSS initialization/shutdown with other libraries
+        AC_CHECK_FUNC(NSS_InitContext,
+        [
+          AC_DEFINE(HAVE_NSS_INITCONTEXT, 1, [if you have the NSS_InitContext function])
+          AC_SUBST(HAVE_NSS_INITCONTEXT, [1])
+        ])
+
         dnl when shared libs were found in a path that the run-time
         dnl linker doesn't search through, we need to add it to
         dnl LD_LIBRARY_PATH to prevent further configure tests to fail
index 61089173c817e7cc71ba250436e40f3c0e094af9..16127ee7f5b30f923deee7b327623ce4087e8f10 100644 (file)
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -78,6 +78,9 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
 
 PRLock * nss_initlock = NULL;
 PRLock * nss_crllock = NULL;
+#ifdef HAVE_NSS_INITCONTEXT
+NSSInitContext * nss_context = NULL;
+#endif
 
 volatile int initialized = 0;
 
@@ -861,29 +864,56 @@ isTLSIntoleranceError(PRInt32 err)
 
 static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
 {
+#ifdef HAVE_NSS_INITCONTEXT
+  if(nss_context != NULL)
+    return CURLE_OK;
+
+  NSSInitParameters initparams;
+  memset((void *) &initparams, '\0', sizeof(initparams));
+  initparams.length = sizeof(initparams);
+#else /* HAVE_NSS_INITCONTEXT */
+  SECStatus rv;
+
   if(NSS_IsInitialized())
     return CURLE_OK;
+#endif
 
   if(cert_dir) {
-    SECStatus rv;
     const bool use_sql = NSS_VersionCheck("3.12.0");
     char *certpath = aprintf("%s%s", use_sql ? "sql:" : "", cert_dir);
     if(!certpath)
       return CURLE_OUT_OF_MEMORY;
 
     infof(data, "Initializing NSS with certpath: %s\n", certpath);
+#ifdef HAVE_NSS_INITCONTEXT
+    nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
+            NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
+    free(certpath);
+
+    if(nss_context != NULL)
+      return CURLE_OK;
+#else /* HAVE_NSS_INITCONTEXT */
     rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
     free(certpath);
 
     if(rv == SECSuccess)
       return CURLE_OK;
+#endif
 
     infof(data, "Unable to initialize NSS database\n");
   }
 
   infof(data, "Initializing NSS with certpath: none\n");
+#ifdef HAVE_NSS_INITCONTEXT
+  nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
+          | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
+          | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
+  if(nss_context != NULL)
+    return CURLE_OK;
+#else /* HAVE_NSS_INITCONTEXT */
   if(NSS_NoDB_Init(NULL) == SECSuccess)
     return CURLE_OK;
+#endif
 
   infof(data, "Unable to initialize NSS\n");
   return CURLE_SSL_CACERT_BADFILE;
@@ -979,7 +1009,12 @@ void Curl_nss_cleanup(void)
       SECMOD_DestroyModule(mod);
       mod = NULL;
     }
+#ifdef HAVE_NSS_INITCONTEXT
+    NSS_ShutdownContext(nss_context);
+    nss_context = NULL;
+#else /* HAVE_NSS_INITCONTEXT */
     NSS_Shutdown();
+#endif
   }
   PR_Unlock(nss_initlock);