# HG changeset patch # User Olaf Wintermann # Date 1395078121 -3600 # Node ID a95ee94b92042b1dcef3d2cd5a91b6cf83a70ab6 # Parent 3e55bed345f9ed18aef72d344374eec4788608fe supports whitespace in paths diff -r 3e55bed345f9 -r a95ee94b9204 dav/Makefile --- a/dav/Makefile Sat Sep 07 14:08:43 2013 +0200 +++ b/dav/Makefile Mon Mar 17 18:42:01 2014 +0100 @@ -30,7 +30,6 @@ SRC = main.c SRC += config.c -SRC += crypto.c SRC += optparser.c diff -r 3e55bed345f9 -r a95ee94b9204 dav/config.c --- a/dav/config.c Sat Sep 07 14:08:43 2013 +0200 +++ b/dav/config.c Mon Mar 17 18:42:01 2014 +0100 @@ -62,7 +62,10 @@ return ret; } -void load_config() { +static DavContext *context; + +void load_config(DavContext *ctx) { + context = ctx; // TODO: free the config somewhere repos = ucx_map_new(16); keys = ucx_map_new(16); @@ -238,6 +241,7 @@ key->length = 32; } ucx_map_cstr_put(keys, key->name, key); + dav_context_add_key(context, key); } else { // TODO: free } diff -r 3e55bed345f9 -r a95ee94b9204 dav/config.h --- a/dav/config.h Sat Sep 07 14:08:43 2013 +0200 +++ b/dav/config.h Mon Mar 17 18:42:01 2014 +0100 @@ -31,13 +31,14 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif typedef struct Repository Repository; -typedef struct Key Key; +typedef struct DavKey Key; typedef struct Proxy Proxy; #define HTTP_PROXY 1 @@ -62,13 +63,6 @@ bool store_key_property; }; -struct Key { - char *name; - KeyType type; - void *data; - size_t length; -}; - struct Proxy { char *url; char *user; @@ -76,7 +70,7 @@ char *no; }; -void load_config(); +void load_config(DavContext *ctx); void load_repository(xmlNode *reponode); void load_key(xmlNode *keynode); void load_proxy(xmlNode *proxynode, int type); diff -r 3e55bed345f9 -r a95ee94b9204 dav/crypto.c --- a/dav/crypto.c Sat Sep 07 14:08:43 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,268 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include -#include "crypto.h" - -AESDecrypter* aes_decrypter_new(Key *key, void *stream, dav_write_func write_func) { - AESDecrypter *dec = malloc(sizeof(AESDecrypter)); - dec->stream = stream; - dec->write = write_func; - dec->key = key; - dec->init = 0; - dec->ivpos = 0; - - return dec; -} - -void aes_decrypter_init(AESDecrypter *dec) { - EVP_CIPHER_CTX_init(&dec->ctx); - dec->init = 1; - if(dec->key->type == KEY_AES128) { - EVP_DecryptInit_ex( - &dec->ctx, - EVP_aes_128_cbc(), - NULL, - dec->key->data, - dec->ivtmp); - } else if(dec->key->type == KEY_AES256) { - EVP_DecryptInit_ex( - &dec->ctx, - EVP_aes_256_cbc(), - NULL, - dec->key->data, - dec->ivtmp); - } else { - fprintf(stderr, "unknown key type\n"); - exit(-1); - } -} - -size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) { - int len = s*n; - if(!dec->init) { - size_t n = 16 - dec->ivpos; - size_t cp = n > len ? len : n; - memcpy(dec->ivtmp + dec->ivpos, buf, cp); - dec->ivpos += cp; - if(dec->ivpos >= 16) { - aes_decrypter_init(dec); - } - if(len == cp) { - return len; - } else { - buf = (char*)buf + cp; - len -= cp; - } - } - - int outlen = len + 16; - unsigned char *out = malloc(outlen); - EVP_DecryptUpdate(&dec->ctx, out, &len, buf, len); - dec->write(out, 1, len, dec->stream); - free(out); - return (s*n) / s; -} - -void aes_decrypter_close(AESDecrypter *dec) { - void *out = malloc(128); - int len = 0; - EVP_DecryptFinal_ex(&dec->ctx, out, &len); - dec->write(out, 1, len, dec->stream); - free(out); - EVP_CIPHER_CTX_cleanup(&dec->ctx); - free(dec); -} - - -AESEncrypter* aes_encrypter_new(Key *key, void *stream, dav_read_func read_func) { - unsigned char *iv = malloc(16); - if(!RAND_bytes(iv, 16)) { - free(iv); - return NULL; - } - - AESEncrypter *enc = malloc(sizeof(AESEncrypter)); - enc->stream = stream; - enc->read = read_func; - enc->tmp = NULL; - enc->tmplen = 0; - enc->tmpoff = 0; - enc->end = 0; - //enc->iv = iv; - enc->iv = iv; - enc->ivlen = 16; - - EVP_CIPHER_CTX_init(&enc->ctx); - if(key->type == KEY_AES128) { - EVP_EncryptInit_ex(&enc->ctx, EVP_aes_128_cbc(), NULL, key->data, enc->iv); - } else if(key->type == KEY_AES256) { - EVP_EncryptInit_ex(&enc->ctx, EVP_aes_256_cbc(), NULL, key->data, enc->iv); - } else { - fprintf(stderr, "unknown key type\n"); - exit(-1); - } - return enc; -} - -size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc) { - size_t len = s*n; - if(enc->tmp) { - size_t tmp_diff = enc->tmplen - enc->tmpoff; - size_t cp_len = tmp_diff > len ? len : tmp_diff; - memcpy(buf, enc->tmp + enc->tmpoff, cp_len); - enc->tmpoff += cp_len; - if(enc->tmpoff >= enc->tmplen) { - free(enc->tmp); - enc->tmp = NULL; - enc->tmplen = 0; - enc->tmpoff = 0; - } - return cp_len / s; - } - - if(enc->end) { - return 0; - } - - void *in = malloc(len); - size_t in_len = enc->read(in, 1, len, enc->stream); - - unsigned char *out = NULL; - int outlen = 0; - size_t ivl = enc->ivlen; - if(in_len != 0) { - outlen = len + 16; - out = malloc(outlen + ivl); - if(enc->iv) { - memcpy(out, enc->iv, ivl); - } - EVP_EncryptUpdate(&enc->ctx, out + ivl, &outlen, in, in_len); - free(in); - } else { - out = malloc(16); - EVP_EncryptFinal_ex(&enc->ctx, out, &outlen); - enc->end = 1; - } - enc->tmp = (char*)out; - enc->tmplen = outlen + ivl; - enc->tmpoff = 0; - - if(enc->iv) { - enc->iv = NULL; - enc->ivlen = 0; - } - - return aes_read(buf, s, n, enc); -} - -void aes_encrypter_close(AESEncrypter *enc) { - if(enc->tmp) { - free(enc->tmp); - } - EVP_CIPHER_CTX_cleanup(&enc->ctx); - free(enc); -} - - -char* aes_encrypt(char *in, Key *key) { - char *iv = malloc(16); - if(!RAND_bytes(iv, 16)) { - free(iv); - return NULL; - } - - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - if(key->type == KEY_AES128) { - EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->data, iv); - } else if(key->type == KEY_AES256) { - EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key->data, iv); - } else { - return NULL; - } - - int len = strlen(in); - int buflen = len + 64; - char *buf = calloc(1, buflen); - memcpy(buf, iv, 16); - - int l = buflen - 16; - EVP_EncryptUpdate(&ctx, buf + 16, &l, in, len); - - int f = 0; - EVP_EncryptFinal_ex(&ctx, buf + 16 + l, &f); - char *out = util_base64encode(buf, 16 + l + f); - free(buf); - return out; -} - -char* aes_decrypt(char *in, Key *key) { - int len; - char *buf = util_base64decode_len(in, &len); - - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - if(key->type == KEY_AES128) { - EVP_DecryptInit_ex( - &ctx, - EVP_aes_128_cbc(), - NULL, - key->data, - buf); - } else if(key->type == KEY_AES256) { - EVP_DecryptInit_ex( - &ctx, - EVP_aes_256_cbc(), - NULL, - key->data, - buf); - } else { - return NULL; - } - - char *out = malloc(len + 1); - int outlen = len; - char *in_buf = buf + 16; - int inlen = len - 16; - int f = 0; - - - - EVP_DecryptUpdate(&ctx, out, &outlen, in_buf, inlen); - EVP_DecryptFinal_ex(&ctx, out + outlen, &f); - out[outlen + f] = '\0'; - free(buf); - return out; -} - diff -r 3e55bed345f9 -r a95ee94b9204 dav/crypto.h --- a/dav/crypto.h Sat Sep 07 14:08:43 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * 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. - */ - -#ifndef DAV_CRYPTO_H -#define DAV_CRYPTO_H - -#include -#include "config.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - EVP_CIPHER_CTX ctx; - void *stream; - dav_write_func write; - Key *key; - int init; - unsigned char ivtmp[16]; - size_t ivpos; -} AESDecrypter; - -typedef struct { - EVP_CIPHER_CTX ctx; - void *iv; - size_t ivlen; - void *stream; - dav_read_func read; - char *tmp; - size_t tmplen; - size_t tmpoff; - int end; -} AESEncrypter; - -AESDecrypter* aes_decrypter_new(Key *key, void *stream, dav_write_func write_func); -size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec); -void aes_decrypter_close(AESDecrypter *dec); -void aes_decrypter_close2(EVP_CIPHER_CTX *ctx); - -AESEncrypter* aes_encrypter_new(Key *key, void *stream, dav_read_func read_func); -size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc); -void aes_encrypter_close(AESEncrypter *enc); - -char* aes_encrypt(char *in, Key *key); -char* aes_decrypt(char *in, Key *key); - -#ifdef __cplusplus -} -#endif - -#endif /* DAV_CRYPTO_H */ - diff -r 3e55bed345f9 -r a95ee94b9204 dav/main.c --- a/dav/main.c Sat Sep 07 14:08:43 2013 +0200 +++ b/dav/main.c Mon Mar 17 18:42:01 2014 +0100 @@ -39,8 +39,8 @@ #include +#include #include "config.h" -#include "crypto.h" #include "main.h" static DavContext *ctx; @@ -52,8 +52,8 @@ int main(int argc, char **argv) { xmlGenericErrorFunc fnc = xmlerrorfnc; initGenericErrorDefaultFunc(&fnc); - load_config(); ctx = dav_context_new(); + load_config(ctx); dav_add_namespace(ctx, "U", "http://www.uap-core.de/"); memcpy(ctx->http_proxy, get_http_proxy(), sizeof(Proxy)); @@ -251,11 +251,11 @@ char *url = a->argv[0]; char *path = NULL; - char *base = NULL; + //char *base = NULL; DavSession *sn = NULL; Repository *repo = url2repo(url, &path); - base = util_concat_path(repo->url, path); - sn = dav_session_new_auth(ctx, base, repo->user, repo->password); + //base = util_concat_path(repo->url, path); + sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password); char *update = cmd_getoption(a, "update"); time_t t = 0; @@ -267,22 +267,25 @@ DavResource *ls; while(ret != 0) { if(cmd_getoption(a, "recursive")) { - printf("base: %s\n", base); + //printf("base: %s\n", base); if(update) { ls = dav_query( sn, - "get U:crypto-key from /* where lastmodified > %t", + "get U:crypto-key from %s* where lastmodified > %t", + path, t); } else { - ls = dav_query(sn, "get U:crypto-key from /*"); + ls = dav_query(sn, "get U:crypto-key from %s*", path); } } else { if(update) { ls = dav_query( sn, - "get U:crypto-key from / where lastmodified > %t", t); + "get U:crypto-key from %s where lastmodified > %t", + path, + t); } else { - ls = dav_query(sn, "get U:crypto-key from /"); + ls = dav_query(sn, "get U:crypto-key from %s", path); } } @@ -317,7 +320,7 @@ } free(path); - free(base); + //free(base); return ret; } diff -r 3e55bed345f9 -r a95ee94b9204 libidav/Makefile --- a/libidav/Makefile Sat Sep 07 14:08:43 2013 +0200 +++ b/libidav/Makefile Mon Mar 17 18:42:01 2014 +0100 @@ -34,6 +34,7 @@ SRC += methods.c SRC += utils.c SRC += davql.c +SRC += crypto.c OBJ = $(SRC:%.c=../build/libidav/%.$(OBJ_EXT)) diff -r 3e55bed345f9 -r a95ee94b9204 libidav/crypto.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libidav/crypto.c Mon Mar 17 18:42:01 2014 +0100 @@ -0,0 +1,267 @@ +/* + * 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 +#include +#include +#include + +#include +#include "crypto.h" + +AESDecrypter* aes_decrypter_new(DavKey *key, void *stream, dav_write_func write_func) { + AESDecrypter *dec = malloc(sizeof(AESDecrypter)); + dec->stream = stream; + dec->write = write_func; + dec->key = key; + dec->init = 0; + dec->ivpos = 0; + + return dec; +} + +void aes_decrypter_init(AESDecrypter *dec) { + EVP_CIPHER_CTX_init(&dec->ctx); + dec->init = 1; + if(dec->key->type == DAV_KEY_AES128) { + EVP_DecryptInit_ex( + &dec->ctx, + EVP_aes_128_cbc(), + NULL, + dec->key->data, + dec->ivtmp); + } else if(dec->key->type == DAV_KEY_AES256) { + EVP_DecryptInit_ex( + &dec->ctx, + EVP_aes_256_cbc(), + NULL, + dec->key->data, + dec->ivtmp); + } else { + fprintf(stderr, "unknown key type\n"); + exit(-1); + } +} + +size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) { + int len = s*n; + if(!dec->init) { + size_t n = 16 - dec->ivpos; + size_t cp = n > len ? len : n; + memcpy(dec->ivtmp + dec->ivpos, buf, cp); + dec->ivpos += cp; + if(dec->ivpos >= 16) { + aes_decrypter_init(dec); + } + if(len == cp) { + return len; + } else { + buf = (char*)buf + cp; + len -= cp; + } + } + + int outlen = len + 16; + unsigned char *out = malloc(outlen); + EVP_DecryptUpdate(&dec->ctx, out, &len, buf, len); + dec->write(out, 1, len, dec->stream); + free(out); + return (s*n) / s; +} + +void aes_decrypter_close(AESDecrypter *dec) { + void *out = malloc(128); + int len = 0; + EVP_DecryptFinal_ex(&dec->ctx, out, &len); + dec->write(out, 1, len, dec->stream); + free(out); + EVP_CIPHER_CTX_cleanup(&dec->ctx); + free(dec); +} + + +AESEncrypter* aes_encrypter_new(DavKey *key, void *stream, dav_read_func read_func) { + unsigned char *iv = malloc(16); + if(!RAND_bytes(iv, 16)) { + free(iv); + return NULL; + } + + AESEncrypter *enc = malloc(sizeof(AESEncrypter)); + enc->stream = stream; + enc->read = read_func; + enc->tmp = NULL; + enc->tmplen = 0; + enc->tmpoff = 0; + enc->end = 0; + //enc->iv = iv; + enc->iv = iv; + enc->ivlen = 16; + + EVP_CIPHER_CTX_init(&enc->ctx); + if(key->type == DAV_KEY_AES128) { + EVP_EncryptInit_ex(&enc->ctx, EVP_aes_128_cbc(), NULL, key->data, enc->iv); + } else if(key->type == DAV_KEY_AES256) { + EVP_EncryptInit_ex(&enc->ctx, EVP_aes_256_cbc(), NULL, key->data, enc->iv); + } else { + fprintf(stderr, "unknown key type\n"); + exit(-1); + } + return enc; +} + +size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc) { + size_t len = s*n; + if(enc->tmp) { + size_t tmp_diff = enc->tmplen - enc->tmpoff; + size_t cp_len = tmp_diff > len ? len : tmp_diff; + memcpy(buf, enc->tmp + enc->tmpoff, cp_len); + enc->tmpoff += cp_len; + if(enc->tmpoff >= enc->tmplen) { + free(enc->tmp); + enc->tmp = NULL; + enc->tmplen = 0; + enc->tmpoff = 0; + } + return cp_len / s; + } + + if(enc->end) { + return 0; + } + + void *in = malloc(len); + size_t in_len = enc->read(in, 1, len, enc->stream); + + unsigned char *out = NULL; + int outlen = 0; + size_t ivl = enc->ivlen; + if(in_len != 0) { + outlen = len + 16; + out = malloc(outlen + ivl); + if(enc->iv) { + memcpy(out, enc->iv, ivl); + } + EVP_EncryptUpdate(&enc->ctx, out + ivl, &outlen, in, in_len); + free(in); + } else { + out = malloc(16); + EVP_EncryptFinal_ex(&enc->ctx, out, &outlen); + enc->end = 1; + } + enc->tmp = (char*)out; + enc->tmplen = outlen + ivl; + enc->tmpoff = 0; + + if(enc->iv) { + enc->iv = NULL; + enc->ivlen = 0; + } + + return aes_read(buf, s, n, enc); +} + +void aes_encrypter_close(AESEncrypter *enc) { + if(enc->tmp) { + free(enc->tmp); + } + EVP_CIPHER_CTX_cleanup(&enc->ctx); + free(enc); +} + + +char* aes_encrypt(char *in, DavKey *key) { + char *iv = malloc(16); + if(!RAND_bytes(iv, 16)) { + free(iv); + return NULL; + } + + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if(key->type == DAV_KEY_AES128) { + EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->data, iv); + } else if(key->type == DAV_KEY_AES256) { + EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key->data, iv); + } else { + return NULL; + } + + int len = strlen(in); + int buflen = len + 64; + char *buf = calloc(1, buflen); + memcpy(buf, iv, 16); + + int l = buflen - 16; + EVP_EncryptUpdate(&ctx, buf + 16, &l, in, len); + + int f = 0; + EVP_EncryptFinal_ex(&ctx, buf + 16 + l, &f); + char *out = util_base64encode(buf, 16 + l + f); + free(buf); + return out; +} + +char* aes_decrypt(char *in, DavKey *key) { + int len; + char *buf = util_base64decode_len(in, &len); + + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if(key->type == DAV_KEY_AES128) { + EVP_DecryptInit_ex( + &ctx, + EVP_aes_128_cbc(), + NULL, + key->data, + buf); + } else if(key->type == DAV_KEY_AES256) { + EVP_DecryptInit_ex( + &ctx, + EVP_aes_256_cbc(), + NULL, + key->data, + buf); + } else { + return NULL; + } + + char *out = malloc(len + 1); + int outlen = len; + char *in_buf = buf + 16; + int inlen = len - 16; + int f = 0; + + + + EVP_DecryptUpdate(&ctx, out, &outlen, in_buf, inlen); + EVP_DecryptFinal_ex(&ctx, out + outlen, &f); + out[outlen + f] = '\0'; + free(buf); + return out; +} diff -r 3e55bed345f9 -r a95ee94b9204 libidav/crypto.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libidav/crypto.h Mon Mar 17 18:42:01 2014 +0100 @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#ifndef DAV_CRYPTO_H +#define DAV_CRYPTO_H + +#include "webdav.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + EVP_CIPHER_CTX ctx; + void *stream; + dav_write_func write; + DavKey *key; + int init; + unsigned char ivtmp[16]; + size_t ivpos; +} AESDecrypter; + +typedef struct { + EVP_CIPHER_CTX ctx; + void *iv; + size_t ivlen; + void *stream; + dav_read_func read; + char *tmp; + size_t tmplen; + size_t tmpoff; + int end; +} AESEncrypter; + +AESDecrypter* aes_decrypter_new(DavKey *key, void *stream, dav_write_func write_func); +size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec); +void aes_decrypter_close(AESDecrypter *dec); +void aes_decrypter_close2(EVP_CIPHER_CTX *ctx); + +AESEncrypter* aes_encrypter_new(DavKey *key, void *stream, dav_read_func read_func); +size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc); +void aes_encrypter_close(AESEncrypter *enc); + +char* aes_encrypt(char *in, DavKey *key); +char* aes_decrypt(char *in, DavKey *key); + +#ifdef __cplusplus +} +#endif + +#endif /* DAV_CRYPTO_H */ + diff -r 3e55bed345f9 -r a95ee94b9204 libidav/resource.c --- a/libidav/resource.c Sat Sep 07 14:08:43 2013 +0200 +++ b/libidav/resource.c Mon Mar 17 18:42:01 2014 +0100 @@ -34,6 +34,7 @@ #include "utils.h" #include "methods.h" #include "davql.h" +#include "crypto.h" #include "ucx/buffer.h" #include "ucx/utils.h" @@ -42,7 +43,8 @@ #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) DavResource* dav_resource_new(DavSession *sn, char *path) { - char *url = util_concat_path(sn->base_url, path); + int plen = 0; + char *url = util_path_to_url(sn, path); char *href = util_url_path(url); DavResource *res = dav_resource_new_href(sn, href); free(url); @@ -50,11 +52,8 @@ } -DavResource* dav_resource_new_href(DavSession *sn, char *href) { - UcxMempool *mp = sn->mp; - UcxAllocator *a = sn->allocator; - - DavResource *res = ucx_mempool_calloc(mp, 1, sizeof(DavResource)); +DavResource* dav_resource_new_href(DavSession *sn, char *href) { + DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource)); res->session = sn; // set name, path and href @@ -75,10 +74,20 @@ sstr_t base_href = sstr(util_url_path(res->session->base_url)); sstr_t path = sstrsubs(href, base_href.length - 1); - UcxAllocator *a = res->session->allocator; - res->name = sstrdup_a(a, name).ptr; + UcxAllocator *a = res->session->mp->allocator; + CURL *handle = res->session->handle; + + int nlen = 0; + char *uname = curl_easy_unescape(handle, name.ptr, name.length , &nlen); + int plen = 0; + char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen); + + res->name = sstrdup_a(a, sstrn(uname, nlen)).ptr; res->href = sstrdup_a(a, href).ptr; - res->path = sstrdup_a(a, path).ptr; + res->path = sstrdup_a(a, sstrn(upath, plen)).ptr; + + curl_free(uname); + curl_free(upath); } DavResourceData* resource_data_new(DavSession *sn) { @@ -88,7 +97,7 @@ if(!data) { return NULL; } - data->properties = ucx_map_new_a(sn->allocator, 32); + data->properties = ucx_map_new_a(sn->mp->allocator, 32); data->set = NULL; data->remove = NULL; data->content = NULL; @@ -101,10 +110,9 @@ if(!val) { return; } - UcxAllocator *a = res->session->allocator; UcxKey key = dav_property_key(ns, name); - sstr_t v = sstrdup_a(a, sstr(val)); + sstr_t v = sstrdup_a(res->session->mp->allocator, sstr(val)); ucx_map_put(((DavResourceData*)res->data)->properties, key, v.ptr); free(key.data); } @@ -189,13 +197,18 @@ } void dav_set_property_ns(DavResource *res, char *ns, char *name, char *value) { - UcxAllocator *a = res->session->allocator; + UcxAllocator *a = res->session->mp->allocator; DavResourceData *data = res->data; - DavProperty *property = a->malloc(a->pool, sizeof(DavProperty)); + DavProperty *property = dav_session_malloc( + res->session, + sizeof(DavProperty)); property->name = sstrdup_a(a, sstr(name)).ptr; property->value = sstrdup_a(a, sstr(value)).ptr; - DavNamespace *namespace = a->malloc(a->pool, sizeof(DavNamespace)); + + DavNamespace *namespace = dav_session_malloc( + res->session, + sizeof(DavNamespace)); namespace->prefix = NULL; namespace->name = sstrdup_a(a, sstr(ns)).ptr; property->ns = namespace; @@ -211,13 +224,18 @@ } void dav_remove_property_ns(DavResource *res, char *ns, char *name) { - UcxAllocator *a = res->session->allocator; DavResourceData *data = res->data; + UcxAllocator *a = res->session->mp->allocator; - DavProperty *property = a->malloc(a->pool, sizeof(DavProperty)); + DavProperty *property = dav_session_malloc( + res->session, + sizeof(DavProperty)); property->name = sstrdup_a(a, sstr(name)).ptr; property->value = NULL; - DavNamespace *namespace = a->malloc(a->pool, sizeof(DavNamespace)); + + DavNamespace *namespace = dav_session_malloc( + res->session, + sizeof(DavNamespace)); namespace->prefix = NULL; namespace->name = sstrdup_a(a, sstr(ns)).ptr; property->ns = namespace; @@ -227,10 +245,24 @@ void dav_set_content(DavResource *res, void *stream, dav_read_func read_func) { - DavResourceData *data = res->data; - data->content = stream; - data->read = read_func; - data->length = 0; + DavSession *sn = res->session; + if((sn->flags & DAV_SESSION_ENCRYPT_FILE) == DAV_SESSION_ENCRYPT_FILE) { + AESEncrypter *enc = aes_encrypter_new(sn->key, stream, read_func); + DavResourceData *data = res->data; + data->content = enc; + data->read = (dav_read_func)aes_read; + data->length = 0; + dav_set_property_ns( + res, + "http://www.uap-core.de/", + "crypto-key", + sn->key->name); + } else { + DavResourceData *data = res->data; + data->content = stream; + data->read = read_func; + data->length = 0; + } } void dav_set_content_data(DavResource *res, char *content, size_t length) { @@ -253,11 +285,7 @@ ucx_map_remove(data->properties, key); } - char *url = util_concat_path(sn->base_url, res->path); - - CURL *handle = sn->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(sn, res->path); UcxBuffer *rqbuf = create_allprop_propfind_request(); UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); @@ -265,13 +293,13 @@ //fwrite(rpbuf->space, 1, rpbuf->size, stdout); //printf("\n"); - CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf); + CURLcode ret = do_propfind_request(sn->handle, rqbuf, rpbuf); int status = 0; - curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); + curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); if(ret == CURLE_OK) { //printf("response\n%s\n", rpbuf->space); // TODO: use parse_propfind_response() - xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, url, NULL, 0); + xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, NULL, NULL, 0); if(!doc) { return 1; } @@ -298,16 +326,13 @@ DavSession *sn = res->session; DavResourceData *data = res->data; - char *url = util_concat_path(sn->base_url, res->path); - CURL *handle = res->session->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(sn, res->path);; // store content if(data->content) { - CURLcode ret = do_put_request(handle, data->content, data->read, data->length); + CURLcode ret = do_put_request(sn->handle, data->content, data->read, data->length); int status = 0; - curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); + curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &status); if(ret == CURLE_OK && (status >= 200 && status < 300)) { res->session->error = 0; // cleanup node data @@ -328,9 +353,9 @@ UcxBuffer *request = create_proppatch_request(data); UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); - CURLcode ret = do_proppatch_request(handle, request, response); + CURLcode ret = do_proppatch_request(sn->handle, request, response); int status = 0; - curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); + curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); if(ret == CURLE_OK && status == 207) { //printf("%s\n", response->space); // TODO: parse response @@ -347,10 +372,8 @@ } int dav_get_content(DavResource *res, void *stream, dav_write_func write_fnc) { - char *url = util_concat_path(res->session->base_url, res->path); CURL *handle = res->session->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(res->session, res->path); curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL); @@ -378,10 +401,8 @@ } int dav_delete(DavResource *res) { - char *url = util_concat_path(res->session->base_url, res->path); CURL *handle = res->session->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(res->session, res->path); UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); CURLcode ret = do_delete_request(handle, response); @@ -401,7 +422,7 @@ } int dav_create(DavResource *res) { - char *url = util_concat_path(res->session->base_url, res->path); + //char *url = util_concat_path(res->session->base_url, res->path); char *parent = util_parent_path(res->path); DavSession *sn = res->session; @@ -422,8 +443,7 @@ } CURL *handle = res->session->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(res->session, res->path); free(parent); // create new collection or do an empty put request @@ -455,7 +475,7 @@ if(ret == CURLE_OK && (status >= 200 && status < 300)) { //printf("response\n%s\n", rpbuf->space); // TODO: use parse_propfind_response() - xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, url, NULL, 0); + xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, NULL, NULL, 0); if(!doc) { return 1; } @@ -481,10 +501,8 @@ int dav_exists(DavResource *res) { DavSession *sn = res->session; - char *url = util_concat_path(sn->base_url, res->path); CURL *handle = sn->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(sn, res->path); CURLcode ret = do_head_request(handle); int status = 0; diff -r 3e55bed345f9 -r a95ee94b9204 libidav/utils.c --- a/libidav/utils.c Sat Sep 07 14:08:43 2013 +0200 +++ b/libidav/utils.c Mon Mar 17 18:42:01 2014 +0100 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ #include #include "utils.h" +#include "webdav.h" time_t util_parse_creationdate(char *str) { @@ -173,6 +175,51 @@ return url.ptr; } +void util_set_url(DavSession *sn, char *path) { + if(path) { + char *url = util_path_to_url(sn, path); + curl_easy_setopt(sn->handle, CURLOPT_URL, url); + free(url); + } else { + curl_easy_setopt(sn->handle, CURLOPT_URL, sn->base_url); + } +} + +char* util_path_to_url(DavSession *sn, char *path) { + UcxBuffer *url = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND); + + // add base url + ucx_buffer_write(sn->base_url, 1, strlen(sn->base_url), url); + // remove trailing slash + ucx_buffer_seek(url, -1, SEEK_CUR); + + sstr_t p = sstr(path); + size_t ntk = 0; + sstr_t *tks = sstrsplit(p, S("/"), &ntk); + + for(int i=0;i 0) { + // TODO: implement file name encryption + char *esc = curl_easy_escape(sn->handle, node.ptr, node.length); + ucx_buffer_putc(url, '/'); + ucx_buffer_write(esc, 1, strlen(esc), url); + curl_free(esc); + free(node.ptr); + } + } + free(tks); + if(path[p.length-1] == '/') { + ucx_buffer_putc(url, '/'); + } + ucx_buffer_putc(url, 0); + + // only free the buffer struct and return the buffer space + char *space = url->space; + free(url); + return space; +} + char* util_parent_path(char *path) { char *name = util_resource_name(path); size_t namelen = strlen(name); diff -r 3e55bed345f9 -r a95ee94b9204 libidav/utils.h --- a/libidav/utils.h Sat Sep 07 14:08:43 2013 +0200 +++ b/libidav/utils.h Mon Mar 17 18:42:01 2014 +0100 @@ -34,6 +34,8 @@ #include #include #include +#include +#include "webdav.h" #ifdef _WIN32 #include @@ -59,6 +61,8 @@ char* util_url_path(char *url); char* util_resource_name(char *url); char* util_concat_path(char *url_base, char *path); +void util_set_url(DavSession *sn, char *path); +char* util_path_to_url(DavSession *sn, char *path); char* util_parent_path(char *path); int util_getboolean(char *v); diff -r 3e55bed345f9 -r a95ee94b9204 libidav/webdav.c --- a/libidav/webdav.c Sat Sep 07 14:08:43 2013 +0200 +++ b/libidav/webdav.c Mon Mar 17 18:42:01 2014 +0100 @@ -53,6 +53,7 @@ free(context); return NULL; } + context->keys = ucx_map_new(16); DavNamespace *davns = malloc(sizeof(DavNamespace)); if(!davns) { ucx_map_free(context->namespaces); @@ -87,6 +88,14 @@ free(ctx); } +void dav_context_add_key(DavContext *context, DavKey *key) { + ucx_map_cstr_put(context->keys, key->name, key); +} + +DavKey* dav_context_get_key(DavContext *context, char *name) { + return ucx_map_cstr_get(context->keys, name); +} + int dav_add_namespace(DavContext *context, char *prefix, char *name) { DavNamespace *namespace = malloc(sizeof(DavNamespace)); if(!namespace) { @@ -135,11 +144,12 @@ return NULL; } DavSession *sn = malloc(sizeof(DavSession)); + sn->key = NULL; sn->errorstr = NULL; sn->error = DAV_OK; sn->flags = 0; if(url.ptr[url.length - 1] == '/') { - sn->base_url = strdup(base_url); + sn->base_url = strdup(base_url); // TODO: mempool } else { char *url_str = malloc(url.length + 2); memcpy(url_str, base_url, url.length); @@ -178,7 +188,6 @@ curl_easy_setopt(sn->handle, CURLOPT_URL, base_url); sn->mp = ucx_mempool_new(1024); - sn->allocator = ucx_mempool_allocator(sn->mp); context->sessions = ucx_list_append(context->sessions, sn); @@ -250,32 +259,25 @@ void* dav_session_malloc(DavSession *sn, size_t size) { - UcxAllocator *a = sn->allocator; - return a->malloc(a->pool, size); + return ucx_mempool_malloc(sn->mp, size); } void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size) { - UcxAllocator *a = sn->allocator; - return a->calloc(a->pool, nelm, size); + return ucx_mempool_calloc(sn->mp, nelm, size); } void* dav_session_realloc(DavSession *sn, void *ptr, size_t size) { - UcxAllocator *a = sn->allocator; - return a->realloc(a->pool, ptr, size); + return ucx_mempool_realloc(sn->mp, ptr, size); } void dav_session_free(DavSession *sn, void *ptr) { - UcxAllocator *a = sn->allocator; - a->free(a->pool, ptr); + ucx_mempool_free(sn->mp, ptr); } -DavResource* dav_get(DavSession *sn, char *path, char *properties) { - char *url = util_concat_path(sn->base_url, path); - +DavResource* dav_get(DavSession *sn, char *path, char *properties) { CURL *handle = sn->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(sn, path); UcxList *proplist = NULL; if(properties) { @@ -302,10 +304,8 @@ } DavResource* dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, char *path, DavQOp *cond, size_t len) { - char *url = util_concat_path(sn->base_url, path); CURL *handle = sn->handle; - curl_easy_setopt(handle, CURLOPT_URL, url); - free(url); + util_set_url(sn, path); UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); DavResource *resource = root; @@ -334,7 +334,7 @@ return stack; } -DavResource* dav_get2(DavSession *sn, DavGetQuery *query) { +DavResource* dav_query_get(DavSession *sn, DavGetQuery *query) { char *path; int depth = 0; if(parse_path_query(query->from, &path, &depth)) { @@ -360,7 +360,7 @@ free(path); int error = 0; if(resource && depth == -1) { - UcxList *stack = NULL; // stack with davResource* elements + UcxList *stack = NULL; // stack with DavResource* elements stack = propfind_stack_push(stack, resource->children); while(stack) { DavResource *sr = stack->data; // get first element from the stack @@ -416,7 +416,7 @@ DavResource *res = NULL; switch(q.command) { case DAV_QUERY_GET: { - res = dav_get2(sn, q.command_data); + res = dav_query_get(sn, q.command_data); free_get_query(q.command_data); break; } diff -r 3e55bed345f9 -r a95ee94b9204 libidav/webdav.h --- a/libidav/webdav.h Sat Sep 07 14:08:43 2013 +0200 +++ b/libidav/webdav.h Mon Mar 17 18:42:01 2014 +0100 @@ -48,6 +48,7 @@ typedef struct DavRequest DavRequest; typedef struct DavNamespace DavNamespace; typedef struct DavProperty DavProperty; +typedef struct DavKey DavKey; #include "davql.h" @@ -66,6 +67,11 @@ typedef enum DavError DavError; +#define DAV_SESSION_ENCRYPT_FILE 0x0001 +#define DAV_SESSION_ENCRYPT_NAME 0x0002 +#define DAV_SESSION_DECRYPT_PATH 0x0004 + + struct DavNamespace { char *prefix; char *name; @@ -93,7 +99,7 @@ CURL *handle; char *base_url; UcxMempool *mp; - UcxAllocator *allocator; + DavKey *key; uint32_t flags; DavError error; const char *errorstr; @@ -101,6 +107,7 @@ struct DavContext { UcxMap *namespaces; + UcxMap *keys; UcxList *sessions; DavProxy *http_proxy; DavProxy *https_proxy; @@ -119,8 +126,23 @@ char *value; }; +#define DAV_KEY_AES128 0 +#define DAV_KEY_AES256 1 +#define DAV_KEY_PASSWORD 2 + +struct DavKey { + char *name; + int type; + void *data; + size_t length; +}; + DavContext* dav_context_new(); void dav_context_destroy(DavContext *ctx); + +void dav_context_add_key(DavContext *context, DavKey *key); +DavKey* dav_context_get_key(DavContext *context, char *name); + int dav_add_namespace(DavContext *context, char *prefix, char *ns); DavNamespace* dav_get_namespace(DavContext *context, char *prefix); @@ -142,7 +164,8 @@ DavResource* dav_get(DavSession *sn, char *path, char *properties); -DavResource* dav_get2(DavSession *sn, DavGetQuery *query); + +DavResource* dav_query_get(DavSession *sn, DavGetQuery *query); UcxList* parse_properties_string(DavContext *context, sstr_t str); diff -r 3e55bed345f9 -r a95ee94b9204 ucx/mempool.c --- a/ucx/mempool.c Sat Sep 07 14:08:43 2013 +0200 +++ b/ucx/mempool.c Mon Mar 17 18:42:01 2014 +0100 @@ -75,6 +75,20 @@ pool->ndata = 0; pool->size = n; + + UcxAllocator *allocator = (UcxAllocator*)malloc(sizeof(UcxAllocator)); + if(!allocator) { + free(pool->data); + free(pool); + return NULL; + } + allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc; + allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc; + allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc; + allocator->free = (ucx_allocator_free)ucx_mempool_free; + allocator->pool = pool; + pool->allocator = allocator; + return pool; } @@ -173,6 +187,7 @@ } } free(pool->data); + free(pool->allocator); free(pool); } @@ -189,16 +204,3 @@ ucx_mempool_set_destr(rd, ucx_mempool_shared_destr); } -UcxAllocator* ucx_mempool_allocator(UcxMempool *pool) { - UcxAllocator *allocator = (UcxAllocator*)ucx_mempool_malloc( - pool, sizeof(UcxAllocator)); - if(!allocator) { - return NULL; - } - allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc; - allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc; - allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc; - allocator->free = (ucx_allocator_free)ucx_mempool_free; - allocator->pool = pool; - return allocator; -} diff -r 3e55bed345f9 -r a95ee94b9204 ucx/mempool.h --- a/ucx/mempool.h Sat Sep 07 14:08:43 2013 +0200 +++ b/ucx/mempool.h Mon Mar 17 18:42:01 2014 +0100 @@ -57,14 +57,17 @@ * UCX mempool structure. */ typedef struct { + /** UcxAllocator based on this pool */ + UcxAllocator *allocator; + /** List of pointers to pooled memory. */ - void **data; + void **data; /** Count of pooled memory items. */ - size_t ndata; + size_t ndata; /** Memory pool size. */ - size_t size; + size_t size; } UcxMempool; /** Shorthand for a new default memory pool with a capacity of 16 elements. */ @@ -210,14 +213,6 @@ */ void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr); -/** - * Creates an UcxAllocator based on an UcxMempool. - * - * @param pool the mempool to create the UcxAllocator for - * @return a new UcxAllocator based on the specified pool - */ -UcxAllocator* ucx_mempool_allocator(UcxMempool *pool); - #ifdef __cplusplus } #endif