Chromium Code Reviews| 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); |
| } |