view cinst/main.c @ 60:6acb1dae6185

Use strn functions and improve error handling. Even if we know the strings are NULL terminated we use length terminated string functions after a first strlen this makes it easier to assert that at one point we know the string is terminated and afterwards use the length of that.
author Andre Heinecke <aheinecke@intevation.de>
date Tue, 18 Mar 2014 11:28:02 +0000
parents 3f6378647371
children fb9f78f7ab2f
line wrap: on
line source
/** @brief Main entry point for the cinst process.
 *
 *  The cinst process may or may not be run with elevated
 *  privileges. When run with elevated privileges this
 *  process will modify system wide certificate stores.
 *  Otherwise only the users certificate stores are modified.
 *
 *  It expects a certificatelist on stdin enclosed in a
 *  -----BEGIN CERTIFICATE LIST-----
 *  ...
 *  -----END CERTIFICATE LIST-----
 *
 *  Followed by additional instruction lines of:
 *  I:<certificate>
 *  R:<certificate>
 *
 *  It will only execute the instructions if the
 *  I and R instructions are also part of the signed
 *  certificate list. The signature is validated with the
 *  built in key.
 *
 *  The special instruction "UNINSTALL" will cause the installer
 *  to remove all certificates (Even those marked with I) that
 *  are part of the list to be removed.
 *
 **/
#define MAX_LINE_LENGTH 1000
#define MAX_LINES 1000
#define MAX_INPUT_SIZE 2000000 /* MAX_LINE_LENGTH * (MAX_LINES *2) */

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "strhelp.h"
#include "listutil.h"
#include "errorcodes.h"

/* @brief Read stdin into data structures.
 *
 * Reads from stdin and sorts the input into the respective
 * variables. The pointers returned need to be freed by the caller.
 * Terminates in OOM conditions.
 *
 * The caller needs to free the memory allocated by this function
 * even when an error is returned.
 *
 * @returns: 0 on success. An error code otherwise.
 */
int readInput(char **certificateList, char ***to_install,
              char ***to_remove)
{
    int lines_read = 0;
    int readingList = 0;
    char buf[MAX_LINE_LENGTH + 1];

    while (fgets(buf, MAX_LINE_LENGTH + 1, stdin)) {
        size_t len = strlen(buf); /* fgets ensures buf is terminated */
        if (lines_read ++ > MAX_LINES) {
            printf("Too many lines\n");
            return ERR_TOO_MUCH_INPUT;
        }
        if (strcmp("-----BEGIN CERTIFICATE LIST-----", buf) == 0){
            readingList = 1;
            continue;
        }
        if (strcmp("-----END CERTIFICATE LIST-----", buf) == 0){
            readingList = 0;
            continue;
        }
        if (readingList) {
            str_append_str(certificateList, buf, len);
            continue;
        }
        if (*buf == 'I') {
            array_append_str(to_install, buf+2, len - 2);
            continue;
        }
        if (*buf == 'R') {
            array_append_str(to_remove, buf+2, len - 2);
            continue;
        }
        if (strcmp("UNINSTALL", buf) == 0) {
            array_append_str(to_remove, buf, len - 2);
        }
    }

    return 0;
}

int main() {

    char **to_install = NULL;
    char **to_remove = NULL;
    char *certificateList = NULL;
    int ret = -1;

    ret = readInput(&certificateList, &to_install, &to_remove);

    if (ret != 0) {
        return ret;
    }

    if (!certificateList) {
        return ERR_INVALID_INPUT_NO_LIST;
    }

    ret = verify_list(certificateList, strlen(certificateList));

    printf ("Verify List returned %i\n", ret);

    return 0;
}

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