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 } |