# HG changeset patch # User Andre Heinecke # Date 1395681685 0 # Node ID 095d0e7f8ed40904efee7e5baed70a207b3ea458 # Parent fc9af77b06b97088dfc082647dbd3ba2dcfe0fc9 Add instruction verification and handle uninstall command in input diff -r fc9af77b06b9 -r 095d0e7f8ed4 cinst/main.c --- 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 #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", 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);