# HG changeset patch # User Raimund Renkert # Date 1395735827 -3600 # Node ID f09a0817e3bcc553c152158e0dacb4e3a215bd4e # Parent c0fdb8d336cf7d01fd0f4f6d7a38693bb83fba6c# Parent dbbd761959ae4b9d7bcc998a5459bdd2aa849b27 merged. diff -r c0fdb8d336cf -r f09a0817e3bc cinst/main.c --- a/cinst/main.c Tue Mar 25 09:22:55 2014 +0100 +++ b/cinst/main.c Tue Mar 25 09:23:47 2014 +0100 @@ -30,6 +30,7 @@ #include #include #include +#include #include "strhelp.h" #include "listutil.h" @@ -49,10 +50,17 @@ * The caller needs to free the memory allocated by this function * even when an error is returned. * + * Uninstall certificates are all certificates that are pa + * + * @param[out] certificate_list the parsed certificate list + * @param[out] to_install strv of installation instructions or NULL + * @param[out] to_remove strv of remove instructions or NULL + * @param[out] all_certs strv of uninstallation instructions or NULL + * * @returns: 0 on success. An error code otherwise. */ int readInput(char **certificate_list, char ***to_install, - char ***to_remove) + char ***to_remove, char ***all_certs) { int lines_read = 0; int readingList = 0; @@ -96,55 +104,84 @@ } if (readingList) { str_append_str(certificate_list, &list_size, buf, len); + } else if (strcmp("UNINSTALL\r\n", buf) == 0) { + /* Remove trailing \r\n */ + strv_append(to_remove, buf, len - 2); continue; } if (*buf == 'I') { /* Remove leading I: and trailing \r\n */ - strv_append(to_install, buf+2, len - 4); + strv_append(readingList ? all_certs : to_install, + buf+2, len - 4); continue; } if (*buf == 'R') { /* Remove leading R: and trailing \r\n */ - strv_append(to_remove, buf+2, len - 4); + strv_append(readingList ? all_certs : to_remove, + buf+2, len - 4); continue; } - if (strcmp("UNINSTALL", buf) == 0) { - /* Remove trailing \r\n */ - strv_append(to_remove, buf, len - 2); - } } return 0; } -/* -int validate_instructions(const char *certificate_list, - const size_t list_len, - const char **to_install, - const char **to_remove) + +/** @brief Check that the insturctions match to the list + * + * Only certificates part of the certificate_list are allowed + * for installation. + * + * @param[in] all_certs strv of all valid certificates in a list + * @param[in] to_validate strv of instructions + * + * @returns 0 on success, an error otherwise + */ +int validate_instructions(char **all_certs, + char **to_validate) { - TODO - (void *) certificate_list; - (void **) to_install; - (void **) to_remove; - (void) list_len; + int i = 0, + j = 0; + + if (!all_certs || strv_length(all_certs) < 1) { + /* Invalid parameters */ + return -1; + } + + if (to_validate == NULL) { + /* Nothing is valid */ + return 0; + } + + for (i=0; to_validate[i]; i++) { + bool found = false; + for (j=0; all_certs[j]; j++) { + if (strncmp(to_validate[i], all_certs[j], MAX_LINE_LENGTH - 2) == 0) { + found = true; + break; + } + } + if (!found) { + printf("Install instruction with invalid certificate\n."); + return ERR_INVALID_INSTRUCTIONS; + } + } return 0; } -*/ + int main() { char **to_install = NULL; char **to_remove = NULL; + char **all_certs = NULL; char *certificate_list = NULL; size_t list_len = 0; int ret = -1; - /* - i = 0 , - uninstall = 0; - */ - ret = readInput(&certificate_list, &to_install, &to_remove); + bool uninstall = false; - if (ret != 0) { + ret = readInput(&certificate_list, &to_install, &to_remove, &all_certs); + + if (ret) { return ret; } @@ -156,7 +193,7 @@ ret = verify_list(certificate_list, list_len); - if (ret != 0) { + if (ret) { return ERR_INVALID_SIGNATURE; } @@ -165,29 +202,38 @@ } - /* Check that the instructions are ok to execute - ret = validate_instructions(certificate_list, list_len, to_install, - to_remove); - if (ret != 0) { - return ERR_INVALID_INSTRUCTIONS; + /* Check that the instructions are ok to execute */ + if (to_install) { + ret = validate_instructions(all_certs, to_install); + if (ret) { + return ret; + } } if (to_remove) { - for (i=0; to_remove[i]; i++) { - if (strncmp("UNINSTALL", to_remove[i], MAX_LINE_LENGTH)) { - uninstall = 1; - break; + if (to_remove[0] && strncmp("UNINSTALL", to_remove[0], MAX_LINE_LENGTH) == 0) { + uninstall = true; + strv_free(to_remove); + to_remove = NULL; + } else { + ret = validate_instructions(all_certs, to_remove); + if (ret) { + return ret; } } } if (uninstall) { - + /* To uninstall does not have to be verified as it part of the + * signed list.*/ + to_remove = all_certs; + } else { + strv_free(all_certs); + all_certs = NULL; } -*/ #ifdef WIN32 - return install_certificates_win((const char**) to_install, 1); + return install_certificates_win((const char**) to_install, true); //remove_certificates_win((const char**) to_remove, 1); #endif diff -r c0fdb8d336cf -r f09a0817e3bc cinst/mozilla.c --- a/cinst/mozilla.c Tue Mar 25 09:22:55 2014 +0100 +++ b/cinst/mozilla.c Tue Mar 25 09:23:47 2014 +0100 @@ -54,6 +54,7 @@ #include #include +#include #include #ifndef _WIN32 @@ -62,6 +63,8 @@ #define UNIX 0 #endif +#define LINEBUFLEN 1000 + /** * @brief Global Return Code * @@ -86,39 +89,77 @@ get_profile_dirs (char *inifile_name) { char **dirs = NULL; + char *inifile_dirname; FILE *inifile; - char line[1000]; + 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) { - while (fgets(line, 1000, inifile) != NULL) + inifile_dirname = port_dirname(inifile_name); + while (fgets(line, LINEBUFLEN, inifile) != NULL) { - if (strncmp(line, "[Profile", 8) == 0) - inprofile = true; + /* 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 (inprofile && - (strncmp(line, "Path=", 5) == 0)) - strv_append(&dirs, line, strlen(line)); + + /* If we are in a profile parse path related stuff */ + if (inprofile) + { + value = line; + key = strsep(&value, "="); + 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) + { + strv_append(&dirs, fqpath, strlen(fqpath)); + free (fqpath); + } + else + return_code |= WARN_MOZ_PROFILE_DOES_NOT_EXIST; + } + else if (str_equal(key, "IsRelative") && + str_starts_with(value, "1")) + relative_path = true; + } } } else { return_code |= WARN_MOZ_FAILED_TO_OPEN_INI; } - return dirs; } int -main () +main (int argc, char *argv[]) { int x = 0; - char **pdirs = - get_profile_dirs("/home/wilde/.mozilla/firefox/profiles.ini"); - while (pdirs[x] != NULL) - puts(pdirs[x++]); - strv_free(pdirs); + if (argc == 2) + { + char **pdirs = + get_profile_dirs(argv[1]); + if (pdirs != NULL) + { + while (pdirs[x] != NULL) + puts(pdirs[x++]); + strv_free(pdirs); + } + } exit(return_code); } diff -r c0fdb8d336cf -r f09a0817e3bc cinst/windowsstore.c --- a/cinst/windowsstore.c Tue Mar 25 09:22:55 2014 +0100 +++ b/cinst/windowsstore.c Tue Mar 25 09:23:47 2014 +0100 @@ -25,17 +25,15 @@ return bufPtr; } -int install_certificates_win(const char **to_install, int user_store) +int install_certificates_win(const char **to_install, bool user_store) { int i = 0; HCERTSTORE hStore = NULL; if (user_store) { - // Access user store hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root"); } else { - // Access machine store hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root"); } @@ -85,6 +83,7 @@ i++; free(buf); } + if(hStore) { CertCloseStore(hStore, 0); } diff -r c0fdb8d336cf -r f09a0817e3bc common/CMakeLists.txt --- a/common/CMakeLists.txt Tue Mar 25 09:22:55 2014 +0100 +++ b/common/CMakeLists.txt Tue Mar 25 09:23:47 2014 +0100 @@ -1,6 +1,7 @@ set (m13_common_src listutil.c strhelp.c + portpath.c ) add_library(m13_common STATIC ${m13_common_src}) diff -r c0fdb8d336cf -r f09a0817e3bc common/errorcodes.h --- a/common/errorcodes.h Tue Mar 25 09:22:55 2014 +0100 +++ b/common/errorcodes.h Tue Mar 25 09:23:47 2014 +0100 @@ -1,6 +1,8 @@ #ifndef ERRORCODES_H #define ERRORCODES_H +/* No error */ +#define NO_ERROR 0 /* No begin certificate / end certificate could be found */ #define ERR_INVALID_INPUT_NO_LIST 2 /* Too much input for the installer process */ @@ -20,12 +22,14 @@ /*********************************************************************** * mozilla specific errors and warnings - * errors range from 0x4D01 to 0x4DFF - * warnings from 0x4F01 to 0x4F80 + * errors range from 0x0081 to 0x08F + * warnings from 0x0091 to 0x0098 * Warnings might be ORed together ... */ /* Warning: Failed to read profile.ini */ -#define WARN_MOZ_FAILED_TO_OPEN_INI 0x4F01 +#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 #endif diff -r c0fdb8d336cf -r f09a0817e3bc common/portpath.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portpath.c Tue Mar 25 09:23:47 2014 +0100 @@ -0,0 +1,30 @@ +#include "portpath.h" + +#include +#include +#include +#include + + +char * +port_dirname(char *path) +{ +#ifndef _WIN32 + return dirname(path); +#else + fprintf(stderr, "Windows Suport missing!"); + abort(); +#endif + +} + +char * +port_realpath(char *path) +{ +#ifndef _WIN32 + return realpath(path, NULL); +#else + fprintf(stderr, "Windows Suport missing!"); + abort(); +#endif +} diff -r c0fdb8d336cf -r f09a0817e3bc common/portpath.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portpath.h Tue Mar 25 09:23:47 2014 +0100 @@ -0,0 +1,41 @@ +#ifndef PORTPATH_H +#define PORTPATH_H + +/** + * @file portpath.h + * @brief Platform independent functions for file and path handling. + * @details portpath contains functions to handle file and path names + * in a platform independent way. The code unsing this functions + * should be protable between GNU/Linux and Windows32 systems. + */ + +/** + * @brief portable version of dirname + * @details return the directory component of the given path. + * The argument path may be altered by the function. + * @param[inout] path the pathname + * @returns a pointer to the string containing the directory component + */ +char *port_dirname(char *path); + + +/** + * @brief portable version of dirname + * @details return the directory component of the given path. + * The argument path may be altered by the function. + * @param[inout] path the pathname + * @returns a pointer to the string containing the directory component + */ +char *port_dirname(char *path); + +/** + * @brief portable version of realpath + * @details return the expanded absolute pathname for the given path. + * The buffer for the resolved path is allocated by this function and + * should be freed by the caller. + * @param[in] path the original pathname + * @returns a pointer to the resolved path or NULL on error + */ +char *port_realpath(char *path); + +#endif diff -r c0fdb8d336cf -r f09a0817e3bc common/strhelp.c --- a/common/strhelp.c Tue Mar 25 09:22:55 2014 +0100 +++ b/common/strhelp.c Tue Mar 25 09:23:47 2014 +0100 @@ -5,6 +5,17 @@ #include #include +/* Remarks regarding the "Flawfinder: ignore" comments in this file: + * + * - strlen: + * + * It's true that strlen might crash if input is not null + * terminated. But by design there is not safe way to get the + * length of an string in C, and defining an additional length + * parameter for string parameter will only transfere the problem to + * the caller. + */ + static void out_of_core(void) { @@ -107,8 +118,8 @@ bool str_equal (char *s1, char *s2) { - size_t l1 = strlen(s1); - size_t l2 = strlen(s2); + size_t l1 = strlen(s1); /* Flawfinder: ignore */ + size_t l2 = strlen(s2); /* Flawfinder: ignore */ if ((l1 == l2) && (strcmp(s1, s2) == 0)) return true; @@ -119,7 +130,8 @@ bool str_starts_with (char *s1, char *s2) { - if (strncmp(s1, s2, strlen(s2)) == 0) + size_t l2 = strlen(s2); /* Flawfinder: ignore */ + if (strncmp(s1, s2, l2) == 0) return true; else return false; @@ -133,7 +145,7 @@ { while (isspace(**s)) (*s)++; - i = strlen(*s); + i = strlen(*s); /* Flawfinder: ignore */ while (isspace((*s)[--i])) (*s)[i] = '\0'; } diff -r c0fdb8d336cf -r f09a0817e3bc ui/tests/cinstprocesstest.cpp --- a/ui/tests/cinstprocesstest.cpp Tue Mar 25 09:22:55 2014 +0100 +++ b/ui/tests/cinstprocesstest.cpp Tue Mar 25 09:23:47 2014 +0100 @@ -17,11 +17,19 @@ return installerProcess; } +#define VERIFY_PROC_DEBUG(x) \ + if (! x ) { \ + qDebug() << "Stdout:" << proc->readAllStandardOutput(); \ + qDebug() << "Stderr:" << proc->readAllStandardError(); \ + qDebug() << "Exit code: " << proc->exitCode(); \ + } \ + QVERIFY(x) + void finishVerify(QProcess *proc, int exitCode) { proc->closeWriteChannel(); proc->waitForFinished(); - QVERIFY(proc->exitStatus() == QProcess::NormalExit); - QVERIFY(proc->exitCode() == exitCode); + VERIFY_PROC_DEBUG(proc->exitStatus() == QProcess::NormalExit); + VERIFY_PROC_DEBUG(proc->exitCode() == exitCode); delete proc; } @@ -38,7 +46,7 @@ installerProcess->write("\r\n"); } - finishVerify(installerProcess, 0); + finishVerify(installerProcess, NO_ERROR); } void CinstProcessTest::initTestCase() { @@ -106,14 +114,26 @@ QProcess* installerProcess = startCinstProcess(); QVERIFY(installerProcess->state() == QProcess::Running); - /* I: as instruction */ installerProcess->write("-----BEGIN CERTIFICATE LIST-----\r\n"); installerProcess->write(validList.rawData().toLatin1()); installerProcess->write("-----END CERTIFICATE LIST-----\r\n"); - installerProcess->write("I:ABCDEF"); + installerProcess->write("I:ABCDEF\r\n"); finishVerify(installerProcess, ERR_INVALID_INSTRUCTIONS); } +void CinstProcessTest::testUninstall() { + QProcess* installerProcess = startCinstProcess(); + QVERIFY(installerProcess->state() == QProcess::Running); + + installerProcess->write("-----BEGIN CERTIFICATE LIST-----\r\n"); + installerProcess->write(validList.rawData().toLatin1()); + installerProcess->write("-----END CERTIFICATE LIST-----\r\n"); + + installerProcess->write("UNINSTALL\r\n"); + + finishVerify(installerProcess, NO_ERROR); +} + QTEST_GUILESS_MAIN (CinstProcessTest); diff -r c0fdb8d336cf -r f09a0817e3bc ui/tests/cinstprocesstest.h --- a/ui/tests/cinstprocesstest.h Tue Mar 25 09:22:55 2014 +0100 +++ b/ui/tests/cinstprocesstest.h Tue Mar 25 09:23:47 2014 +0100 @@ -28,6 +28,7 @@ void testNoList(); void testGarbageInput(); void testNoInstructions(); + void testUninstall(); }; #endif