From e83247720ea6322f783fad03523de15bbbb29706 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Wed, 28 May 2025 20:16:41 +0200 Subject: [PATCH] update libidav --- libidav/config.c | 2 +- libidav/crypto.c | 73 +++++++++++++++++++++++++++-------------- libidav/crypto.h | 17 +++++++--- libidav/methods.c | 2 -- libidav/resource.c | 13 +++----- libidav/utils.c | 81 +++++++++++++++++++++++++++++++++++++++++++--- libidav/utils.h | 3 ++ libidav/webdav.c | 4 +-- 8 files changed, 147 insertions(+), 48 deletions(-) diff --git a/libidav/config.c b/libidav/config.c index 9c295bb..715f98b 100644 --- a/libidav/config.c +++ b/libidav/config.c @@ -198,7 +198,7 @@ void dav_cfg_uint_remove(CfgUInt *cint) { DavConfig* dav_config_new(xmlDoc *doc) { - CxMempool *cfg_mp = cxMempoolCreate(128, NULL); + CxMempool *cfg_mp = cxMempoolCreateSimple(128); DavConfig *config = cxMalloc(cfg_mp->allocator, sizeof(DavConfig)); memset(config, 0, sizeof(DavConfig)); config->mp = cfg_mp; diff --git a/libidav/crypto.c b/libidav/crypto.c index d52e845..240406f 100644 --- a/libidav/crypto.c +++ b/libidav/crypto.c @@ -66,7 +66,7 @@ int dav_rand_bytes(unsigned char *buf, size_t len) { AESDecrypter* aes_decrypter_new(DavKey *key, void *stream, dav_write_func write_func) { AESDecrypter *dec = calloc(1, sizeof(AESDecrypter)); - SHA256_Init(&dec->sha256); + dav_sha256_init(&dec->sha256); dec->stream = stream; dec->write = write_func; dec->key = key; @@ -122,7 +122,7 @@ size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) { unsigned char *out = malloc(outlen); EVP_DecryptUpdate(dec->ctx, out, &outlen, buf, len); ssize_t wlen = dec->write(out, 1, outlen, dec->stream); - SHA256_Update(&dec->sha256, out, wlen); + dav_sha256_update(&dec->sha256, out, wlen); free(out); return (s*n) / s; } @@ -133,7 +133,7 @@ void aes_decrypter_shutdown(AESDecrypter *dec) { int len = 0; EVP_DecryptFinal_ex(dec->ctx, out, &len); dec->write(out, 1, len, dec->stream); - SHA256_Update(&dec->sha256, out, len); + dav_sha256_update(&dec->sha256, out, len); free(out); //EVP_CIPHER_CTX_cleanup(&dec->ctx); EVP_CIPHER_CTX_free(dec->ctx); @@ -153,7 +153,7 @@ AESEncrypter* aes_encrypter_new(DavKey *key, void *stream, dav_read_func read_fu } AESEncrypter *enc = malloc(sizeof(AESEncrypter)); - SHA256_Init(&enc->sha256); + dav_sha256_init(&enc->sha256); enc->stream = stream; enc->read = read_func; enc->seek = seek_func; @@ -200,7 +200,7 @@ size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc) { void *in = malloc(len); size_t in_len = enc->read(in, 1, len, enc->stream); - SHA256_Update(&enc->sha256, in, in_len); + dav_sha256_update(&enc->sha256, in, in_len); unsigned char *out = NULL; int outlen = 0; @@ -357,33 +357,56 @@ char* aes_decrypt(const char *in, size_t *length, DavKey *key) { void dav_get_hash(DAV_SHA_CTX *sha256, unsigned char *buf){ - SHA256_Final((unsigned char*)buf, sha256); + dav_sha256_final(sha256, (unsigned char*)buf); } char* dav_create_hash(const char *data, size_t len) { unsigned char hash[DAV_SHA256_DIGEST_LENGTH]; DAV_SHA_CTX ctx; - SHA256_Init(&ctx); - SHA256_Update(&ctx, data, len); - SHA256_Final(hash, &ctx); + dav_sha256_init(&ctx); + dav_sha256_update(&ctx, data, len); + dav_sha256_final(&ctx, hash); return util_hexstr(hash, DAV_SHA256_DIGEST_LENGTH); } -DAV_SHA_CTX* dav_hash_init(void) { +DAV_SHA_CTX* dav_sha256_create(void) { DAV_SHA_CTX *ctx = malloc(sizeof(DAV_SHA_CTX)); - SHA256_Init(ctx); + dav_sha256_init(ctx); return ctx; } -void dav_hash_update(DAV_SHA_CTX *ctx, const char *data, size_t len) { - SHA256_Update(ctx, data, len); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + +void dav_sha256_init(DAV_SHA_CTX *ctx) { + SHA256_Init(ctx); } -void dav_hash_final(DAV_SHA_CTX *ctx, unsigned char *buf) { - SHA256_Final(buf, ctx); - free(ctx); +void dav_sha256_update(DAV_SHA_CTX *ctx, const void *data, size_t length) { + SHA256_Update(ctx, data, length); +} + +void dav_sha256_final(char *md, DAV_SHA_CTX *ctx) { + SHA256_Final(md, ctx); +} + +#else + +void dav_sha256_init(DAV_SHA_CTX *ctx) { + EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); + EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); + *ctx = mdctx; +} + +void dav_sha256_update(DAV_SHA_CTX *ctx, const char *data, size_t length) { + EVP_DigestUpdate(*ctx, data, length); } +void dav_sha256_final(DAV_SHA_CTX *ctx, unsigned char *md) { + EVP_DigestFinal(*ctx, md, NULL); +} + +#endif + #if OPENSSL_VERSION_NUMBER < 0x10100000L static int crypto_pw2key_error = 0; DavKey* dav_pw2key(const char *password, const unsigned char *salt, int saltlen, int pwfunc, int enc) { @@ -819,17 +842,17 @@ char* dav_create_hash(const char *data, size_t len) { return util_hexstr(hash, DAV_SHA256_DIGEST_LENGTH); } -DAV_SHA_CTX* dav_hash_init(void) { +DAV_SHA_CTX* dav_sha256_create(void) { DAV_SHA_CTX *ctx = malloc(sizeof(DAV_SHA_CTX)); CC_SHA256_Init(ctx); return ctx; } -void dav_hash_update(DAV_SHA_CTX *ctx, const char *data, size_t len) { +void dav_sha256_update(DAV_SHA_CTX *ctx, const char *data, size_t len) { CC_SHA256_Update(ctx, data, len); } -void dav_hash_final(DAV_SHA_CTX *ctx, unsigned char *buf) { +void dav_sha256_final(DAV_SHA_CTX *ctx, unsigned char *buf) { CC_SHA256_Final(buf, ctx); free(ctx); } @@ -1396,15 +1419,15 @@ void dav_get_hash(DAV_SHA_CTX *sha256, unsigned char *buf) { char* dav_create_hash(const char *data, size_t len) { unsigned char hash[DAV_SHA256_DIGEST_LENGTH]; - DAV_SHA_CTX *ctx = dav_hash_init(); + DAV_SHA_CTX *ctx = dav_sha256_create(); if(ctx) { - dav_hash_update(ctx, data, len); - dav_hash_final(ctx, hash); + dav_sha256_update(ctx, data, len); + dav_sha256_final(ctx, hash); } return util_hexstr(hash, DAV_SHA256_DIGEST_LENGTH); } -DAV_SHA_CTX* dav_hash_init(void) { +DAV_SHA_CTX* dav_sha256_create(void) { DAV_SHA_CTX *ctx = malloc(sizeof(DAV_SHA_CTX)); if(!ctx) { return NULL; @@ -1416,11 +1439,11 @@ DAV_SHA_CTX* dav_hash_init(void) { return ctx; } -void dav_hash_update(DAV_SHA_CTX *ctx, const char *data, size_t len) { +void dav_sha256_update(DAV_SHA_CTX *ctx, const char *data, size_t len) { BCryptHashData(ctx->hHash, (PUCHAR)data, len, 0); } -void dav_hash_final(DAV_SHA_CTX *ctx, unsigned char *buf) { +void dav_sha256_final(DAV_SHA_CTX *ctx, unsigned char *buf) { BCryptFinishHash(ctx->hHash, (PUCHAR)buf, DAV_SHA256_DIGEST_LENGTH, 0); // cleanup diff --git a/libidav/crypto.h b/libidav/crypto.h index b058488..3bc5937 100644 --- a/libidav/crypto.h +++ b/libidav/crypto.h @@ -74,14 +74,20 @@ typedef struct WinBCryptSHACTX { #else /* unix/linux */ +#include +#include + #define DAV_USE_OPENSSL #define DAV_AES_CTX EVP_CIPHER_CTX* + +#if OPENSSL_VERSION_NUMBER < 0x30000000L #define DAV_SHA_CTX SHA256_CTX +#else +#define DAV_SHA_CTX EVP_MD_CTX* +#endif #define DAV_SHA256_DIGEST_LENGTH 32 -#include -#include #if defined(__sun) && defined(__SunOS_5_10) #include @@ -149,9 +155,10 @@ void dav_get_hash(DAV_SHA_CTX *sha256, unsigned char *buf); char* dav_create_hash(const char *data, size_t len); -DAV_SHA_CTX* dav_hash_init(void); -void dav_hash_update(DAV_SHA_CTX *ctx, const char *data, size_t len); -void dav_hash_final(DAV_SHA_CTX *ctx, unsigned char *buf); +void dav_sha256_init(DAV_SHA_CTX *ctx); +DAV_SHA_CTX* dav_sha256_create(void); +void dav_sha256_update(DAV_SHA_CTX *ctx, const char *data, size_t len); +void dav_sha256_final(DAV_SHA_CTX *ctx, unsigned char *buf); DavKey* dav_pw2key(const char *password, const unsigned char *salt, int saltlen, int pwfunc, int enc); diff --git a/libidav/methods.c b/libidav/methods.c index 7c425db..cbe0685 100644 --- a/libidav/methods.c +++ b/libidav/methods.c @@ -1102,7 +1102,6 @@ CURLcode do_mkcol_request(DavSession *sn, char *lock) { } curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "MKCOL"); - curl_easy_setopt(handle, CURLOPT_PUT, 0L); curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, dummy_write); @@ -1140,7 +1139,6 @@ CURLcode do_copy_move_request(DavSession *sn, char *dest, char *lock, DavBool co } else { curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "MOVE"); } - curl_easy_setopt(handle, CURLOPT_PUT, 0L); curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, dummy_write); diff --git a/libidav/resource.c b/libidav/resource.c index 91efa90..19ddffa 100644 --- a/libidav/resource.c +++ b/libidav/resource.c @@ -786,7 +786,7 @@ int dav_load(DavResource *res) { } int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop) { - CxMempool *mp = cxMempoolCreate(64, NULL); + CxMempool *mp = cxMempoolCreateSimple(64); const CxAllocator *a = mp->allocator; CxList *proplist = cxArrayListCreate(a, NULL, sizeof(DavProperty), numprop); @@ -823,11 +823,11 @@ static void init_hash_stream(HashStream *hstr, void *stream, dav_read_func readf static size_t dav_read_h(void *buf, size_t size, size_t nelm, void *stream) { HashStream *s = stream; if(!s->sha) { - s->sha = dav_hash_init(); + s->sha = dav_sha256_create(); } size_t r = s->read(buf, size, nelm, s->stream); - dav_hash_update(s->sha, buf, r); + dav_sha256_update(s->sha, buf, r); return r; } @@ -835,7 +835,7 @@ static int dav_seek_h(void *stream, long offset, int whence) { HashStream *s = stream; if(offset == 0 && whence == SEEK_SET) { unsigned char buf[DAV_SHA256_DIGEST_LENGTH]; - dav_hash_final(s->sha, buf); + dav_sha256_final(s->sha, buf); s->sha = NULL; } else { s->error = 1; @@ -938,7 +938,7 @@ int dav_store(DavResource *res) { data->length); if(hstr.sha) { - dav_hash_final(hstr.sha, (unsigned char*)data->hash); + dav_sha256_final(hstr.sha, (unsigned char*)data->hash); char *hash = util_hexstr((unsigned char*)data->hash, 32); dav_set_string_property_ns(res, DAV_NS, "content-hash", hash); free(hash); @@ -1115,7 +1115,6 @@ int dav_get_content(DavResource *res, void *stream, dav_write_func write_fnc) { curl_easy_setopt(handle, CURLOPT_HTTPHEADER, NULL); curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL); - curl_easy_setopt(handle, CURLOPT_PUT, 0L); curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_fnc); @@ -1662,7 +1661,6 @@ DavInputStream* dav_inputstream_open(DavResource *res) { curl_easy_setopt(in->c, CURLOPT_HTTPHEADER, NULL); curl_easy_setopt(in->c, CURLOPT_CUSTOMREQUEST, NULL); - curl_easy_setopt(in->c, CURLOPT_PUT, 0L); curl_easy_setopt(in->c, CURLOPT_UPLOAD, 0L); curl_multi_add_handle(in->m, in->c); @@ -1800,7 +1798,6 @@ DavOutputStream* dav_outputstream_open(DavResource *res) { curl_easy_setopt(out->c, CURLOPT_HEADERFUNCTION, NULL); curl_easy_setopt(out->c, CURLOPT_HTTPHEADER, NULL); curl_easy_setopt(out->c, CURLOPT_CUSTOMREQUEST, NULL); - curl_easy_setopt(out->c, CURLOPT_PUT, 1L); curl_easy_setopt(out->c, CURLOPT_UPLOAD, 1L); curl_easy_setopt(out->c, CURLOPT_READFUNCTION, read_fnc); curl_easy_setopt(out->c, CURLOPT_READDATA, stream); diff --git a/libidav/utils.c b/libidav/utils.c index 9b195e3..c6f1eb1 100644 --- a/libidav/utils.c +++ b/libidav/utils.c @@ -348,10 +348,81 @@ cxstring util_url_path_s(cxstring url) { return path; } +char* util_url_encode(DavSession *sn, const char *url) { + CURL *handle = sn ? sn->handle : NULL; +#if LIBCURL_VERSION_NUM < 0x075200 + int cleanup_handle = 0; + if(!handle) { + handle = curl_easy_init(); + cleanup_handle = 1; + } +#endif + + char *esc = curl_easy_escape(handle, url, strlen(url)); + char *ret = esc ? strdup(esc) : NULL; + curl_free(esc); + +#if LIBCURL_VERSION_NUM < 0x075200 + if(cleanup_handle) { + curl_easy_cleanup(handle); + } +#endif + + return ret; +} + char* util_url_decode(DavSession *sn, const char *url) { - char *unesc = curl_easy_unescape(sn->handle, url, strlen(url), NULL); - char *ret = strdup(unesc); + CURL *handle = sn ? sn->handle : NULL; +#if LIBCURL_VERSION_NUM < 0x075200 + int cleanup_handle = 0; + if(!handle) { + handle = curl_easy_init(); + cleanup_handle = 1; + } +#endif + + char *unesc = curl_easy_unescape(handle, url, strlen(url), NULL); + char *ret = unesc ? strdup(unesc) : NULL; + curl_free(unesc); + +#if LIBCURL_VERSION_NUM < 0x075200 + if(cleanup_handle) { + curl_easy_cleanup(handle); + } +#endif + + return ret; +} + +cxmutstr util_url_encode_s(const CxAllocator *a, cxstring url) { + CURL *handle = NULL; +#if LIBCURL_VERSION_NUM < 0x075200 + handle = curl_easy_init(); +#endif + + char *esc = curl_easy_escape(handle, url.ptr, url.length); + cxmutstr ret = esc ? cx_strdup_a(a, cx_str(esc)) : (cxmutstr){NULL, 0}; + curl_free(esc); + +#if LIBCURL_VERSION_NUM < 0x075200 + curl_easy_cleanup(handle); +#endif + return ret; +} + +cxmutstr util_url_decode_s(const CxAllocator *a, cxstring url) { + CURL *handle = NULL; +#if LIBCURL_VERSION_NUM < 0x075200 + handle = curl_easy_init(); +#endif + + char *unesc = curl_easy_unescape(handle, url.ptr, url.length, NULL); + cxmutstr ret = unesc ? cx_strdup_a(a, cx_str(unesc)) : (cxmutstr){NULL, 0}; curl_free(unesc); + +#if LIBCURL_VERSION_NUM < 0x075200 + curl_easy_cleanup(handle); +#endif return ret; } @@ -1290,16 +1361,16 @@ char* util_file_hash(const char *path) { return NULL; } - DAV_SHA_CTX *sha = dav_hash_init(); + DAV_SHA_CTX *sha = dav_sha256_create(); char *buf = malloc(16384); size_t r; while((r = fread(buf, 1, 16384, in)) > 0) { - dav_hash_update(sha, buf, r); + dav_sha256_update(sha, buf, r); } unsigned char hash[DAV_SHA256_DIGEST_LENGTH]; - dav_hash_final(sha, hash); + dav_sha256_final(sha, hash); free(buf); fclose(in); diff --git a/libidav/utils.h b/libidav/utils.h index 8952c76..62a203a 100644 --- a/libidav/utils.h +++ b/libidav/utils.h @@ -76,7 +76,10 @@ char* util_url_base(const char *url); cxstring util_url_base_s(cxstring url); const char* util_url_path(const char *url); cxstring util_url_path_s(cxstring url); +char* util_url_encode(DavSession *sn, const char *url); char* util_url_decode(DavSession *sn, const char *url); +cxmutstr util_url_encode_s(const CxAllocator *a, cxstring url); +cxmutstr util_url_decode_s(const CxAllocator *a, cxstring url); const char* util_resource_name(const char *url); const char* util_resource_name_c(const char *url, char pathseparator); const char* util_path_file_name(const char *url); diff --git a/libidav/webdav.c b/libidav/webdav.c index 262e15c..1111bfb 100644 --- a/libidav/webdav.c +++ b/libidav/webdav.c @@ -353,8 +353,8 @@ int dav_context_remove_session(DavContext *context, DavSession *sn) { int ret = 0; dav_context_lock(context); CxList *sessions = context->sessions; - ssize_t i = cxListFind(sessions, sn); - if(i >= 0) { + size_t i = cxListFind(sessions, sn); + if(cxListIndexValid(sessions, i)) { cxListRemove(sessions, i); } else { ret = 1; -- 2.43.5