diff -r 6bd37fe6d905 -r ee4e4742391e libidav/config.c --- a/libidav/config.c Wed Oct 23 21:46:43 2024 +0200 +++ b/libidav/config.c Sun Oct 27 18:24:37 2024 +0100 @@ -79,7 +79,7 @@ static int load_secretstore(DavConfig *config, xmlNode *node); -int dav_cfg_string_set_value(DavConfig *config, CfgString *str, xmlNode *node) { +int dav_cfg_string_set_node_value(DavConfig *config, CfgString *str, xmlNode *node) { str->node = node; char *value = util_xml_get_text(node); if(value) { @@ -91,12 +91,111 @@ } } -void dav_cfg_bool_set_value(DavConfig *config, CfgBool *cbool, xmlNode *node) { +void dav_cfg_bool_set_node_value(DavConfig *config, CfgBool *cbool, xmlNode *node) { cbool->node = node; char *value = util_xml_get_text(node); cbool->value = util_getboolean(value); } +static void set_xml_content(xmlNode *node, const char *content) { + xmlNode *child = node->children; + while(child) { + xmlNode *next = child->next; + xmlUnlinkNode(child); + xmlFreeNode(child); + child = next; + } + + if(content) { + xmlChar *encoded = xmlEncodeSpecialChars(node->doc, (const xmlChar*)content); + if(encoded) { + xmlNodeSetContent(node, encoded); + xmlFree(encoded); + } + } +} + +void dav_cfg_string_set_value(DavConfig *config, CfgString *str, xmlNode *parent, cxstring new_value, const char *nodename) { + if(str->value.ptr) { + cxFree(config->mp->allocator, str->value.ptr); + } + if(new_value.ptr) { + str->value = cx_strdup_a(config->mp->allocator, new_value); + } else { + str->value = cx_mutstrn(NULL, 0); + } + + if(!str->node) { + str->node = xmlNewNode(NULL, (const xmlChar*) nodename); + xmlAddChild(parent, str->node); + } + set_xml_content(str->node, new_value.ptr); +} + +void dav_cfg_bool_set_value(DavConfig *config, CfgBool *cbool, xmlNode *parent, DavBool new_value, const char *nodename) { + const char *content = new_value ? "true" : "false"; + cbool->value = new_value; + if(!cbool->node) { + cbool->node = xmlNewNode(NULL, (const xmlChar*) nodename); + xmlAddChild(parent, cbool->node); + } + set_xml_content(cbool->node, content); +} + +void dav_cfg_int_set_value(DavConfig *config, CfgInt *cint, xmlNode *parent, int64_t new_value, const char *nodename) { + char content[32]; + snprintf(content, 32, "%" PRId64, new_value); + cint->value = new_value; + if(!cint->node) { + cint->node = xmlNewNode(NULL, (const xmlChar*) nodename); + xmlAddChild(parent, cint->node); + } + set_xml_content(cint->node, content); +} + +void dav_cfg_uint_set_value(DavConfig *config, CfgUInt *cint, xmlNode *parent, uint64_t new_value, const char *nodename) { + char content[32]; + snprintf(content, 32, "%" PRIu64, new_value); + cint->value = new_value; + if(!cint->node) { + cint->node = xmlNewNode(NULL, (const xmlChar*) nodename); + xmlAddChild(parent, cint->node); + } + set_xml_content(cint->node, content); +} + +void dav_cfg_string_remove(CfgString *str) { + if(str->node) { + xmlUnlinkNode(str->node); + xmlFreeNode(str->node); + str->node = NULL; + } +} + +void dav_cfg_bool_remove(CfgBool *cbool) { + if(cbool->node) { + xmlUnlinkNode(cbool->node); + xmlFreeNode(cbool->node); + cbool->node = NULL; + } +} + +void dav_cfg_int_remove(CfgInt *cint) { + if(cint->node) { + xmlUnlinkNode(cint->node); + xmlFreeNode(cint->node); + cint->node = NULL; + } +} + +void dav_cfg_uint_remove(CfgUInt *cint) { + if(cint->node) { + xmlUnlinkNode(cint->node); + xmlFreeNode(cint->node); + cint->node = NULL; + } +} + DavConfig* dav_config_new(xmlDoc *doc) { CxMempool *cfg_mp = cxMempoolCreate(128, NULL); @@ -212,55 +311,37 @@ } if(xstreq(key, "name")) { - dav_cfg_string_set_value(config, &repo->name, node); + dav_cfg_string_set_node_value(config, &repo->name, node); } else if(xstreq(key, "url")) { - dav_cfg_string_set_value(config, &repo->url, node); + dav_cfg_string_set_node_value(config, &repo->url, node); } else if(xstreq(key, "user")) { - dav_cfg_string_set_value(config, &repo->user, node); + dav_cfg_string_set_node_value(config, &repo->user, node); } else if(xstreq(key, "password")) { - dav_cfg_string_set_value(config, &repo->password, node); + dav_cfg_string_set_node_value(config, &repo->password, node); } else if(xstreq(key, "stored-user")) { - dav_cfg_string_set_value(config, &repo->stored_user, node); + dav_cfg_string_set_node_value(config, &repo->stored_user, node); } else if(xstreq(key, "default-key")) { - dav_cfg_string_set_value(config, &repo->default_key, node); + dav_cfg_string_set_node_value(config, &repo->default_key, node); } else if(xstreq(key, "full-encryption")) { - dav_cfg_bool_set_value(config, &repo->full_encryption, node); + dav_cfg_bool_set_node_value(config, &repo->full_encryption, node); } else if(xstreq(key, "content-encryption")) { - dav_cfg_bool_set_value(config, &repo->content_encryption, node); + dav_cfg_bool_set_node_value(config, &repo->content_encryption, node); } else if(xstreq(key, "decrypt-content")) { - dav_cfg_bool_set_value(config, &repo->decrypt_content, node); + dav_cfg_bool_set_node_value(config, &repo->decrypt_content, node); } else if(xstreq(key, "decrypt-name")) { - dav_cfg_bool_set_value(config, &repo->decrypt_name, node); + dav_cfg_bool_set_node_value(config, &repo->decrypt_name, node); } else if(xstreq(key, "cert")) { - dav_cfg_string_set_value(config, &repo->cert, node); + dav_cfg_string_set_node_value(config, &repo->cert, node); } else if(xstreq(key, "verification")) { - dav_cfg_bool_set_value(config, &repo->verification, node); + dav_cfg_bool_set_node_value(config, &repo->verification, node); } else if(xstreq(key, "ssl-version")) { repo->ssl_version.node = node; - if(xstrEQ(value, "TLSv1")) { - repo->ssl_version.value = CURL_SSLVERSION_TLSv1; - } else if(xstrEQ(value, "SSLv2")) { - repo->ssl_version.value = CURL_SSLVERSION_SSLv2; - } else if(xstrEQ(value, "SSLv3")) { - repo->ssl_version.value = CURL_SSLVERSION_SSLv3; - } -#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7034 - else if(xstrEQ(value, "TLSv1.0")) { - repo->ssl_version.value = CURL_SSLVERSION_TLSv1_0; - } else if(xstrEQ(value, "TLSv1.1")) { - repo->ssl_version.value = CURL_SSLVERSION_TLSv1_1; - } else if(xstrEQ(value, "TLSv1.2")) { - repo->ssl_version.value = CURL_SSLVERSION_TLSv1_2; - } -#endif -#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7052 - else if(xstrEQ(value, "TLSv1.3")) { - repo->ssl_version.value = CURL_SSLVERSION_TLSv1_3; - } -#endif - else { + int ssl_version = dav_str2ssl_version((const char*)value); + if(ssl_version == -1) { print_warning(lineno, "unknown ssl version: %s\n", value); repo->ssl_version.value = CURL_SSLVERSION_DEFAULT; + } else { + repo->ssl_version.value = ssl_version; } } else if(xstreq(key, "authmethods")) { repo->authmethods.node = node; @@ -295,6 +376,31 @@ return 0; } +int dav_str2ssl_version(const char *value) { + if(xstrEQ(value, "TLSv1")) { + return CURL_SSLVERSION_TLSv1; + } else if(xstrEQ(value, "SSLv2")) { + return CURL_SSLVERSION_SSLv2; + } else if(xstrEQ(value, "SSLv3")) { + return CURL_SSLVERSION_SSLv3; + } +#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7034 + else if(xstrEQ(value, "TLSv1.0")) { + return CURL_SSLVERSION_TLSv1_0; + } else if(xstrEQ(value, "TLSv1.1")) { + return CURL_SSLVERSION_TLSv1_1; + } else if(xstrEQ(value, "TLSv1.2")) { + return CURL_SSLVERSION_TLSv1_2; + } +#endif +#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7052 + else if(xstrEQ(value, "TLSv1.3")) { + return CURL_SSLVERSION_TLSv1_3; + } +#endif + return -1; +} + static int load_repository( DavConfig *config, DavCfgRepository **list_begin, @@ -520,9 +626,9 @@ while(node) { if(node->type == XML_ELEMENT_NODE) { if(xstreq(node->name, "name")) { - dav_cfg_string_set_value(config, &key->name, node); + dav_cfg_string_set_node_value(config, &key->name, node); } else if(xstreq(node->name, "file")) { - dav_cfg_string_set_value(config, &key->file, node); + dav_cfg_string_set_node_value(config, &key->file, node); } else if(xstreq(node->name, "type")) { const char *value = util_xml_get_text(node); key->type_node = node; @@ -613,13 +719,13 @@ if(node->type == XML_ELEMENT_NODE) { int reportmissingvalue = 0; if(xstreq(node->name, "url")) { - reportmissingvalue = dav_cfg_string_set_value(config, &proxy->url, node); + reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->url, node); } else if(xstreq(node->name, "user")) { - reportmissingvalue = dav_cfg_string_set_value(config, &proxy->user, node); + reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->user, node); } else if(xstreq(node->name, "password")) { - reportmissingvalue = dav_cfg_string_set_value(config, &proxy->password, node); + reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->password, node); } else if(xstreq(node->name, "no")) { - reportmissingvalue = dav_cfg_string_set_value(config, &proxy->noproxy, node); + reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->noproxy, node); } else { proxy->unknown_elements++; } @@ -724,9 +830,9 @@ while(node) { if(node->type == XML_ELEMENT_NODE) { if(xstreq(node->name, "unlock-command")) { - dav_cfg_string_set_value(config, &config->secretstore->unlock_cmd, node); + dav_cfg_string_set_node_value(config, &config->secretstore->unlock_cmd, node); } else if(xstreq(node->name, "lock-command")) { - dav_cfg_string_set_value(config, &config->secretstore->lock_cmd, node); + dav_cfg_string_set_node_value(config, &config->secretstore->lock_cmd, node); } } node = node->next;