diff -r 6518b035a9df -r 03076907b58a libidav/methods.c
--- a/libidav/methods.c Tue Mar 18 13:59:02 2014 +0100
+++ b/libidav/methods.c Thu Jun 05 15:11:29 2014 +0200
@@ -33,6 +33,8 @@
#include "utils.h"
#include "methods.h"
#include "davql.h"
+#include "crypto.h"
+#include "session.h"
#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
@@ -80,16 +82,38 @@
return buf;
}
-UcxBuffer* create_propfind_request(UcxList *properties) {
+UcxBuffer* create_propfind_request(DavSession *sn, UcxList *properties) {
UcxBuffer *buf = ucx_buffer_new(NULL, 512, 0);
sstr_t s;
+ int add_crypto_name = 1;
+ int add_crypto_key = 1;
+ char *crypto_ns = "idav";
UcxMap *namespaces = ucx_map_new(8);
UCX_FOREACH(elm, properties) {
DavProperty *p = elm->data;
if(strcmp(p->ns->name, "DAV:")) {
ucx_map_cstr_put(namespaces, p->ns->prefix, p->ns);
}
+
+ // if the properties list contains the idav properties crypto-name
+ // and crypto-key, mark them as existent
+ if(!strcmp(p->ns->name, DAV_NS)) {
+ if(!strcmp(p->name, "crypto-name")) {
+ add_crypto_name = 0;
+ crypto_ns = p->ns->prefix;
+ } else if(!strcmp(p->name, "crypto-key")) {
+ add_crypto_key = 0;
+ crypto_ns = p->ns->prefix;
+ }
+ }
+ }
+
+ DavNamespace idav_ns;
+ if(add_crypto_name && add_crypto_key && DAV_CRYPTO(sn)) {
+ idav_ns.prefix = "idav";
+ idav_ns.name = DAV_NS;
+ ucx_map_cstr_put(namespaces, "idav", &idav_ns);
}
s = S("\n");
@@ -129,6 +153,22 @@
s = S("\n");
ucx_buffer_write(s.ptr, 1, s.length, buf);
+ // crypto properties
+ if(DAV_CRYPTO(sn)) {
+ if(add_crypto_name) {
+ ucx_buffer_putc(buf, '<');
+ ucx_buffer_puts(buf, crypto_ns);
+ s = S(":crypto-name />\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ }
+ if(add_crypto_key) {
+ ucx_buffer_putc(buf, '<');
+ ucx_buffer_puts(buf, crypto_ns);
+ s = S(":crypto-key />\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ }
+ }
+
// extra properties
UCX_FOREACH(elm, properties) {
DavProperty *prop = elm->data;
@@ -151,11 +191,44 @@
return buf;
}
+UcxBuffer* create_basic_propfind_request() {
+ UcxBuffer *buf = ucx_buffer_new(NULL, 512, 0);
+ sstr_t s;
+
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ // properties
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ // end
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ return buf;
+}
+
DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len) {
char *url = NULL;
curl_easy_getinfo(sn->handle, CURLINFO_EFFECTIVE_URL, &url);
if(!root) {
- root = dav_resource_new_href(sn, util_url_path(url));
+ root = dav_resource_new_href(sn, util_url_path(url)); // TODO: remove
}
xmlDoc *doc = xmlReadMemory(response->space, response->size, url, NULL, 0);
@@ -181,7 +254,17 @@
}
int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t clen) {
- DavResource *res = resource;
+ DavSession *sn = resource->session;
+
+ //DavResource *res = resource;
+ DavResource *res = NULL;
+ char *href = NULL;
+ UcxList *properties = NULL; // xmlNode list
+ char *crypto_name = NULL; // name set by crypto-name property
+ char *crypto_key = NULL;
+
+ int iscollection = 0; // TODO: remove
+
node = node->children;
while(node) {
if(node->type == XML_ELEMENT_NODE) {
@@ -189,16 +272,16 @@
xmlNode *href_node = node->children;
if(href_node->type != XML_TEXT_NODE) {
// error
- resource->session->error = DAV_ERROR;
+ sn->error = DAV_ERROR;
return 1;
}
- char *href = (char*)href_node->content;
- href = util_url_path(href);
+ //char *href = (char*)href_node->content;
+ href = util_url_path((char*)href_node->content);
if(xstreq(resource->href, href)) {
res = resource;
} else {
- res = dav_resource_new_href(resource->session, href);
- res->parent = resource;
+ //res = dav_resource_new_href(resource->session, href);
+ //res->parent = resource;
}
} else if(xstreq(node->name, "propstat")) {
xmlNode *n = node->children;
@@ -212,12 +295,12 @@
} else if(xstreq(n->name, "status")) {
xmlNode *status_node = n->children;
if(status_node->type != XML_TEXT_NODE) {
- resource->session->error = DAV_ERROR;
+ sn->error = DAV_ERROR;
return 1;
}
sstr_t status_str = sstr((char*)status_node->content);
if(status_str.length < 13) {
- resource->session->error = DAV_ERROR;
+ sn->error = DAV_ERROR;
return 1;
}
status_str = sstrsubsl(status_str, 9, 3);
@@ -233,21 +316,19 @@
n = prop_node->children;
while(n) {
if(n->type == XML_ELEMENT_NODE) {
+ properties = ucx_list_append(properties, n);
if(xstreq(n->name, "resourcetype")) {
xmlNode *rsnode = n->children;
if(rsnode && rsnode->type == XML_ELEMENT_NODE) {
// TODO: this is a ugly lazy hack
- resource_add_property(res, "DAV:", (char*)n->name, "collection");
- res->iscollection = 1;
+ //resource_add_property(res, "DAV:", (char*)n->name, "collection");
+ iscollection = 1;
}
- } else {
- xmlNode *content = n->children;
- if(content) {
- resource_add_property(
- res,
- (char*)n->ns->href,
- (char*)n->name,
- (char*)content->content);
+ } else if(xstreq(n->ns->href, DAV_NS)) {
+ if(xstreq(n->name, "crypto-name")) {
+ crypto_name = util_xml_get_text(n);
+ } else if(xstreq(n->name, "crypto-key")) {
+ crypto_key = util_xml_get_text(n);
}
}
}
@@ -260,6 +341,39 @@
node = node->next;
}
+ if(!res) {
+ // create new resource object
+ char *name = NULL;
+ if(DAV_DECRYPT_NAME(sn) && crypto_name) {
+ if(!crypto_key) {
+ // TODO: error
+ fprintf(stderr, "encrypted resource without key\n");
+ }
+ name = util_decrypt_str(sn, crypto_name, crypto_key);
+ if(!name) {
+ // TODO: error
+ fprintf(stderr, "decrypted name is null\n");
+ }
+ } else {
+ name = util_resource_name(href);
+ }
+
+ href = dav_session_strdup(sn, href);
+ res = dav_resource_new_full(sn, resource->path, name, href);
+ }
+ res->iscollection = iscollection;
+
+ // add properties
+ UCX_FOREACH(elm, properties) {
+ xmlNode *prop = elm->data;
+
+ // TODO: add xml data instead of a string
+ char *text = util_xml_get_text(prop);
+ if(text) {
+ resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, text);
+ }
+ }
+
set_davprops(res);
if(res != resource) {
if(clen > 0) {
@@ -436,6 +550,41 @@
return buf;
}
+UcxBuffer* create_crypto_proppatch_request(DavSession *sn, DavKey *key, char *name) {
+ UcxBuffer *buf = ucx_buffer_new(NULL, 512, 0);
+ sstr_t s;
+
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ s = S("\n\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ if(DAV_ENCRYPT_NAME(sn)) {
+ s = S("");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ char *crname = aes_encrypt(name, key);
+ ucx_buffer_puts(buf, crname);
+ free(crname);
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ }
+
+ s = S("");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+ ucx_buffer_puts(buf, key->name);
+ s = S("\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ s = S("\n\n\n");
+ ucx_buffer_write(s.ptr, 1, s.length, buf);
+
+ return buf;
+}
+
/* ----------------------------- PUT ----------------------------- */
static size_t dummy_write(void *buf, size_t s, size_t n, void *data) {
@@ -448,6 +597,10 @@
curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
+ // clear headers
+ struct curl_slist *headers = NULL;
+ curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
+
UcxBuffer *buf = NULL;
if(!read_func) {
buf = ucx_buffer_new(data, length, 0);
@@ -478,6 +631,9 @@
}
CURLcode do_delete_request(CURL *handle, UcxBuffer *response) {
+ struct curl_slist *headers = NULL;
+ curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
+
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(handle, CURLOPT_PUT, 0L);
curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
@@ -491,6 +647,9 @@
}
CURLcode do_mkcol_request(CURL *handle) {
+ struct curl_slist *headers = NULL;
+ curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
+
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "MKCOL");
curl_easy_setopt(handle, CURLOPT_PUT, 0L);
curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);