--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/config.c Mon Aug 12 14:40:19 2013 +0200 @@ -0,0 +1,197 @@ +/* + * 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 <ucx/map.h> +#include <libxml/tree.h> + +#include "config.h" +#include "utils.h" + +#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) + +static UcxMap *repos; +static UcxMap *keys; + +void load_config() { + repos = ucx_map_new(16); + keys = ucx_map_new(16); + + char *file = util_concat_path(getenv("HOME"), ".dav/config.xml"); + xmlDoc *doc = xmlReadFile(file, NULL, 0); + 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); + } + } + node = node->next; + } + + // TODO: free doc +} + +void load_repository(xmlNode *reponode) { + xmlNode *node = reponode->children; + Repository *repo = calloc(1, sizeof(Repository)); + repo->store_key_property = true; + repo->decrypt = true; + 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")) { + // TODO: use base64 + repo->password = strdup(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) { + ucx_map_cstr_put(repos, repo->name, repo); + } else { + // TODO: free + } +} + +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(getenv("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); +}