libidav/resource.c

changeset 150
37fb12574acd
parent 146
e48048334602
child 151
a316613205dc
equal deleted inserted replaced
149:509e9e1cbdcc 150:37fb12574acd
82 res->session = sn; 82 res->session = sn;
83 83
84 // set name, path and href 84 // set name, path and href
85 sstr_t n = sstr(name); 85 sstr_t n = sstr(name);
86 res->name = sstrdup_a(sn->mp->allocator, n).ptr; 86 res->name = sstrdup_a(sn->mp->allocator, n).ptr;
87 if(n.ptr[n.length-1] == '/') { 87 if(n.length > 0 && n.ptr[n.length-1] == '/') {
88 res->name[n.length-1] = '\0'; 88 res->name[n.length-1] = '\0';
89 } 89 }
90 90
91 char *path = util_concat_path(parent_path, name); 91 char *path = util_concat_path(parent_path, name);
92 res->path = dav_session_strdup(sn, path); 92 res->path = dav_session_strdup(sn, path);
568 sn->key, 568 sn->key,
569 buf, 569 buf,
570 (dav_read_func)ucx_buffer_read); 570 (dav_read_func)ucx_buffer_read);
571 } 571 }
572 572
573 // create an empty resource 573 // put resource
574 ret = do_put_request( 574 ret = do_put_request(
575 sn->handle, 575 sn->handle,
576 enc, 576 enc,
577 (dav_read_func)aes_read, 577 (dav_read_func)aes_read,
578 0); 578 0);
579
580 // get sha256 hash
581 char sha[SHA256_DIGEST_LENGTH];
582 dav_get_hash(&enc->sha256, sha);
583 char *enc_hash = aes_encrypt(sha, SHA256_DIGEST_LENGTH, sn->key);
584
579 aes_encrypter_close(enc); 585 aes_encrypter_close(enc);
580 if(buf) { 586 if(buf) {
581 ucx_buffer_free(buf); 587 ucx_buffer_free(buf);
582 } 588 }
583 589
584 // add crypto properties 590 // add crypto properties
585 // TODO: store the properties later 591 // TODO: store the properties later
586 if(resource_add_crypto_info(sn, res->href, res->name)) { 592 if(resource_add_crypto_info(sn, res->href, res->name, enc_hash)) {
593 free(enc_hash);
587 return 1; 594 return 1;
588 } 595 }
596 resource_add_property(res, DAV_NS, "crypto-hash", enc_hash);
597 free(enc_hash);
589 } else { 598 } else {
590 ret = do_put_request( 599 ret = do_put_request(
591 sn->handle, 600 sn->handle,
592 data->content, 601 data->content,
593 data->read, 602 data->read,
661 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_fnc); 670 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_fnc);
662 curl_easy_setopt(handle, CURLOPT_WRITEDATA, stream); 671 curl_easy_setopt(handle, CURLOPT_WRITEDATA, stream);
663 672
664 CURLcode ret = curl_easy_perform(handle); 673 CURLcode ret = curl_easy_perform(handle);
665 674
675 char *hash = NULL;
666 if(dec) { 676 if(dec) {
677 // get hash
678 char sha[SHA256_DIGEST_LENGTH];
679 dav_get_hash(&dec->sha256, sha);
680 hash = util_hexstr(sha, 32);
681
667 aes_decrypter_close(dec); 682 aes_decrypter_close(dec);
668 } 683 }
669 684
670 int status = 0; 685 int status = 0;
671 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 686 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
672 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 687 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
688 int verify_failed = 0;
689 if(DAV_DECRYPT_CONTENT(sn)) {
690 // try to verify the content
691 char *res_hash = dav_get_property_ns(res, DAV_NS, "crypto-hash");
692
693 if(res_hash) {
694 size_t len = 0;
695 char *dec_hash = aes_decrypt(res_hash, &len, sn->key);
696 char *hex_hash = util_hexstr(dec_hash, 32);
697 if(strcmp(hash, hex_hash)) {
698 verify_failed = 1;
699 }
700 free(dec_hash);
701 free(hex_hash);
702 }
703 }
704
705 if(verify_failed) {
706 res->session->error = DAV_CONTENT_VERIFICATION_ERROR;
707 return 1;
708 }
709
673 res->session->error = DAV_OK; 710 res->session->error = DAV_OK;
674 return 0; 711 return 0;
675 } else { 712 } else {
676 dav_session_set_error(res->session, ret, status); 713 dav_session_set_error(res->session, ret, status);
677 return 1; 714 return 1;
731 char *name = util_resource_name(p); 768 char *name = util_resource_name(p);
732 int len = strlen(name); 769 int len = strlen(name);
733 if(name[len - 1] == '/') { 770 if(name[len - 1] == '/') {
734 name[len - 1] = '\0'; 771 name[len - 1] = '\0';
735 } 772 }
736 if(resource_add_crypto_info(sn, h, name)) { 773 if(resource_add_crypto_info(sn, h, name, NULL)) {
737 // TODO: error 774 // TODO: error
738 } 775 }
739 break; 776 break;
740 } else if(status == 405) { 777 } else if(status == 405) {
741 // parent already exists 778 // parent already exists
773 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &s); 810 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &s);
774 *status = s; 811 *status = s;
775 if(code == CURLE_OK && (s >= 200 && s < 300)) { 812 if(code == CURLE_OK && (s >= 200 && s < 300)) {
776 sn->error = DAV_OK; 813 sn->error = DAV_OK;
777 // if the session has encrypted file names, add crypto infos 814 // if the session has encrypted file names, add crypto infos
778 resource_add_crypto_info(sn, res->href, res->name); // TODO: check return type 815 resource_add_crypto_info(sn, res->href, res->name, NULL); // TODO: check return type
779 816
780 // do a minimal propfind request 817 // do a minimal propfind request
781 UcxBuffer *rqbuf = create_propfind_request(sn, NULL); 818 UcxBuffer *rqbuf = create_propfind_request(sn, NULL);
782 int ret = dav_propfind(sn, res, rqbuf); 819 int ret = dav_propfind(sn, res, rqbuf);
783 ucx_buffer_free(rqbuf); 820 ucx_buffer_free(rqbuf);
820 return 0; 857 return 0;
821 } 858 }
822 } 859 }
823 860
824 861
825 int resource_add_crypto_info(DavSession *sn, char *href, char *name) { 862 int resource_add_crypto_info(DavSession *sn, char *href, char *name, char *hash) {
826 if(!DAV_IS_ENCRYPTED(sn)) { 863 if(!DAV_IS_ENCRYPTED(sn)) {
827 return 0; 864 return 0;
828 } 865 }
829 866
830 UcxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name); 867 UcxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash);
831 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 868 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
832 869
833 util_set_url(sn, href); 870 util_set_url(sn, href);
834 CURLcode ret = do_proppatch_request(sn->handle, request, response); 871 CURLcode ret = do_proppatch_request(sn->handle, request, response);
872 ucx_buffer_free(request);
835 int status = 0; 873 int status = 0;
836 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); 874 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
837 if(ret == CURLE_OK && status == 207) { 875 if(ret == CURLE_OK && status == 207) {
838 // TODO: parse response 876 // TODO: parse response
839 sn->error = DAV_OK; 877 sn->error = DAV_OK;
878 ucx_buffer_free(response);
840 return 0; 879 return 0;
841 } else { 880 } else {
842 dav_session_set_error(sn, ret, status); 881 dav_session_set_error(sn, ret, status);
882 ucx_buffer_free(response);
843 return 1; 883 return 1;
844 } 884 }
845 } 885 }

mercurial