1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2018 Olaf Wintermann. All rights reserved. |
4 * Copyright 2019 Olaf Wintermann. All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
515 locked = TRUE; |
515 locked = TRUE; |
516 locktokenfile = create_locktoken_file(dir->name, lock->token); |
516 locktokenfile = create_locktoken_file(dir->name, lock->token); |
517 } |
517 } |
518 |
518 |
519 int ret = 0; |
519 int ret = 0; |
520 DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags,idav:finfo,idav:xattributes from / with depth = infinity"); |
520 DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags,idav:finfo,idav:xattributes,idav:content-hash from / with depth = infinity"); |
521 if(!ls) { |
521 if(!ls) { |
522 print_resource_error(sn, "/"); |
522 print_resource_error(sn, "/"); |
523 if(locked) { |
523 if(locked) { |
524 if(dav_unlock(root)) { |
524 if(dav_unlock(root)) { |
525 print_resource_error(sn, "/"); |
525 print_resource_error(sn, "/"); |
2053 } |
2053 } |
2054 |
2054 |
2055 int ret = 0; |
2055 int ret = 0; |
2056 if(err == 0) { |
2056 if(err == 0) { |
2057 char *etag = dav_get_string_property(remote, "D:getetag"); |
2057 char *etag = dav_get_string_property(remote, "D:getetag"); |
2058 char *hash = dav_get_string_property(remote, "idav:content-hash"); |
2058 char *hash = sync_get_content_hash(remote); |
2059 if(hash || res->hash) { |
2059 if(hash || res->hash) { |
2060 if(!nullstrcmp(hash, res->hash)) { |
2060 if(!nullstrcmp(hash, res->hash)) { |
2061 ret = 1; |
2061 ret = 1; |
2062 } |
2062 } |
2063 } else if(!res->etag) { |
2063 } else if(!res->etag) { |
2808 } |
2808 } |
2809 |
2809 |
2810 // set content-hash |
2810 // set content-hash |
2811 char content_hash[DAV_SHA256_DIGEST_LENGTH]; |
2811 char content_hash[DAV_SHA256_DIGEST_LENGTH]; |
2812 dav_hash_final(sha, content_hash); |
2812 dav_hash_final(sha, content_hash); |
2813 char *hash_hex = util_hexstr(content_hash, DAV_SHA256_DIGEST_LENGTH); |
2813 sync_set_content_hash(res, content_hash); |
2814 dav_set_string_property_ns(res, DAV_NS, "content-hash", hash_hex); |
2814 local->hash = util_hexstr(content_hash, DAV_SHA256_DIGEST_LENGTH); |
2815 local->hash = hash_hex; |
|
2816 |
2815 |
2817 // get etags from uploaded resources |
2816 // get etags from uploaded resources |
2818 // also delete everything, that is not part of the file |
2817 // also delete everything, that is not part of the file |
2819 UcxList *updated_parts = NULL; |
2818 UcxList *updated_parts = NULL; |
2820 DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path); |
2819 DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path); |
4132 free(path); |
4131 free(path); |
4133 return NULL; |
4132 return NULL; |
4134 } |
4133 } |
4135 } |
4134 } |
4136 |
4135 |
|
4136 char* sync_get_content_hash(DavResource *res) { |
|
4137 uint32_t flags = res->session->flags; |
|
4138 if((flags & DAV_SESSION_ENCRYPT_CONTENT) == DAV_SESSION_ENCRYPT_CONTENT) { |
|
4139 char *enc_hash = dav_get_string_property_ns(res, DAV_NS, "crypto-hash"); |
|
4140 char *keyname = dav_get_string_property_ns(res, DAV_NS, "crypto-key"); |
|
4141 if(enc_hash && keyname) { |
|
4142 DavKey *key = dav_context_get_key(res->session->context, keyname); |
|
4143 if(!key) { |
|
4144 return NULL; |
|
4145 } |
|
4146 |
|
4147 size_t len = 0; |
|
4148 char *dec_hash = aes_decrypt(enc_hash, &len, key); |
|
4149 if(!dec_hash) { |
|
4150 return NULL; |
|
4151 } |
|
4152 |
|
4153 char *hex_hash = util_hexstr((unsigned char*)dec_hash, len); |
|
4154 free(dec_hash); |
|
4155 return hex_hash; |
|
4156 } |
|
4157 } else { |
|
4158 return dav_get_string_property_ns(res, DAV_NS, "content-hash"); |
|
4159 } |
|
4160 return NULL; |
|
4161 } |
|
4162 |
|
4163 void sync_set_content_hash(DavResource *res, const char *hashdata) { |
|
4164 uint32_t flags = res->session->flags; |
|
4165 if((flags & DAV_SESSION_ENCRYPT_CONTENT) == DAV_SESSION_ENCRYPT_CONTENT) { |
|
4166 if(res->session->key) { |
|
4167 char *enc_hash = aes_encrypt(hashdata, DAV_SHA256_DIGEST_LENGTH, res->session->key); |
|
4168 if(enc_hash) { |
|
4169 dav_set_string_property_ns(res, DAV_NS, "crypto-hash", enc_hash); |
|
4170 free(enc_hash); |
|
4171 } |
|
4172 } |
|
4173 } else { |
|
4174 char *hex_hash = util_hexstr((const unsigned char*)hashdata, DAV_SHA256_DIGEST_LENGTH); |
|
4175 dav_set_string_property_ns(res, DAV_NS, "content-hash", hex_hash); |
|
4176 free(hex_hash); |
|
4177 } |
|
4178 } |