aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-04 19:40:23 +0200
committerMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-04 19:40:23 +0200
commit815ded19f106990a37bbacec83546b1b897491f6 (patch)
tree9f9b013616809dad4cec996f96d0ca5e59331410 /src/namestore
parent080519e980d8f8a3b138c733f837417bdb1b6757 (diff)
downloadgnunet-815ded19f106990a37bbacec83546b1b897491f6.tar.gz
gnunet-815ded19f106990a37bbacec83546b1b897491f6.zip
rest: fix #6462
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/plugin_rest_namestore.c242
1 files changed, 122 insertions, 120 deletions
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
index f1cbfb38b..c993518ea 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -85,6 +85,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
85static char *allow_methods; 85static char *allow_methods;
86 86
87/** 87/**
88 * Ego list
89 */
90static struct EgoEntry *ego_head;
91
92/**
93 * Ego list
94 */
95static struct EgoEntry *ego_tail;
96
97/**
98 * The processing state
99 */
100static int state;
101
102/**
103 * Handle to NAMESTORE
104 */
105static struct GNUNET_NAMESTORE_Handle *ns_handle;
106
107/**
108 * Handle to Identity service.
109 */
110static struct GNUNET_IDENTITY_Handle *identity_handle;
111
112/**
88 * @brief struct returned by the initialization function of the plugin 113 * @brief struct returned by the initialization function of the plugin
89 */ 114 */
90struct Plugin 115struct Plugin
@@ -170,15 +195,6 @@ struct RequestHandle
170 */ 195 */
171 json_t *resp_object; 196 json_t *resp_object;
172 197
173 /**
174 * The processing state
175 */
176 int state;
177
178 /**
179 * Handle to NAMESTORE
180 */
181 struct GNUNET_NAMESTORE_Handle *ns_handle;
182 198
183 /** 199 /**
184 * Handle to NAMESTORE it 200 * Handle to NAMESTORE it
@@ -196,26 +212,11 @@ struct RequestHandle
196 struct EgoEntry *ego_entry; 212 struct EgoEntry *ego_entry;
197 213
198 /** 214 /**
199 * Ego list
200 */
201 struct EgoEntry *ego_head;
202
203 /**
204 * Ego list
205 */
206 struct EgoEntry *ego_tail;
207
208 /**
209 * IDENTITY Operation 215 * IDENTITY Operation
210 */ 216 */
211 struct GNUNET_IDENTITY_Operation *op; 217 struct GNUNET_IDENTITY_Operation *op;
212 218
213 /** 219 /**
214 * Handle to Identity service.
215 */
216 struct GNUNET_IDENTITY_Handle *identity_handle;
217
218 /**
219 * Rest connection 220 * Rest connection
220 */ 221 */
221 struct GNUNET_REST_RequestHandle *rest_handle; 222 struct GNUNET_REST_RequestHandle *rest_handle;
@@ -264,8 +265,6 @@ static void
264cleanup_handle (void *cls) 265cleanup_handle (void *cls)
265{ 266{
266 struct RequestHandle *handle = cls; 267 struct RequestHandle *handle = cls;
267 struct EgoEntry *ego_entry;
268 struct EgoEntry *ego_tmp;
269 268
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
271 if (NULL != handle->timeout_task) 270 if (NULL != handle->timeout_task)
@@ -294,21 +293,6 @@ cleanup_handle (void *cls)
294 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it); 293 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
295 if (NULL != handle->ns_qe) 294 if (NULL != handle->ns_qe)
296 GNUNET_NAMESTORE_cancel (handle->ns_qe); 295 GNUNET_NAMESTORE_cancel (handle->ns_qe);
297 if (NULL != handle->identity_handle)
298 GNUNET_IDENTITY_disconnect (handle->identity_handle);
299 if (NULL != handle->ns_handle)
300 {
301 GNUNET_NAMESTORE_disconnect (handle->ns_handle);
302 }
303
304 for (ego_entry = handle->ego_head; NULL != ego_entry;)
305 {
306 ego_tmp = ego_entry;
307 ego_entry = ego_entry->next;
308 GNUNET_free (ego_tmp->identifier);
309 GNUNET_free (ego_tmp->keystring);
310 GNUNET_free (ego_tmp);
311 }
312 296
313 if (NULL != handle->resp_object) 297 if (NULL != handle->resp_object)
314 { 298 {
@@ -368,7 +352,7 @@ get_egoentry_namestore (struct RequestHandle *handle, char *name)
368 if (NULL == name) 352 if (NULL == name)
369 return NULL; 353 return NULL;
370 tmp = strtok (copy, "/"); 354 tmp = strtok (copy, "/");
371 for (ego_entry = handle->ego_head; NULL != ego_entry; 355 for (ego_entry = ego_head; NULL != ego_entry;
372 ego_entry = ego_entry->next) 356 ego_entry = ego_entry->next)
373 { 357 {
374 if (0 != strcasecmp (tmp, ego_entry->identifier)) 358 if (0 != strcasecmp (tmp, ego_entry->identifier))
@@ -647,7 +631,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
647 if (1 >= strlen (labelname)) 631 if (1 >= strlen (labelname))
648 { 632 {
649 handle->list_it = 633 handle->list_it =
650 GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, 634 GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
651 handle->zone_pkey, 635 handle->zone_pkey,
652 &namestore_iteration_error, 636 &namestore_iteration_error,
653 handle, 637 handle,
@@ -664,7 +648,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
664 return; 648 return;
665 } 649 }
666 handle->record_name = GNUNET_strdup (labelname + 1); 650 handle->record_name = GNUNET_strdup (labelname + 1);
667 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, 651 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
668 handle->zone_pkey, 652 handle->zone_pkey,
669 handle->record_name, 653 handle->record_name,
670 &ns_lookup_error_cb, 654 &ns_lookup_error_cb,
@@ -699,7 +683,7 @@ ns_lookup_cb (void *cls,
699 } 683 }
700 for (j = 0; j < handle->rd_count; j++) 684 for (j = 0; j < handle->rd_count; j++)
701 rd_new[i + j] = handle->rd[j]; 685 rd_new[i + j] = handle->rd[j];
702 handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 686 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
703 handle->zone_pkey, 687 handle->zone_pkey,
704 handle->record_name, 688 handle->record_name,
705 i + j, 689 i + j,
@@ -791,7 +775,7 @@ namestore_add_or_update (struct GNUNET_REST_RequestHandle *con_handle,
791 return; 775 return;
792 } 776 }
793 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 777 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
794 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, 778 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
795 handle->zone_pkey, 779 handle->zone_pkey,
796 handle->record_name, 780 handle->record_name,
797 &ns_lookup_error_cb, 781 &ns_lookup_error_cb,
@@ -892,7 +876,7 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
892 } 876 }
893 877
894 handle->record_name = GNUNET_strdup (labelname + 1); 878 handle->record_name = GNUNET_strdup (labelname + 1);
895 handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 879 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
896 handle->zone_pkey, 880 handle->zone_pkey,
897 handle->record_name, 881 handle->record_name,
898 0, 882 0,
@@ -932,90 +916,79 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
932} 916}
933 917
934 918
935/**
936 * Handle rest request
937 *
938 * @param handle the request handle
939 */
940static void
941init_cont (struct RequestHandle *handle)
942{
943 struct GNUNET_REST_RequestHandlerError err;
944 static const struct GNUNET_REST_RequestHandler handlers[] =
945 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
946 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
947 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
948 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete },
949 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
950 GNUNET_REST_HANDLER_END };
951
952 if (GNUNET_NO ==
953 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
954 {
955 handle->response_code = err.error_code;
956 GNUNET_SCHEDULER_add_now (&do_error, handle);
957 }
958}
959
960
961/**
962 * This function is initially called for all egos and then again
963 * whenever a ego's identifier changes or if it is deleted. At the
964 * end of the initial pass over all egos, the function is once called
965 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
966 * be invoked in the future or that there was an error.
967 *
968 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
969 * this function is only called ONCE, and 'NULL' being passed in
970 * 'ego' does indicate an error (i.e. name is taken or no default
971 * value is known). If 'ego' is non-NULL and if '*ctx'
972 * is set in those callbacks, the value WILL be passed to a subsequent
973 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
974 * that one was not NULL).
975 *
976 * When an identity is renamed, this function is called with the
977 * (known) ego but the NEW identifier.
978 *
979 * When an identity is deleted, this function is called with the
980 * (known) ego and "NULL" for the 'identifier'. In this case,
981 * the 'ego' is henceforth invalid (and the 'ctx' should also be
982 * cleaned up).
983 *
984 * @param cls closure
985 * @param ego ego handle
986 * @param ctx context for application to store data for this ego
987 * (during the lifetime of this process, initially NULL)
988 * @param name identifier assigned by the user for this ego,
989 * NULL if the user just deleted the ego and it
990 * must thus no longer be used
991 */
992static void 919static void
993id_connect_cb (void *cls, 920list_ego (void *cls,
994 struct GNUNET_IDENTITY_Ego *ego, 921 struct GNUNET_IDENTITY_Ego *ego,
995 void **ctx, 922 void **ctx,
996 const char *name) 923 const char *identifier)
997{ 924{
998 struct RequestHandle *handle = cls;
999 struct EgoEntry *ego_entry; 925 struct EgoEntry *ego_entry;
1000 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 926 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1001 927
1002 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 928 if ((NULL == ego) && (ID_REST_STATE_INIT == state))
1003 { 929 {
1004 handle->state = ID_REST_STATE_POST_INIT; 930 state = ID_REST_STATE_POST_INIT;
1005 init_cont (handle);
1006 return; 931 return;
1007 } 932 }
1008 if (ID_REST_STATE_INIT == handle->state) 933 if (ID_REST_STATE_INIT == state)
1009 { 934 {
1010 ego_entry = GNUNET_new (struct EgoEntry); 935 ego_entry = GNUNET_new (struct EgoEntry);
1011 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 936 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1012 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 937 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1013 ego_entry->ego = ego; 938 ego_entry->ego = ego;
1014 GNUNET_asprintf (&ego_entry->identifier, "%s", name); 939 ego_entry->identifier = GNUNET_strdup (identifier);
1015 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 940 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1016 handle->ego_tail, 941 ego_tail,
1017 ego_entry); 942 ego_entry);
1018 } 943 }
944 /* Ego renamed or added */
945 if (identifier != NULL)
946 {
947 for (ego_entry = ego_head; NULL != ego_entry;
948 ego_entry = ego_entry->next)
949 {
950 if (ego_entry->ego == ego)
951 {
952 /* Rename */
953 GNUNET_free (ego_entry->identifier);
954 ego_entry->identifier = GNUNET_strdup (identifier);
955 break;
956 }
957 }
958 if (NULL == ego_entry)
959 {
960 /* Add */
961 ego_entry = GNUNET_new (struct EgoEntry);
962 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
963 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
964 ego_entry->ego = ego;
965 ego_entry->identifier = GNUNET_strdup (identifier);
966 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
967 ego_tail,
968 ego_entry);
969 }
970 }
971 else
972 {
973 /* Delete */
974 for (ego_entry = ego_head; NULL != ego_entry;
975 ego_entry = ego_entry->next)
976 {
977 if (ego_entry->ego == ego)
978 break;
979 }
980 if (NULL == ego_entry)
981 return; /* Not found */
982
983 GNUNET_CONTAINER_DLL_remove (ego_head,
984 ego_tail,
985 ego_entry);
986 GNUNET_free (ego_entry->identifier);
987 GNUNET_free (ego_entry->keystring);
988 GNUNET_free (ego_entry);
989 return;
990 }
991
1019} 992}
1020 993
1021 994
@@ -1030,12 +1003,20 @@ id_connect_cb (void *cls,
1030 * @param proc_cls closure for callback function 1003 * @param proc_cls closure for callback function
1031 * @return GNUNET_OK if request accepted 1004 * @return GNUNET_OK if request accepted
1032 */ 1005 */
1033static void 1006static enum GNUNET_GenericReturnValue
1034rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 1007rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1035 GNUNET_REST_ResultProcessor proc, 1008 GNUNET_REST_ResultProcessor proc,
1036 void *proc_cls) 1009 void *proc_cls)
1037{ 1010{
1038 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 1011 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1012 struct GNUNET_REST_RequestHandlerError err;
1013 static const struct GNUNET_REST_RequestHandler handlers[] =
1014 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
1015 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
1016 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
1017 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete },
1018 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
1019 GNUNET_REST_HANDLER_END };
1039 1020
1040 handle->response_code = 0; 1021 handle->response_code = 0;
1041 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1022 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1048,14 +1029,18 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1048 if (handle->url[strlen (handle->url) - 1] == '/') 1029 if (handle->url[strlen (handle->url) - 1] == '/')
1049 handle->url[strlen (handle->url) - 1] = '\0'; 1030 handle->url[strlen (handle->url) - 1] = '\0';
1050 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 1031 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1032 if (GNUNET_NO ==
1033 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1034 {
1035 cleanup_handle (handle);
1036 return GNUNET_NO;
1037 }
1051 1038
1052 handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
1053 handle->identity_handle =
1054 GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle);
1055 handle->timeout_task = 1039 handle->timeout_task =
1056 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); 1040 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1057 1041
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 1042 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1043 return GNUNET_YES;
1059} 1044}
1060 1045
1061 1046
@@ -1087,6 +1072,8 @@ libgnunet_plugin_rest_namestore_init (void *cls)
1087 MHD_HTTP_METHOD_PUT, 1072 MHD_HTTP_METHOD_PUT,
1088 MHD_HTTP_METHOD_DELETE, 1073 MHD_HTTP_METHOD_DELETE,
1089 MHD_HTTP_METHOD_OPTIONS); 1074 MHD_HTTP_METHOD_OPTIONS);
1075 ns_handle = GNUNET_NAMESTORE_connect (cfg);
1076 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
1090 1077
1091 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n")); 1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n"));
1092 return api; 1079 return api;
@@ -1104,8 +1091,23 @@ libgnunet_plugin_rest_namestore_done (void *cls)
1104{ 1091{
1105 struct GNUNET_REST_Plugin *api = cls; 1092 struct GNUNET_REST_Plugin *api = cls;
1106 struct Plugin *plugin = api->cls; 1093 struct Plugin *plugin = api->cls;
1094 struct EgoEntry *ego_entry;
1095 struct EgoEntry *ego_tmp;
1107 1096
1108 plugin->cfg = NULL; 1097 plugin->cfg = NULL;
1098 if (NULL != identity_handle)
1099 GNUNET_IDENTITY_disconnect (identity_handle);
1100 if (NULL != ns_handle)
1101 GNUNET_NAMESTORE_disconnect (ns_handle);
1102
1103 for (ego_entry = ego_head; NULL != ego_entry;)
1104 {
1105 ego_tmp = ego_entry;
1106 ego_entry = ego_entry->next;
1107 GNUNET_free (ego_tmp->identifier);
1108 GNUNET_free (ego_tmp->keystring);
1109 GNUNET_free (ego_tmp);
1110 }
1109 1111
1110 GNUNET_free (allow_methods); 1112 GNUNET_free (allow_methods);
1111 GNUNET_free (api); 1113 GNUNET_free (api);