diff options
| -rw-r--r-- | RELEASE-NOTES | 2 | ||||
| -rw-r--r-- | configure.ac | 8 | ||||
| -rw-r--r-- | lib/nss.c | 37 | 
3 files changed, 46 insertions, 1 deletions
diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 58a4cbd65..15b1d0a2a 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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 diff --git a/configure.ac b/configure.ac index 541c74f3d..89f26f47a 100644 --- a/configure.ac +++ b/configure.ac @@ -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 @@ -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);  | 
