changeset 188:a3bde2aaabd9

merged.
author Raimund Renkert <rrenkert@intevation.de>
date Wed, 26 Mar 2014 09:12:10 +0100
parents 0c06a608e15f (current diff) ee37c085b9f7 (diff)
children 5f0d45ca9de4
files
diffstat 18 files changed, 592 insertions(+), 223 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Mar 26 09:10:46 2014 +0100
+++ b/CMakeLists.txt	Wed Mar 26 09:12:10 2014 +0100
@@ -28,7 +28,7 @@
    if (NOT CMAKE_BUILD_TYPE)
       set (CMAKE_BUILD_TYPE RELEASE)
    endif (NOT CMAKE_BUILD_TYPE)
-   add_definitions (RELEASE_BUILD)
+   add_definitions (-DRELEASE_BUILD)
 else()
 # Default to debug build
    if (NOT CMAKE_BUILD_TYPE)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HACKING	Wed Mar 26 09:12:10 2014 +0100
@@ -0,0 +1,10 @@
+Please keep C code according to GNU coding standards.
+
+With regards to the style:
+    astyle --style=gnu --indent=spaces=2 --pad-paren-out
+
+For the C++ Ui code please use the kdelibs coding style
+    astyle --indent=spaces=4 --brackets=linux \
+           --indent-labels --pad-oper --unpad-paren --pad-header \
+           --keep-one-line-statements --convert-tabs \
+           --indent-preprocessor
--- a/cinst/CMakeLists.txt	Wed Mar 26 09:10:46 2014 +0100
+++ b/cinst/CMakeLists.txt	Wed Mar 26 09:12:10 2014 +0100
@@ -29,6 +29,7 @@
 
 target_link_libraries(mozilla
    m13_common
+   ${POLARSSL_LIBRARIES}
    ${PROFILING_LIBS})
 
 install(TARGETS mozilla DESTINATION bin)
--- a/cinst/main.c	Wed Mar 26 09:10:46 2014 +0100
+++ b/cinst/main.c	Wed Mar 26 09:12:10 2014 +0100
@@ -59,71 +59,84 @@
  *
  * @returns: 0 on success. An error code otherwise.
  */
-int readInput(char **certificate_list, char ***to_install,
-              char ***to_remove, char ***all_certs)
+int
+readInput (char **certificate_list, char ***to_install,
+           char ***to_remove, char ***all_certs)
 {
-    int lines_read = 0;
-    int readingList = 0;
-    size_t list_size = 0;
-    char buf[MAX_LINE_LENGTH + 2];
+  int lines_read = 0;
+  int readingList = 0;
+  size_t list_size = 0;
+  char buf[MAX_LINE_LENGTH + 2];
 
-    if (*certificate_list || *to_install || *to_remove) {
-        printf("Error invalid parameters\n");
-        return -1;
+  if (*certificate_list || *to_install || *to_remove)
+    {
+      printf ("Error invalid parameters\n");
+      return -1;
     }
 
-    while (fgets(buf, MAX_LINE_LENGTH + 1, stdin)) {
-        size_t len = strlen(buf); /* fgets ensures buf is terminated */
-        if (len <= 3) {
-            printf("Line too short.\n");
-            return ERR_INVALID_INPUT;
+  while (fgets (buf, MAX_LINE_LENGTH + 1, stdin) )
+    {
+      size_t len = strlen (buf);	/* fgets ensures buf is terminated */
+      if (len <= 3)
+        {
+          printf ("Line too short.\n");
+          return ERR_INVALID_INPUT;
         }
-        if (lines_read ++ > MAX_LINES) {
-            printf("Too many lines\n");
-            return ERR_TOO_MUCH_INPUT;
+      if (lines_read++ > MAX_LINES)
+        {
+          printf ("Too many lines\n");
+          return ERR_TOO_MUCH_INPUT;
         }
 
-        if (buf[len-2] != '\r') {
-            if (buf[len-1] != '\n') {
-                printf("Line too long.\n");
-                return ERR_INVALID_INPUT;
+      if (buf[len - 2] != '\r')
+        {
+          if (buf[len - 1] != '\n')
+            {
+              printf ("Line too long.\n");
+              return ERR_INVALID_INPUT;
             }
-            buf[len-1] = '\r';
-            buf[len] = '\n';
-            buf[len+1] = '\0';
-            len++;
+          buf[len - 1] = '\r';
+          buf[len] = '\n';
+          buf[len + 1] = '\0';
+          len++;
         }
 
-        if (strcmp("-----BEGIN CERTIFICATE LIST-----\r\n", buf) == 0){
-            readingList = 1;
-            continue;
-        }
-        if (strcmp("-----END CERTIFICATE LIST-----\r\n", buf) == 0){
-            readingList = 0;
-            continue;
+      if (strcmp ("-----BEGIN CERTIFICATE LIST-----\r\n", buf) == 0)
+        {
+          readingList = 1;
+          continue;
         }
-        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 (strcmp ("-----END CERTIFICATE LIST-----\r\n", buf) == 0)
+        {
+          readingList = 0;
+          continue;
         }
-        if (*buf == 'I') {
-            /* Remove leading I: and trailing \r\n */
-            strv_append(readingList ? all_certs : to_install,
-                    buf+2, len - 4);
-            continue;
+      if (readingList)
+        {
+          str_append_str (certificate_list, &list_size, buf, len);
         }
-        if (*buf == 'R') {
-            /* Remove leading R: and trailing \r\n */
-            strv_append(readingList ? all_certs : to_remove,
-                    buf+2, len - 4);
-            continue;
+      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 (readingList ? all_certs : to_install,
+                       buf + 2, len - 4);
+          continue;
+        }
+      if (*buf == 'R')
+        {
+          /* Remove leading R: and trailing \r\n */
+          strv_append (readingList ? all_certs : to_remove, buf + 2, len - 4);
+          continue;
         }
     }
 
-    return 0;
+  return 0;
 }
 
 /** @brief Check that the insturctions match to the list
@@ -136,111 +149,133 @@
  *
  * @returns 0 on success, an error otherwise
  */
-int validate_instructions(char **all_certs,
-                          char **to_validate)
+int
+validate_instructions (char **all_certs, char **to_validate)
 {
-    int i = 0,
-        j = 0;
+  int i = 0, j = 0;
 
-    if (!all_certs || strv_length(all_certs) < 1) {
-        /* Invalid parameters */
-        return -1;
+  if (!all_certs || strv_length (all_certs) < 1)
+    {
+      /* Invalid parameters */
+      return -1;
     }
 
-    if (to_validate == NULL) {
-        /* Nothing is valid */
-        return 0;
+  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;
+  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;
+      if (!found)
+        {
+          printf ("Install instruction with invalid certificate\n.");
+          return ERR_INVALID_INSTRUCTIONS;
         }
     }
 
-    return 0;
+  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;
-    bool uninstall = false;
+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;
+  bool uninstall = false;
 
-    ret = readInput(&certificate_list, &to_install, &to_remove, &all_certs);
+  ret = readInput (&certificate_list, &to_install, &to_remove, &all_certs);
 
-    if (ret) {
-        return ret;
+  if (ret)
+    {
+      return ret;
     }
 
-    if (!certificate_list) {
-        return ERR_INVALID_INPUT_NO_LIST;
+  if (!certificate_list)
+    {
+      return ERR_INVALID_INPUT_NO_LIST;
     }
 
-    list_len = strnlen(certificate_list, MAX_INPUT_SIZE);
+  list_len = strnlen (certificate_list, MAX_INPUT_SIZE);
 
-    ret = verify_list(certificate_list, list_len);
+  ret = verify_list (certificate_list, list_len);
 
-    if (ret) {
-        return ERR_INVALID_SIGNATURE;
+  if (ret)
+    {
+      return ERR_INVALID_SIGNATURE;
     }
 
-    if (!strv_length(to_install) && !strv_length(to_remove)) {
-        return ERR_NO_INSTRUCTIONS;
+  if (!strv_length (to_install) && !strv_length (to_remove) )
+    {
+      return ERR_NO_INSTRUCTIONS;
     }
 
 
-    /* Check that the instructions are ok to execute */
-    if (to_install) {
-        ret = validate_instructions(all_certs, to_install);
-        if (ret) {
-            return ret;
+  /* 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) {
-        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 (to_remove)
+    {
+      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;
+  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, true);
-    //remove_certificates_win((const char**) to_remove, 1);
+  return write_stores_win (to_install, to_remove, true);
 #endif
 
-    /* Make valgrind happy */
-    strv_free(to_install);
-    strv_free(to_remove);
-    free(certificate_list);
+  /* Make valgrind happy */
+  strv_free (to_install);
+  strv_free (to_remove);
+  free (certificate_list);
 
-    return 0;
+  return 0;
 }
--- a/cinst/mozilla.c	Wed Mar 26 09:10:46 2014 +0100
+++ b/cinst/mozilla.c	Wed Mar 26 09:12:10 2014 +0100
@@ -48,19 +48,22 @@
  * 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 UNIX 1
+#define LINUX 1
 #else
-#define UNIX 0
+#define LINUX 0
 #endif
 
 #define LINEBUFLEN 1000
@@ -76,6 +79,47 @@
 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.
@@ -101,6 +145,8 @@
 
   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)
         {
@@ -116,8 +162,8 @@
           /* If we are in a profile parse path related stuff */
           if (inprofile)
             {
-              value = line;
-              key = strsep(&value, "=");
+              key = strtok(line, "=");
+              value = strtok(NULL, "=");
               str_trim(&value);
               if (str_equal(key, "Path"))
                 {
@@ -127,39 +173,114 @@
                     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
-                    return_code |= WARN_MOZ_PROFILE_DOES_NOT_EXIST;
+                    {
+                      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 argc, char *argv[])
+main ()
 {
   int x = 0;
-  if (argc == 2)
-    {
-      char **pdirs =
-        get_profile_dirs(argv[1]);
-      if (pdirs != NULL)
-        {
-          while (pdirs[x] != NULL)
-            puts(pdirs[x++]);
-          strv_free(pdirs);
-        }
-    }
+  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);
 }
--- a/cinst/windowsstore.c	Wed Mar 26 09:10:46 2014 +0100
+++ b/cinst/windowsstore.c	Wed Mar 26 09:12:10 2014 +0100
@@ -1,92 +1,101 @@
 #ifdef WIN32
 
-#include <polarssl/base64.h>
-#include "windowsstore.h"
+#include <stdio.h>
 
-static LPWSTR getLastErrorMsg() {
-    LPWSTR bufPtr = NULL;
-    DWORD err = GetLastError();
-    FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                   FORMAT_MESSAGE_FROM_SYSTEM |
-                   FORMAT_MESSAGE_IGNORE_INSERTS,
-                   NULL, err, 0, (LPWSTR)&bufPtr, 0, NULL);
-    if (!bufPtr) {
-        HMODULE hWinhttp = GetModuleHandleW(L"winhttp");
-        if (hWinhttp) {
-            FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                           FORMAT_MESSAGE_FROM_HMODULE |
-                           FORMAT_MESSAGE_IGNORE_INSERTS,
-                           hWinhttp, HRESULT_CODE(err), 0,
-                           (LPWSTR)&bufPtr, 0, NULL);
+#include "windowsstore.h"
+#include "errorcodes.h"
+#include "listutil.h"
+#include "strhelp.h"
+
+static LPWSTR getLastErrorMsg()
+{
+  LPWSTR bufPtr = NULL;
+  DWORD err = GetLastError();
+  FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                  FORMAT_MESSAGE_FROM_SYSTEM |
+                  FORMAT_MESSAGE_IGNORE_INSERTS,
+                  NULL, err, 0, (LPWSTR) &bufPtr, 0, NULL);
+  if (!bufPtr)
+    {
+      HMODULE hWinhttp = GetModuleHandleW (L"crypt32");
+      if (hWinhttp)
+        {
+          FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                          FORMAT_MESSAGE_FROM_HMODULE |
+                          FORMAT_MESSAGE_IGNORE_INSERTS,
+                          hWinhttp, HRESULT_CODE (err), 0,
+                          (LPWSTR) &bufPtr, 0, NULL);
         }
     }
-    if (!bufPtr)
-        printf("Error getting last error\n");
-    return bufPtr;
+  if (!bufPtr)
+    printf ("Error getting last error for code: %lx \n", err);
+  return bufPtr;
 }
 
-int install_certificates_win(const char **to_install, bool user_store)
+int write_stores_win (char **to_install, char **to_remove, bool user_store)
 {
-    int i = 0;
-    HCERTSTORE hStore = NULL;
+  int i = 0;
+  int ret = -1;
+  HCERTSTORE hStore = NULL;
 
-    if (user_store) {
-        hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
-                               0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root");
-    } else {
-        hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
-                               0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root");
+  if (user_store)
+    {
+      hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0,
+                              0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root");
     }
-
-    if (!hStore) {
-        return ERR_STORE_ACCESS_DENIED;
+  else
+    {
+      hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0,
+                              0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root");
     }
 
-    while (to_install[i]) {
-        size_t needed_len = 0;
-        size_t cert_len = strnlen(to_install[i], MAX_LINE_LENGTH);
-        int ret = -1;
-        unsigned char *buf;
-
-        /* Check the needed size for the buffer */
-        ret = base64_decode(NULL, &needed_len,
-                            (unsigned char *)to_install[i], cert_len);
+  if (!hStore)
+    {
+      return ERR_STORE_ACCESS_DENIED;
+    }
 
-        if (ret != 0 && ret != POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) {
-            return ERR_INVALID_INSTRUCTIONS;
-        }
+  for (i=0; to_install[i]; i++)
+    {
+      size_t cert_len = strnlen (to_install[i], MAX_LINE_LENGTH),
+             buf_size = 0;
+      char *buf = NULL;
 
-        buf = xmalloc(needed_len);
-        memset (buf, 0, needed_len);
+      ret = str_base64_decode (&buf, &buf_size, to_install[i], cert_len);
 
-        ret = base64_decode(buf, &needed_len,
-                            (unsigned char *)to_install[i], cert_len);
-
-        if (ret != 0) {
-            return ERR_INVALID_INSTRUCTIONS;
+      if (ret != 0)
+        {
+          return ERR_INVALID_INSTRUCTIONS;
         }
 
-        ret = CertAddEncodedCertificateToStore (hStore,
-                                                X509_ASN_ENCODING,
-                                                (PBYTE)buf,
-                                                needed_len,
-                                                CERT_STORE_ADD_ALWAYS,
-                                                NULL);
+      ret = CertAddEncodedCertificateToStore (hStore,
+                                              X509_ASN_ENCODING,
+                                              (PBYTE) buf,
+                                              buf_size,
+                                              CERT_STORE_ADD_ALWAYS,
+                                              NULL);
 
-        if (ret == 0) {
-            LPWSTR error = getLastErrorMsg();
-            if (error) {
-                printf("Failed to add certificate: %S \n", error);
-                LocalFree(error);
+      if (ret == 0)
+        {
+          LPWSTR error = getLastErrorMsg();
+          if (error)
+            {
+              printf ("Failed to add certificate: %S \n", error);
+              LocalFree (error);
             }
         }
-        i++;
-        free(buf);
+      i++;
+      free (buf);
     }
 
-    if(hStore) {
-        CertCloseStore(hStore, 0);
+  for (i=0; to_remove[i]; i++)
+    {
+      // TODO
     }
-    return 0;
+
+  if (hStore)
+    {
+      CertCloseStore (hStore, 0);
+    }
+  return 0;
 }
 #endif // WIN32
--- a/cinst/windowsstore.h	Wed Mar 26 09:10:46 2014 +0100
+++ b/cinst/windowsstore.h	Wed Mar 26 09:12:10 2014 +0100
@@ -4,14 +4,19 @@
 
 #include <windows.h>
 #include <wincrypt.h>
-/** @brief Install certificates into Windows store
+
+#include <stdbool.h>
+
+/** @brief Access the Windows certificate store
  *
- * @param [in] to_install NULL terminated array of base64 encoded certificates.
+ * @param [in] to_install strv of DER encoded certificates to be added.
+ * @param [in] to_remove strv of DER encoded certificates to be remvoed.
  * @param [in] user_store set to True if the certificates should be installed
  *             only for the current user. O for system wide installation.
  * @returns 0 on success an errorcode otherwise.
  */
-int install_certificates_win(const char **to_install, int user_store)
+int write_stores_win (char **to_install, char **to_remove,
+                      bool user_store);
 
 #endif // WINDOWSSTORE_H
 #endif // WIN32
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/debug.h	Wed Mar 26 09:12:10 2014 +0100
@@ -0,0 +1,20 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/**
+ * @file  debug.h
+ * @brief Helper macros for debugging
+ */
+
+/**
+ * @brief Debug printf
+ *
+ * Prints to stderr if RELEASE_BUILD is not defined.
+ */
+#ifndef RELEASE_BUILD
+#define DEBUGFPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__);
+#else
+#define DEBUGFPRINT(fmt, ...)
+#endif
+
+#endif
--- a/common/errorcodes.h	Wed Mar 26 09:10:46 2014 +0100
+++ b/common/errorcodes.h	Wed Mar 26 09:12:10 2014 +0100
@@ -2,7 +2,7 @@
 #define ERRORCODES_H
 
 /* No error */
-#define NO_ERROR 0
+#define ERR_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 */
@@ -27,9 +27,14 @@
  * Warnings might be ORed together ...
  */
 
+/* Error: could not determine current users HOME */
+#define ERR_MOZ_HOMELESS 0x0081
+
 /* Warning: Failed to read profile.ini */
 #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
 
 #endif
--- a/common/listutil.c	Wed Mar 26 09:10:46 2014 +0100
+++ b/common/listutil.c	Wed Mar 26 09:12:10 2014 +0100
@@ -22,7 +22,7 @@
 #include <polarssl/sha256.h>
 #pragma GCC diagnostic pop
 
-#define MAX_FILESIZE MAX_LINE_LENGTH * MAX_LINES
+#define MAX_FILESIZE (MAX_LINE_LENGTH * MAX_LINES)
 
 /**
  *  @brief Read a file into memory.
@@ -192,6 +192,8 @@
         }
         if (ret == READ_FILE_UNREADABLE) {
             /* TODO: work with errno ? */
+	    /* errsv = errno; */
+	    /* perror("read_and_verify_list(), READ_FILE_UNREADABLE:");  */
             return SeekFailed;
         }
         if (ret == READ_FILE_READ_FAILED) {
--- a/common/portpath.c	Wed Mar 26 09:10:46 2014 +0100
+++ b/common/portpath.c	Wed Mar 26 09:12:10 2014 +0100
@@ -4,6 +4,9 @@
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 
 char *
@@ -12,10 +15,18 @@
 #ifndef _WIN32
   return dirname(path);
 #else
-  fprintf(stderr, "Windows Suport missing!");
-  abort();
+  char drive[_MAX_DRIVE];
+  char dir[_MAX_DIR];
+  _splitpath(path, drive, dir, NULL, NULL);
+  size_t dlen = strlen(dir);
+  if ((dlen > 0) &&
+      ((dir[dlen-1] == '/') || (dir[dlen-1] == '\\')))
+    dir[dlen-1] = '\0';
+  /* We assume: drive + dir is shorter than
+   * drive + dir + fname + ext */
+  sprintf(path, "%s%s", drive, dir);
+  return path;
 #endif
- 
 }
 
 char *
@@ -24,7 +35,46 @@
 #ifndef _WIN32
   return realpath(path, NULL);
 #else
-  fprintf(stderr, "Windows Suport missing!");
-  abort();
+  char *fp = _fullpath(NULL, path, 0);
+  if (port_fileexits(fp))
+    return fp;
+  else
+    return NULL;
 #endif
 }
+
+bool
+port_fileexits(char *path)
+{
+  int ret;
+#ifndef _WIN32
+  struct stat sb;
+  ret = stat(path, &sb);
+#else
+  struct _stat sb;
+  ret = _stat(path, &sb);
+#endif
+
+  if (ret == 0)
+    return true;
+  else
+    return false;
+}
+
+bool
+port_isdir(char *path)
+{
+  int ret;
+#ifndef _WIN32
+  struct stat sb;
+  ret = stat(path, &sb);
+#else
+  struct _stat sb;
+  ret = _stat(path, &sb);
+#endif
+
+  if ((ret == 0) && S_ISDIR(sb.st_mode))
+    return true;
+  else
+    return false;
+}
--- a/common/portpath.h	Wed Mar 26 09:10:46 2014 +0100
+++ b/common/portpath.h	Wed Mar 26 09:12:10 2014 +0100
@@ -1,6 +1,8 @@
 #ifndef PORTPATH_H
 #define PORTPATH_H
 
+#include <stdbool.h>
+
 /**
  * @file  portpath.h
  * @brief Platform independent functions for file and path handling.
@@ -18,16 +20,6 @@
  */
 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.
@@ -38,4 +30,22 @@
  */
 char *port_realpath(char *path);
 
+/**
+ * @brief test if a file exists
+ * @details uses a platform specific stat call to test if the given
+ * file exists.
+ * @param[in] path the path to the file
+ * @returns true if the file exists and false otherwise
+ */
+bool port_fileexits(char *path);
+
+/**
+ * @brief test if a file is a directory
+ * @details uses a platform specific stat call to test if the given
+ * file is an directory.
+ * @param[in] path the path to the file
+ * @returns true if the file is an directory and false otherwise
+ */
+bool port_isdir(char *path);
+
 #endif
--- a/common/strhelp.c	Wed Mar 26 09:10:46 2014 +0100
+++ b/common/strhelp.c	Wed Mar 26 09:12:10 2014 +0100
@@ -5,6 +5,8 @@
 #include <string.h>
 #include <assert.h>
 
+#include <polarssl/base64.h>
+
 /* Remarks regarding the "Flawfinder: ignore" comments in this file:
  *
  * - strlen:
@@ -150,3 +152,33 @@
         (*s)[i] = '\0';
     }
 }
+
+int str_base64_decode(char **dst, size_t *dst_size, char *src,
+                      size_t src_size)
+{
+    int ret = -1;
+
+    if (!dst || *dst) {
+        return -1;
+    }
+
+    /* Check the needed size for the buffer */
+    ret = base64_decode(NULL, dst_size,
+                        (unsigned char *)src, src_size);
+
+    if (ret != 0 && ret != POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) {
+        return ret;
+    }
+
+    *dst = xmalloc(*dst_size);
+    memset (*dst, 0, *dst_size);
+
+    ret = base64_decode((unsigned char *)*dst, dst_size,
+                        (unsigned char *)src, src_size);
+    if (ret) {
+        free (*dst);
+        *dst = NULL;
+        *dst_size = 0;
+    }
+    return ret;
+}
--- a/common/strhelp.h	Wed Mar 26 09:10:46 2014 +0100
+++ b/common/strhelp.h	Wed Mar 26 09:12:10 2014 +0100
@@ -1,6 +1,10 @@
 #ifndef STRHELP_H
 #define STRHELP_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdbool.h>
 
 /**
@@ -75,4 +79,22 @@
  */
 bool str_trim (char **s);
 
+/** @brief decode base64 encoded data
+ *
+ * The memory allocated for dest needs to be free'd by the
+ * caller.
+ *
+ * @param [out] dst Pointer to the destination. Needs to be NULL
+ * @param [out] dst_size Size allocated for the destination.
+ * @param [in] src Pointer to the base64 encoded data.
+ * @param [in] src_size Size of the encoded data.
+ *
+ * @returns 0 on success a polarssl error or -1 otherwise
+ */
+int str_base64_decode(char **dst, size_t *dst_size, char *src,
+                      size_t src_size);
+#ifdef __cplusplus
+}
 #endif
+
+#endif
--- a/ui/tests/CMakeLists.txt	Wed Mar 26 09:10:46 2014 +0100
+++ b/ui/tests/CMakeLists.txt	Wed Mar 26 09:12:10 2014 +0100
@@ -37,6 +37,7 @@
 
 # Cinstprocess
 add_m13_test(cinstprocesstest.cpp "${CERTIFICATELIST_SOURCES}")
+add_m13_test(commontest.cpp "")
 
 #add_m13_test(${CMAKE_SOURCE_DIR}/ui/main.cpp "${M13UI_SOURCES}")
 
--- a/ui/tests/cinstprocesstest.cpp	Wed Mar 26 09:10:46 2014 +0100
+++ b/ui/tests/cinstprocesstest.cpp	Wed Mar 26 09:12:10 2014 +0100
@@ -46,7 +46,7 @@
         installerProcess->write("\r\n");
     }
 
-    finishVerify(installerProcess, NO_ERROR);
+    finishVerify(installerProcess, ERR_NO_ERROR);
 }
 
 void CinstProcessTest::initTestCase() {
@@ -133,7 +133,7 @@
 
     installerProcess->write("UNINSTALL\r\n");
 
-    finishVerify(installerProcess, NO_ERROR);
+    finishVerify(installerProcess, ERR_NO_ERROR);
 }
 
 QTEST_GUILESS_MAIN (CinstProcessTest);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/tests/commontest.cpp	Wed Mar 26 09:12:10 2014 +0100
@@ -0,0 +1,33 @@
+#include <QString>
+#include <QByteArray>
+#include <QTest>
+
+#include "commontest.h"
+#include "strhelp.h"
+
+void CommonTest::testStrBase64Decode() {
+    char garbage[1000];
+    char *data = NULL;
+    size_t data_size = 0;
+    int ret;
+    for (int i = 0; i < 1000; i++) {
+        garbage[i] = (char) qrand() % 255;
+    }
+
+    QByteArray ba(garbage, 1000);
+
+    QByteArray baB64 = ba.toBase64();
+
+    ret = str_base64_decode(&data, &data_size, (char *)baB64.constData(), baB64.size());
+
+    QVERIFY(ret == 0);
+    QVERIFY(data_size == 1000);
+    QVERIFY(data);
+
+    for (size_t i = 0; i < data_size; i++) {
+        QVERIFY(garbage[i] == data[i]);
+    }
+    free (data);
+}
+
+QTEST_GUILESS_MAIN (CommonTest);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/tests/commontest.h	Wed Mar 26 09:12:10 2014 +0100
@@ -0,0 +1,13 @@
+#ifndef COMMONTEST_H
+#define COMMONTEST_H
+
+#include <QObject>
+
+class CommonTest: public QObject
+{
+  Q_OBJECT
+
+private Q_SLOTS:
+  void testStrBase64Decode();
+};
+#endif

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