Mercurial > trustbridge
view cinst/mozilla.c @ 181:bea93c8651b7
Merged
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Tue, 25 Mar 2014 17:56:56 +0100 |
parents | 344b8a79ad2e 8fafd0fc2173 |
children | d4e97c9b199f |
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 <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> #ifndef _WIN32 #define LINUX 1 #else #define 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 users home path, on windows including drive letter * @returns a pointer to a string containing the home path, it should * be freed by the caller. */ static char * get_home() { char *home, *homevar, *fqhome; char *homedrive = NULL; size_t len; if (LINUX) homevar = "HOME"; else homevar = "HOMEPATH"; if ((home = getenv(homevar)) == NULL) { DEBUGFPRINT("DEBUG: FATAL! No HOME in environment.\n"); exit(ERR_MOZ_HOMELESS); } len = strlen(home); if (!LINUX) homedrive = getenv("HOMEDRIVE"); if (homedrive != NULL) len += strlen(homedrive); len++; /* Room for \0 */ fqhome = xmalloc(len); if (homedrive == NULL) snprintf(fqhome, len, "%s", home); else snprintf(fqhome, len, "%s%s", homedrive, home); return fqhome; } /** * @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) { DEBUGFPRINT("DEBUG: 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) { DEBUGFPRINT("DEBUG: Found profile path: '%s'\n", fqpath); strv_append(&dirs, fqpath, strlen(fqpath)); free (fqpath); } else { DEBUGFPRINT("DEBUG: 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 { DEBUGFPRINT("DEBUG: 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; char *mozdirname; DIR *mozdir; struct dirent *mozdirent; char *home = get_home(); if (LINUX) { mozdirname = ".mozilla"; } else { mozdirname = "AppData/Roaming/Mozilla"; } snprintf(path, LINEBUFLEN, "%s/%s", home, mozdirname); if ((mozdir = opendir(path)) != NULL) { while ((mozdirent = readdir(mozdir)) != NULL) { snprintf(path, LINEBUFLEN, "%s/%s/%s", home, mozdirname, mozdirent->d_name); if (port_isdir(path)) { snprintf(path, LINEBUFLEN, "%s/%s/%s/%s", home, mozdirname, mozdirent->d_name, "profiles.ini"); DEBUGFPRINT("DEBUG: checking for %s...\n", path); if ((fqpath = port_realpath(path)) != NULL) { strv_append(&inis, fqpath, strlen(fqpath)); DEBUGFPRINT("DEBUG: Found mozilla ini file: '%s'\n", fqpath); free(fqpath); } } } closedir(mozdir); } else { DEBUGFPRINT("DEBUG: Could not open %s/%s\n", home, mozdirname); exit(WARN_MOZ_NO_PROFILES); } return inis; } int main () { int x = 0; 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) { while (pdirs[x] != NULL) puts(pdirs[x++]); strv_free(pdirs); } } exit(return_code); }