changeset 148:095d0e7f8ed4

Add instruction verification and handle uninstall command in input
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 24 Mar 2014 17:21:25 +0000
parents fc9af77b06b9
children bd5a5d3e5674
files cinst/main.c
diffstat 1 files changed, 82 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/cinst/main.c	Mon Mar 24 17:24:37 2014 +0100
+++ b/cinst/main.c	Mon Mar 24 17:21:25 2014 +0000
@@ -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", 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,26 +202,35 @@
     }
 
 
-    /* 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);

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