Index: base/nss_util.cc |
diff --git a/base/nss_util.cc b/base/nss_util.cc |
index fe78fe0c218bfb37162702f2cf6b5815b52cbe41..985e11702307fa739748a4d3ec88a8e717b284bf 100644 |
--- a/base/nss_util.cc |
+++ b/base/nss_util.cc |
@@ -204,6 +204,12 @@ class NSSInitSingleton { |
} |
#endif // defined(USE_NSS) |
+ // This method is used to force NSS to ne initialized without a DB. |
wtc
2011/03/15 21:37:20
Typo: ne => be
|
+ // Call this method before NSSInitSingleton() is constructed. |
+ static void ForceNoDBInit() { |
+ force_nodb_init_ = true; |
+ } |
+ |
private: |
friend struct DefaultLazyInstanceTraits<NSSInitSingleton>; |
@@ -236,63 +242,69 @@ class NSSInitSingleton { |
} |
SECStatus status = SECFailure; |
+ bool nodb_init = force_nodb_init_; |
+ |
#if !defined(USE_NSS) |
// Use the system certificate store, so initialize NSS without database. |
- status = NSS_NoDB_Init(NULL); |
- if (status != SECSuccess) { |
- LOG(ERROR) << "Error initializing NSS without a persistent " |
- "database: NSS error code " << PR_GetError(); |
- } |
-#else |
- FilePath database_dir = GetInitialConfigDirectory(); |
- if (!database_dir.empty()) { |
- // This duplicates the work which should have been done in |
- // EarlySetupForNSSInit. However, this function is idempotent so there's |
- // no harm done. |
- UseLocalCacheOfNSSDatabaseIfNFS(database_dir); |
- |
- // Initialize with a persistent database (likely, ~/.pki/nssdb). |
- // Use "sql:" which can be shared by multiple processes safely. |
- std::string nss_config_dir = |
- StringPrintf("sql:%s", database_dir.value().c_str()); |
+ nodb_init = true; |
+#endif |
+ |
+ if (nodb_init) { |
+ status = NSS_NoDB_Init(NULL); |
+ if (status != SECSuccess) { |
+ LOG(ERROR) << "Error initializing NSS without a persistent " |
+ "database: NSS error code " << PR_GetError(); |
+ } |
+ } else { |
+ FilePath database_dir = GetInitialConfigDirectory(); |
+ if (!database_dir.empty()) { |
+ // This duplicates the work which should have been done in |
+ // EarlySetupForNSSInit. However, this function is idempotent so |
+ // there's no harm done. |
+ UseLocalCacheOfNSSDatabaseIfNFS(database_dir); |
+ |
+ // Initialize with a persistent database (likely, ~/.pki/nssdb). |
+ // Use "sql:" which can be shared by multiple processes safely. |
+ std::string nss_config_dir = |
+ StringPrintf("sql:%s", database_dir.value().c_str()); |
#if defined(OS_CHROMEOS) |
- status = NSS_Init(nss_config_dir.c_str()); |
+ status = NSS_Init(nss_config_dir.c_str()); |
#else |
- status = NSS_InitReadWrite(nss_config_dir.c_str()); |
+ status = NSS_InitReadWrite(nss_config_dir.c_str()); |
#endif |
- if (status != SECSuccess) { |
- LOG(ERROR) << "Error initializing NSS with a persistent " |
- "database (" << nss_config_dir |
- << "): NSS error code " << PR_GetError(); |
+ if (status != SECSuccess) { |
+ LOG(ERROR) << "Error initializing NSS with a persistent " |
+ "database (" << nss_config_dir |
+ << "): NSS error code " << PR_GetError(); |
+ } |
} |
- } |
- if (status != SECSuccess) { |
- LOG(WARNING) << "Initialize NSS without a persistent database " |
- "(~/.pki/nssdb)."; |
- status = NSS_NoDB_Init(NULL); |
if (status != SECSuccess) { |
- LOG(ERROR) << "Error initializing NSS without a persistent " |
- "database: NSS error code " << PR_GetError(); |
- return; |
+ LOG(WARNING) << "Initialize NSS without a persistent database " |
+ "(~/.pki/nssdb)."; |
+ status = NSS_NoDB_Init(NULL); |
+ if (status != SECSuccess) { |
+ LOG(ERROR) << "Error initializing NSS without a persistent " |
+ "database: NSS error code " << PR_GetError(); |
+ return; |
+ } |
} |
- } |
- PK11_SetPasswordFunc(PKCS11PasswordFunc); |
- |
- // If we haven't initialized the password for the NSS databases, |
- // initialize an empty-string password so that we don't need to |
- // log in. |
- PK11SlotInfo* slot = PK11_GetInternalKeySlot(); |
- if (slot) { |
- // PK11_InitPin may write to the keyDB, but no other thread can use NSS |
- // yet, so we don't need to lock. |
- if (PK11_NeedUserInit(slot)) |
- PK11_InitPin(slot, NULL, NULL); |
- PK11_FreeSlot(slot); |
- } |
+ PK11_SetPasswordFunc(PKCS11PasswordFunc); |
+ |
+ // If we haven't initialized the password for the NSS databases, |
+ // initialize an empty-string password so that we don't need to |
+ // log in. |
+ PK11SlotInfo* slot = PK11_GetInternalKeySlot(); |
+ if (slot) { |
+ // PK11_InitPin may write to the keyDB, but no other thread can use NSS |
+ // yet, so we don't need to lock. |
+ if (PK11_NeedUserInit(slot)) |
+ PK11_InitPin(slot, NULL, NULL); |
+ PK11_FreeSlot(slot); |
+ } |
- root_ = InitDefaultRootCerts(); |
-#endif // !defined(USE_NSS) |
+ root_ = InitDefaultRootCerts(); |
wtc
2011/03/15 21:37:20
This function and PKCS11PasswordFunc at line 292 a
|
+ } |
} |
// NOTE(willchan): We don't actually execute this code since we leak NSS to |
@@ -337,6 +349,9 @@ class NSSInitSingleton { |
return db_slot; |
} |
+ // If this is set to true NSS is forced to be initialized without a DB. |
+ static bool force_nodb_init_; |
+ |
PK11SlotInfo* real_db_slot_; // Overrides internal key slot if non-NULL. |
PK11SlotInfo* test_db_slot_; // Overrides internal key slot and real_db_slot_ |
SECMODModule *root_; |
@@ -348,6 +363,8 @@ class NSSInitSingleton { |
#endif // defined(USE_NSS) |
}; |
+bool NSSInitSingleton::force_nodb_init_ = false; |
wtc
2011/03/15 21:37:20
Nit: add a comment:
// static
before this line.
|
+ |
LazyInstance<NSSInitSingleton, LeakyLazyInstanceTraits<NSSInitSingleton> > |
g_nss_singleton(LINKER_INITIALIZED); |
@@ -373,6 +390,15 @@ void EnsureNSSInit() { |
g_nss_singleton.Get(); |
} |
+void ForceNSSNoDBInit() { |
+ NSSInitSingleton::ForceNoDBInit(); |
+} |
+ |
+void DisableNSSForkCheck() { |
+ scoped_ptr<Environment> env(Environment::Create()); |
+ env->SetVar("NSS_STRICT_NOFORK", "DISABLED"); |
+} |
+ |
bool CheckNSSVersion(const char* version) { |
return !!NSS_VersionCheck(version); |
} |