aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--smime/lib/e-cert-db.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/smime/lib/e-cert-db.c b/smime/lib/e-cert-db.c
index d737887e7a..5e275a063c 100644
--- a/smime/lib/e-cert-db.c
+++ b/smime/lib/e-cert-db.c
@@ -78,6 +78,7 @@
#include "ssl.h"
#include "p12plcy.h"
#include "pk11func.h"
+#include "nssckbi.h"
#include "secmod.h"
#include "certdb.h"
#include "plstr.h"
@@ -213,44 +214,73 @@ initialize_nss (void)
static void
install_loadable_roots (void)
{
- gboolean has_roots;
- PK11SlotList *list;
-
- has_roots = FALSE;
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
- if (list) {
- PK11SlotListElement *le;
-
- for (le = list->head; le; le = le->next) {
- if (PK11_HasRootCerts(le->slot)) {
- has_roots = TRUE;
- break;
+ SECMODModuleList *list = SECMOD_GetDefaultModuleList ();
+ SECMODListLock *lock = SECMOD_GetDefaultModuleListLock ();
+ SECMODModule *RootsModule = NULL;
+ int i;
+
+ SECMOD_GetReadLock (lock);
+ while (!RootsModule && list) {
+ SECMODModule *module = list->module;
+
+ for (i = 0; i < module->slotCount; i++) {
+ PK11SlotInfo *slot = module->slots[i];
+ if (PK11_IsPresent (slot)) {
+ if (PK11_HasRootCerts(slot)) {
+ RootsModule = module;
+ break;
+ }
}
}
+
+ list = list->next;
}
-
- if (!has_roots) {
+ SECMOD_ReleaseReadLock (lock);
+
+ if (RootsModule) {
+ /* Check version, and unload module if it is too old */
+ CK_INFO info;
+ if (PK11_GetModInfo (RootsModule, &info) != SECSuccess) {
+ /* Do not use this module */
+ RootsModule = NULL;
+ } else {
+ /* NSS_BUILTINS_LIBRARY_VERSION_MAJOR and NSS_BUILTINS_LIBRARY_VERSION_MINOR
+ * define the version we expect to have.
+ * Later version are fine.
+ * Older versions are not ok, and we will replace with our own version.
+ */
+ if ((info.libraryVersion.major < NSS_BUILTINS_LIBRARY_VERSION_MAJOR)
+ || (info.libraryVersion.major == NSS_BUILTINS_LIBRARY_VERSION_MAJOR
+ && info.libraryVersion.minor < NSS_BUILTINS_LIBRARY_VERSION_MINOR)) {
+ PRInt32 modType;
+
+ SECMOD_DeleteModule (RootsModule->commonName, &modType);
+
+ RootsModule = NULL;
+ }
+ }
+ }
+
+ if (!RootsModule) {
/* grovel in various places for mozilla's built-in
cert module.
-
+
XXX yes this is gross. *sigh*
*/
char *paths_to_check[] = {
"/usr/lib",
"/usr/lib/mozilla",
};
- int i;
-
+
for (i = 0; i < G_N_ELEMENTS (paths_to_check); i ++) {
- char *dll_path = g_module_build_path (paths_to_check [i],
- "nssckbi");
-
+ char *dll_path = g_module_build_path (paths_to_check [i], "nssckbi");
+
if (g_file_test (dll_path, G_FILE_TEST_EXISTS)) {
SECMOD_AddNewModule("Mozilla Root Certs",dll_path, 0, 0);
g_free (dll_path);
break;
}
-
+
g_free (dll_path);
}
}