# HG changeset patch # User Sascha Wilde # Date 1396444953 -7200 # Node ID d13d51f7a0e2252247901565263f6247e15c4d8b # Parent 0f73fe4230c1db9721a27b74326ca38c07883756# Parent e265431f3e9281c2c61140613a3b9615cf31e8d0 Merged diff -r e265431f3e92 -r d13d51f7a0e2 cinst/mozilla.c --- 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); diff -r e265431f3e92 -r d13d51f7a0e2 common/errorcodes.h --- 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