Mercurial > trustbridge
view cinst/mozilla.c @ 228:19de529ce7fb
Moved debug prefix to macro and added component specific prefix.
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Thu, 27 Mar 2014 18:31:26 +0100 |
parents | 29467940b07b |
children | e99e39d72af2 |
line wrap: on
line source
/** * @file * @brief Mozilla installation process * * Reads from stdin a list of instructions in the form: * * I:<base64 DER econded certificate>\r\n * R:<base64 DER econded certificate>\r\n * ... * * The maximum size of an input line is 9999 characters * (including the \r\n) at the end of the line. * * Certificates marked with I: will be installed and the ones * marked with R: will be searched and if available removed from * the databases. * * This tool tries to find all NSS databases the user has * access to and to execute the instructions on all of them. * * If there are other processes accessing the databases the caller * has to ensure that those are terminated before this process is * executed. * * Returns 0 on success (Even when no stores where found) an error value * as defined in errorcodes.h otherwise. * * Success messages are written to stdout. Errors to stderr. For logging * purposes each installation / removal of a certificate will be reported * with the profile name that it modified. * */ /* @brief IniParser for mozilla profiles.ini * * Parse data to find values formed in * * [Profile99] * IsRelative=1 * Path=Profiles/fooo.bar * * or * [Profile0] * IsRelative=0 * Path=c:\foo\bar\baz * * Mozilla also accepts the ini file on Windows even if it is UTF-16 * encoded. * */ #include <dirent.h> #include <cert.h> #include <certt.h> #include <nss.h> #include <pk11pub.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include "debug.h" #include "errorcodes.h" #include "portpath.h" #include "strhelp.h" #define DEBUGPREFIX "MOZ-" #ifndef _WIN32 #define CONFDIRS ".mozilla", ".thunderbird" #define TARGET_LINUX 1 #else #define CONFDIRS "Mozilla", "Thunderbird" #define TARGET_LINUX 0 #endif #define LINEBUFLEN 1000 /** * @brief Global Return Code * * This will be retuned by the programm and might be set to an * error code on fatal errors and to and warning code on non-fatal * errors. In case of mor than one warning the warning codes will be * ORed together. */ int return_code = 0; /** * @brief Return configuration base directory. * @returns A pointer to a string containing the path to the base * directory holding the configuration directories for e.g. mozilla * and thunderbird. */ static char * get_conf_basedir() { char *cdir, *envvar; if (TARGET_LINUX) envvar = "HOME" ; else envvar = "APPDATA"; if ((cdir = getenv(envvar)) != NULL) return cdir; else { DEBUGPRINTF("FATAL! No %s in environment.\n", envvar); exit(ERR_MOZ_HOMELESS); } } /** * @brief Get a list of all mozilla profile directories * * Read the profiles.ini and extract all profile paths from that. * * @param[in] inifile_name path of the profile.ini to read. * @return NULL terminated array of strings containing containing the * absolute path of the profile directories. The array needs to * be freed by the caller. */ static char ** get_profile_dirs (char *inifile_name) { char **dirs = NULL; char *inifile_dirname; FILE *inifile; char line[LINEBUFLEN]; char *key; char *value; char path[LINEBUFLEN]; char *fqpath; bool inprofile = false; bool relative_path = false; if ((inifile = fopen(inifile_name, "r")) != NULL) { DEBUGPRINTF("Searching for profile paths in: '%s'\n", inifile_name); inifile_dirname = port_dirname(inifile_name); while (fgets(line, LINEBUFLEN, inifile) != NULL) { /* Determine if we are in an profile section */ if (str_starts_with(line, "[Profile")) { relative_path = false; inprofile = true; } else if (line[0] == '[') inprofile = false; /* If we are in a profile parse path related stuff */ if (inprofile) { key = strtok(line, "="); value = strtok(NULL, "="); str_trim(&value); if (str_equal(key, "Path")) { if (relative_path) snprintf(path, LINEBUFLEN, "%s/%s", inifile_dirname, value); else strncpy(path, value, LINEBUFLEN); if ((fqpath = port_realpath(path)) != NULL) { DEBUGPRINTF("Found profile path: '%s'\n", fqpath); strv_append(&dirs, fqpath, strlen(fqpath)); free (fqpath); } else { DEBUGPRINTF("WARN! Non existent profile path: '%s'\n", path); return_code |= WARN_MOZ_PROFILE_DOES_NOT_EXIST; } } else if (str_equal(key, "IsRelative") && str_starts_with(value, "1")) relative_path = true; } } fclose(inifile); } else { DEBUGPRINTF("WARN! Could not open ini file: '%s'\n", inifile_name); return_code |= WARN_MOZ_FAILED_TO_OPEN_INI; } return dirs; } /** * @brief Search for mozilla profiles.ini files * * Use well known paths and heuristics to find the current users * profiles.ini files on GNU/Linux and Windows systems. * * @return NULL terminated array of strings containing the absolute * path of the profiles.ini files. The array needs to be freed by the * caller. */ static char ** get_profile_inis () { char **inis = NULL; char path[LINEBUFLEN]; char *fqpath; DIR *mozdir; struct dirent *mozdirent; char *confbase = get_conf_basedir(); const char *confdirs[] = { CONFDIRS, NULL }; for (int i=0; confdirs[i] != NULL; i++) { snprintf(path, LINEBUFLEN, "%s/%s", confbase, confdirs[i]); if ((mozdir = opendir(path)) != NULL) { while ((mozdirent = readdir(mozdir)) != NULL) { snprintf(path, LINEBUFLEN, "%s/%s/%s", confbase, confdirs[i], mozdirent->d_name); if (port_isdir(path) && (strcmp(mozdirent->d_name, "..") != 0)) { snprintf(path, LINEBUFLEN, "%s/%s/%s/%s", confbase, confdirs[i], mozdirent->d_name, "profiles.ini"); DEBUGPRINTF("checking for %s...\n", path); if ((fqpath = port_realpath(path)) != NULL) { strv_append(&inis, fqpath, strlen(fqpath)); DEBUGPRINTF("Found mozilla ini file: '%s'\n", fqpath); free(fqpath); } } } closedir(mozdir); } else { DEBUGPRINTF("Could not open %s/%s\n", confbase, confdirs[i]); } } if (inis == NULL) { DEBUGPRINTF("No ini files found - will do nothing!\n"); exit(WARN_MOZ_NO_PROFILES); } return inis; } /** * @brief list certificates from nss certificate store * @param[in] confdir the directory with the certificate store */ static void nss_list_certs (char *confdir) { CERTCertList *list; CERTCertListNode *node; char *name; if (NSS_Initialize(confdir, "", "", "secmod.db", NSS_INIT_READONLY) == SECSuccess) { list = PK11_ListCerts(PK11CertListAll, NULL); for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node)) { name = node->appData; printf ("Found certificate \"%s\"\n", name); } CERT_DestroyCertList(list); NSS_Shutdown(); } else DEBUGPRINTF("Could not open nss cer store in %s!", confdir); } int main () { int y = 0; char **mozinis, **pdirs; if ((mozinis = get_profile_inis()) != NULL) while (mozinis[y] != NULL) { pdirs = get_profile_dirs(mozinis[y++]); if (pdirs != NULL) { for (int x=0; pdirs[x] != NULL; x++) { puts(pdirs[x]); nss_list_certs(pdirs[x]); } strv_free(pdirs); } } exit(return_code); }