dav/config.c

Mon, 02 Sep 2013 10:31:29 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 02 Sep 2013 10:31:29 +0200
changeset 36
c8755c87ce7f
parent 33
0bbbb0341606
child 38
b855f76e965b
permissions
-rw-r--r--

added proxy config

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2013 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <ucx/map.h>
#include <errno.h>
#include <libxml/tree.h>

#include "config.h"
#include <libidav/utils.h>

#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)

#ifdef _WIN32
#define ENV_HOME getenv("USERPROFILE")
#else
#define ENV_HOME getenv("HOME")
#endif /* _WIN32 */

static UcxMap *repos;
static UcxMap *keys;
static Proxy  *http_proxy;
static Proxy  *https_proxy;

int check_config_dir() {
    char *file = util_concat_path(ENV_HOME, ".dav");
    int ret = 0;
    if(util_mkdir(file, S_IRWXU)) {
        if(errno != EEXIST) {
            ret = 1;
        }
    }
    free(file);
    return ret;
}

void load_config() {
    // TODO: free the config somewhere
    repos = ucx_map_new(16);
    keys = ucx_map_new(16);
    http_proxy = calloc(1, sizeof(Proxy));
    https_proxy = calloc(1, sizeof(Proxy));
    if(check_config_dir()) {
        return;
    }
    
    char *file = util_concat_path(ENV_HOME, ".dav/config.xml");
    xmlDoc *doc = xmlReadFile(file, NULL, 0);
    if(!doc) {
        doc = xmlNewDoc(BAD_CAST "1.0");
        xmlNode *root = xmlNewNode(NULL, BAD_CAST "configuration");
        xmlDocSetRootElement(doc, root);
        xmlSaveFormatFileEnc(file, doc, "UTF-8", 1);
        xmlFreeDoc(doc);
        free(file);
        return;
    }
    free(file);
    
    xmlNode *xml_root = xmlDocGetRootElement(doc);
    xmlNode *node = xml_root->children;
    while(node) {
        if(node->type == XML_ELEMENT_NODE) {
            if(xstreq(node->name, "repository")) {
                load_repository(node);
            } else if(xstreq(node->name, "key")) {
                load_key(node);
            } else if (xstreq(node->name, "http-proxy")) {
                load_proxy(node, HTTP_PROXY);
            } else if (xstreq(node->name, "https-proxy")) {
                load_proxy(node, HTTPS_PROXY);
            }
        }
        node = node->next;
    }
    
    xmlFreeDoc(doc);
}

void load_repository(xmlNode *reponode) {
    xmlNode *node = reponode->children;
    Repository *repo = calloc(1, sizeof(Repository));
    repo->store_key_property = true;
    repo->decrypt = false;
    while(node) {
        if(node->type == XML_ELEMENT_NODE) {
            char *value = util_xml_get_text(node);
            if(!value) {
                // next
            } else if(xstreq(node->name, "name")) {
                repo->name = strdup(value);
            } else if(xstreq(node->name, "url")) {
                repo->url = strdup(value);
            } else if(xstreq(node->name, "user")) {
                repo->user = strdup(value);
            } else if(xstreq(node->name, "password")) {
                repo->password = util_base64decode(value);
            } else if(xstreq(node->name, "default-key")) {
                repo->default_key = strdup(value);
            } else if(xstreq(node->name, "encrypt")) {
                repo->encrypt = util_getboolean(value);
            } else if(xstreq(node->name, "decrypt")) {
                repo->decrypt = util_getboolean(value);
            } else if(xstreq(node->name, "store-key-property")) {
                repo->store_key_property = util_getboolean(value);
            }
        }
        node = node->next;
    }
    
    if(!repo->name) {
        fprintf(
                stderr,
                "Cannot load config.xml: missing name for repository.\n");
        fprintf(stderr, "Abort.\n");
        exit(-1);
    }
    if(!repo->url) {
        fprintf(
                stderr,
                "Cannot load config.xml: "
                "missing url for repository '%s'.\n", repo->name);
        fprintf(stderr, "Abort.\n");
        exit(-1);
    }
    
    ucx_map_cstr_put(repos, repo->name, repo);
}

void load_proxy(xmlNode *proxynode, int type) {
    Proxy *proxy;
    const char *stype;
    if (type == HTTPS_PROXY) {
        proxy = https_proxy;
        stype = "https";
    } else if (type == HTTP_PROXY) {
        proxy = http_proxy;
        stype = "http";
    }
    
    xmlNode *node = proxynode->children;
    while(node) {
        if(node->type == XML_ELEMENT_NODE) {
            char *value = util_xml_get_text(node);
            if(!value) {
                // next
            } else if(xstreq(node->name, "url")) {
                proxy->url = strdup(value);
            } else if(xstreq(node->name, "user")) {
                proxy->user = strdup(value);
            } else if(xstreq(node->name, "password")) {
                proxy->password = util_base64decode(value);
            } else if(xstreq(node->name, "no")) {
                proxy->no = strdup(value);
            }
        }
        node = node->next;
    }
    
    if(!proxy->url) {
        fprintf(stderr,
            "Cannot load config.xml: missing url for %s proxy.\n", stype);
        fprintf(stderr, "Abort.\n");
        exit(-1);
    }
}

void load_key(xmlNode *keynode) {
    xmlNode *node = keynode->children;
    Key *key = calloc(1, sizeof(Key));
    key->type = KEY_AES256;
    
    while(node) {
        if(node->type == XML_ELEMENT_NODE) {
            char *value = util_xml_get_text(node);
            if(!value) {
                // next
            } else if(xstreq(node->name, "name")) {
                key->name = strdup(value);
            } else if(xstreq(node->name, "file")) {
                // load key file
                sstr_t key_data = load_key_file(value);
                if(key_data.length > 0) {
                    key->data = key_data.ptr;
                    key->length = key_data.length;
                }
            } else if(xstreq(node->name, "type")) {
                if(!strcmp(value, "aes128")) {
                    key->type = KEY_AES128;
                } else if(!strcmp(value, "aes256")) {
                    key->type = KEY_AES256;
                }
            }
                
        }
        node = node->next;
    }
    
    if(key->name) {
        if(key->type == KEY_AES128) {
            if(key->length < 16) {
                return;
            }
            key->length = 16;
        }
        if(key->type == KEY_AES256) {
            if(key->length < 32) {
                return;
            }
            key->length = 32;
        }
        ucx_map_cstr_put(keys, key->name, key);
    } else {
        // TODO: free
    }
}

sstr_t load_key_file(char *filename) {
    sstr_t k;
    k.ptr = NULL;
    k.length = 0;
    
    FILE *file = NULL;
    if(filename[0] == '/') {
        file = fopen(filename, "r");
    } else {
        char *path = util_concat_path(ENV_HOME, ".dav/");
        char *p2 = util_concat_path(path, filename);
        file = fopen(p2, "r");
        free(path);
        free(p2);
    }
    
    if(!file) {
        return k;
    }
    
    char *data = malloc(256);
    size_t r = fread(data, 1, 256, file);
    k.ptr = data;
    k.length = r;
    
    fclose(file);
    return k;
} 

Repository* get_repository(char *name) {
    if(!name) {
        return NULL;
    }
    return ucx_map_cstr_get(repos, name);
}

Key* get_key(char *name) {
    if(!name) {
        return NULL;
    }
    return ucx_map_cstr_get(keys, name);
}

Proxy* get_http_proxy() {
    return http_proxy;
}

Proxy* get_https_proxy() {
    return https_proxy;
}

mercurial