changeset 156:f09a0817e3bc

merged.
author Raimund Renkert <rrenkert@intevation.de>
date Tue, 25 Mar 2014 09:23:47 +0100
parents c0fdb8d336cf (current diff) dbbd761959ae (diff)
children fb3b2d77518f 0c06a608e15f
files
diffstat 10 files changed, 261 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- 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 <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <stdbool.h>
 
 #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
 
--- 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 <string.h>
 
 #include <errorcodes.h>
+#include <portpath.h>
 #include <strhelp.h>
 
 #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);
 }
--- 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);
     }
--- 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})
--- 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
--- /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 <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+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
+}
--- /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
--- 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 <string.h>
 #include <assert.h>
 
+/* 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';
     }
--- 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);
--- 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
 

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