aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-12-14 22:15:55 +0000
committerChristian Grothoff <christian@grothoff.org>2014-12-14 22:15:55 +0000
commit6c8fa85819a2b02b3c4a175a08c1779283eda209 (patch)
tree3d635a2aa58f321fbb8779b6e086113558dc1c52
parent6d7c1dd00a193fc054d1f1588ae7c98dc95b6257 (diff)
downloadgnunet-6c8fa85819a2b02b3c4a175a08c1779283eda209.tar.gz
gnunet-6c8fa85819a2b02b3c4a175a08c1779283eda209.zip
fix key management issue with LOC signing identified in #3559
-rw-r--r--src/fs/Makefile.am3
-rw-r--r--src/fs/fs.h71
-rw-r--r--src/fs/fs_api.h46
-rw-r--r--src/fs/fs_publish.c148
-rw-r--r--src/fs/fs_uri.c45
-rw-r--r--src/fs/gnunet-service-fs.c195
-rw-r--r--src/fs/gnunet-service-fs_lc.c40
-rw-r--r--src/fs/test_fs_uri.c32
-rw-r--r--src/fs/test_fs_uri_data.conf5
-rw-r--r--src/include/gnunet_fs_service.h28
-rw-r--r--src/include/gnunet_protocols.h12
11 files changed, 454 insertions, 171 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 1dd6065f0..39c9e3c85 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -380,7 +380,7 @@ test_fs_search_with_and_SOURCES = \
380test_fs_search_with_and_LDADD = \ 380test_fs_search_with_and_LDADD = \
381 $(top_builddir)/src/testing/libgnunettesting.la \ 381 $(top_builddir)/src/testing/libgnunettesting.la \
382 libgnunetfs.la \ 382 libgnunetfs.la \
383 $(top_builddir)/src/util/libgnunetutil.la 383 $(top_builddir)/src/util/libgnunetutil.la
384 384
385test_fs_search_probes_SOURCES = \ 385test_fs_search_probes_SOURCES = \
386 test_fs_search_probes.c 386 test_fs_search_probes.c
@@ -525,7 +525,6 @@ EXTRA_DIST = \
525 test_fs_publish_data.conf \ 525 test_fs_publish_data.conf \
526 test_fs_search_data.conf \ 526 test_fs_search_data.conf \
527 test_fs_unindex_data.conf \ 527 test_fs_unindex_data.conf \
528 test_fs_uri_data.conf \
529 test_gnunet_service_fs_migration_data.conf \ 528 test_gnunet_service_fs_migration_data.conf \
530 test_gnunet_service_fs_p2p_cadet.conf \ 529 test_gnunet_service_fs_p2p_cadet.conf \
531 test_gnunet_fs_idx_data.conf \ 530 test_gnunet_fs_idx_data.conf \
diff --git a/src/fs/fs.h b/src/fs/fs.h
index ae6ca489a..5fa4261b2 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -66,6 +66,77 @@ struct ContentHashKey
66 66
67GNUNET_NETWORK_STRUCT_BEGIN 67GNUNET_NETWORK_STRUCT_BEGIN
68 68
69
70/**
71 * Message sent from a GNUnet (fs) publishing activity to sign
72 * a LOC URI.
73 */
74struct RequestLocSignatureMessage
75{
76
77 /**
78 * Message type will be #GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGN.
79 */
80 struct GNUNET_MessageHeader header;
81
82 /**
83 * Requested signature purpose. For now, always
84 * #GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT.
85 */
86 uint32_t purpose GNUNET_PACKED;
87
88 /**
89 * Requested expiration time.
90 */
91 struct GNUNET_TIME_AbsoluteNBO expiration_time;
92
93 /**
94 * Information about the shared file (to be signed).
95 */
96 struct ContentHashKey chk;
97
98 /**
99 * Size of the shared file (to be signed).
100 */
101 uint64_t file_length;
102};
103
104
105/**
106 * Message sent from the service with the signed LOC URI.
107 */
108struct ResponseLocSignatureMessage
109{
110
111 /**
112 * Message type will be
113 * #GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGNATURE.
114 */
115 struct GNUNET_MessageHeader header;
116
117 /**
118 * Purpose of the generated signature. For now, always
119 * #GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT.
120 */
121 uint32_t purpose GNUNET_PACKED;
122
123 /**
124 * Expiration time that was actually used (rounded!).
125 */
126 struct GNUNET_TIME_AbsoluteNBO expiration_time;
127
128 /**
129 * The requested signature.
130 */
131 struct GNUNET_CRYPTO_EddsaSignature signature;
132
133 /**
134 * Identity of the peer sharing the file.
135 */
136 struct GNUNET_PeerIdentity peer;
137};
138
139
69/** 140/**
70 * Message sent from a GNUnet (fs) publishing activity to the 141 * Message sent from a GNUnet (fs) publishing activity to the
71 * gnunet-fs-service to initiate indexing of a file. The service is 142 * gnunet-fs-service to initiate indexing of a file. The service is
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h
index 46f398e86..157662a65 100644
--- a/src/fs/fs_api.h
+++ b/src/fs/fs_api.h
@@ -416,15 +416,17 @@ struct GNUNET_FS_FileInformation
416 * @param cls closure 416 * @param cls closure
417 * @param client handle to use for FS communication 417 * @param client handle to use for FS communication
418 */ 418 */
419typedef void (*GNUNET_FS_QueueStart) (void *cls, 419typedef void
420 struct GNUNET_CLIENT_Connection * client); 420(*GNUNET_FS_QueueStart) (void *cls,
421 struct GNUNET_CLIENT_Connection *client);
421 422
422 423
423/** 424/**
424 * The job must now stop to run and should destry the client handle as 425 * The job must now stop to run and should destry the client handle as
425 * soon as possible (ideally prior to returning). 426 * soon as possible (ideally prior to returning).
426 */ 427 */
427typedef void (*GNUNET_FS_QueueStop) (void *cls); 428typedef void
429(*GNUNET_FS_QueueStop) (void *cls);
428 430
429 431
430 432
@@ -680,7 +682,7 @@ GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qe);
680 * that the caller might need to go backwards 682 * that the caller might need to go backwards
681 * a bit at times 683 * a bit at times
682 * @param max maximum number of bytes that should be 684 * @param max maximum number of bytes that should be
683 * copied to buf; readers are not allowed 685 * copied to @a buf; readers are not allowed
684 * to provide less data unless there is an error; 686 * to provide less data unless there is an error;
685 * a value of "0" will be used at the end to allow 687 * a value of "0" will be used at the end to allow
686 * the reader to clean up its internal state 688 * the reader to clean up its internal state
@@ -689,12 +691,15 @@ GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qe);
689 * @return number of bytes written, usually "max", 0 on error 691 * @return number of bytes written, usually "max", 0 on error
690 */ 692 */
691size_t 693size_t
692GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf, 694GNUNET_FS_data_reader_file_ (void *cls,
695 uint64_t offset,
696 size_t max,
697 void *buf,
693 char **emsg); 698 char **emsg);
694 699
695 700
696/** 701/**
697 * Create the closure for the 'GNUNET_FS_data_reader_file_' callback. 702 * Create the closure for the #GNUNET_FS_data_reader_file_() callback.
698 * 703 *
699 * @param filename file to read 704 * @param filename file to read
700 * @return closure to use 705 * @return closure to use
@@ -712,23 +717,26 @@ GNUNET_FS_make_file_reader_context_ (const char *filename);
712 * that the caller might need to go backwards 717 * that the caller might need to go backwards
713 * a bit at times 718 * a bit at times
714 * @param max maximum number of bytes that should be 719 * @param max maximum number of bytes that should be
715 * copied to buf; readers are not allowed 720 * copied to @a buf; readers are not allowed
716 * to provide less data unless there is an error; 721 * to provide less data unless there is an error;
717 * a value of "0" will be used at the end to allow 722 * a value of "0" will be used at the end to allow
718 * the reader to clean up its internal state 723 * the reader to clean up its internal state
719 * @param buf where the reader should write the data 724 * @param buf where the reader should write the data
720 * @param emsg location for the reader to store an error message 725 * @param emsg location for the reader to store an error message
721 * @return number of bytes written, usually "max", 0 on error 726 * @return number of bytes written, usually @a max, 0 on error
722 */ 727 */
723size_t 728size_t
724GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf, 729GNUNET_FS_data_reader_copy_ (void *cls,
730 uint64_t offset,
731 size_t max,
732 void *buf,
725 char **emsg); 733 char **emsg);
726 734
727 735
728/** 736/**
729 * Notification of FS that a search probe has made progress. 737 * Notification of FS that a search probe has made progress.
730 * This function is used INSTEAD of the client's event handler 738 * This function is used INSTEAD of the client's event handler
731 * for downloads where the GNUNET_FS_DOWNLOAD_IS_PROBE flag is set. 739 * for downloads where the #GNUNET_FS_DOWNLOAD_IS_PROBE flag is set.
732 * 740 *
733 * @param cls closure, always NULL (!), actual closure 741 * @param cls closure, always NULL (!), actual closure
734 * is in the client-context of the info struct 742 * is in the client-context of the info struct
@@ -738,7 +746,7 @@ GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf,
738 * for this operation; should be set to NULL for 746 * for this operation; should be set to NULL for
739 * SUSPEND and STOPPED events). The value returned 747 * SUSPEND and STOPPED events). The value returned
740 * will be passed to future callbacks in the respective 748 * will be passed to future callbacks in the respective
741 * field in the GNUNET_FS_ProgressInfo struct. 749 * field in the `struct GNUNET_FS_ProgressInfo`.
742 */ 750 */
743void * 751void *
744GNUNET_FS_search_probe_progress_ (void *cls, 752GNUNET_FS_search_probe_progress_ (void *cls,
@@ -764,7 +772,8 @@ GNUNET_FS_publish_main_ (void *cls,
764 * @param file_id computed hash, NULL on error 772 * @param file_id computed hash, NULL on error
765 */ 773 */
766void 774void
767GNUNET_FS_unindex_process_hash_ (void *cls, const struct GNUNET_HashCode * file_id); 775GNUNET_FS_unindex_process_hash_ (void *cls,
776 const struct GNUNET_HashCode *file_id);
768 777
769 778
770/** 779/**
@@ -890,6 +899,7 @@ GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc);
890void 899void
891GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr); 900GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr);
892 901
902
893/** 903/**
894 * Remove serialization/deserialization file from disk. 904 * Remove serialization/deserialization file from disk.
895 * 905 *
@@ -898,7 +908,8 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr);
898 * @param ent entity identifier 908 * @param ent entity identifier
899 */ 909 */
900void 910void
901GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, const char *ext, 911GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h,
912 const char *ext,
902 const char *ent); 913 const char *ent);
903 914
904 915
@@ -991,7 +1002,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc);
991 * Create SUSPEND event for the given publish operation 1002 * Create SUSPEND event for the given publish operation
992 * and then clean up our state (without stop signal). 1003 * and then clean up our state (without stop signal).
993 * 1004 *
994 * @param cls the 'struct GNUNET_FS_PublishContext' to signal for 1005 * @param cls the `struct GNUNET_FS_PublishContext` to signal for
995 */ 1006 */
996void 1007void
997GNUNET_FS_publish_signal_suspend_ (void *cls); 1008GNUNET_FS_publish_signal_suspend_ (void *cls);
@@ -1021,7 +1032,7 @@ GNUNET_FS_download_signal_suspend_ (void *cls);
1021 * Create SUSPEND event for the given unindex operation 1032 * Create SUSPEND event for the given unindex operation
1022 * and then clean up our state (without stop signal). 1033 * and then clean up our state (without stop signal).
1023 * 1034 *
1024 * @param cls the 'struct GNUNET_FS_UnindexContext' to signal for 1035 * @param cls the `struct GNUNET_FS_UnindexContext` to signal for
1025 */ 1036 */
1026void 1037void
1027GNUNET_FS_unindex_signal_suspend_ (void *cls); 1038GNUNET_FS_unindex_signal_suspend_ (void *cls);
@@ -1212,6 +1223,11 @@ struct GNUNET_FS_PublishContext
1212 struct GNUNET_FS_Handle *h; 1223 struct GNUNET_FS_Handle *h;
1213 1224
1214 /** 1225 /**
1226 * Connection to FS service (only used for LOC URI signing).
1227 */
1228 struct GNUNET_CLIENT_Handle *fs_client;
1229
1230 /**
1215 * Our top-level activity entry (if we are top-level, otherwise NULL). 1231 * Our top-level activity entry (if we are top-level, otherwise NULL).
1216 */ 1232 */
1217 struct TopLevelActivity *top; 1233 struct TopLevelActivity *top;
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index beeab8b12..a8a9a220f 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -823,6 +823,116 @@ hash_for_index_cb (void *cls,
823 823
824 824
825/** 825/**
826 * We've computed the CHK/LOC URI, now publish the KSKs (if applicable).
827 *
828 * @param pc publishing context to do this for
829 */
830static void
831publish_kblocks (struct GNUNET_FS_PublishContext *pc)
832{
833 struct GNUNET_FS_FileInformation *p;
834
835 p = pc->fi_pos;
836 /* upload of "p" complete, publish KBlocks! */
837 if (NULL != p->keywords)
838 {
839 pc->ksk_pc = GNUNET_FS_publish_ksk (pc->h,
840 p->keywords,
841 p->meta,
842 p->chk_uri,
843 &p->bo,
844 pc->options,
845 &publish_kblocks_cont, pc);
846 }
847 else
848 {
849 publish_kblocks_cont (pc, p->chk_uri, NULL);
850 }
851}
852
853
854/**
855 * Process the response (or lack thereof) from
856 * the "fs" service to our LOC sign request.
857 *
858 * @param cls closure (of type `struct GNUNET_FS_PublishContext *`)
859 * @param msg the response we got
860 */
861static void
862process_signature_response (void *cls,
863 const struct GNUNET_MessageHeader *msg)
864{
865 struct GNUNET_FS_PublishContext *pc = cls;
866 const struct ResponseLocSignatureMessage *sig;
867 struct GNUNET_FS_FileInformation *p;
868
869 p = pc->fi_pos;
870 if (NULL == msg)
871 {
872 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
873 _("Can not create LOC URI. Will continue with CHK instead.\n"));
874 publish_kblocks (pc);
875 return;
876 }
877 if (sizeof (struct ResponseLocSignatureMessage) !=
878 ntohs (msg->size))
879 {
880 GNUNET_break (0);
881 publish_kblocks (pc);
882 return;
883 }
884 sig = (const struct ResponseLocSignatureMessage *) msg;
885 p->chk_uri->type = GNUNET_FS_URI_LOC;
886 /* p->data.loc.fi kept from CHK before */
887 p->chk_uri->data.loc.peer = sig->peer;
888 p->chk_uri->data.loc.expirationTime = GNUNET_TIME_absolute_ntoh (sig->expiration_time);
889 p->chk_uri->data.loc.contentSignature = sig->signature;
890 GNUNET_FS_file_information_sync_ (p);
891 GNUNET_FS_publish_sync_ (pc);
892 publish_kblocks (pc);
893}
894
895
896/**
897 * We're publishing without anonymity. Contact the FS service
898 * to create a signed LOC URI for further processing, then
899 * continue with KSKs.
900 *
901 * @param pc the publishing context do to this for
902 */
903static void
904create_loc_uri (struct GNUNET_FS_PublishContext *pc)
905{
906 struct RequestLocSignatureMessage req;
907 struct GNUNET_FS_FileInformation *p;
908
909 if (NULL == pc->client)
910 pc->client = GNUNET_CLIENT_connect ("fs", pc->h->cfg);
911 if (NULL == pc->client)
912 {
913 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
914 _("Can not create LOC URI. Will continue with CHK instead.\n"));
915 publish_kblocks (pc);
916 return;
917 }
918 p = pc->fi_pos;
919 req.header.size = htons (sizeof (struct RequestLocSignatureMessage));
920 req.header.type = htons (GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGN);
921 req.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
922 req.expiration_time = GNUNET_TIME_absolute_hton (p->bo.expiration_time);
923 req.chk = p->chk_uri->data.chk.chk;
924 req.file_length = GNUNET_htonll (p->chk_uri->data.chk.file_length);
925 GNUNET_break (GNUNET_YES ==
926 GNUNET_CLIENT_transmit_and_get_response (pc->client,
927 &req.header,
928 GNUNET_TIME_UNIT_FOREVER_REL,
929 GNUNET_YES,
930 &process_signature_response,
931 pc));
932}
933
934
935/**
826 * Main function that performs the upload. 936 * Main function that performs the upload.
827 * 937 *
828 * @param cls `struct GNUNET_FS_PublishContext *` identifies the upload 938 * @param cls `struct GNUNET_FS_PublishContext *` identifies the upload
@@ -835,7 +945,6 @@ GNUNET_FS_publish_main_ (void *cls,
835 struct GNUNET_FS_PublishContext *pc = cls; 945 struct GNUNET_FS_PublishContext *pc = cls;
836 struct GNUNET_FS_ProgressInfo pi; 946 struct GNUNET_FS_ProgressInfo pi;
837 struct GNUNET_FS_FileInformation *p; 947 struct GNUNET_FS_FileInformation *p;
838 struct GNUNET_FS_Uri *loc;
839 char *fn; 948 char *fn;
840 949
841 pc->upload_task = GNUNET_SCHEDULER_NO_TASK; 950 pc->upload_task = GNUNET_SCHEDULER_NO_TASK;
@@ -875,13 +984,17 @@ GNUNET_FS_publish_main_ (void *cls,
875 p = p->dir; 984 p = p->dir;
876 if (fn != NULL) 985 if (fn != NULL)
877 { 986 {
878 GNUNET_asprintf (&p->emsg, _("Recursive upload failed at `%s': %s"), fn, 987 GNUNET_asprintf (&p->emsg,
988 _("Recursive upload failed at `%s': %s"),
989 fn,
879 p->emsg); 990 p->emsg);
880 GNUNET_free (fn); 991 GNUNET_free (fn);
881 } 992 }
882 else 993 else
883 { 994 {
884 GNUNET_asprintf (&p->emsg, _("Recursive upload failed: %s"), p->emsg); 995 GNUNET_asprintf (&p->emsg,
996 _("Recursive upload failed: %s"),
997 p->emsg);
885 } 998 }
886 pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; 999 pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR;
887 pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; 1000 pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -897,31 +1010,18 @@ GNUNET_FS_publish_main_ (void *cls,
897 { 1010 {
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1011 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899 "File upload complete, now publishing KSK blocks.\n"); 1012 "File upload complete, now publishing KSK blocks.\n");
900 if (0 == p->bo.anonymity_level)
901 {
902 /* zero anonymity, box CHK URI in LOC URI */
903 loc = GNUNET_FS_uri_loc_create (p->chk_uri,
904 pc->h->cfg,
905 p->bo.expiration_time);
906 GNUNET_FS_uri_destroy (p->chk_uri);
907 p->chk_uri = loc;
908 GNUNET_FS_file_information_sync_ (p);
909 }
910 GNUNET_FS_publish_sync_ (pc); 1013 GNUNET_FS_publish_sync_ (pc);
911 /* upload of "p" complete, publish KBlocks! */ 1014
912 if (NULL != p->keywords) 1015 if ( (0 == p->bo.anonymity_level) &&
1016 (GNUNET_YES !=
1017 GNUNET_FS_uri_test_loc (p->chk_uri)) )
913 { 1018 {
914 pc->ksk_pc = GNUNET_FS_publish_ksk (pc->h, 1019 /* zero anonymity, box CHK URI in LOC URI */
915 p->keywords, 1020 create_loc_uri (pc);
916 p->meta,
917 p->chk_uri,
918 &p->bo,
919 pc->options,
920 &publish_kblocks_cont, pc);
921 } 1021 }
922 else 1022 else
923 { 1023 {
924 publish_kblocks_cont (pc, p->chk_uri, NULL); 1024 publish_kblocks (pc);
925 } 1025 }
926 return; 1026 return;
927 } 1027 }
@@ -1320,7 +1420,7 @@ fip_signal_stop (void *cls,
1320 pc->skip_next_fi_callback = GNUNET_YES; 1420 pc->skip_next_fi_callback = GNUNET_YES;
1321 GNUNET_FS_file_information_inspect (fi, &fip_signal_stop, pc); 1421 GNUNET_FS_file_information_inspect (fi, &fip_signal_stop, pc);
1322 } 1422 }
1323 if (fi->serialization != NULL) 1423 if (NULL != fi->serialization)
1324 { 1424 {
1325 GNUNET_FS_remove_sync_file_ (pc->h, GNUNET_FS_SYNC_PATH_FILE_INFO, 1425 GNUNET_FS_remove_sync_file_ (pc->h, GNUNET_FS_SYNC_PATH_FILE_INFO,
1326 fi->serialization); 1426 fi->serialization);
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index 1597f38ae..883e4b84a 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -837,61 +837,46 @@ GNUNET_FS_uri_loc_get_uri (const struct GNUNET_FS_Uri *uri)
837 837
838/** 838/**
839 * Construct a location URI (this peer will be used for the location). 839 * Construct a location URI (this peer will be used for the location).
840 * This function should only be called from within gnunet-service-fs,
841 * as it requires the peer's private key which is generally unavailable
842 * to processes directly under the user's control. However, for
843 * testing and as it logically fits under URIs, it is in this API.
840 * 844 *
841 * @param baseUri content offered by the sender 845 * @param base_uri content offered by the sender
842 * @param cfg configuration information (used to find our hostkey) 846 * @param sign_key private key of the peer
843 * @param expiration_time how long will the content be offered? 847 * @param expiration_time how long will the content be offered?
844 * @return the location URI, NULL on error 848 * @return the location URI, NULL on error
845 */ 849 */
846struct GNUNET_FS_Uri * 850struct GNUNET_FS_Uri *
847GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri, 851GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *base_uri,
848 const struct GNUNET_CONFIGURATION_Handle *cfg, 852 const struct GNUNET_CRYPTO_EddsaPrivateKey *sign_key,
849 struct GNUNET_TIME_Absolute expiration_time) 853 struct GNUNET_TIME_Absolute expiration_time)
850{ 854{
851 struct GNUNET_FS_Uri *uri; 855 struct GNUNET_FS_Uri *uri;
852 struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
853 struct GNUNET_CRYPTO_EddsaPublicKey my_public_key; 856 struct GNUNET_CRYPTO_EddsaPublicKey my_public_key;
854 char *keyfile;
855 struct LocUriAssembly ass; 857 struct LocUriAssembly ass;
856 struct GNUNET_TIME_Absolute et; 858 struct GNUNET_TIME_Absolute et;
857 859
858 if (baseUri->type != GNUNET_FS_URI_CHK) 860 if (GNUNET_FS_URI_CHK != base_uri->type)
859 return NULL; 861 return NULL;
860 if (GNUNET_OK !=
861 GNUNET_CONFIGURATION_get_value_filename (cfg,
862 "PEER", "PRIVATE_KEY",
863 &keyfile))
864 {
865 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
866 _("Lacking key configuration settings.\n"));
867 return NULL;
868 }
869 if (NULL ==
870 (my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile)))
871 {
872 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
873 _("Could not access hostkey file `%s'.\n"), keyfile);
874 GNUNET_free (keyfile);
875 return NULL;
876 }
877 GNUNET_free (keyfile);
878 /* we round expiration time to full seconds for SKS URIs */ 862 /* we round expiration time to full seconds for SKS URIs */
879 et.abs_value_us = (expiration_time.abs_value_us / 1000000LL) * 1000000LL; 863 et.abs_value_us = (expiration_time.abs_value_us / 1000000LL) * 1000000LL;
880 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_public_key); 864 GNUNET_CRYPTO_eddsa_key_get_public (sign_key,
865 &my_public_key);
881 ass.purpose.size = htonl (sizeof (struct LocUriAssembly)); 866 ass.purpose.size = htonl (sizeof (struct LocUriAssembly));
882 ass.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT); 867 ass.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
883 ass.exptime = GNUNET_TIME_absolute_hton (et); 868 ass.exptime = GNUNET_TIME_absolute_hton (et);
884 ass.fi = baseUri->data.chk; 869 ass.fi = base_uri->data.chk;
885 ass.peer.public_key = my_public_key; 870 ass.peer.public_key = my_public_key;
886 uri = GNUNET_new (struct GNUNET_FS_Uri); 871 uri = GNUNET_new (struct GNUNET_FS_Uri);
887 uri->type = GNUNET_FS_URI_LOC; 872 uri->type = GNUNET_FS_URI_LOC;
888 uri->data.loc.fi = baseUri->data.chk; 873 uri->data.loc.fi = base_uri->data.chk;
889 uri->data.loc.expirationTime = et; 874 uri->data.loc.expirationTime = et;
890 uri->data.loc.peer.public_key = my_public_key; 875 uri->data.loc.peer.public_key = my_public_key;
891 GNUNET_assert (GNUNET_OK == 876 GNUNET_assert (GNUNET_OK ==
892 GNUNET_CRYPTO_eddsa_sign (my_private_key, &ass.purpose, 877 GNUNET_CRYPTO_eddsa_sign (sign_key,
878 &ass.purpose,
893 &uri->data.loc.contentSignature)); 879 &uri->data.loc.contentSignature));
894 GNUNET_free (my_private_key);
895 return uri; 880 return uri;
896} 881}
897 882
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index 6652ecb16..dd7d61118 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) 3 (C) 2009-2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -45,6 +45,7 @@
45#include "gnunet-service-fs_put.h" 45#include "gnunet-service-fs_put.h"
46#include "gnunet-service-fs_cadet.h" 46#include "gnunet-service-fs_cadet.h"
47#include "fs.h" 47#include "fs.h"
48#include "fs_api.h"
48 49
49/** 50/**
50 * Size for the hash map for DHT requests from the FS 51 * Size for the hash map for DHT requests from the FS
@@ -159,6 +160,11 @@ int GSF_enable_randomized_delays;
159static struct GNUNET_CONFIGURATION_Handle *block_cfg; 160static struct GNUNET_CONFIGURATION_Handle *block_cfg;
160 161
161/** 162/**
163 * Private key of this peer. Used to sign LOC URI requests.
164 */
165static struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
166
167/**
162 * ID of our task that we use to age the cover counters. 168 * ID of our task that we use to age the cover counters.
163 */ 169 */
164static GNUNET_SCHEDULER_TaskIdentifier cover_age_task; 170static GNUNET_SCHEDULER_TaskIdentifier cover_age_task;
@@ -173,6 +179,7 @@ static struct GNUNET_LOAD_Value *datastore_get_load;
173 */ 179 */
174static struct GNUNET_PeerIdentity my_id; 180static struct GNUNET_PeerIdentity my_id;
175 181
182
176/** 183/**
177 * Task that periodically ages our cover traffic statistics. 184 * Task that periodically ages our cover traffic statistics.
178 * 185 *
@@ -180,7 +187,8 @@ static struct GNUNET_PeerIdentity my_id;
180 * @param tc task context 187 * @param tc task context
181 */ 188 */
182static void 189static void
183age_cover_counters (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 190age_cover_counters (void *cls,
191 const struct GNUNET_SCHEDULER_TaskContext *tc)
184{ 192{
185 GSF_cover_content_count = (GSF_cover_content_count * 15) / 16; 193 GSF_cover_content_count = (GSF_cover_content_count * 15) / 16;
186 GSF_cover_query_count = (GSF_cover_query_count * 15) / 16; 194 GSF_cover_query_count = (GSF_cover_query_count * 15) / 16;
@@ -288,11 +296,12 @@ update_latencies (void *cls,
288 * @param other the other peer involved (sender or receiver, NULL 296 * @param other the other peer involved (sender or receiver, NULL
289 * for loopback messages where we are both sender and receiver) 297 * for loopback messages where we are both sender and receiver)
290 * @param message the actual message 298 * @param message the actual message
291 * @return GNUNET_OK to keep the connection open, 299 * @return #GNUNET_OK to keep the connection open,
292 * GNUNET_SYSERR to close it (signal serious error) 300 * #GNUNET_SYSERR to close it (signal serious error)
293 */ 301 */
294static int 302static int
295handle_p2p_put (void *cls, const struct GNUNET_PeerIdentity *other, 303handle_p2p_put (void *cls,
304 const struct GNUNET_PeerIdentity *other,
296 const struct GNUNET_MessageHeader *message) 305 const struct GNUNET_MessageHeader *message)
297{ 306{
298 struct GSF_ConnectedPeer *cp; 307 struct GSF_ConnectedPeer *cp;
@@ -349,7 +358,8 @@ consider_request_for_forwarding (void *cls,
349 * @param result final datastore lookup result 358 * @param result final datastore lookup result
350 */ 359 */
351static void 360static void
352consider_forwarding (void *cls, struct GSF_PendingRequest *pr, 361consider_forwarding (void *cls,
362 struct GSF_PendingRequest *pr,
353 enum GNUNET_BLOCK_EvaluationResult result) 363 enum GNUNET_BLOCK_EvaluationResult result)
354{ 364{
355 if (GNUNET_BLOCK_EVALUATION_OK_LAST == result) 365 if (GNUNET_BLOCK_EVALUATION_OK_LAST == result)
@@ -365,11 +375,12 @@ consider_forwarding (void *cls, struct GSF_PendingRequest *pr,
365 * @param other the other peer involved (sender or receiver, NULL 375 * @param other the other peer involved (sender or receiver, NULL
366 * for loopback messages where we are both sender and receiver) 376 * for loopback messages where we are both sender and receiver)
367 * @param message the actual message 377 * @param message the actual message
368 * @return GNUNET_OK to keep the connection open, 378 * @return #GNUNET_OK to keep the connection open,
369 * GNUNET_SYSERR to close it (signal serious error) 379 * #GNUNET_SYSERR to close it (signal serious error)
370 */ 380 */
371static int 381static int
372handle_p2p_get (void *cls, const struct GNUNET_PeerIdentity *other, 382handle_p2p_get (void *cls,
383 const struct GNUNET_PeerIdentity *other,
373 const struct GNUNET_MessageHeader *message) 384 const struct GNUNET_MessageHeader *message)
374{ 385{
375 struct GSF_PendingRequest *pr; 386 struct GSF_PendingRequest *pr;
@@ -378,7 +389,8 @@ handle_p2p_get (void *cls, const struct GNUNET_PeerIdentity *other,
378 if (NULL == pr) 389 if (NULL == pr)
379 return GNUNET_SYSERR; 390 return GNUNET_SYSERR;
380 GSF_pending_request_get_data_ (pr)->has_started = GNUNET_YES; 391 GSF_pending_request_get_data_ (pr)->has_started = GNUNET_YES;
381 GSF_local_lookup_ (pr, &consider_forwarding, NULL); 392 GSF_local_lookup_ (pr,
393 &consider_forwarding, NULL);
382 return GNUNET_OK; 394 return GNUNET_OK;
383} 395}
384 396
@@ -389,18 +401,20 @@ handle_p2p_get (void *cls, const struct GNUNET_PeerIdentity *other,
389 * result status). Also signal that we can now 401 * result status). Also signal that we can now
390 * receive more request information from the client. 402 * receive more request information from the client.
391 * 403 *
392 * @param cls the client doing the request ('struct GNUNET_SERVER_Client') 404 * @param cls the client doing the request (`struct GNUNET_SERVER_Client`)
393 * @param pr the pending request we were processing 405 * @param pr the pending request we were processing
394 * @param result final datastore lookup result 406 * @param result final datastore lookup result
395 */ 407 */
396static void 408static void
397start_p2p_processing (void *cls, struct GSF_PendingRequest *pr, 409start_p2p_processing (void *cls,
410 struct GSF_PendingRequest *pr,
398 enum GNUNET_BLOCK_EvaluationResult result) 411 enum GNUNET_BLOCK_EvaluationResult result)
399{ 412{
400 struct GNUNET_SERVER_Client *client = cls; 413 struct GNUNET_SERVER_Client *client = cls;
401 struct GSF_PendingRequestData *prd; 414 struct GSF_PendingRequestData *prd;
402 415
403 GNUNET_SERVER_receive_done (client, GNUNET_OK); 416 GNUNET_SERVER_receive_done (client,
417 GNUNET_OK);
404 if (GNUNET_BLOCK_EVALUATION_OK_LAST == result) 418 if (GNUNET_BLOCK_EVALUATION_OK_LAST == result)
405 return; /* we're done, 'pr' was already destroyed... */ 419 return; /* we're done, 'pr' was already destroyed... */
406 prd = GSF_pending_request_get_data_ (pr); 420 prd = GSF_pending_request_get_data_ (pr);
@@ -441,25 +455,32 @@ start_p2p_processing (void *cls, struct GSF_PendingRequest *pr,
441 * @param message the actual message 455 * @param message the actual message
442 */ 456 */
443static void 457static void
444handle_start_search (void *cls, struct GNUNET_SERVER_Client *client, 458handle_start_search (void *cls,
459 struct GNUNET_SERVER_Client *client,
445 const struct GNUNET_MessageHeader *message) 460 const struct GNUNET_MessageHeader *message)
446{ 461{
447 struct GSF_PendingRequest *pr; 462 struct GSF_PendingRequest *pr;
448 int ret; 463 int ret;
449 464
450 pr = NULL; 465 pr = NULL;
451 ret = GSF_local_client_start_search_handler_ (client, message, &pr); 466 ret = GSF_local_client_start_search_handler_ (client,
467 message,
468 &pr);
452 switch (ret) 469 switch (ret)
453 { 470 {
454 case GNUNET_SYSERR: 471 case GNUNET_SYSERR:
455 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 472 GNUNET_SERVER_receive_done (client,
473 GNUNET_SYSERR);
456 break; 474 break;
457 case GNUNET_NO: 475 case GNUNET_NO:
458 GNUNET_SERVER_receive_done (client, GNUNET_OK); 476 GNUNET_SERVER_receive_done (client,
477 GNUNET_OK);
459 break; 478 break;
460 case GNUNET_YES: 479 case GNUNET_YES:
461 GSF_pending_request_get_data_ (pr)->has_started = GNUNET_YES; 480 GSF_pending_request_get_data_ (pr)->has_started = GNUNET_YES;
462 GSF_local_lookup_ (pr, &start_p2p_processing, client); 481 GSF_local_lookup_ (pr,
482 &start_p2p_processing,
483 client);
463 break; 484 break;
464 default: 485 default:
465 GNUNET_assert (0); 486 GNUNET_assert (0);
@@ -468,13 +489,56 @@ handle_start_search (void *cls, struct GNUNET_SERVER_Client *client,
468 489
469 490
470/** 491/**
492 * Handle request to sign a LOC URI (from client).
493 *
494 * @param cls closure (NULL)
495 * @param client identification of the client
496 * @param message the actual message
497 */
498static void
499handle_loc_sign (void *cls,
500 struct GNUNET_SERVER_Client *client,
501 const struct GNUNET_MessageHeader *message)
502{
503 const struct RequestLocSignatureMessage *msg;
504 struct GNUNET_FS_Uri base;
505 struct GNUNET_FS_Uri *loc;
506 struct ResponseLocSignatureMessage resp;
507 struct GSF_LocalClient *lc;
508
509 msg = (const struct RequestLocSignatureMessage *) message;
510 GNUNET_break (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT ==
511 ntohl (msg->purpose));
512 base.type = GNUNET_FS_URI_CHK;
513 base.data.chk.chk = msg->chk;
514 base.data.chk.file_length = GNUNET_ntohll (msg->file_length);
515 loc = GNUNET_FS_uri_loc_create (&base,
516 pk,
517 GNUNET_TIME_absolute_ntoh (msg->expiration_time));
518 resp.header.size = htons (sizeof (struct ResponseLocSignatureMessage));
519 resp.header.type = htons (GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGNATURE);
520 resp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
521 resp.expiration_time = GNUNET_TIME_absolute_hton (loc->data.loc.expirationTime);
522 resp.signature = loc->data.loc.contentSignature;
523 resp.peer = loc->data.loc.peer;
524 GNUNET_FS_uri_destroy (loc);
525 lc = GSF_local_client_lookup_ (client);
526 GSF_local_client_transmit_ (lc,
527 &resp.header);
528 GNUNET_free (loc);
529 GNUNET_SERVER_receive_done (client, GNUNET_OK);
530}
531
532
533/**
471 * Task run during shutdown. 534 * Task run during shutdown.
472 * 535 *
473 * @param cls unused 536 * @param cls unused
474 * @param tc unused 537 * @param tc unused
475 */ 538 */
476static void 539static void
477shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 540shutdown_task (void *cls,
541 const struct GNUNET_SCHEDULER_TaskContext *tc)
478{ 542{
479 GSF_cadet_stop_client (); 543 GSF_cadet_stop_client ();
480 GSF_cadet_stop_server (); 544 GSF_cadet_stop_server ();
@@ -524,10 +588,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
524 * @param cls the 'struct GSF_ConnectedPeer' of the new peer 588 * @param cls the 'struct GSF_ConnectedPeer' of the new peer
525 * @param key query for the request 589 * @param key query for the request
526 * @param pr handle to the pending request 590 * @param pr handle to the pending request
527 * @return GNUNET_YES to continue to iterate 591 * @return #GNUNET_YES to continue to iterate
528 */ 592 */
529static int 593static int
530consider_peer_for_forwarding (void *cls, const struct GNUNET_HashCode * key, 594consider_peer_for_forwarding (void *cls,
595 const struct GNUNET_HashCode *key,
531 struct GSF_PendingRequest *pr) 596 struct GSF_PendingRequest *pr)
532{ 597{
533 struct GSF_ConnectedPeer *cp = cls; 598 struct GSF_ConnectedPeer *cp = cls;
@@ -568,11 +633,15 @@ connected_peer_cb (void *cls, struct GSF_ConnectedPeer *cp)
568 * @param peer peer identity this notification is about 633 * @param peer peer identity this notification is about
569 */ 634 */
570static void 635static void
571peer_connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer) 636peer_connect_handler (void *cls,
637 const struct GNUNET_PeerIdentity *peer)
572{ 638{
573 if (0 == memcmp (&my_id, peer, sizeof (struct GNUNET_PeerIdentity))) 639 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_id,
640 peer))
574 return; 641 return;
575 GSF_peer_connect_handler_ (peer, &connected_peer_cb, NULL); 642 GSF_peer_connect_handler_ (peer,
643 &connected_peer_cb,
644 NULL);
576} 645}
577 646
578 647
@@ -590,7 +659,13 @@ static void
590peer_init_handler (void *cls, 659peer_init_handler (void *cls,
591 const struct GNUNET_PeerIdentity *my_identity) 660 const struct GNUNET_PeerIdentity *my_identity)
592{ 661{
593 my_id = *my_identity; 662 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_id,
663 my_identity))
664 {
665 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
666 "Peer identity missmatch, refusing to start!\n");
667 GNUNET_SCHEDULER_shutdown ();
668 }
594} 669}
595 670
596 671
@@ -605,31 +680,36 @@ main_init (struct GNUNET_SERVER_Handle *server,
605 const struct GNUNET_CONFIGURATION_Handle *c) 680 const struct GNUNET_CONFIGURATION_Handle *c)
606{ 681{
607 static const struct GNUNET_CORE_MessageHandler no_p2p_handlers[] = { 682 static const struct GNUNET_CORE_MessageHandler no_p2p_handlers[] = {
608 {NULL, 0, 0} 683 { NULL, 0, 0 }
609 }; 684 };
610 static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = { 685 static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = {
611 {&handle_p2p_get, 686 { &handle_p2p_get,
612 GNUNET_MESSAGE_TYPE_FS_GET, 0}, 687 GNUNET_MESSAGE_TYPE_FS_GET, 0 },
613 {&handle_p2p_put, 688 { &handle_p2p_put,
614 GNUNET_MESSAGE_TYPE_FS_PUT, 0}, 689 GNUNET_MESSAGE_TYPE_FS_PUT, 0 },
615 {&GSF_handle_p2p_migration_stop_, 690 { &GSF_handle_p2p_migration_stop_,
616 GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP, 691 GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP,
617 sizeof (struct MigrationStopMessage)}, 692 sizeof (struct MigrationStopMessage) },
618 {NULL, 0, 0} 693 { NULL, 0, 0 }
619 }; 694 };
620 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 695 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
621 {&GNUNET_FS_handle_index_start, NULL, 696 { &GNUNET_FS_handle_index_start, NULL,
622 GNUNET_MESSAGE_TYPE_FS_INDEX_START, 0}, 697 GNUNET_MESSAGE_TYPE_FS_INDEX_START, 0 },
623 {&GNUNET_FS_handle_index_list_get, NULL, 698 { &GNUNET_FS_handle_index_list_get, NULL,
624 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET, 699 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET,
625 sizeof (struct GNUNET_MessageHeader)}, 700 sizeof (struct GNUNET_MessageHeader) },
626 {&GNUNET_FS_handle_unindex, NULL, GNUNET_MESSAGE_TYPE_FS_UNINDEX, 701 { &GNUNET_FS_handle_unindex, NULL,
627 sizeof (struct UnindexMessage)}, 702 GNUNET_MESSAGE_TYPE_FS_UNINDEX,
628 {&handle_start_search, NULL, GNUNET_MESSAGE_TYPE_FS_START_SEARCH, 703 sizeof (struct UnindexMessage) },
629 0}, 704 { &handle_start_search, NULL,
705 GNUNET_MESSAGE_TYPE_FS_START_SEARCH, 0 },
706 { &handle_loc_sign, NULL,
707 GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGN,
708 sizeof (struct RequestLocSignatureMessage) },
630 {NULL, NULL, 0, 0} 709 {NULL, NULL, 0, 0}
631 }; 710 };
632 int anon_p2p_off; 711 int anon_p2p_off;
712 char *keyfile;
633 713
634 /* this option is really only for testcases that need to disable 714 /* this option is really only for testcases that need to disable
635 _anonymous_ file-sharing for some reason */ 715 _anonymous_ file-sharing for some reason */
@@ -637,10 +717,31 @@ main_init (struct GNUNET_SERVER_Handle *server,
637 GNUNET_CONFIGURATION_get_value_yesno (GSF_cfg, 717 GNUNET_CONFIGURATION_get_value_yesno (GSF_cfg,
638 "fs", 718 "fs",
639 "DISABLE_ANON_TRANSFER")); 719 "DISABLE_ANON_TRANSFER"));
640 GSF_core = 720
641 GNUNET_CORE_connect (GSF_cfg, NULL, &peer_init_handler, 721 if (GNUNET_OK !=
642 &peer_connect_handler, &GSF_peer_disconnect_handler_, 722 GNUNET_CONFIGURATION_get_value_filename (GSF_cfg,
643 NULL, GNUNET_NO, NULL, GNUNET_NO, 723 "PEER",
724 "PRIVATE_KEY",
725 &keyfile))
726 {
727 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
728 _("FS service is lacking HOSTKEY configuration setting. Exiting.\n"));
729 GNUNET_SCHEDULER_shutdown ();
730 return GNUNET_SYSERR;
731 }
732 pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile);
733 GNUNET_free (keyfile);
734 GNUNET_assert (NULL != pk);
735 GNUNET_CRYPTO_eddsa_key_get_public (pk,
736 &my_id.public_key);
737
738 GSF_core
739 = GNUNET_CORE_connect (GSF_cfg, NULL,
740 &peer_init_handler,
741 &peer_connect_handler,
742 &GSF_peer_disconnect_handler_,
743 NULL, GNUNET_NO,
744 NULL, GNUNET_NO,
644 (GNUNET_YES == anon_p2p_off) 745 (GNUNET_YES == anon_p2p_off)
645 ? no_p2p_handlers 746 ? no_p2p_handlers
646 : p2p_handlers); 747 : p2p_handlers);
diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c
index ef30ba32a..6d3b761be 100644
--- a/src/fs/gnunet-service-fs_lc.c
+++ b/src/fs/gnunet-service-fs_lc.c
@@ -17,13 +17,11 @@
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20
21/** 20/**
22 * @file fs/gnunet-service-fs_lc.c 21 * @file fs/gnunet-service-fs_lc.c
23 * @brief API to handle 'local clients' 22 * @brief API to handle 'local clients'
24 * @author Christian Grothoff 23 * @author Christian Grothoff
25 */ 24 */
26
27#include "platform.h" 25#include "platform.h"
28#include "gnunet-service-fs.h" 26#include "gnunet-service-fs.h"
29#include "gnunet-service-fs_lc.h" 27#include "gnunet-service-fs_lc.h"
@@ -150,7 +148,6 @@ struct GSF_LocalClient
150 */ 148 */
151static struct GSF_LocalClient *client_head; 149static struct GSF_LocalClient *client_head;
152 150
153
154/** 151/**
155 * Head of linked list of our local clients. 152 * Head of linked list of our local clients.
156 */ 153 */
@@ -176,7 +173,9 @@ GSF_local_client_lookup_ (struct GNUNET_SERVER_Client *client)
176 return pos; 173 return pos;
177 pos = GNUNET_new (struct GSF_LocalClient); 174 pos = GNUNET_new (struct GSF_LocalClient);
178 pos->client = client; 175 pos->client = client;
179 GNUNET_CONTAINER_DLL_insert (client_head, client_tail, pos); 176 GNUNET_CONTAINER_DLL_insert (client_head,
177 client_tail,
178 pos);
180 return pos; 179 return pos;
181} 180}
182 181
@@ -209,7 +208,7 @@ client_request_destroy (void *cls,
209 * Handle a reply to a pending request. Also called if a request 208 * Handle a reply to a pending request. Also called if a request
210 * expires (then with data == NULL). The handler may be called 209 * expires (then with data == NULL). The handler may be called
211 * many times (depending on the request type), but will not be 210 * many times (depending on the request type), but will not be
212 * called during or after a call to GSF_pending_request_cancel 211 * called during or after a call to #GSF_pending_request_cancel()
213 * and will also not be called anymore after a call signalling 212 * and will also not be called anymore after a call signalling
214 * expiration. 213 * expiration.
215 * 214 *
@@ -217,19 +216,21 @@ client_request_destroy (void *cls,
217 * @param eval evaluation of the result 216 * @param eval evaluation of the result
218 * @param pr handle to the original pending request 217 * @param pr handle to the original pending request
219 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown" 218 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
220 * @param expiration when does 'data' expire? 219 * @param expiration when does @a data expire?
221 * @param last_transmission when was the last time we've tried to download this block? (FOREVER if unknown) 220 * @param last_transmission when was the last time we've tried to download this block? (FOREVER if unknown)
222 * @param type type of the block 221 * @param type type of the block
223 * @param data response data, NULL on request expiration 222 * @param data response data, NULL on request expiration
224 * @param data_len number of bytes in @e data 223 * @param data_len number of bytes in @a data
225 */ 224 */
226static void 225static void
227client_response_handler (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, 226client_response_handler (void *cls,
227 enum GNUNET_BLOCK_EvaluationResult eval,
228 struct GSF_PendingRequest *pr, 228 struct GSF_PendingRequest *pr,
229 uint32_t reply_anonymity_level, 229 uint32_t reply_anonymity_level,
230 struct GNUNET_TIME_Absolute expiration, 230 struct GNUNET_TIME_Absolute expiration,
231 struct GNUNET_TIME_Absolute last_transmission, 231 struct GNUNET_TIME_Absolute last_transmission,
232 enum GNUNET_BLOCK_Type type, const void *data, 232 enum GNUNET_BLOCK_Type type,
233 const void *data,
233 size_t data_len) 234 size_t data_len)
234{ 235{
235 struct ClientRequest *cr = cls; 236 struct ClientRequest *cr = cls;
@@ -405,13 +406,15 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client,
405 * If we were able to transmit messages and there are still more 406 * If we were able to transmit messages and there are still more
406 * pending, ask core again for further calls to this function. 407 * pending, ask core again for further calls to this function.
407 * 408 *
408 * @param cls closure, pointer to the 'struct GSF_LocalClient' 409 * @param cls closure, pointer to the `struct GSF_LocalClient`
409 * @param size number of bytes available in buf 410 * @param size number of bytes available in @a buf
410 * @param buf where the callee should write the message 411 * @param buf where the callee should write the message
411 * @return number of bytes written to buf 412 * @return number of bytes written to @a buf
412 */ 413 */
413static size_t 414static size_t
414transmit_to_client (void *cls, size_t size, void *buf) 415transmit_to_client (void *cls,
416 size_t size,
417 void *buf)
415{ 418{
416 struct GSF_LocalClient *lc = cls; 419 struct GSF_LocalClient *lc = cls;
417 char *cbuf = buf; 420 char *cbuf = buf;
@@ -458,8 +461,12 @@ GSF_local_client_transmit_ (struct GSF_LocalClient *lc,
458 res = GNUNET_malloc (sizeof (struct ClientResponse) + msize); 461 res = GNUNET_malloc (sizeof (struct ClientResponse) + msize);
459 res->lc = lc; 462 res->lc = lc;
460 res->msize = msize; 463 res->msize = msize;
461 memcpy (&res[1], msg, msize); 464 memcpy (&res[1],
462 GNUNET_CONTAINER_DLL_insert_tail (lc->res_head, lc->res_tail, res); 465 msg,
466 msize);
467 GNUNET_CONTAINER_DLL_insert_tail (lc->res_head,
468 lc->res_tail,
469 res);
463 if (NULL == lc->th) 470 if (NULL == lc->th)
464 lc->th = 471 lc->th =
465 GNUNET_SERVER_notify_transmit_ready (lc->client, msize, 472 GNUNET_SERVER_notify_transmit_ready (lc->client, msize,
@@ -476,7 +483,8 @@ GSF_local_client_transmit_ (struct GSF_LocalClient *lc,
476 * @param client handle of the client 483 * @param client handle of the client
477 */ 484 */
478void 485void
479GSF_client_disconnect_handler_ (void *cls, struct GNUNET_SERVER_Client *client) 486GSF_client_disconnect_handler_ (void *cls,
487 struct GNUNET_SERVER_Client *client)
480{ 488{
481 struct GSF_LocalClient *pos; 489 struct GSF_LocalClient *pos;
482 struct ClientRequest *cr; 490 struct ClientRequest *cr;
diff --git a/src/fs/test_fs_uri.c b/src/fs/test_fs_uri.c
index afc80ef71..fdc39ce05 100644
--- a/src/fs/test_fs_uri.c
+++ b/src/fs/test_fs_uri.c
@@ -42,12 +42,12 @@ testKeyword ()
42 } 42 }
43 GNUNET_free (emsg); 43 GNUNET_free (emsg);
44 ret = GNUNET_FS_uri_parse ("gnunet://fs/ksk/foo+bar", &emsg); 44 ret = GNUNET_FS_uri_parse ("gnunet://fs/ksk/foo+bar", &emsg);
45 if (ret == NULL) 45 if (NULL == ret)
46 { 46 {
47 GNUNET_free (emsg); 47 GNUNET_free (emsg);
48 GNUNET_assert (0); 48 GNUNET_assert (0);
49 } 49 }
50 if (!GNUNET_FS_uri_test_ksk (ret)) 50 if (! GNUNET_FS_uri_test_ksk (ret))
51 { 51 {
52 GNUNET_FS_uri_destroy (ret); 52 GNUNET_FS_uri_destroy (ret);
53 GNUNET_assert (0); 53 GNUNET_assert (0);
@@ -81,7 +81,7 @@ testLocation ()
81 struct GNUNET_FS_Uri *uri2; 81 struct GNUNET_FS_Uri *uri2;
82 struct GNUNET_FS_Uri *baseURI; 82 struct GNUNET_FS_Uri *baseURI;
83 char *emsg; 83 char *emsg;
84 struct GNUNET_CONFIGURATION_Handle *cfg; 84 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
85 85
86 baseURI = 86 baseURI =
87 GNUNET_FS_uri_parse 87 GNUNET_FS_uri_parse
@@ -89,38 +89,31 @@ testLocation ()
89 &emsg); 89 &emsg);
90 GNUNET_assert (baseURI != NULL); 90 GNUNET_assert (baseURI != NULL);
91 GNUNET_assert (emsg == NULL); 91 GNUNET_assert (emsg == NULL);
92 cfg = GNUNET_CONFIGURATION_create (); 92 pk = GNUNET_CRYPTO_eddsa_key_create ();
93 if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, "test_fs_uri_data.conf")) 93 uri = GNUNET_FS_uri_loc_create (baseURI,
94 { 94 pk,
95 FPRINTF (stderr, "%s", "Failed to parse configuration file\n"); 95 GNUNET_TIME_absolute_get ());
96 GNUNET_FS_uri_destroy (baseURI); 96 GNUNET_free (pk);
97 GNUNET_CONFIGURATION_destroy (cfg); 97 if (NULL == uri)
98 return 1;
99 }
100 uri = GNUNET_FS_uri_loc_create (baseURI, cfg, GNUNET_TIME_absolute_get ());
101 if (uri == NULL)
102 { 98 {
103 GNUNET_break (0); 99 GNUNET_break (0);
104 GNUNET_FS_uri_destroy (baseURI); 100 GNUNET_FS_uri_destroy (baseURI);
105 GNUNET_CONFIGURATION_destroy (cfg);
106 return 1; 101 return 1;
107 } 102 }
108 if (!GNUNET_FS_uri_test_loc (uri)) 103 if (! GNUNET_FS_uri_test_loc (uri))
109 { 104 {
110 GNUNET_break (0); 105 GNUNET_break (0);
111 GNUNET_FS_uri_destroy (uri); 106 GNUNET_FS_uri_destroy (uri);
112 GNUNET_FS_uri_destroy (baseURI); 107 GNUNET_FS_uri_destroy (baseURI);
113 GNUNET_CONFIGURATION_destroy (cfg);
114 return 1; 108 return 1;
115 } 109 }
116 uri2 = GNUNET_FS_uri_loc_get_uri (uri); 110 uri2 = GNUNET_FS_uri_loc_get_uri (uri);
117 if (!GNUNET_FS_uri_test_equal (baseURI, uri2)) 111 if (! GNUNET_FS_uri_test_equal (baseURI, uri2))
118 { 112 {
119 GNUNET_break (0); 113 GNUNET_break (0);
120 GNUNET_FS_uri_destroy (uri); 114 GNUNET_FS_uri_destroy (uri);
121 GNUNET_FS_uri_destroy (uri2); 115 GNUNET_FS_uri_destroy (uri2);
122 GNUNET_FS_uri_destroy (baseURI); 116 GNUNET_FS_uri_destroy (baseURI);
123 GNUNET_CONFIGURATION_destroy (cfg);
124 return 1; 117 return 1;
125 } 118 }
126 GNUNET_FS_uri_destroy (uri2); 119 GNUNET_FS_uri_destroy (uri2);
@@ -137,7 +130,6 @@ testLocation ()
137 fprintf (stderr, "URI parsing failed: %s\n", emsg); 130 fprintf (stderr, "URI parsing failed: %s\n", emsg);
138 GNUNET_break (0); 131 GNUNET_break (0);
139 GNUNET_FS_uri_destroy (uri); 132 GNUNET_FS_uri_destroy (uri);
140 GNUNET_CONFIGURATION_destroy (cfg);
141 GNUNET_free (emsg); 133 GNUNET_free (emsg);
142 return 1; 134 return 1;
143 } 135 }
@@ -147,12 +139,10 @@ testLocation ()
147 GNUNET_break (0); 139 GNUNET_break (0);
148 GNUNET_FS_uri_destroy (uri); 140 GNUNET_FS_uri_destroy (uri);
149 GNUNET_FS_uri_destroy (uri2); 141 GNUNET_FS_uri_destroy (uri2);
150 GNUNET_CONFIGURATION_destroy (cfg);
151 return 1; 142 return 1;
152 } 143 }
153 GNUNET_FS_uri_destroy (uri2); 144 GNUNET_FS_uri_destroy (uri2);
154 GNUNET_FS_uri_destroy (uri); 145 GNUNET_FS_uri_destroy (uri);
155 GNUNET_CONFIGURATION_destroy (cfg);
156 return 0; 146 return 0;
157} 147}
158 148
diff --git a/src/fs/test_fs_uri_data.conf b/src/fs/test_fs_uri_data.conf
deleted file mode 100644
index fcf6f42d4..000000000
--- a/src/fs/test_fs_uri_data.conf
+++ /dev/null
@@ -1,5 +0,0 @@
1@INLINE@ test_fs_defaults.conf
2[PATHS]
3GNUNET_TEST_HOME = /tmp/gnunet-test-fs-uri/
4
5
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 9f3ff0d12..9ea278d87 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -162,7 +162,8 @@ GNUNET_FS_uri_ksk_remove_keyword (struct GNUNET_FS_Uri *uri,
162 * @return NULL on error 162 * @return NULL on error
163 */ 163 */
164struct GNUNET_FS_Uri * 164struct GNUNET_FS_Uri *
165GNUNET_FS_uri_parse (const char *uri, char **emsg); 165GNUNET_FS_uri_parse (const char *uri,
166 char **emsg);
166 167
167 168
168/** 169/**
@@ -233,15 +234,19 @@ GNUNET_FS_uri_loc_get_expiration (const struct GNUNET_FS_Uri *uri);
233 234
234/** 235/**
235 * Construct a location URI (this peer will be used for the location). 236 * Construct a location URI (this peer will be used for the location).
237 * This function should only be called from within gnunet-service-fs,
238 * as it requires the peer's private key which is generally unavailable
239 * to processes directly under the user's control. However, for
240 * testing and as it logically fits under URIs, it is in this API.
236 * 241 *
237 * @param baseUri content offered by the sender 242 * @param base_uri content offered by the sender
238 * @param cfg configuration information (used to find our hostkey) 243 * @param sign_key private key of the peer
239 * @param expiration_time how long will the content be offered? 244 * @param expiration_time how long will the content be offered?
240 * @return the location URI, NULL on error 245 * @return the location URI, NULL on error
241 */ 246 */
242struct GNUNET_FS_Uri * 247struct GNUNET_FS_Uri *
243GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri, 248GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *base_uri,
244 const struct GNUNET_CONFIGURATION_Handle *cfg, 249 const struct GNUNET_CRYPTO_EddsaPrivateKey *sign_key,
245 struct GNUNET_TIME_Absolute expiration_time); 250 struct GNUNET_TIME_Absolute expiration_time);
246 251
247 252
@@ -285,7 +290,8 @@ GNUNET_FS_uri_dup (const struct GNUNET_FS_Uri *uri);
285 * if keywords is not legal (i.e. empty). 290 * if keywords is not legal (i.e. empty).
286 */ 291 */
287struct GNUNET_FS_Uri * 292struct GNUNET_FS_Uri *
288GNUNET_FS_uri_ksk_create (const char *keywords, char **emsg); 293GNUNET_FS_uri_ksk_create (const char *keywords,
294 char **emsg);
289 295
290 296
291/** 297/**
@@ -436,8 +442,9 @@ GNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData
436 * @return #GNUNET_OK on success 442 * @return #GNUNET_OK on success
437 */ 443 */
438int 444int
439GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext 445GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
440 *ctx, void *scls, const char *option, 446 void *scls,
447 const char *option,
441 const char *value); 448 const char *value);
442 449
443 450
@@ -454,8 +461,9 @@ GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
454 * @return #GNUNET_OK on success 461 * @return #GNUNET_OK on success
455 */ 462 */
456int 463int
457GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext 464GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
458 *ctx, void *scls, const char *option, 465 void *scls,
466 const char *option,
459 const char *value); 467 const char *value);
460 468
461 469
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index f9e8df77f..1279dd703 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001-2013 Christian Grothoff (and other contributing authors) 3 (C) 2001-2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -459,6 +459,16 @@ extern "C"
459 ******************************************************************************/ 459 ******************************************************************************/
460 460
461/** 461/**
462 * Message sent by fs client to request LOC signature.
463 */
464#define GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGN 126
465
466/**
467 * Reply sent by fs service with LOC signature.
468 */
469#define GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGNATURE 127
470
471/**
462 * Message sent by fs client to start indexing. 472 * Message sent by fs client to start indexing.
463 */ 473 */
464#define GNUNET_MESSAGE_TYPE_FS_INDEX_START 128 474#define GNUNET_MESSAGE_TYPE_FS_INDEX_START 128