changeset 282:d13d51f7a0e2

Merged
author Sascha Wilde <wilde@intevation.de>
date Wed, 02 Apr 2014 15:22:33 +0200
parents 0f73fe4230c1 (diff) e265431f3e92 (current diff)
children fb9e14f4b4c9
files
diffstat 2 files changed, 168 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/cinst/mozilla.c	Wed Apr 02 13:39:22 2014 +0200
+++ b/cinst/mozilla.c	Wed Apr 02 15:22:33 2014 +0200
@@ -270,7 +270,6 @@
   if (inis == NULL)
     {
       DEBUGPRINTF("No ini files found - will do nothing!\n");
-      exit(WARN_MOZ_NO_PROFILES);
     }
   return inis;
 }
@@ -306,12 +305,13 @@
   return alldirs;
 }
 
+#ifdef DEBUGOUTPUT
 /**
  * @brief list certificates from nss certificate store
  * @param[in] confdir the directory with the certificate store
  */
 static void
-nss_list_certs (char *confdir)
+DEBUG_nss_list_certs (char *confdir)
 {
   CERTCertList *list;
   CERTCertListNode *node;
@@ -325,14 +325,17 @@
            node = CERT_LIST_NEXT(node)) {
         name = node->appData;
 
-        printf ("Found certificate \"%s\"\n", name);
+        DEBUGPRINTF("Found certificate \"%s\"\n", name);
       }
       CERT_DestroyCertList(list);
       NSS_Shutdown();
     }
   else
-    DEBUGPRINTF("Could not open nss certificate store in %s!\n", confdir);
+    {
+      DEBUGPRINTF("Could not open nss certificate store in %s!\n", confdir);
+    }
 }
+#endif
 
 /**
  * @brief Create a string with the name for cert in SECItem.
@@ -355,6 +358,14 @@
   return name;
 }
 
+/**
+ * @brief Convert a base64 encoded DER certificate to SECItem
+ * @param[in] b64 pointer to the base64 encoded certificate
+ * @param[in] b64len length of the base64 encoded certificate
+ * @param[out] secitem pointer to the SECItem in which to store the
+ * raw DER certifiacte.
+ * @returns true on success and false on failure
+ */
 static bool
 base64_to_secitem(char *b64, size_t b64len, SECItem *secitem)
 {
@@ -370,11 +381,144 @@
       return true;
     }
   else
-    DEBUGPRINTF("Base64 decode failed for: %s\n", b64);
+    {
+      DEBUGPRINTF("Base64 decode failed for: %s\n", b64);
+    }
   return false;
 }
 
 /**
+ * @brief Store DER certificate in mozilla store.
+ * @param[in] pdir the mozilla profile directory with the certificate
+ * store to manipulate.
+ * @param[in] dercert pointer to a SECItem holding the DER certificate
+ * to install
+ * @returns true on success and false on failure
+ */
+static bool
+import_cert(char *pdir, SECItem *dercert)
+{
+  PK11SlotInfo *pk11slot = NULL;
+  bool success = false;
+  char *cert_name = nss_cert_name(dercert);
+
+  DEBUGPRINTF("INSTALLING cert: '%s' to: %s\n", cert_name, pdir);
+  if (NSS_Initialize(pdir, "", "", "secmod.db", 0) == SECSuccess)
+    {
+      pk11slot = PK11_GetInternalKeySlot();
+      if (PK11_ImportDERCert(pk11slot, dercert, CK_INVALID_HANDLE,
+                             cert_name, PR_FALSE)
+          == SECSuccess)
+        {
+          success = true;
+        }
+      else
+        {
+          DEBUGPRINTF("Failed to install certificate '%s' to '%s'!\n", cert_name, pdir);
+        }
+      PK11_FreeSlot(pk11slot);
+      NSS_Shutdown();
+    }
+  else
+    {
+      DEBUGPRINTF("Could not open nss certificate store in %s!\n", pdir);
+    }
+
+  free(cert_name);
+  return success;
+}
+
+/**
+ * @brief Remove DER certificate from mozilla store.
+ * @param[in] pdir the mozilla profile directory with the certificate
+ * store to manipulate.
+ * @param[in] dercert pointer to a SECItem holding the DER certificate
+ * to remove
+ * @returns true on success and false on failure
+ */
+static bool
+remove_cert(char *pdir, SECItem *dercert)
+{
+  PK11SlotInfo *pk11slot = NULL;
+  bool success = false;
+  char *cert_name = nss_cert_name(dercert);
+  CERTCertificate *cert = NULL;
+
+  DEBUGPRINTF("REMOVING cert: '%s' from: %s\n", cert_name, pdir);
+  if (NSS_Initialize(pdir, "", "", "secmod.db", 0) == SECSuccess)
+    {
+      pk11slot = PK11_GetInternalKeySlot();
+      cert = PK11_FindCertFromDERCertItem(pk11slot,
+                                          dercert, NULL);
+      if (cert != NULL)
+        {
+          if (SEC_DeletePermCertificate(cert) == SECSuccess)
+            {
+              success = true;
+            }
+          else
+            {
+              DEBUGPRINTF("Failed to remove certificate '%s' from '%s'!\n", cert_name, pdir);
+            }
+          CERT_DestroyCertificate(cert);
+        }
+      else
+        {
+          DEBUGPRINTF("Could not find Certificate '%s' in store '%s'.\n", cert_name, pdir);
+        }
+      PK11_FreeSlot(pk11slot);
+      NSS_Shutdown();
+    }
+  else
+    {
+      DEBUGPRINTF("Could not open nss certificate store in %s!\n", pdir);
+    }
+  free(cert_name);
+  return success;
+}
+
+/**
+ * @brief Apply a function to a list of certificates and profiles
+ *
+ * The function must have the signature:
+ *
+ *   bool function(char *pdir, SECItem der_cert)
+ *
+ * where pdir is the path of an profile and der_cert is an raw DER
+ * formatted certificate.  The function must return true on success
+ * and false on failure.
+ *
+ * This function is intended wor use with the import_cert and
+ * remove_cert functions.
+ *
+ * @param[in] fn the function to apply
+ * @param[inout] certs a secitem list holding the certificates
+ * the list will be change (emptied)!
+ * @param[in] pdirs the NULL terminated list of profile directories
+ * @returns true on success and false on failure
+ */
+bool
+apply_to_certs_and_profiles(bool fn(char *, SECItem *),
+                            seciteml_t **certs, char **pdirs)
+{
+  SECItem *cert;
+  bool success = true;
+
+  while ((cert = seciteml_pop(certs)) != NULL)
+    {
+      for (int i=0; pdirs[i] != NULL; i++)
+        {
+          if (! (*fn)(pdirs[i], cert))
+            success = false;
+        }
+      free(cert->data);
+      free(cert);
+    }
+
+  return success;
+}
+
+/**
  * @brief Parse IPC commands from standard input.
  *
  * Reads command lines (R: and I:) from standard input and puts the
@@ -443,11 +587,6 @@
   char **pdirs;
   seciteml_t *certs_to_remove = NULL;
   seciteml_t *certs_to_add = NULL;
-  SECItem *secitemp;
-  SECStatus rv;
-  PK11SlotInfo *pk11slot = NULL;
-  char *cert_name;
-  CERTCertificate *cert = NULL;
 
   pdirs =
     get_all_profile_dirs();
@@ -456,74 +595,24 @@
     {
       parse_commands(&certs_to_add, &certs_to_remove);
 
-      while ((secitemp = seciteml_pop(&certs_to_remove)) != NULL)
-        {
-          cert_name = nss_cert_name(secitemp);
-          for (int i=0; pdirs[i] != NULL; i++)
-            {
-              puts(pdirs[i]);
-              nss_list_certs(pdirs[i]);
+#ifdef DEBUGOUTPUT
+      DEBUGPRINTF("OLD List of installed certs:");
+      for (int i=0; pdirs[i] != NULL; i++)
+        DEBUG_nss_list_certs(pdirs[i]);
+#endif
 
-              printf("Will now DELETE cert: '%s' from %s\n", cert_name, pdirs[i]);
-              if (NSS_Initialize(pdirs[i], "", "", "secmod.db", 0)
-                  == SECSuccess)
-                {
-                  pk11slot = PK11_GetInternalKeySlot();
-                  cert = PK11_FindCertFromDERCertItem(pk11slot,
-                                                      secitemp, NULL);
-                  if (cert != NULL)
-                    {
-                      rv = SEC_DeletePermCertificate(cert);
-                      if (rv != SECSuccess)
-                        {
-                          DEBUGPRINTF("Failed to remove certificate '%s' from '%s'!\n", cert_name, pdirs[i]);
-                          DEBUGPRINTF("Error was %d\n", rv);
-                        }
-                    }
-                  else
-                    {
-                      DEBUGPRINTF("Could not find Certificate %s in store.\n", cert_name);
-                    }
-                  CERT_DestroyCertificate(cert);
-                  PK11_FreeSlot(pk11slot);
-                  NSS_Shutdown();
-                }
-              puts("List new:");
-              nss_list_certs(pdirs[i]);
-            }
-          free(cert_name);
-          free(secitemp->data);
-          free(secitemp);
-        }
+      if (! apply_to_certs_and_profiles(remove_cert, &certs_to_remove, pdirs))
+        return_code |= WARN_MOZ_COULD_NOT_REMOVE_CERT;
 
-      while ((secitemp = seciteml_pop(&certs_to_add)) != NULL)
-        {
-          cert_name = nss_cert_name(secitemp);
-          for (int i=0; pdirs[i] != NULL; i++)
-            {
-              puts(pdirs[i]);
-              nss_list_certs(pdirs[i]);
+      if (! apply_to_certs_and_profiles(import_cert, &certs_to_add, pdirs))
+        return_code |= WARN_MOZ_COULD_NOT_ADD_CERT;
 
-              printf("Will now ADD cert: '%s' to %s\n", cert_name, pdirs[i]);
-              if (NSS_Initialize(pdirs[i], "", "", "secmod.db", 0)
-                  == SECSuccess)
-                {
-                  pk11slot = PK11_GetInternalKeySlot();
-                  rv = PK11_ImportDERCert(pk11slot, secitemp, CK_INVALID_HANDLE, cert_name, PR_FALSE);
-                  if (rv != SECSuccess) {
-                    DEBUGPRINTF("Failed to install certificate '%s' to '%s'!\n", cert_name, pdirs[i]);
-                    DEBUGPRINTF("Error was %d\n", rv);
-                  }
-                  PK11_FreeSlot(pk11slot);
-                  NSS_Shutdown();
-                }
-              puts("List new:");
-              nss_list_certs(pdirs[i]);
-            }
-          free(cert_name);
-          free(secitemp->data);
-          free(secitemp);
-        }
+#ifdef DEBUGOUTPUT
+      DEBUGPRINTF("NEW List of installed certs:");
+      for (int i=0; pdirs[i] != NULL; i++)
+        DEBUG_nss_list_certs(pdirs[i]);
+#endif
+
       strv_free(pdirs);
     }
   exit(return_code);
--- a/common/errorcodes.h	Wed Apr 02 13:39:22 2014 +0200
+++ b/common/errorcodes.h	Wed Apr 02 15:22:33 2014 +0200
@@ -37,7 +37,9 @@
 #define WARN_MOZ_FAILED_TO_OPEN_INI 0x0091
 /* Warning: Some profile paths from profile.ini don't exist */
 #define WARN_MOZ_PROFILE_DOES_NOT_EXIST 0x0092
-/* Warning: no profiles found */
-#define WARN_MOZ_NO_PROFILES 0x0094
+/* Warning: could not install some certs */
+#define WARN_MOZ_COULD_NOT_ADD_CERT 0x0094
+/* Warning: could not remove some certs */
+#define WARN_MOZ_COULD_NOT_REMOVE_CERT 0x0098
 
 #endif

http://wald.intevation.org/projects/trustbridge/