diff options
author | t3sserakt <t3ss@posteo.de> | 2020-08-06 16:25:51 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2020-08-06 16:25:51 +0200 |
commit | 38193fe48a572e475b4f84717ff5b3edbcaf2d2a (patch) | |
tree | d6deeb56d81f75ab411d88a03b865f7da7eaaed4 /src | |
parent | 33954ae13d4d26cefa45ac86f5e2184b6abd724f (diff) | |
parent | 6ab14a20690a499ad32e3f2ad448d64d4e6b65fc (diff) | |
download | gnunet-38193fe48a572e475b4f84717ff5b3edbcaf2d2a.tar.gz gnunet-38193fe48a572e475b4f84717ff5b3edbcaf2d2a.zip |
Merge branch 'master' of ssh://gnunet.org/gnunet
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/plugin_rest_gns.c | 65 | ||||
-rw-r--r-- | src/identity/plugin_rest_identity.c | 290 | ||||
-rw-r--r-- | src/include/gnunet_buffer_lib.h | 6 | ||||
-rw-r--r-- | src/include/gnunet_rest_plugin.h | 8 | ||||
-rw-r--r-- | src/include/gnunet_strings_lib.h | 24 | ||||
-rw-r--r-- | src/namestore/namestore_api.c | 2 | ||||
-rw-r--r-- | src/namestore/plugin_rest_namestore.c | 242 | ||||
-rw-r--r-- | src/peerinfo-tool/plugin_rest_peerinfo.c | 66 | ||||
-rw-r--r-- | src/reclaim/gnunet-service-reclaim.c | 4 | ||||
-rw-r--r-- | src/reclaim/oidc_helper.c | 532 | ||||
-rw-r--r-- | src/reclaim/oidc_helper.h | 39 | ||||
-rw-r--r-- | src/reclaim/plugin_rest_openid_connect.c | 823 | ||||
-rw-r--r-- | src/reclaim/plugin_rest_reclaim.c | 296 | ||||
-rw-r--r-- | src/reclaim/reclaim_api.c | 2 | ||||
-rw-r--r-- | src/rest/gnunet-rest-server.c | 379 | ||||
-rw-r--r-- | src/rest/plugin_rest_config.c | 7 | ||||
-rw-r--r-- | src/rest/plugin_rest_copying.c | 32 | ||||
-rw-r--r-- | src/transport/transport-testing2.c | 9 | ||||
-rw-r--r-- | src/util/buffer.c | 21 | ||||
-rw-r--r-- | src/util/strings.c | 158 | ||||
-rw-r--r-- | src/util/test_strings.c | 14 |
21 files changed, 1779 insertions, 1240 deletions
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c index 37313c529..a3006ce23 100644 --- a/src/gns/plugin_rest_gns.c +++ b/src/gns/plugin_rest_gns.c | |||
@@ -63,6 +63,11 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
63 | static char *allow_methods; | 63 | static char *allow_methods; |
64 | 64 | ||
65 | /** | 65 | /** |
66 | * Connection to GNS | ||
67 | */ | ||
68 | static struct GNUNET_GNS_Handle *gns; | ||
69 | |||
70 | /** | ||
66 | * @brief struct returned by the initialization function of the plugin | 71 | * @brief struct returned by the initialization function of the plugin |
67 | */ | 72 | */ |
68 | struct Plugin | 73 | struct Plugin |
@@ -76,11 +81,6 @@ struct Plugin | |||
76 | struct RequestHandle | 81 | struct RequestHandle |
77 | { | 82 | { |
78 | /** | 83 | /** |
79 | * Connection to GNS | ||
80 | */ | ||
81 | struct GNUNET_GNS_Handle *gns; | ||
82 | |||
83 | /** | ||
84 | * Active GNS lookup | 84 | * Active GNS lookup |
85 | */ | 85 | */ |
86 | struct GNUNET_GNS_LookupWithTldRequest *gns_lookup; | 86 | struct GNUNET_GNS_LookupWithTldRequest *gns_lookup; |
@@ -153,12 +153,6 @@ cleanup_handle (void *cls) | |||
153 | GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup); | 153 | GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup); |
154 | handle->gns_lookup = NULL; | 154 | handle->gns_lookup = NULL; |
155 | } | 155 | } |
156 | if (NULL != handle->gns) | ||
157 | { | ||
158 | GNUNET_GNS_disconnect (handle->gns); | ||
159 | handle->gns = NULL; | ||
160 | } | ||
161 | |||
162 | if (NULL != handle->timeout_task) | 156 | if (NULL != handle->timeout_task) |
163 | { | 157 | { |
164 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | 158 | GNUNET_SCHEDULER_cancel (handle->timeout_task); |
@@ -318,7 +312,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
318 | handle->record_type = GNUNET_GNSRECORD_TYPE_ANY; | 312 | handle->record_type = GNUNET_GNSRECORD_TYPE_ANY; |
319 | } | 313 | } |
320 | 314 | ||
321 | handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns, | 315 | handle->gns_lookup = GNUNET_GNS_lookup_with_tld (gns, |
322 | handle->name, | 316 | handle->name, |
323 | handle->record_type, | 317 | handle->record_type, |
324 | GNUNET_GNS_LO_DEFAULT, | 318 | GNUNET_GNS_LO_DEFAULT, |
@@ -352,29 +346,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
352 | 346 | ||
353 | 347 | ||
354 | /** | 348 | /** |
355 | * Handle rest request | ||
356 | * | ||
357 | * @param handle the request handle | ||
358 | */ | ||
359 | static void | ||
360 | init_cont (struct RequestHandle *handle) | ||
361 | { | ||
362 | struct GNUNET_REST_RequestHandlerError err; | ||
363 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
364 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont }, | ||
365 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont }, | ||
366 | GNUNET_REST_HANDLER_END }; | ||
367 | |||
368 | if (GNUNET_NO == | ||
369 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) | ||
370 | { | ||
371 | handle->response_code = err.error_code; | ||
372 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | |||
377 | /** | ||
378 | * Function processing the REST call | 349 | * Function processing the REST call |
379 | * | 350 | * |
380 | * @param method HTTP method | 351 | * @param method HTTP method |
@@ -385,12 +356,17 @@ init_cont (struct RequestHandle *handle) | |||
385 | * @param proc_cls closure for callback function | 356 | * @param proc_cls closure for callback function |
386 | * @return GNUNET_OK if request accepted | 357 | * @return GNUNET_OK if request accepted |
387 | */ | 358 | */ |
388 | static void | 359 | static enum GNUNET_GenericReturnValue |
389 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 360 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, |
390 | GNUNET_REST_ResultProcessor proc, | 361 | GNUNET_REST_ResultProcessor proc, |
391 | void *proc_cls) | 362 | void *proc_cls) |
392 | { | 363 | { |
393 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 364 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
365 | struct GNUNET_REST_RequestHandlerError err; | ||
366 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
367 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont }, | ||
368 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont }, | ||
369 | GNUNET_REST_HANDLER_END }; | ||
394 | 370 | ||
395 | handle->response_code = 0; | 371 | handle->response_code = 0; |
396 | handle->timeout = | 372 | handle->timeout = |
@@ -402,14 +378,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | |||
402 | handle->url = GNUNET_strdup (rest_handle->url); | 378 | handle->url = GNUNET_strdup (rest_handle->url); |
403 | if (handle->url[strlen (handle->url) - 1] == '/') | 379 | if (handle->url[strlen (handle->url) - 1] == '/') |
404 | handle->url[strlen (handle->url) - 1] = '\0'; | 380 | handle->url[strlen (handle->url) - 1] = '\0'; |
405 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | 381 | if (GNUNET_NO == |
406 | handle->gns = GNUNET_GNS_connect (cfg); | 382 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) |
407 | init_cont (handle); | 383 | { |
384 | cleanup_handle (handle); | ||
385 | return GNUNET_NO; | ||
386 | } | ||
387 | |||
408 | 388 | ||
409 | handle->timeout_task = | 389 | handle->timeout_task = |
410 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); | 390 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); |
411 | 391 | return GNUNET_YES; | |
412 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | ||
413 | } | 392 | } |
414 | 393 | ||
415 | 394 | ||
@@ -441,6 +420,7 @@ libgnunet_plugin_rest_gns_init (void *cls) | |||
441 | MHD_HTTP_METHOD_PUT, | 420 | MHD_HTTP_METHOD_PUT, |
442 | MHD_HTTP_METHOD_DELETE, | 421 | MHD_HTTP_METHOD_DELETE, |
443 | MHD_HTTP_METHOD_OPTIONS); | 422 | MHD_HTTP_METHOD_OPTIONS); |
423 | gns = GNUNET_GNS_connect (cfg); | ||
444 | 424 | ||
445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n")); | 425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n")); |
446 | return api; | 426 | return api; |
@@ -460,6 +440,9 @@ libgnunet_plugin_rest_gns_done (void *cls) | |||
460 | struct Plugin *plugin = api->cls; | 440 | struct Plugin *plugin = api->cls; |
461 | 441 | ||
462 | plugin->cfg = NULL; | 442 | plugin->cfg = NULL; |
443 | if (NULL != gns) | ||
444 | GNUNET_GNS_disconnect (gns); | ||
445 | |||
463 | 446 | ||
464 | GNUNET_free (allow_methods); | 447 | GNUNET_free (allow_methods); |
465 | GNUNET_free (api); | 448 | GNUNET_free (api); |
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c index 02e42d03f..6859396d6 100644 --- a/src/identity/plugin_rest_identity.c +++ b/src/identity/plugin_rest_identity.c | |||
@@ -127,6 +127,26 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
127 | static char *allow_methods; | 127 | static char *allow_methods; |
128 | 128 | ||
129 | /** | 129 | /** |
130 | * Ego list | ||
131 | */ | ||
132 | static struct EgoEntry *ego_head; | ||
133 | |||
134 | /** | ||
135 | * Ego list | ||
136 | */ | ||
137 | static struct EgoEntry *ego_tail; | ||
138 | |||
139 | /** | ||
140 | * The processing state | ||
141 | */ | ||
142 | static int state; | ||
143 | |||
144 | /** | ||
145 | * Handle to Identity service. | ||
146 | */ | ||
147 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
148 | |||
149 | /** | ||
130 | * @brief struct returned by the initialization function of the plugin | 150 | * @brief struct returned by the initialization function of the plugin |
131 | */ | 151 | */ |
132 | struct Plugin | 152 | struct Plugin |
@@ -185,27 +205,6 @@ struct RequestHandle | |||
185 | */ | 205 | */ |
186 | size_t data_size; | 206 | size_t data_size; |
187 | 207 | ||
188 | |||
189 | /** | ||
190 | * Ego list | ||
191 | */ | ||
192 | struct EgoEntry *ego_head; | ||
193 | |||
194 | /** | ||
195 | * Ego list | ||
196 | */ | ||
197 | struct EgoEntry *ego_tail; | ||
198 | |||
199 | /** | ||
200 | * The processing state | ||
201 | */ | ||
202 | int state; | ||
203 | |||
204 | /** | ||
205 | * Handle to Identity service. | ||
206 | */ | ||
207 | struct GNUNET_IDENTITY_Handle *identity_handle; | ||
208 | |||
209 | /** | 208 | /** |
210 | * IDENTITY Operation | 209 | * IDENTITY Operation |
211 | */ | 210 | */ |
@@ -260,8 +259,6 @@ static void | |||
260 | cleanup_handle (void *cls) | 259 | cleanup_handle (void *cls) |
261 | { | 260 | { |
262 | struct RequestHandle *handle = cls; | 261 | struct RequestHandle *handle = cls; |
263 | struct EgoEntry *ego_entry; | ||
264 | struct EgoEntry *ego_tmp; | ||
265 | 262 | ||
266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); | 263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); |
267 | if (NULL != handle->timeout_task) | 264 | if (NULL != handle->timeout_task) |
@@ -276,17 +273,6 @@ cleanup_handle (void *cls) | |||
276 | GNUNET_free (handle->emsg); | 273 | GNUNET_free (handle->emsg); |
277 | if (NULL != handle->name) | 274 | if (NULL != handle->name) |
278 | GNUNET_free (handle->name); | 275 | GNUNET_free (handle->name); |
279 | if (NULL != handle->identity_handle) | ||
280 | GNUNET_IDENTITY_disconnect (handle->identity_handle); | ||
281 | |||
282 | for (ego_entry = handle->ego_head; NULL != ego_entry;) | ||
283 | { | ||
284 | ego_tmp = ego_entry; | ||
285 | ego_entry = ego_entry->next; | ||
286 | GNUNET_free (ego_tmp->identifier); | ||
287 | GNUNET_free (ego_tmp->keystring); | ||
288 | GNUNET_free (ego_tmp); | ||
289 | } | ||
290 | 276 | ||
291 | GNUNET_free (handle); | 277 | GNUNET_free (handle); |
292 | } | 278 | } |
@@ -338,7 +324,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name) | |||
338 | 324 | ||
339 | if (NULL != pubkey) | 325 | if (NULL != pubkey) |
340 | { | 326 | { |
341 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 327 | for (ego_entry = ego_head; NULL != ego_entry; |
342 | ego_entry = ego_entry->next) | 328 | ego_entry = ego_entry->next) |
343 | { | 329 | { |
344 | if (0 != strcasecmp (pubkey, ego_entry->keystring)) | 330 | if (0 != strcasecmp (pubkey, ego_entry->keystring)) |
@@ -348,7 +334,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name) | |||
348 | } | 334 | } |
349 | if (NULL != name) | 335 | if (NULL != name) |
350 | { | 336 | { |
351 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 337 | for (ego_entry = ego_head; NULL != ego_entry; |
352 | ego_entry = ego_entry->next) | 338 | ego_entry = ego_entry->next) |
353 | { | 339 | { |
354 | if (0 != strcasecmp (name, ego_entry->identifier)) | 340 | if (0 != strcasecmp (name, ego_entry->identifier)) |
@@ -438,7 +424,7 @@ ego_get_subsystem (struct GNUNET_REST_RequestHandle *con_handle, | |||
438 | // requested default identity of subsystem | 424 | // requested default identity of subsystem |
439 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem); | 425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem); |
440 | 426 | ||
441 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | 427 | handle->op = GNUNET_IDENTITY_get (identity_handle, |
442 | subsystem, | 428 | subsystem, |
443 | &ego_get_for_subsystem, | 429 | &ego_get_for_subsystem, |
444 | handle); | 430 | handle); |
@@ -476,7 +462,7 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle, | |||
476 | 462 | ||
477 | json_root = json_array (); | 463 | json_root = json_array (); |
478 | // Return ego/egos | 464 | // Return ego/egos |
479 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 465 | for (ego_entry = ego_head; NULL != ego_entry; |
480 | ego_entry = ego_entry->next) | 466 | ego_entry = ego_entry->next) |
481 | { | 467 | { |
482 | json_ego = json_object (); | 468 | json_ego = json_object (); |
@@ -766,7 +752,7 @@ ego_edit (struct RequestHandle *handle, struct EgoEntry *ego_entry) | |||
766 | json_decref (data_js); | 752 | json_decref (data_js); |
767 | return; | 753 | return; |
768 | } | 754 | } |
769 | handle->op = GNUNET_IDENTITY_rename (handle->identity_handle, | 755 | handle->op = GNUNET_IDENTITY_rename (identity_handle, |
770 | ego_entry->identifier, | 756 | ego_entry->identifier, |
771 | newname, | 757 | newname, |
772 | &do_finished, | 758 | &do_finished, |
@@ -956,7 +942,7 @@ ego_edit_subsystem (struct GNUNET_REST_RequestHandle *con_handle, | |||
956 | } | 942 | } |
957 | 943 | ||
958 | handle->response_code = MHD_HTTP_NO_CONTENT; | 944 | handle->response_code = MHD_HTTP_NO_CONTENT; |
959 | handle->op = GNUNET_IDENTITY_set (handle->identity_handle, | 945 | handle->op = GNUNET_IDENTITY_set (identity_handle, |
960 | newsubsys, | 946 | newsubsys, |
961 | ego_entry->ego, | 947 | ego_entry->ego, |
962 | &do_finished, | 948 | &do_finished, |
@@ -1047,7 +1033,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, | |||
1047 | return; | 1033 | return; |
1048 | } | 1034 | } |
1049 | GNUNET_STRINGS_utf8_tolower (egoname, egoname); | 1035 | GNUNET_STRINGS_utf8_tolower (egoname, egoname); |
1050 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 1036 | for (ego_entry = ego_head; NULL != ego_entry; |
1051 | ego_entry = ego_entry->next) | 1037 | ego_entry = ego_entry->next) |
1052 | { | 1038 | { |
1053 | if (0 == strcasecmp (egoname, ego_entry->identifier)) | 1039 | if (0 == strcasecmp (egoname, ego_entry->identifier)) |
@@ -1073,7 +1059,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, | |||
1073 | pk_ptr = NULL; | 1059 | pk_ptr = NULL; |
1074 | json_decref (data_js); | 1060 | json_decref (data_js); |
1075 | handle->response_code = MHD_HTTP_CREATED; | 1061 | handle->response_code = MHD_HTTP_CREATED; |
1076 | handle->op = GNUNET_IDENTITY_create (handle->identity_handle, | 1062 | handle->op = GNUNET_IDENTITY_create (identity_handle, |
1077 | handle->name, | 1063 | handle->name, |
1078 | pk_ptr, | 1064 | pk_ptr, |
1079 | &do_finished_create, | 1065 | &do_finished_create, |
@@ -1118,7 +1104,7 @@ ego_delete_pubkey (struct GNUNET_REST_RequestHandle *con_handle, | |||
1118 | } | 1104 | } |
1119 | 1105 | ||
1120 | handle->response_code = MHD_HTTP_NO_CONTENT; | 1106 | handle->response_code = MHD_HTTP_NO_CONTENT; |
1121 | handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, | 1107 | handle->op = GNUNET_IDENTITY_delete (identity_handle, |
1122 | ego_entry->identifier, | 1108 | ego_entry->identifier, |
1123 | &do_finished, | 1109 | &do_finished, |
1124 | handle); | 1110 | handle); |
@@ -1162,7 +1148,7 @@ ego_delete_name (struct GNUNET_REST_RequestHandle *con_handle, | |||
1162 | } | 1148 | } |
1163 | 1149 | ||
1164 | handle->response_code = MHD_HTTP_NO_CONTENT; | 1150 | handle->response_code = MHD_HTTP_NO_CONTENT; |
1165 | handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, | 1151 | handle->op = GNUNET_IDENTITY_delete (identity_handle, |
1166 | ego_entry->identifier, | 1152 | ego_entry->identifier, |
1167 | &do_finished, | 1153 | &do_finished, |
1168 | handle); | 1154 | handle); |
@@ -1193,144 +1179,78 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1193 | } | 1179 | } |
1194 | 1180 | ||
1195 | 1181 | ||
1196 | /** | ||
1197 | * Handle rest request | ||
1198 | * | ||
1199 | * @param handle the request handle | ||
1200 | */ | ||
1201 | static void | ||
1202 | init_cont (struct RequestHandle *handle) | ||
1203 | { | ||
1204 | struct GNUNET_REST_RequestHandlerError err; | ||
1205 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
1206 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all }, | ||
1207 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, | ||
1208 | &ego_get_pubkey }, | ||
1209 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name }, | ||
1210 | { MHD_HTTP_METHOD_GET, | ||
1211 | GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, | ||
1212 | &ego_get_subsystem }, | ||
1213 | { MHD_HTTP_METHOD_PUT, | ||
1214 | GNUNET_REST_API_NS_IDENTITY_PUBKEY, | ||
1215 | &ego_edit_pubkey }, | ||
1216 | { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name }, | ||
1217 | { MHD_HTTP_METHOD_PUT, | ||
1218 | GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, | ||
1219 | &ego_edit_subsystem }, | ||
1220 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, | ||
1221 | { MHD_HTTP_METHOD_DELETE, | ||
1222 | GNUNET_REST_API_NS_IDENTITY_PUBKEY, | ||
1223 | &ego_delete_pubkey }, | ||
1224 | { MHD_HTTP_METHOD_DELETE, | ||
1225 | GNUNET_REST_API_NS_IDENTITY_NAME, | ||
1226 | &ego_delete_name }, | ||
1227 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, | ||
1228 | GNUNET_REST_HANDLER_END }; | ||
1229 | |||
1230 | if (GNUNET_NO == | ||
1231 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) | ||
1232 | { | ||
1233 | handle->response_code = err.error_code; | ||
1234 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1235 | } | ||
1236 | } | ||
1237 | |||
1238 | |||
1239 | /** | ||
1240 | * If listing is enabled, prints information about the egos. | ||
1241 | * | ||
1242 | * This function is initially called for all egos and then again | ||
1243 | * whenever a ego's identifier changes or if it is deleted. At the | ||
1244 | * end of the initial pass over all egos, the function is once called | ||
1245 | * with 'NULL' for 'ego'. That does NOT mean that the callback won't | ||
1246 | * be invoked in the future or that there was an error. | ||
1247 | * | ||
1248 | * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', | ||
1249 | * this function is only called ONCE, and 'NULL' being passed in | ||
1250 | * 'ego' does indicate an error (i.e. name is taken or no default | ||
1251 | * value is known). If 'ego' is non-NULL and if '*ctx' | ||
1252 | * is set in those callbacks, the value WILL be passed to a subsequent | ||
1253 | * call to the identity callback of 'GNUNET_IDENTITY_connect' (if | ||
1254 | * that one was not NULL). | ||
1255 | * | ||
1256 | * When an identity is renamed, this function is called with the | ||
1257 | * (known) ego but the NEW identifier. | ||
1258 | * | ||
1259 | * When an identity is deleted, this function is called with the | ||
1260 | * (known) ego and "NULL" for the 'identifier'. In this case, | ||
1261 | * the 'ego' is henceforth invalid (and the 'ctx' should also be | ||
1262 | * cleaned up). | ||
1263 | * | ||
1264 | * @param cls closure | ||
1265 | * @param ego ego handle | ||
1266 | * @param ctx context for application to store data for this ego | ||
1267 | * (during the lifetime of this process, initially NULL) | ||
1268 | * @param identifier identifier assigned by the user for this ego, | ||
1269 | * NULL if the user just deleted the ego and it | ||
1270 | * must thus no longer be used | ||
1271 | */ | ||
1272 | static void | 1182 | static void |
1273 | init_egos (void *cls, | 1183 | list_ego (void *cls, |
1274 | struct GNUNET_IDENTITY_Ego *ego, | 1184 | struct GNUNET_IDENTITY_Ego *ego, |
1275 | void **ctx, | 1185 | void **ctx, |
1276 | const char *identifier) | 1186 | const char *identifier) |
1277 | { | 1187 | { |
1278 | struct RequestHandle *handle = cls; | ||
1279 | struct EgoEntry *ego_entry; | 1188 | struct EgoEntry *ego_entry; |
1280 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | 1189 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; |
1281 | 1190 | ||
1282 | if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) | 1191 | if ((NULL == ego) && (ID_REST_STATE_INIT == state)) |
1283 | { | 1192 | { |
1284 | handle->state = ID_REST_STATE_POST_INIT; | 1193 | state = ID_REST_STATE_POST_INIT; |
1285 | init_cont (handle); | ||
1286 | return; | 1194 | return; |
1287 | } | 1195 | } |
1288 | if (ID_REST_STATE_INIT == handle->state) | 1196 | if (ID_REST_STATE_INIT == state) |
1289 | { | 1197 | { |
1290 | ego_entry = GNUNET_new (struct EgoEntry); | 1198 | ego_entry = GNUNET_new (struct EgoEntry); |
1291 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | 1199 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); |
1292 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | 1200 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
1293 | ego_entry->ego = ego; | 1201 | ego_entry->ego = ego; |
1294 | ego_entry->identifier = GNUNET_strdup (identifier); | 1202 | ego_entry->identifier = GNUNET_strdup (identifier); |
1295 | GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, | 1203 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, |
1296 | handle->ego_tail, | 1204 | ego_tail, |
1297 | ego_entry); | 1205 | ego_entry); |
1298 | return; | ||
1299 | } | 1206 | } |
1300 | // Check if ego exists | 1207 | /* Ego renamed or added */ |
1301 | for (ego_entry = handle->ego_head; NULL != ego_entry;) | 1208 | if (identifier != NULL) |
1302 | { | 1209 | { |
1303 | struct EgoEntry *tmp = ego_entry; | 1210 | for (ego_entry = ego_head; NULL != ego_entry; |
1304 | ego_entry = ego_entry->next; | 1211 | ego_entry = ego_entry->next) |
1305 | if (ego != tmp->ego) | ||
1306 | continue; | ||
1307 | // Deleted | ||
1308 | if (NULL == identifier) | ||
1309 | { | 1212 | { |
1310 | GNUNET_CONTAINER_DLL_remove (handle->ego_head, | 1213 | if (ego_entry->ego == ego) |
1311 | handle->ego_tail, | 1214 | { |
1312 | tmp); | 1215 | /* Rename */ |
1313 | GNUNET_free (tmp->keystring); | 1216 | GNUNET_free (ego_entry->identifier); |
1314 | GNUNET_free (tmp->identifier); | 1217 | ego_entry->identifier = GNUNET_strdup (identifier); |
1315 | GNUNET_free (tmp); | 1218 | break; |
1219 | } | ||
1316 | } | 1220 | } |
1317 | else | 1221 | if (NULL == ego_entry) |
1318 | { | 1222 | { |
1319 | // Renamed | 1223 | /* Add */ |
1320 | GNUNET_free (tmp->identifier); | 1224 | ego_entry = GNUNET_new (struct EgoEntry); |
1321 | tmp->identifier = GNUNET_strdup (identifier); | 1225 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); |
1226 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | ||
1227 | ego_entry->ego = ego; | ||
1228 | ego_entry->identifier = GNUNET_strdup (identifier); | ||
1229 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, | ||
1230 | ego_tail, | ||
1231 | ego_entry); | ||
1322 | } | 1232 | } |
1233 | } | ||
1234 | else | ||
1235 | { | ||
1236 | /* Delete */ | ||
1237 | for (ego_entry = ego_head; NULL != ego_entry; | ||
1238 | ego_entry = ego_entry->next) | ||
1239 | { | ||
1240 | if (ego_entry->ego == ego) | ||
1241 | break; | ||
1242 | } | ||
1243 | if (NULL == ego_entry) | ||
1244 | return; /* Not found */ | ||
1245 | |||
1246 | GNUNET_CONTAINER_DLL_remove (ego_head, | ||
1247 | ego_tail, | ||
1248 | ego_entry); | ||
1249 | GNUNET_free (ego_entry->identifier); | ||
1250 | GNUNET_free (ego_entry->keystring); | ||
1251 | GNUNET_free (ego_entry); | ||
1323 | return; | 1252 | return; |
1324 | } | 1253 | } |
1325 | // New ego | ||
1326 | ego_entry = GNUNET_new (struct EgoEntry); | ||
1327 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | ||
1328 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | ||
1329 | ego_entry->ego = ego; | ||
1330 | GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); | ||
1331 | GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, | ||
1332 | handle->ego_tail, | ||
1333 | ego_entry); | ||
1334 | 1254 | ||
1335 | } | 1255 | } |
1336 | 1256 | ||
@@ -1346,12 +1266,38 @@ init_egos (void *cls, | |||
1346 | * @param proc_cls closure for callback function | 1266 | * @param proc_cls closure for callback function |
1347 | * @return GNUNET_OK if request accepted | 1267 | * @return GNUNET_OK if request accepted |
1348 | */ | 1268 | */ |
1349 | static void | 1269 | static enum GNUNET_GenericReturnValue |
1350 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 1270 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, |
1351 | GNUNET_REST_ResultProcessor proc, | 1271 | GNUNET_REST_ResultProcessor proc, |
1352 | void *proc_cls) | 1272 | void *proc_cls) |
1353 | { | 1273 | { |
1354 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 1274 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
1275 | struct GNUNET_REST_RequestHandlerError err; | ||
1276 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
1277 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all }, | ||
1278 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, | ||
1279 | &ego_get_pubkey }, | ||
1280 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name }, | ||
1281 | { MHD_HTTP_METHOD_GET, | ||
1282 | GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, | ||
1283 | &ego_get_subsystem }, | ||
1284 | { MHD_HTTP_METHOD_PUT, | ||
1285 | GNUNET_REST_API_NS_IDENTITY_PUBKEY, | ||
1286 | &ego_edit_pubkey }, | ||
1287 | { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name }, | ||
1288 | { MHD_HTTP_METHOD_PUT, | ||
1289 | GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, | ||
1290 | &ego_edit_subsystem }, | ||
1291 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, | ||
1292 | { MHD_HTTP_METHOD_DELETE, | ||
1293 | GNUNET_REST_API_NS_IDENTITY_PUBKEY, | ||
1294 | &ego_delete_pubkey }, | ||
1295 | { MHD_HTTP_METHOD_DELETE, | ||
1296 | GNUNET_REST_API_NS_IDENTITY_NAME, | ||
1297 | &ego_delete_name }, | ||
1298 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, | ||
1299 | GNUNET_REST_HANDLER_END }; | ||
1300 | |||
1355 | 1301 | ||
1356 | handle->response_code = 0; | 1302 | handle->response_code = 0; |
1357 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 1303 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
@@ -1365,13 +1311,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | |||
1365 | if (handle->url[strlen (handle->url) - 1] == '/') | 1311 | if (handle->url[strlen (handle->url) - 1] == '/') |
1366 | handle->url[strlen (handle->url) - 1] = '\0'; | 1312 | handle->url[strlen (handle->url) - 1] = '\0'; |
1367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | 1313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); |
1368 | 1314 | if (GNUNET_NO == | |
1369 | handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle); | 1315 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) |
1316 | { | ||
1317 | cleanup_handle (handle); | ||
1318 | return GNUNET_NO; | ||
1319 | } | ||
1370 | 1320 | ||
1371 | handle->timeout_task = | 1321 | handle->timeout_task = |
1372 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); | 1322 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); |
1373 | |||
1374 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | 1323 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); |
1324 | return GNUNET_YES; | ||
1375 | } | 1325 | } |
1376 | 1326 | ||
1377 | 1327 | ||
@@ -1403,6 +1353,7 @@ libgnunet_plugin_rest_identity_init (void *cls) | |||
1403 | MHD_HTTP_METHOD_PUT, | 1353 | MHD_HTTP_METHOD_PUT, |
1404 | MHD_HTTP_METHOD_DELETE, | 1354 | MHD_HTTP_METHOD_DELETE, |
1405 | MHD_HTTP_METHOD_OPTIONS); | 1355 | MHD_HTTP_METHOD_OPTIONS); |
1356 | identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); | ||
1406 | 1357 | ||
1407 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n")); | 1358 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n")); |
1408 | return api; | 1359 | return api; |
@@ -1420,8 +1371,21 @@ libgnunet_plugin_rest_identity_done (void *cls) | |||
1420 | { | 1371 | { |
1421 | struct GNUNET_REST_Plugin *api = cls; | 1372 | struct GNUNET_REST_Plugin *api = cls; |
1422 | struct Plugin *plugin = api->cls; | 1373 | struct Plugin *plugin = api->cls; |
1374 | struct EgoEntry *ego_entry; | ||
1375 | struct EgoEntry *ego_tmp; | ||
1423 | 1376 | ||
1424 | plugin->cfg = NULL; | 1377 | plugin->cfg = NULL; |
1378 | if (NULL != identity_handle) | ||
1379 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
1380 | |||
1381 | for (ego_entry = ego_head; NULL != ego_entry;) | ||
1382 | { | ||
1383 | ego_tmp = ego_entry; | ||
1384 | ego_entry = ego_entry->next; | ||
1385 | GNUNET_free (ego_tmp->identifier); | ||
1386 | GNUNET_free (ego_tmp->keystring); | ||
1387 | GNUNET_free (ego_tmp); | ||
1388 | } | ||
1425 | 1389 | ||
1426 | GNUNET_free (allow_methods); | 1390 | GNUNET_free (allow_methods); |
1427 | GNUNET_free (api); | 1391 | GNUNET_free (api); |
diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h index 046aee72b..0c566df75 100644 --- a/src/include/gnunet_buffer_lib.h +++ b/src/include/gnunet_buffer_lib.h | |||
@@ -116,12 +116,12 @@ GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str); | |||
116 | * | 116 | * |
117 | * @param buf buffer to write to | 117 | * @param buf buffer to write to |
118 | * @param data data to read from | 118 | * @param data data to read from |
119 | * @param len number of bytes to copy from @a data to @a buf | 119 | * @param data_len number of bytes to copy from @a data to @a buf |
120 | */ | 120 | */ |
121 | void | 121 | void |
122 | GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, | 122 | GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, |
123 | const char *data, | 123 | const void *data, |
124 | size_t len); | 124 | size_t data_len); |
125 | 125 | ||
126 | 126 | ||
127 | /** | 127 | /** |
diff --git a/src/include/gnunet_rest_plugin.h b/src/include/gnunet_rest_plugin.h index 770ba66f2..96454f66b 100644 --- a/src/include/gnunet_rest_plugin.h +++ b/src/include/gnunet_rest_plugin.h | |||
@@ -69,10 +69,12 @@ struct GNUNET_REST_Plugin | |||
69 | * @param data_size the length of the data | 69 | * @param data_size the length of the data |
70 | * @param proc the callback for result | 70 | * @param proc the callback for result |
71 | * @param proc_cls closure for callback | 71 | * @param proc_cls closure for callback |
72 | * @return GNUNET_YES if the request was processed | ||
72 | */ | 73 | */ |
73 | void (*process_request) (struct GNUNET_REST_RequestHandle *handle, | 74 | enum GNUNET_GenericReturnValue (*process_request)( |
74 | GNUNET_REST_ResultProcessor proc, | 75 | struct GNUNET_REST_RequestHandle *handle, |
75 | void *proc_cls); | 76 | GNUNET_REST_ResultProcessor proc, |
77 | void *proc_cls); | ||
76 | }; | 78 | }; |
77 | 79 | ||
78 | 80 | ||
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 663b44194..8d829d42e 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -350,6 +350,18 @@ GNUNET_STRINGS_base64_encode (const void *in, | |||
350 | 350 | ||
351 | 351 | ||
352 | /** | 352 | /** |
353 | * url/percent encode (RFC3986). | ||
354 | * | ||
355 | * @param data the data to decode | ||
356 | * @param len the length of the input | ||
357 | * @param output where to write the output (*output should be NULL, | ||
358 | * is allocated) | ||
359 | * @return the size of the output | ||
360 | */ | ||
361 | size_t | ||
362 | GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out); | ||
363 | |||
364 | /** | ||
353 | * Encode into Base64url. RFC7515 | 365 | * Encode into Base64url. RFC7515 |
354 | * | 366 | * |
355 | * @param in the data to encode | 367 | * @param in the data to encode |
@@ -389,6 +401,18 @@ GNUNET_STRINGS_base64_decode (const char *data, | |||
389 | size_t | 401 | size_t |
390 | GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out); | 402 | GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out); |
391 | 403 | ||
404 | /** | ||
405 | * url/percent encode (RFC3986). | ||
406 | * | ||
407 | * @param data the data to encode | ||
408 | * @param len the length of the input | ||
409 | * @param output where to write the output (*output should be NULL, | ||
410 | * is allocated) | ||
411 | * @return the size of the output | ||
412 | */ | ||
413 | size_t | ||
414 | GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out); | ||
415 | |||
392 | 416 | ||
393 | /** | 417 | /** |
394 | * Convert a peer path to a human-readable string. | 418 | * Convert a peer path to a human-readable string. |
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index 2a085cf04..f383f8b4a 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c | |||
@@ -373,6 +373,8 @@ handle_record_store_response (void *cls, | |||
373 | emsg = _ ("Namestore failed to store record\n"); | 373 | emsg = _ ("Namestore failed to store record\n"); |
374 | else | 374 | else |
375 | emsg = NULL; | 375 | emsg = NULL; |
376 | if (NULL == qe) | ||
377 | return; | ||
376 | if (NULL != qe->cont) | 378 | if (NULL != qe->cont) |
377 | qe->cont (qe->cont_cls, res, emsg); | 379 | qe->cont (qe->cont_cls, res, emsg); |
378 | free_qe (qe); | 380 | free_qe (qe); |
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; | |||
85 | static char *allow_methods; | 85 | static char *allow_methods; |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * Ego list | ||
89 | */ | ||
90 | static struct EgoEntry *ego_head; | ||
91 | |||
92 | /** | ||
93 | * Ego list | ||
94 | */ | ||
95 | static struct EgoEntry *ego_tail; | ||
96 | |||
97 | /** | ||
98 | * The processing state | ||
99 | */ | ||
100 | static int state; | ||
101 | |||
102 | /** | ||
103 | * Handle to NAMESTORE | ||
104 | */ | ||
105 | static struct GNUNET_NAMESTORE_Handle *ns_handle; | ||
106 | |||
107 | /** | ||
108 | * Handle to Identity service. | ||
109 | */ | ||
110 | static 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 | */ |
90 | struct Plugin | 115 | struct 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 | |||
264 | cleanup_handle (void *cls) | 265 | cleanup_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 | */ | ||
940 | static void | ||
941 | init_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 | */ | ||
992 | static void | 919 | static void |
993 | id_connect_cb (void *cls, | 920 | list_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 | */ |
1033 | static void | 1006 | static enum GNUNET_GenericReturnValue |
1034 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 1007 | rest_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); |
diff --git a/src/peerinfo-tool/plugin_rest_peerinfo.c b/src/peerinfo-tool/plugin_rest_peerinfo.c index 1ab6d6f75..1d7461b1a 100644 --- a/src/peerinfo-tool/plugin_rest_peerinfo.c +++ b/src/peerinfo-tool/plugin_rest_peerinfo.c | |||
@@ -70,7 +70,12 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
70 | /** | 70 | /** |
71 | * HTTP methods allows for this plugin | 71 | * HTTP methods allows for this plugin |
72 | */ | 72 | */ |
73 | static char*allow_methods; | 73 | static char *allow_methods; |
74 | |||
75 | /** | ||
76 | * Handle to PEERINFO | ||
77 | */ | ||
78 | static struct GNUNET_PEERINFO_Handle *peerinfo_handle; | ||
74 | 79 | ||
75 | /** | 80 | /** |
76 | * @brief struct returned by the initialization function of the plugin | 81 | * @brief struct returned by the initialization function of the plugin |
@@ -204,10 +209,6 @@ struct RequestHandle | |||
204 | */ | 209 | */ |
205 | struct GNUNET_PEERINFO_IteratorContext *list_it; | 210 | struct GNUNET_PEERINFO_IteratorContext *list_it; |
206 | 211 | ||
207 | /** | ||
208 | * Handle to PEERINFO | ||
209 | */ | ||
210 | struct GNUNET_PEERINFO_Handle *peerinfo_handle; | ||
211 | 212 | ||
212 | /** | 213 | /** |
213 | * Rest connection | 214 | * Rest connection |
@@ -294,10 +295,10 @@ cleanup_handle (void *cls) | |||
294 | GNUNET_PEERINFO_iterate_cancel (handle->list_it); | 295 | GNUNET_PEERINFO_iterate_cancel (handle->list_it); |
295 | handle->list_it = NULL; | 296 | handle->list_it = NULL; |
296 | } | 297 | } |
297 | if (NULL != handle->peerinfo_handle) | 298 | if (NULL != peerinfo_handle) |
298 | { | 299 | { |
299 | GNUNET_PEERINFO_disconnect (handle->peerinfo_handle); | 300 | GNUNET_PEERINFO_disconnect (peerinfo_handle); |
300 | handle->peerinfo_handle = NULL; | 301 | peerinfo_handle = NULL; |
301 | } | 302 | } |
302 | 303 | ||
303 | GNUNET_free (handle); | 304 | GNUNET_free (handle); |
@@ -664,7 +665,7 @@ peerinfo_get (struct GNUNET_REST_RequestHandle *con_handle, | |||
664 | // specific_peer = GNUNET_PEER_resolve2(peer_id); | 665 | // specific_peer = GNUNET_PEER_resolve2(peer_id); |
665 | } | 666 | } |
666 | 667 | ||
667 | handle->list_it = GNUNET_PEERINFO_iterate (handle->peerinfo_handle, | 668 | handle->list_it = GNUNET_PEERINFO_iterate (peerinfo_handle, |
668 | include_friend_only, | 669 | include_friend_only, |
669 | specific_peer, | 670 | specific_peer, |
670 | &peerinfo_list_iteration, | 671 | &peerinfo_list_iteration, |
@@ -699,32 +700,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
699 | 700 | ||
700 | 701 | ||
701 | /** | 702 | /** |
702 | * Handle rest request | ||
703 | * | ||
704 | * @param handle the request handle | ||
705 | */ | ||
706 | static void | ||
707 | init_cont (struct RequestHandle *handle) | ||
708 | { | ||
709 | struct GNUNET_REST_RequestHandlerError err; | ||
710 | static const struct GNUNET_REST_RequestHandler handlers[] = { | ||
711 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get }, | ||
712 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont }, | ||
713 | GNUNET_REST_HANDLER_END | ||
714 | }; | ||
715 | |||
716 | if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, | ||
717 | handlers, | ||
718 | &err, | ||
719 | handle)) | ||
720 | { | ||
721 | handle->response_code = err.error_code; | ||
722 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | |||
727 | /** | ||
728 | * Function processing the REST call | 703 | * Function processing the REST call |
729 | * | 704 | * |
730 | * @param method HTTP method | 705 | * @param method HTTP method |
@@ -735,12 +710,18 @@ init_cont (struct RequestHandle *handle) | |||
735 | * @param proc_cls closure for callback function | 710 | * @param proc_cls closure for callback function |
736 | * @return GNUNET_OK if request accepted | 711 | * @return GNUNET_OK if request accepted |
737 | */ | 712 | */ |
738 | static void | 713 | static enum GNUNET_GenericReturnValue |
739 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 714 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, |
740 | GNUNET_REST_ResultProcessor proc, | 715 | GNUNET_REST_ResultProcessor proc, |
741 | void *proc_cls) | 716 | void *proc_cls) |
742 | { | 717 | { |
743 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 718 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
719 | struct GNUNET_REST_RequestHandlerError err; | ||
720 | static const struct GNUNET_REST_RequestHandler handlers[] = { | ||
721 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get }, | ||
722 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont }, | ||
723 | GNUNET_REST_HANDLER_END | ||
724 | }; | ||
744 | 725 | ||
745 | handle->response_code = 0; | 726 | handle->response_code = 0; |
746 | handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | 727 | handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, |
@@ -753,14 +734,20 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | |||
753 | if (handle->url[strlen (handle->url) - 1] == '/') | 734 | if (handle->url[strlen (handle->url) - 1] == '/') |
754 | handle->url[strlen (handle->url) - 1] = '\0'; | 735 | handle->url[strlen (handle->url) - 1] = '\0'; |
755 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | 736 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); |
756 | handle->peerinfo_handle = GNUNET_PEERINFO_connect (cfg); | 737 | if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, |
757 | init_cont (handle); | 738 | handlers, |
739 | &err, | ||
740 | handle)) | ||
741 | { | ||
742 | cleanup_handle (handle); | ||
743 | return GNUNET_NO; | ||
744 | } | ||
758 | handle->timeout_task = | 745 | handle->timeout_task = |
759 | GNUNET_SCHEDULER_add_delayed (handle->timeout, | 746 | GNUNET_SCHEDULER_add_delayed (handle->timeout, |
760 | &do_error, | 747 | &do_error, |
761 | handle); | 748 | handle); |
762 | |||
763 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | 749 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); |
750 | return GNUNET_YES; | ||
764 | } | 751 | } |
765 | 752 | ||
766 | 753 | ||
@@ -792,6 +779,7 @@ libgnunet_plugin_rest_peerinfo_init (void *cls) | |||
792 | MHD_HTTP_METHOD_PUT, | 779 | MHD_HTTP_METHOD_PUT, |
793 | MHD_HTTP_METHOD_DELETE, | 780 | MHD_HTTP_METHOD_DELETE, |
794 | MHD_HTTP_METHOD_OPTIONS); | 781 | MHD_HTTP_METHOD_OPTIONS); |
782 | peerinfo_handle = GNUNET_PEERINFO_connect (cfg); | ||
795 | 783 | ||
796 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 784 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
797 | _ ("Peerinfo REST API initialized\n")); | 785 | _ ("Peerinfo REST API initialized\n")); |
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index d4d44c3fc..0cd8c10a5 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c | |||
@@ -850,8 +850,8 @@ consume_result_cb (void *cls, | |||
850 | struct ConsumeTicketResultMessage *crm; | 850 | struct ConsumeTicketResultMessage *crm; |
851 | struct GNUNET_MQ_Envelope *env; | 851 | struct GNUNET_MQ_Envelope *env; |
852 | char *data_tmp; | 852 | char *data_tmp; |
853 | size_t attrs_len; | 853 | size_t attrs_len = 0; |
854 | size_t attests_len; | 854 | size_t attests_len = 0; |
855 | 855 | ||
856 | if (GNUNET_OK != success) | 856 | if (GNUNET_OK != success) |
857 | { | 857 | { |
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index ad2839200..9b5938c43 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -47,9 +47,9 @@ struct OIDC_Parameters | |||
47 | struct GNUNET_RECLAIM_Ticket ticket; | 47 | struct GNUNET_RECLAIM_Ticket ticket; |
48 | 48 | ||
49 | /** | 49 | /** |
50 | * The nonce | 50 | * The nonce length |
51 | */ | 51 | */ |
52 | uint32_t nonce GNUNET_PACKED; | 52 | uint32_t nonce_len GNUNET_PACKED; |
53 | 53 | ||
54 | /** | 54 | /** |
55 | * The length of the PKCE code_challenge | 55 | * The length of the PKCE code_challenge |
@@ -69,6 +69,51 @@ struct OIDC_Parameters | |||
69 | 69 | ||
70 | GNUNET_NETWORK_STRUCT_END | 70 | GNUNET_NETWORK_STRUCT_END |
71 | 71 | ||
72 | /** | ||
73 | * Standard claims represented by the "profile" scope in OIDC | ||
74 | */ | ||
75 | static char OIDC_profile_claims[14][32] = { | ||
76 | "name", "family_name", "given_name", "middle_name", "nickname", | ||
77 | "preferred_username", "profile", "picture", "website", "gender", "birthdate", | ||
78 | "zoneinfo", "locale", "updated_at" | ||
79 | }; | ||
80 | |||
81 | /** | ||
82 | * Standard claims represented by the "email" scope in OIDC | ||
83 | */ | ||
84 | static char OIDC_email_claims[2][16] = { | ||
85 | "email", "email_verified" | ||
86 | }; | ||
87 | |||
88 | /** | ||
89 | * Standard claims represented by the "phone" scope in OIDC | ||
90 | */ | ||
91 | static char OIDC_phone_claims[2][32] = { | ||
92 | "phone_number", "phone_number_verified" | ||
93 | }; | ||
94 | |||
95 | /** | ||
96 | * Standard claims represented by the "address" scope in OIDC | ||
97 | */ | ||
98 | static char OIDC_address_claims[5][32] = { | ||
99 | "street_address", "locality", "region", "postal_code", "country" | ||
100 | }; | ||
101 | |||
102 | static enum GNUNET_GenericReturnValue | ||
103 | is_claim_in_address_scope (const char *claim) | ||
104 | { | ||
105 | int i; | ||
106 | for (i = 0; i < 5; i++) | ||
107 | { | ||
108 | if (0 == strcmp (claim, OIDC_address_claims[i])) | ||
109 | { | ||
110 | return GNUNET_YES; | ||
111 | } | ||
112 | } | ||
113 | return GNUNET_NO; | ||
114 | } | ||
115 | |||
116 | |||
72 | static char * | 117 | static char * |
73 | create_jwt_header (void) | 118 | create_jwt_header (void) |
74 | { | 119 | { |
@@ -109,49 +154,22 @@ fix_base64 (char *str) | |||
109 | replace_char (str, '/', '_'); | 154 | replace_char (str, '/', '_'); |
110 | } | 155 | } |
111 | 156 | ||
112 | 157 | static json_t* | |
113 | /** | 158 | generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, |
114 | * Create a JWT from attributes | 159 | struct GNUNET_RECLAIM_AttributeList *attrs, |
115 | * | 160 | struct GNUNET_RECLAIM_AttestationList *attests) |
116 | * @param aud_key the public of the audience | ||
117 | * @param sub_key the public key of the subject | ||
118 | * @param attrs the attribute list | ||
119 | * @param expiration_time the validity of the token | ||
120 | * @param secret_key the key used to sign the JWT | ||
121 | * @return a new base64-encoded JWT string. | ||
122 | */ | ||
123 | char * | ||
124 | OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | ||
125 | const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | ||
126 | struct GNUNET_RECLAIM_AttributeList *attrs, | ||
127 | struct GNUNET_RECLAIM_AttestationList *attests, | ||
128 | const struct GNUNET_TIME_Relative *expiration_time, | ||
129 | const char *nonce, | ||
130 | const char *secret_key) | ||
131 | { | 161 | { |
132 | struct GNUNET_RECLAIM_AttributeListEntry *le; | 162 | struct GNUNET_RECLAIM_AttributeListEntry *le; |
133 | struct GNUNET_RECLAIM_AttestationListEntry *ale; | 163 | struct GNUNET_RECLAIM_AttestationListEntry *ale; |
134 | struct GNUNET_HashCode signature; | ||
135 | struct GNUNET_TIME_Absolute exp_time; | ||
136 | struct GNUNET_TIME_Absolute time_now; | ||
137 | char *audience; | ||
138 | char *subject; | 164 | char *subject; |
139 | char *header; | ||
140 | char *body_str; | ||
141 | char *aggr_names_str; | ||
142 | char *aggr_sources_str; | ||
143 | char *source_name; | 165 | char *source_name; |
144 | char *result; | ||
145 | char *header_base64; | ||
146 | char *body_base64; | ||
147 | char *signature_target; | ||
148 | char *signature_base64; | ||
149 | char *attr_val_str; | 166 | char *attr_val_str; |
150 | char *attest_val_str; | 167 | char *attest_val_str; |
151 | json_t *body; | 168 | json_t *body; |
152 | json_t *aggr_names; | 169 | json_t *aggr_names; |
153 | json_t *aggr_sources; | 170 | json_t *aggr_sources; |
154 | json_t *aggr_sources_jwt; | 171 | json_t *aggr_sources_jwt; |
172 | json_t *addr_claim = NULL; | ||
155 | int num_attestations = 0; | 173 | int num_attestations = 0; |
156 | for (le = attrs->list_head; NULL != le; le = le->next) | 174 | for (le = attrs->list_head; NULL != le; le = le->next) |
157 | { | 175 | { |
@@ -159,22 +177,10 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
159 | num_attestations++; | 177 | num_attestations++; |
160 | } | 178 | } |
161 | 179 | ||
162 | // iat REQUIRED time now | ||
163 | time_now = GNUNET_TIME_absolute_get (); | ||
164 | // exp REQUIRED time expired from config | ||
165 | exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); | ||
166 | // auth_time only if max_age | ||
167 | // nonce only if nonce | ||
168 | // OPTIONAL acr,amr,azp | ||
169 | subject = | 180 | subject = |
170 | GNUNET_STRINGS_data_to_string_alloc (sub_key, | 181 | GNUNET_STRINGS_data_to_string_alloc (sub_key, |
171 | sizeof(struct | 182 | sizeof(struct |
172 | GNUNET_CRYPTO_EcdsaPublicKey)); | 183 | GNUNET_CRYPTO_EcdsaPublicKey)); |
173 | audience = | ||
174 | GNUNET_STRINGS_data_to_string_alloc (aud_key, | ||
175 | sizeof(struct | ||
176 | GNUNET_CRYPTO_EcdsaPublicKey)); | ||
177 | header = create_jwt_header (); | ||
178 | body = json_object (); | 184 | body = json_object (); |
179 | aggr_names = json_object (); | 185 | aggr_names = json_object (); |
180 | aggr_sources = json_object (); | 186 | aggr_sources = json_object (); |
@@ -185,26 +191,7 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
185 | json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); | 191 | json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); |
186 | // sub REQUIRED public key identity, not exceed 255 ASCII length | 192 | // sub REQUIRED public key identity, not exceed 255 ASCII length |
187 | json_object_set_new (body, "sub", json_string (subject)); | 193 | json_object_set_new (body, "sub", json_string (subject)); |
188 | // aud REQUIRED public key client_id must be there | ||
189 | json_object_set_new (body, "aud", json_string (audience)); | ||
190 | // iat | ||
191 | json_object_set_new (body, | ||
192 | "iat", | ||
193 | json_integer (time_now.abs_value_us / (1000 * 1000))); | ||
194 | // exp | ||
195 | json_object_set_new (body, | ||
196 | "exp", | ||
197 | json_integer (exp_time.abs_value_us / (1000 * 1000))); | ||
198 | // nbf | ||
199 | json_object_set_new (body, | ||
200 | "nbf", | ||
201 | json_integer (time_now.abs_value_us / (1000 * 1000))); | ||
202 | // nonce | ||
203 | if (NULL != nonce) | ||
204 | json_object_set_new (body, "nonce", json_string (nonce)); | ||
205 | attest_val_str = NULL; | 194 | attest_val_str = NULL; |
206 | aggr_names_str = NULL; | ||
207 | aggr_sources_str = NULL; | ||
208 | source_name = NULL; | 195 | source_name = NULL; |
209 | int i = 0; | 196 | int i = 0; |
210 | for (ale = attests->list_head; NULL != ale; ale = ale->next) | 197 | for (ale = attests->list_head; NULL != ale; ale = ale->next) |
@@ -236,8 +223,26 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
236 | GNUNET_RECLAIM_attribute_value_to_string (le->attribute->type, | 223 | GNUNET_RECLAIM_attribute_value_to_string (le->attribute->type, |
237 | le->attribute->data, | 224 | le->attribute->data, |
238 | le->attribute->data_size); | 225 | le->attribute->data_size); |
239 | json_object_set_new (body, le->attribute->name, | 226 | /** |
240 | json_string (attr_val_str)); | 227 | * There is this wierd quirk that the individual address claim(s) must be |
228 | * inside a JSON object of the "address" claim. | ||
229 | * FIXME: Possibly include formatted claim here | ||
230 | */ | ||
231 | if (GNUNET_YES == is_claim_in_address_scope (le->attribute->name)) | ||
232 | { | ||
233 | if (NULL == addr_claim) | ||
234 | { | ||
235 | addr_claim = json_object (); | ||
236 | } | ||
237 | json_object_set_new (addr_claim, le->attribute->name, | ||
238 | json_string (attr_val_str)); | ||
239 | |||
240 | } | ||
241 | else | ||
242 | { | ||
243 | json_object_set_new (body, le->attribute->name, | ||
244 | json_string (attr_val_str)); | ||
245 | } | ||
241 | GNUNET_free (attr_val_str); | 246 | GNUNET_free (attr_val_str); |
242 | } | 247 | } |
243 | else | 248 | else |
@@ -262,21 +267,113 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
262 | GNUNET_free (source_name); | 267 | GNUNET_free (source_name); |
263 | } | 268 | } |
264 | } | 269 | } |
270 | if (NULL != addr_claim) | ||
271 | json_object_set_new (body, "address", addr_claim); | ||
265 | 272 | ||
266 | if (NULL != attest_val_str) | 273 | if (NULL != attest_val_str) |
267 | GNUNET_free (attest_val_str); | 274 | GNUNET_free (attest_val_str); |
268 | if (0 != i) | 275 | if (0 != i) |
269 | { | 276 | { |
270 | aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT); | 277 | json_object_set_new (body, "_claim_names", aggr_names); |
271 | aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0) | 278 | json_object_set_new (body, "_claim_sources", aggr_sources); |
272 | | JSON_COMPACT); | ||
273 | json_object_set_new (body, "_claim_names", json_string (aggr_names_str)); | ||
274 | json_object_set_new (body, "_claim_sources", json_string ( | ||
275 | aggr_sources_str)); | ||
276 | } | 279 | } |
277 | 280 | ||
278 | json_decref (aggr_names); | 281 | return body; |
279 | json_decref (aggr_sources); | 282 | } |
283 | |||
284 | /** | ||
285 | * Generate userinfo JSON as string | ||
286 | * | ||
287 | * @param sub_key the subject (user) | ||
288 | * @param attrs user attribute list | ||
289 | * @param attests user attribute attestation list (may be empty) | ||
290 | * @return Userinfo JSON | ||
291 | */ | ||
292 | char * | ||
293 | OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | ||
294 | struct GNUNET_RECLAIM_AttributeList *attrs, | ||
295 | struct GNUNET_RECLAIM_AttestationList *attests) | ||
296 | { | ||
297 | char *body_str; | ||
298 | json_t* body = generate_userinfo_json (sub_key, | ||
299 | attrs, | ||
300 | attests); | ||
301 | body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); | ||
302 | json_decref (body); | ||
303 | return body_str; | ||
304 | } | ||
305 | |||
306 | |||
307 | /** | ||
308 | * Create a JWT from attributes | ||
309 | * | ||
310 | * @param aud_key the public of the audience | ||
311 | * @param sub_key the public key of the subject | ||
312 | * @param attrs the attribute list | ||
313 | * @param expiration_time the validity of the token | ||
314 | * @param secret_key the key used to sign the JWT | ||
315 | * @return a new base64-encoded JWT string. | ||
316 | */ | ||
317 | char * | ||
318 | OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | ||
319 | const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | ||
320 | struct GNUNET_RECLAIM_AttributeList *attrs, | ||
321 | struct GNUNET_RECLAIM_AttestationList *attests, | ||
322 | const struct GNUNET_TIME_Relative *expiration_time, | ||
323 | const char *nonce, | ||
324 | const char *secret_key) | ||
325 | { | ||
326 | struct GNUNET_HashCode signature; | ||
327 | struct GNUNET_TIME_Absolute exp_time; | ||
328 | struct GNUNET_TIME_Absolute time_now; | ||
329 | char *audience; | ||
330 | char *subject; | ||
331 | char *header; | ||
332 | char *body_str; | ||
333 | char *result; | ||
334 | char *header_base64; | ||
335 | char *body_base64; | ||
336 | char *signature_target; | ||
337 | char *signature_base64; | ||
338 | json_t *body; | ||
339 | |||
340 | body = generate_userinfo_json (sub_key, | ||
341 | attrs, | ||
342 | attests); | ||
343 | // iat REQUIRED time now | ||
344 | time_now = GNUNET_TIME_absolute_get (); | ||
345 | // exp REQUIRED time expired from config | ||
346 | exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); | ||
347 | // auth_time only if max_age | ||
348 | // nonce only if nonce | ||
349 | // OPTIONAL acr,amr,azp | ||
350 | subject = | ||
351 | GNUNET_STRINGS_data_to_string_alloc (sub_key, | ||
352 | sizeof(struct | ||
353 | GNUNET_CRYPTO_EcdsaPublicKey)); | ||
354 | audience = | ||
355 | GNUNET_STRINGS_data_to_string_alloc (aud_key, | ||
356 | sizeof(struct | ||
357 | GNUNET_CRYPTO_EcdsaPublicKey)); | ||
358 | header = create_jwt_header (); | ||
359 | |||
360 | // aud REQUIRED public key client_id must be there | ||
361 | json_object_set_new (body, "aud", json_string (audience)); | ||
362 | // iat | ||
363 | json_object_set_new (body, | ||
364 | "iat", | ||
365 | json_integer (time_now.abs_value_us / (1000 * 1000))); | ||
366 | // exp | ||
367 | json_object_set_new (body, | ||
368 | "exp", | ||
369 | json_integer (exp_time.abs_value_us / (1000 * 1000))); | ||
370 | // nbf | ||
371 | json_object_set_new (body, | ||
372 | "nbf", | ||
373 | json_integer (time_now.abs_value_us / (1000 * 1000))); | ||
374 | // nonce | ||
375 | if (NULL != nonce) | ||
376 | json_object_set_new (body, "nonce", json_string (nonce)); | ||
280 | 377 | ||
281 | body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); | 378 | body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); |
282 | json_decref (body); | 379 | json_decref (body); |
@@ -315,10 +412,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
315 | GNUNET_free (signature_target); | 412 | GNUNET_free (signature_target); |
316 | GNUNET_free (header); | 413 | GNUNET_free (header); |
317 | GNUNET_free (body_str); | 414 | GNUNET_free (body_str); |
318 | if (NULL != aggr_sources_str) | ||
319 | GNUNET_free (aggr_sources_str); | ||
320 | if (NULL != aggr_names_str) | ||
321 | GNUNET_free (aggr_names_str); | ||
322 | GNUNET_free (signature_base64); | 415 | GNUNET_free (signature_base64); |
323 | GNUNET_free (body_base64); | 416 | GNUNET_free (body_base64); |
324 | GNUNET_free (header_base64); | 417 | GNUNET_free (header_base64); |
@@ -326,89 +419,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
326 | } | 419 | } |
327 | 420 | ||
328 | 421 | ||
329 | static void | ||
330 | derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
331 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
332 | struct GNUNET_HashCode *key_material) | ||
333 | { | ||
334 | static const char ctx_key[] = "reclaim-aes-ctx-key"; | ||
335 | static const char ctx_iv[] = "reclaim-aes-ctx-iv"; | ||
336 | |||
337 | GNUNET_CRYPTO_kdf (key, | ||
338 | sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
339 | ctx_key, | ||
340 | strlen (ctx_key), | ||
341 | key_material, | ||
342 | sizeof(struct GNUNET_HashCode), | ||
343 | NULL); | ||
344 | GNUNET_CRYPTO_kdf (iv, | ||
345 | sizeof( | ||
346 | struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
347 | ctx_iv, | ||
348 | strlen (ctx_iv), | ||
349 | key_material, | ||
350 | sizeof(struct GNUNET_HashCode), | ||
351 | NULL); | ||
352 | } | ||
353 | |||
354 | |||
355 | static void | ||
356 | calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
357 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
358 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | ||
359 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub) | ||
360 | { | ||
361 | struct GNUNET_HashCode key_material; | ||
362 | |||
363 | GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material); | ||
364 | derive_aes_key (key, iv, &key_material); | ||
365 | } | ||
366 | |||
367 | |||
368 | static void | ||
369 | calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
370 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
371 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | ||
372 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv) | ||
373 | { | ||
374 | struct GNUNET_HashCode key_material; | ||
375 | |||
376 | GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material); | ||
377 | derive_aes_key (key, iv, &key_material); | ||
378 | } | ||
379 | |||
380 | |||
381 | static void | ||
382 | decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | ||
383 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, | ||
384 | const char *ct, | ||
385 | size_t ct_len, | ||
386 | char *buf) | ||
387 | { | ||
388 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
389 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
390 | |||
391 | calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub); | ||
392 | GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf)); | ||
393 | } | ||
394 | |||
395 | |||
396 | static void | ||
397 | encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | ||
398 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, | ||
399 | const char *payload, | ||
400 | size_t payload_len, | ||
401 | char *buf) | ||
402 | { | ||
403 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
404 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
405 | |||
406 | calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv); | ||
407 | GNUNET_break ( | ||
408 | GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); | ||
409 | } | ||
410 | |||
411 | |||
412 | /** | 422 | /** |
413 | * Builds an OIDC authorization code including | 423 | * Builds an OIDC authorization code including |
414 | * a reclaim ticket and nonce | 424 | * a reclaim ticket and nonce |
@@ -439,34 +449,21 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
439 | size_t attr_list_len = 0; | 449 | size_t attr_list_len = 0; |
440 | size_t attests_list_len = 0; | 450 | size_t attests_list_len = 0; |
441 | size_t code_challenge_len = 0; | 451 | size_t code_challenge_len = 0; |
442 | uint32_t nonce; | 452 | uint32_t nonce_len = 0; |
443 | uint32_t nonce_tmp; | ||
444 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 453 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
445 | struct GNUNET_CRYPTO_EcdhePrivateKey ecdh_priv; | ||
446 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub; | ||
447 | 454 | ||
448 | /** PLAINTEXT **/ | 455 | /** PLAINTEXT **/ |
449 | // Assign ticket | 456 | // Assign ticket |
450 | memset (¶ms, 0, sizeof(params)); | 457 | memset (¶ms, 0, sizeof(params)); |
451 | params.ticket = *ticket; | 458 | params.ticket = *ticket; |
452 | // Assign nonce | 459 | // Assign nonce |
453 | nonce = 0; | ||
454 | payload_len = sizeof(struct OIDC_Parameters); | 460 | payload_len = sizeof(struct OIDC_Parameters); |
455 | if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) | 461 | if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) |
456 | { | 462 | { |
457 | if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) | 463 | nonce_len = strlen (nonce_str); |
458 | { | 464 | payload_len += nonce_len; |
459 | GNUNET_break (0); | ||
460 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); | ||
461 | return NULL; | ||
462 | } | ||
463 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
464 | "Got nonce: %u from %s\n", | ||
465 | nonce, | ||
466 | nonce_str); | ||
467 | } | 465 | } |
468 | nonce_tmp = htonl (nonce); | 466 | params.nonce_len = htonl (nonce_len); |
469 | params.nonce = nonce_tmp; | ||
470 | // Assign code challenge | 467 | // Assign code challenge |
471 | if (NULL != code_challenge) | 468 | if (NULL != code_challenge) |
472 | code_challenge_len = strlen (code_challenge); | 469 | code_challenge_len = strlen (code_challenge); |
@@ -506,6 +503,11 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
506 | memcpy (tmp, code_challenge, code_challenge_len); | 503 | memcpy (tmp, code_challenge, code_challenge_len); |
507 | tmp += code_challenge_len; | 504 | tmp += code_challenge_len; |
508 | } | 505 | } |
506 | if (0 < nonce_len) | ||
507 | { | ||
508 | memcpy (tmp, nonce_str, nonce_len); | ||
509 | tmp += nonce_len; | ||
510 | } | ||
509 | if (0 < attr_list_len) | 511 | if (0 < attr_list_len) |
510 | GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp); | 512 | GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp); |
511 | if (0 < attests_list_len) | 513 | if (0 < attests_list_len) |
@@ -513,36 +515,24 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
513 | 515 | ||
514 | /** END **/ | 516 | /** END **/ |
515 | 517 | ||
516 | /** ENCRYPT **/ | ||
517 | // Get length | 518 | // Get length |
518 | code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 519 | code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
519 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) | ||
520 | + payload_len + sizeof(struct | 520 | + payload_len + sizeof(struct |
521 | GNUNET_CRYPTO_EcdsaSignature); | 521 | GNUNET_CRYPTO_EcdsaSignature); |
522 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 522 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
523 | "Length of data to encode: %lu\n", | 523 | "Length of data to encode: %lu\n", |
524 | code_payload_len); | 524 | code_payload_len); |
525 | 525 | ||
526 | // Generate ECDH key | ||
527 | GNUNET_CRYPTO_ecdhe_key_create (&ecdh_priv); | ||
528 | GNUNET_CRYPTO_ecdhe_key_get_public (&ecdh_priv, &ecdh_pub); | ||
529 | // Initialize code payload | 526 | // Initialize code payload |
530 | code_payload = GNUNET_malloc (code_payload_len); | 527 | code_payload = GNUNET_malloc (code_payload_len); |
531 | GNUNET_assert (NULL != code_payload); | 528 | GNUNET_assert (NULL != code_payload); |
532 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; | 529 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; |
533 | purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 530 | purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
534 | + sizeof(ecdh_pub) + payload_len); | 531 | + payload_len); |
535 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); | 532 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); |
536 | // Store pubkey | 533 | // Store pubkey |
537 | buf_ptr = (char *) &purpose[1]; | 534 | buf_ptr = (char *) &purpose[1]; |
538 | memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub)); | 535 | memcpy (buf_ptr, payload, payload_len); |
539 | buf_ptr += sizeof(ecdh_pub); | ||
540 | // Encrypt plaintext and store | ||
541 | encrypt_payload (&ticket->audience, | ||
542 | &ecdh_priv, | ||
543 | payload, | ||
544 | payload_len, | ||
545 | buf_ptr); | ||
546 | GNUNET_free (payload); | 536 | GNUNET_free (payload); |
547 | buf_ptr += payload_len; | 537 | buf_ptr += payload_len; |
548 | // Sign and store signature | 538 | // Sign and store signature |
@@ -570,14 +560,16 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
570 | * | 560 | * |
571 | * @param audience the expected audience of the code | 561 | * @param audience the expected audience of the code |
572 | * @param code the string representation of the code | 562 | * @param code the string representation of the code |
573 | * @param code_verfier PKCE code verifier | 563 | * @param code_verfier PKCE code verifier. Optional, must be provided |
564 | * if used in request. | ||
574 | * @param ticket where to store the ticket | 565 | * @param ticket where to store the ticket |
575 | * @param attrs the attributes in the code | 566 | * @param attrs the attributes in the code |
576 | * @param nonce where to store the nonce | 567 | * @param attests the attestations in the code (if any) |
568 | * @param nonce_str where to store the nonce (if contained) | ||
577 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 569 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
578 | */ | 570 | */ |
579 | int | 571 | int |
580 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 572 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, |
581 | const char *code, | 573 | const char *code, |
582 | const char *code_verifier, | 574 | const char *code_verifier, |
583 | struct GNUNET_RECLAIM_Ticket *ticket, | 575 | struct GNUNET_RECLAIM_Ticket *ticket, |
@@ -595,14 +587,12 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
595 | char *code_verifier_hash; | 587 | char *code_verifier_hash; |
596 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 588 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
597 | struct GNUNET_CRYPTO_EcdsaSignature *signature; | 589 | struct GNUNET_CRYPTO_EcdsaSignature *signature; |
598 | struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; | ||
599 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub; | ||
600 | uint32_t code_challenge_len; | 590 | uint32_t code_challenge_len; |
601 | uint32_t attrs_ser_len; | 591 | uint32_t attrs_ser_len; |
602 | uint32_t attests_ser_len; | 592 | uint32_t attests_ser_len; |
603 | size_t plaintext_len; | 593 | size_t plaintext_len; |
604 | size_t code_payload_len; | 594 | size_t code_payload_len; |
605 | uint32_t nonce = 0; | 595 | uint32_t nonce_len = 0; |
606 | struct OIDC_Parameters *params; | 596 | struct OIDC_Parameters *params; |
607 | 597 | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); | 598 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); |
@@ -611,7 +601,6 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
611 | GNUNET_STRINGS_base64url_decode (code, strlen (code), | 601 | GNUNET_STRINGS_base64url_decode (code, strlen (code), |
612 | (void **) &code_payload); | 602 | (void **) &code_payload); |
613 | if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 603 | if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
614 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) | ||
615 | + sizeof(struct OIDC_Parameters) | 604 | + sizeof(struct OIDC_Parameters) |
616 | + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) | 605 | + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) |
617 | { | 606 | { |
@@ -624,16 +613,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
624 | plaintext_len = code_payload_len; | 613 | plaintext_len = code_payload_len; |
625 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); | 614 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); |
626 | ptr = (char *) &purpose[1]; | 615 | ptr = (char *) &purpose[1]; |
627 | // Public ECDH key | ||
628 | ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr; | ||
629 | ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); | ||
630 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); | ||
631 | |||
632 | // Decrypt ciphertext | ||
633 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); | 616 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); |
634 | plaintext = GNUNET_malloc (plaintext_len); | 617 | plaintext = ptr; |
635 | decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); | ||
636 | // ptr = plaintext; | ||
637 | ptr += plaintext_len; | 618 | ptr += plaintext_len; |
638 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; | 619 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; |
639 | params = (struct OIDC_Parameters *) plaintext; | 620 | params = (struct OIDC_Parameters *) plaintext; |
@@ -658,11 +639,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
658 | // encode code verifier | 639 | // encode code verifier |
659 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, | 640 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, |
660 | &expected_code_challenge); | 641 | &expected_code_challenge); |
661 | code_challenge = (char *) ¶ms[1]; | 642 | code_challenge = ((char *) ¶ms[1]); |
662 | GNUNET_free (code_verifier_hash); | 643 | GNUNET_free (code_verifier_hash); |
663 | if ((strlen (expected_code_challenge) != code_challenge_len) || | 644 | if (0 != |
664 | (0 != | 645 | strncmp (expected_code_challenge, code_challenge, code_challenge_len)) |
665 | strncmp (expected_code_challenge, code_challenge, code_challenge_len))) | ||
666 | { | 646 | { |
667 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 647 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
668 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | 648 | "Invalid code verifier! Expected: %s, Got: %.*s\n", |
@@ -675,17 +655,23 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
675 | } | 655 | } |
676 | GNUNET_free (expected_code_challenge); | 656 | GNUNET_free (expected_code_challenge); |
677 | } | 657 | } |
658 | nonce_len = ntohl (params->nonce_len); | ||
659 | if (0 != nonce_len) | ||
660 | { | ||
661 | *nonce_str = GNUNET_strndup (code_challenge + code_challenge_len, | ||
662 | nonce_len); | ||
663 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %s\n", *nonce_str); | ||
664 | } | ||
665 | |||
678 | // Ticket | 666 | // Ticket |
679 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); | 667 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); |
680 | // Nonce | ||
681 | nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr)); | ||
682 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); | ||
683 | // Signature | 668 | // Signature |
684 | GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); | 669 | // GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); |
685 | if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) | 670 | if (0 != GNUNET_memcmp (audience, &ticket->audience)) |
686 | { | 671 | { |
687 | GNUNET_free (code_payload); | 672 | GNUNET_free (code_payload); |
688 | GNUNET_free (plaintext); | 673 | if (NULL != *nonce_str) |
674 | GNUNET_free (*nonce_str); | ||
689 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 675 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
690 | "Audience in ticket does not match client!\n"); | 676 | "Audience in ticket does not match client!\n"); |
691 | return GNUNET_SYSERR; | 677 | return GNUNET_SYSERR; |
@@ -697,12 +683,13 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
697 | &ticket->identity)) | 683 | &ticket->identity)) |
698 | { | 684 | { |
699 | GNUNET_free (code_payload); | 685 | GNUNET_free (code_payload); |
700 | GNUNET_free (plaintext); | 686 | if (NULL != *nonce_str) |
687 | GNUNET_free (*nonce_str); | ||
701 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); | 688 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); |
702 | return GNUNET_SYSERR; | 689 | return GNUNET_SYSERR; |
703 | } | 690 | } |
704 | // Attributes | 691 | // Attributes |
705 | attrs_ser = ((char *) ¶ms[1]) + code_challenge_len; | 692 | attrs_ser = ((char *) ¶ms[1]) + code_challenge_len + nonce_len; |
706 | attrs_ser_len = ntohl (params->attr_list_len); | 693 | attrs_ser_len = ntohl (params->attr_list_len); |
707 | *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len); | 694 | *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len); |
708 | attests_ser = ((char*) attrs_ser) + attrs_ser_len; | 695 | attests_ser = ((char*) attrs_ser) + attrs_ser_len; |
@@ -710,11 +697,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
710 | *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser, | 697 | *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser, |
711 | attests_ser_len); | 698 | attests_ser_len); |
712 | 699 | ||
713 | *nonce_str = NULL; | ||
714 | if (nonce != 0) | ||
715 | GNUNET_asprintf (nonce_str, "%u", nonce); | ||
716 | GNUNET_free (code_payload); | 700 | GNUNET_free (code_payload); |
717 | GNUNET_free (plaintext); | ||
718 | return GNUNET_OK; | 701 | return GNUNET_OK; |
719 | } | 702 | } |
720 | 703 | ||
@@ -757,15 +740,102 @@ OIDC_build_token_response (const char *access_token, | |||
757 | * Generate a new access token | 740 | * Generate a new access token |
758 | */ | 741 | */ |
759 | char * | 742 | char * |
760 | OIDC_access_token_new () | 743 | OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket) |
761 | { | 744 | { |
762 | char *access_token; | 745 | char *access_token; |
763 | uint64_t random_number; | ||
764 | 746 | ||
765 | random_number = | 747 | GNUNET_STRINGS_base64_encode (ticket, |
766 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); | 748 | sizeof(*ticket), |
767 | GNUNET_STRINGS_base64_encode (&random_number, | ||
768 | sizeof(uint64_t), | ||
769 | &access_token); | 749 | &access_token); |
770 | return access_token; | 750 | return access_token; |
771 | } | 751 | } |
752 | |||
753 | |||
754 | /** | ||
755 | * Parse an access token | ||
756 | */ | ||
757 | int | ||
758 | OIDC_access_token_parse (const char *token, | ||
759 | struct GNUNET_RECLAIM_Ticket **ticket) | ||
760 | { | ||
761 | if (sizeof (struct GNUNET_RECLAIM_Ticket) != | ||
762 | GNUNET_STRINGS_base64_decode (token, | ||
763 | strlen (token), | ||
764 | (void**) ticket)) | ||
765 | return GNUNET_SYSERR; | ||
766 | return GNUNET_OK; | ||
767 | } | ||
768 | |||
769 | |||
770 | /** | ||
771 | * Checks if a claim is implicitly requested through standard | ||
772 | * scope(s) | ||
773 | * | ||
774 | * @param scopes the scopes which have been requested | ||
775 | * @param attr the attribute name to check | ||
776 | * @return GNUNET_YES if attribute is implcitly requested | ||
777 | */ | ||
778 | enum GNUNET_GenericReturnValue | ||
779 | OIDC_check_scopes_for_claim_request (const char*scopes, | ||
780 | const char*attr) | ||
781 | { | ||
782 | char *scope_variables; | ||
783 | char *scope_variable; | ||
784 | char delimiter[] = " "; | ||
785 | int i; | ||
786 | |||
787 | scope_variables = GNUNET_strdup (scopes); | ||
788 | scope_variable = strtok (scope_variables, delimiter); | ||
789 | while (NULL != scope_variable) | ||
790 | { | ||
791 | if (0 == strcmp ("profile", scope_variable)) | ||
792 | { | ||
793 | for (i = 0; i < 14; i++) | ||
794 | { | ||
795 | if (0 == strcmp (attr, OIDC_profile_claims[i])) | ||
796 | { | ||
797 | GNUNET_free (scope_variables); | ||
798 | return GNUNET_YES; | ||
799 | } | ||
800 | } | ||
801 | } | ||
802 | else if (0 == strcmp ("address", scope_variable)) | ||
803 | { | ||
804 | for (i = 0; i < 5; i++) | ||
805 | { | ||
806 | if (0 == strcmp (attr, OIDC_address_claims[i])) | ||
807 | { | ||
808 | GNUNET_free (scope_variables); | ||
809 | return GNUNET_YES; | ||
810 | } | ||
811 | } | ||
812 | } | ||
813 | else if (0 == strcmp ("email", scope_variable)) | ||
814 | { | ||
815 | for (i = 0; i < 2; i++) | ||
816 | { | ||
817 | if (0 == strcmp (attr, OIDC_email_claims[i])) | ||
818 | { | ||
819 | GNUNET_free (scope_variables); | ||
820 | return GNUNET_YES; | ||
821 | } | ||
822 | } | ||
823 | } | ||
824 | else if (0 == strcmp ("phone", scope_variable)) | ||
825 | { | ||
826 | for (i = 0; i < 2; i++) | ||
827 | { | ||
828 | if (0 == strcmp (attr, OIDC_phone_claims[i])) | ||
829 | { | ||
830 | GNUNET_free (scope_variables); | ||
831 | return GNUNET_YES; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | } | ||
836 | scope_variable = strtok (NULL, delimiter); | ||
837 | } | ||
838 | GNUNET_free (scope_variables); | ||
839 | return GNUNET_NO; | ||
840 | |||
841 | } | ||
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index 2c533357e..e713dab62 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h | |||
@@ -49,7 +49,7 @@ | |||
49 | * @return a new base64-encoded JWT string. | 49 | * @return a new base64-encoded JWT string. |
50 | */ | 50 | */ |
51 | char* | 51 | char* |
52 | OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | 52 | OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, |
53 | const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | 53 | const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, |
54 | struct GNUNET_RECLAIM_AttributeList *attrs, | 54 | struct GNUNET_RECLAIM_AttributeList *attrs, |
55 | struct GNUNET_RECLAIM_AttestationList *attests, | 55 | struct GNUNET_RECLAIM_AttestationList *attests, |
@@ -90,7 +90,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
90 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 90 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
91 | */ | 91 | */ |
92 | int | 92 | int |
93 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 93 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, |
94 | const char *code, | 94 | const char *code, |
95 | const char *code_verifier, | 95 | const char *code_verifier, |
96 | struct GNUNET_RECLAIM_Ticket *ticket, | 96 | struct GNUNET_RECLAIM_Ticket *ticket, |
@@ -117,7 +117,40 @@ OIDC_build_token_response (const char *access_token, | |||
117 | * Generate a new access token | 117 | * Generate a new access token |
118 | */ | 118 | */ |
119 | char* | 119 | char* |
120 | OIDC_access_token_new (); | 120 | OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket); |
121 | 121 | ||
122 | /** | ||
123 | * Parse an access token | ||
124 | */ | ||
125 | int | ||
126 | OIDC_access_token_parse (const char* token, | ||
127 | struct GNUNET_RECLAIM_Ticket **ticket); | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Checks if a claim is implicitly requested through standard | ||
132 | * scope(s) | ||
133 | * | ||
134 | * @param scopes the scopes which have been requested | ||
135 | * @param attr the attribute name to check | ||
136 | * @return GNUNET_YES if attribute is implcitly requested | ||
137 | */ | ||
138 | enum GNUNET_GenericReturnValue | ||
139 | OIDC_check_scopes_for_claim_request (const char*scopes, | ||
140 | const char*attr); | ||
141 | |||
142 | |||
143 | /** | ||
144 | * Generate userinfo JSON as string | ||
145 | * | ||
146 | * @param sub_key the subject (user) | ||
147 | * @param attrs user attribute list | ||
148 | * @param attests user attribute attestation list (may be empty) | ||
149 | * @return Userinfo JSON | ||
150 | */ | ||
151 | char * | ||
152 | OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | ||
153 | struct GNUNET_RECLAIM_AttributeList *attrs, | ||
154 | struct GNUNET_RECLAIM_AttestationList *attests); | ||
122 | 155 | ||
123 | #endif | 156 | #endif |
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 36ae937c1..06e1b0061 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <inttypes.h> | 28 | #include <inttypes.h> |
29 | #include <jansson.h> | 29 | #include <jansson.h> |
30 | 30 | ||
31 | #include "gnunet_buffer_lib.h" | ||
32 | #include "gnunet_strings_lib.h" | ||
31 | #include "gnunet_gns_service.h" | 33 | #include "gnunet_gns_service.h" |
32 | #include "gnunet_gnsrecord_lib.h" | 34 | #include "gnunet_gnsrecord_lib.h" |
33 | #include "gnunet_identity_service.h" | 35 | #include "gnunet_identity_service.h" |
@@ -39,12 +41,18 @@ | |||
39 | #include "gnunet_signatures.h" | 41 | #include "gnunet_signatures.h" |
40 | #include "microhttpd.h" | 42 | #include "microhttpd.h" |
41 | #include "oidc_helper.h" | 43 | #include "oidc_helper.h" |
44 | |||
42 | /** | 45 | /** |
43 | * REST root namespace | 46 | * REST root namespace |
44 | */ | 47 | */ |
45 | #define GNUNET_REST_API_NS_OIDC "/openid" | 48 | #define GNUNET_REST_API_NS_OIDC "/openid" |
46 | 49 | ||
47 | /** | 50 | /** |
51 | * OIDC config | ||
52 | */ | ||
53 | #define GNUNET_REST_API_NS_OIDC_CONFIG "/.well-known/openid-configuration" | ||
54 | |||
55 | /** | ||
48 | * Authorize endpoint | 56 | * Authorize endpoint |
49 | */ | 57 | */ |
50 | #define GNUNET_REST_API_NS_AUTHORIZE "/openid/authorize" | 58 | #define GNUNET_REST_API_NS_AUTHORIZE "/openid/authorize" |
@@ -237,12 +245,6 @@ static char *OIDC_ignored_parameter_array[] = { "display", | |||
237 | struct GNUNET_CONTAINER_MultiHashMap *OIDC_cookie_jar_map; | 245 | struct GNUNET_CONTAINER_MultiHashMap *OIDC_cookie_jar_map; |
238 | 246 | ||
239 | /** | 247 | /** |
240 | * Hash map that links the issued access token to the corresponding ticket and | ||
241 | * ego | ||
242 | */ | ||
243 | struct GNUNET_CONTAINER_MultiHashMap *OIDC_access_token_map; | ||
244 | |||
245 | /** | ||
246 | * The configuration handle | 248 | * The configuration handle |
247 | */ | 249 | */ |
248 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 250 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
@@ -253,6 +255,36 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
253 | static char *allow_methods; | 255 | static char *allow_methods; |
254 | 256 | ||
255 | /** | 257 | /** |
258 | * Ego list | ||
259 | */ | ||
260 | static struct EgoEntry *ego_head; | ||
261 | |||
262 | /** | ||
263 | * Ego list | ||
264 | */ | ||
265 | static struct EgoEntry *ego_tail; | ||
266 | |||
267 | /** | ||
268 | * The processing state | ||
269 | */ | ||
270 | static int state; | ||
271 | |||
272 | /** | ||
273 | * Handle to Identity service. | ||
274 | */ | ||
275 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
276 | |||
277 | /** | ||
278 | * GNS handle | ||
279 | */ | ||
280 | static struct GNUNET_GNS_Handle *gns_handle; | ||
281 | |||
282 | /** | ||
283 | * Identity Provider | ||
284 | */ | ||
285 | static struct GNUNET_RECLAIM_Handle *idp; | ||
286 | |||
287 | /** | ||
256 | * @brief struct returned by the initialization function of the plugin | 288 | * @brief struct returned by the initialization function of the plugin |
257 | */ | 289 | */ |
258 | struct Plugin | 290 | struct Plugin |
@@ -325,10 +357,6 @@ struct OIDC_Variables | |||
325 | */ | 357 | */ |
326 | char *code_verifier; | 358 | char *code_verifier; |
327 | 359 | ||
328 | /** | ||
329 | * The response JSON | ||
330 | */ | ||
331 | json_t *response; | ||
332 | }; | 360 | }; |
333 | 361 | ||
334 | /** | 362 | /** |
@@ -365,15 +393,6 @@ struct EgoEntry | |||
365 | 393 | ||
366 | struct RequestHandle | 394 | struct RequestHandle |
367 | { | 395 | { |
368 | /** | ||
369 | * Ego list | ||
370 | */ | ||
371 | struct EgoEntry *ego_head; | ||
372 | |||
373 | /** | ||
374 | * Ego list | ||
375 | */ | ||
376 | struct EgoEntry *ego_tail; | ||
377 | 396 | ||
378 | /** | 397 | /** |
379 | * Selected ego | 398 | * Selected ego |
@@ -391,39 +410,14 @@ struct RequestHandle | |||
391 | struct OIDC_Variables *oidc; | 410 | struct OIDC_Variables *oidc; |
392 | 411 | ||
393 | /** | 412 | /** |
394 | * The processing state | ||
395 | */ | ||
396 | int state; | ||
397 | |||
398 | /** | ||
399 | * Handle to Identity service. | ||
400 | */ | ||
401 | struct GNUNET_IDENTITY_Handle *identity_handle; | ||
402 | |||
403 | /** | ||
404 | * Rest connection | ||
405 | */ | ||
406 | struct GNUNET_REST_RequestHandle *rest_handle; | ||
407 | |||
408 | /** | ||
409 | * GNS handle | ||
410 | */ | ||
411 | struct GNUNET_GNS_Handle *gns_handle; | ||
412 | |||
413 | /** | ||
414 | * GNS lookup op | 413 | * GNS lookup op |
415 | */ | 414 | */ |
416 | struct GNUNET_GNS_LookupRequest *gns_op; | 415 | struct GNUNET_GNS_LookupRequest *gns_op; |
417 | 416 | ||
418 | /** | 417 | /** |
419 | * Handle to NAMESTORE | 418 | * Rest connection |
420 | */ | ||
421 | struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
422 | |||
423 | /** | ||
424 | * Iterator for NAMESTORE | ||
425 | */ | 419 | */ |
426 | struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; | 420 | struct GNUNET_REST_RequestHandle *rest_handle; |
427 | 421 | ||
428 | /** | 422 | /** |
429 | * Attribute claim list for id_token | 423 | * Attribute claim list for id_token |
@@ -446,10 +440,6 @@ struct RequestHandle | |||
446 | */ | 440 | */ |
447 | struct GNUNET_IDENTITY_Operation *op; | 441 | struct GNUNET_IDENTITY_Operation *op; |
448 | 442 | ||
449 | /** | ||
450 | * Identity Provider | ||
451 | */ | ||
452 | struct GNUNET_RECLAIM_Handle *idp; | ||
453 | 443 | ||
454 | /** | 444 | /** |
455 | * Idp Operation | 445 | * Idp Operation |
@@ -531,8 +521,14 @@ struct RequestHandle | |||
531 | * Reponse code | 521 | * Reponse code |
532 | */ | 522 | */ |
533 | int response_code; | 523 | int response_code; |
524 | |||
525 | /** | ||
526 | * Public client | ||
527 | */ | ||
528 | int public_client; | ||
534 | }; | 529 | }; |
535 | 530 | ||
531 | |||
536 | /** | 532 | /** |
537 | * Cleanup lookup handle | 533 | * Cleanup lookup handle |
538 | * @param handle Handle to clean up | 534 | * @param handle Handle to clean up |
@@ -540,13 +536,10 @@ struct RequestHandle | |||
540 | static void | 536 | static void |
541 | cleanup_handle (struct RequestHandle *handle) | 537 | cleanup_handle (struct RequestHandle *handle) |
542 | { | 538 | { |
543 | struct EgoEntry *ego_entry; | ||
544 | 539 | ||
545 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); | 540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); |
546 | if (NULL != handle->timeout_task) | 541 | if (NULL != handle->timeout_task) |
547 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | 542 | GNUNET_SCHEDULER_cancel (handle->timeout_task); |
548 | if (NULL != handle->identity_handle) | ||
549 | GNUNET_IDENTITY_disconnect (handle->identity_handle); | ||
550 | if (NULL != handle->attr_it) | 543 | if (NULL != handle->attr_it) |
551 | GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); | 544 | GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); |
552 | if (NULL != handle->attest_it) | 545 | if (NULL != handle->attest_it) |
@@ -555,8 +548,6 @@ cleanup_handle (struct RequestHandle *handle) | |||
555 | GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); | 548 | GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); |
556 | if (NULL != handle->idp_op) | 549 | if (NULL != handle->idp_op) |
557 | GNUNET_RECLAIM_cancel (handle->idp_op); | 550 | GNUNET_RECLAIM_cancel (handle->idp_op); |
558 | if (NULL != handle->idp) | ||
559 | GNUNET_RECLAIM_disconnect (handle->idp); | ||
560 | GNUNET_free (handle->url); | 551 | GNUNET_free (handle->url); |
561 | GNUNET_free (handle->tld); | 552 | GNUNET_free (handle->tld); |
562 | GNUNET_free (handle->redirect_prefix); | 553 | GNUNET_free (handle->redirect_prefix); |
@@ -565,11 +556,6 @@ cleanup_handle (struct RequestHandle *handle) | |||
565 | GNUNET_free (handle->edesc); | 556 | GNUNET_free (handle->edesc); |
566 | if (NULL != handle->gns_op) | 557 | if (NULL != handle->gns_op) |
567 | GNUNET_GNS_lookup_cancel (handle->gns_op); | 558 | GNUNET_GNS_lookup_cancel (handle->gns_op); |
568 | if (NULL != handle->gns_handle) | ||
569 | GNUNET_GNS_disconnect (handle->gns_handle); | ||
570 | |||
571 | if (NULL != handle->namestore_handle) | ||
572 | GNUNET_NAMESTORE_disconnect (handle->namestore_handle); | ||
573 | if (NULL != handle->oidc) | 559 | if (NULL != handle->oidc) |
574 | { | 560 | { |
575 | GNUNET_free (handle->oidc->client_id); | 561 | GNUNET_free (handle->oidc->client_id); |
@@ -579,7 +565,6 @@ cleanup_handle (struct RequestHandle *handle) | |||
579 | GNUNET_free (handle->oidc->response_type); | 565 | GNUNET_free (handle->oidc->response_type); |
580 | GNUNET_free (handle->oidc->scope); | 566 | GNUNET_free (handle->oidc->scope); |
581 | GNUNET_free (handle->oidc->state); | 567 | GNUNET_free (handle->oidc->state); |
582 | json_decref (handle->oidc->response); | ||
583 | GNUNET_free (handle->oidc); | 568 | GNUNET_free (handle->oidc); |
584 | } | 569 | } |
585 | if (NULL!=handle->attr_idtoken_list) | 570 | if (NULL!=handle->attr_idtoken_list) |
@@ -589,15 +574,6 @@ cleanup_handle (struct RequestHandle *handle) | |||
589 | if (NULL!=handle->attests_list) | 574 | if (NULL!=handle->attests_list) |
590 | GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list); | 575 | GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list); |
591 | 576 | ||
592 | while (NULL != (ego_entry = handle->ego_head)) | ||
593 | { | ||
594 | GNUNET_CONTAINER_DLL_remove (handle->ego_head, | ||
595 | handle->ego_tail, | ||
596 | ego_entry); | ||
597 | GNUNET_free (ego_entry->identifier); | ||
598 | GNUNET_free (ego_entry->keystring); | ||
599 | GNUNET_free (ego_entry); | ||
600 | } | ||
601 | GNUNET_free (handle); | 577 | GNUNET_free (handle); |
602 | } | 578 | } |
603 | 579 | ||
@@ -655,6 +631,8 @@ do_userinfo_error (void *cls) | |||
655 | struct MHD_Response *resp; | 631 | struct MHD_Response *resp; |
656 | char *error; | 632 | char *error; |
657 | 633 | ||
634 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
635 | "Error: %s\n", handle->edesc); | ||
658 | GNUNET_asprintf (&error, | 636 | GNUNET_asprintf (&error, |
659 | "error=\"%s\", error_description=\"%s\"", | 637 | "error=\"%s\", error_description=\"%s\"", |
660 | handle->emsg, | 638 | handle->emsg, |
@@ -710,27 +688,6 @@ do_timeout (void *cls) | |||
710 | 688 | ||
711 | 689 | ||
712 | /** | 690 | /** |
713 | * Return attributes for claim | ||
714 | * | ||
715 | * @param cls the request handle | ||
716 | */ | ||
717 | static void | ||
718 | return_userinfo_response (void *cls) | ||
719 | { | ||
720 | char *result_str; | ||
721 | struct RequestHandle *handle = cls; | ||
722 | struct MHD_Response *resp; | ||
723 | |||
724 | result_str = json_dumps (handle->oidc->response, 0); | ||
725 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str); | ||
726 | resp = GNUNET_REST_create_response (result_str); | ||
727 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
728 | GNUNET_free (result_str); | ||
729 | cleanup_handle (handle); | ||
730 | } | ||
731 | |||
732 | |||
733 | /** | ||
734 | * Respond to OPTIONS request | 691 | * Respond to OPTIONS request |
735 | * | 692 | * |
736 | * @param con_handle the connection handle | 693 | * @param con_handle the connection handle |
@@ -854,7 +811,9 @@ login_redirect (void *cls) | |||
854 | { | 811 | { |
855 | char *login_base_url; | 812 | char *login_base_url; |
856 | char *new_redirect; | 813 | char *new_redirect; |
814 | char *tmp; | ||
857 | struct MHD_Response *resp; | 815 | struct MHD_Response *resp; |
816 | struct GNUNET_Buffer buf = { 0 }; | ||
858 | struct RequestHandle *handle = cls; | 817 | struct RequestHandle *handle = cls; |
859 | 818 | ||
860 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, | 819 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -862,27 +821,68 @@ login_redirect (void *cls) | |||
862 | "address", | 821 | "address", |
863 | &login_base_url)) | 822 | &login_base_url)) |
864 | { | 823 | { |
865 | GNUNET_asprintf (&new_redirect, | 824 | GNUNET_buffer_write_str (&buf, login_base_url); |
866 | "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | 825 | GNUNET_buffer_write_fstr (&buf, |
867 | login_base_url, | 826 | "?%s=%s", |
868 | OIDC_RESPONSE_TYPE_KEY, | 827 | OIDC_RESPONSE_TYPE_KEY, |
869 | handle->oidc->response_type, | 828 | handle->oidc->response_type); |
870 | OIDC_CLIENT_ID_KEY, | 829 | GNUNET_buffer_write_fstr (&buf, |
871 | handle->oidc->client_id, | 830 | "&%s=%s", |
872 | OIDC_REDIRECT_URI_KEY, | 831 | OIDC_CLIENT_ID_KEY, |
873 | handle->oidc->redirect_uri, | 832 | handle->oidc->client_id); |
874 | OIDC_SCOPE_KEY, | 833 | GNUNET_STRINGS_urlencode (handle->oidc->redirect_uri, |
875 | handle->oidc->scope, | 834 | strlen (handle->oidc->redirect_uri), |
876 | OIDC_STATE_KEY, | 835 | &tmp); |
877 | (NULL != handle->oidc->state) ? handle->oidc->state : "", | 836 | GNUNET_buffer_write_fstr (&buf, |
878 | OIDC_CODE_CHALLENGE_KEY, | 837 | "&%s=%s", |
879 | (NULL != handle->oidc->code_challenge) ? | 838 | OIDC_REDIRECT_URI_KEY, |
880 | handle->oidc->code_challenge : "", | 839 | tmp); |
881 | OIDC_NONCE_KEY, | 840 | GNUNET_free (tmp); |
882 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "", | 841 | GNUNET_STRINGS_urlencode (handle->oidc->scope, |
883 | OIDC_CLAIMS_KEY, | 842 | strlen (handle->oidc->scope), |
884 | (NULL != handle->oidc->claims) ? handle->oidc->claims : | 843 | &tmp); |
885 | ""); | 844 | GNUNET_buffer_write_fstr (&buf, |
845 | "&%s=%s", | ||
846 | OIDC_SCOPE_KEY, | ||
847 | tmp); | ||
848 | GNUNET_free (tmp); | ||
849 | if (NULL != handle->oidc->state) | ||
850 | { | ||
851 | GNUNET_STRINGS_urlencode (handle->oidc->state, | ||
852 | strlen (handle->oidc->state), | ||
853 | &tmp); | ||
854 | GNUNET_buffer_write_fstr (&buf, | ||
855 | "&%s=%s", | ||
856 | OIDC_STATE_KEY, | ||
857 | handle->oidc->state); | ||
858 | GNUNET_free (tmp); | ||
859 | } | ||
860 | if (NULL != handle->oidc->code_challenge) | ||
861 | { | ||
862 | GNUNET_buffer_write_fstr (&buf, | ||
863 | "&%s=%s", | ||
864 | OIDC_CODE_CHALLENGE_KEY, | ||
865 | handle->oidc->code_challenge); | ||
866 | } | ||
867 | if (NULL != handle->oidc->nonce) | ||
868 | { | ||
869 | GNUNET_buffer_write_fstr (&buf, | ||
870 | "&%s=%s", | ||
871 | OIDC_NONCE_KEY, | ||
872 | handle->oidc->nonce); | ||
873 | } | ||
874 | if (NULL != handle->oidc->claims) | ||
875 | { | ||
876 | GNUNET_STRINGS_urlencode (handle->oidc->claims, | ||
877 | strlen (handle->oidc->claims), | ||
878 | &tmp); | ||
879 | GNUNET_buffer_write_fstr (&buf, | ||
880 | "&%s=%s", | ||
881 | OIDC_CLAIMS_KEY, | ||
882 | tmp); | ||
883 | GNUNET_free (tmp); | ||
884 | } | ||
885 | new_redirect = GNUNET_buffer_reap_str (&buf); | ||
886 | resp = GNUNET_REST_create_response (""); | 886 | resp = GNUNET_REST_create_response (""); |
887 | MHD_add_response_header (resp, "Location", new_redirect); | 887 | MHD_add_response_header (resp, "Location", new_redirect); |
888 | GNUNET_free (login_base_url); | 888 | GNUNET_free (login_base_url); |
@@ -954,6 +954,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | |||
954 | handle->redirect_prefix, | 954 | handle->redirect_prefix, |
955 | handle->tld, | 955 | handle->tld, |
956 | handle->redirect_suffix, | 956 | handle->redirect_suffix, |
957 | (NULL == strchr (handle->redirect_suffix, '?') ? "?" : | ||
958 | "&"), | ||
957 | handle->oidc->response_type, | 959 | handle->oidc->response_type, |
958 | code_string, | 960 | code_string, |
959 | handle->oidc->state); | 961 | handle->oidc->state); |
@@ -961,8 +963,10 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | |||
961 | else | 963 | else |
962 | { | 964 | { |
963 | GNUNET_asprintf (&redirect_uri, | 965 | GNUNET_asprintf (&redirect_uri, |
964 | "%s?%s=%s&state=%s", | 966 | "%s%s%s=%s&state=%s", |
965 | handle->oidc->redirect_uri, | 967 | handle->oidc->redirect_uri, |
968 | (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" : | ||
969 | "&"), | ||
966 | handle->oidc->response_type, | 970 | handle->oidc->response_type, |
967 | code_string, | 971 | code_string, |
968 | handle->oidc->state); | 972 | handle->oidc->state); |
@@ -1041,7 +1045,7 @@ oidc_attest_collect_finished_cb (void *cls) | |||
1041 | handle->attest_it = NULL; | 1045 | handle->attest_it = NULL; |
1042 | merged_list = attribute_list_merge (handle->attr_idtoken_list, | 1046 | merged_list = attribute_list_merge (handle->attr_idtoken_list, |
1043 | handle->attr_userinfo_list); | 1047 | handle->attr_userinfo_list); |
1044 | handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp, | 1048 | handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, |
1045 | &handle->priv_key, | 1049 | &handle->priv_key, |
1046 | &handle->oidc->client_pkey, | 1050 | &handle->oidc->client_pkey, |
1047 | merged_list, | 1051 | merged_list, |
@@ -1108,7 +1112,7 @@ oidc_attr_collect_finished_cb (void *cls) | |||
1108 | } | 1112 | } |
1109 | handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList); | 1113 | handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList); |
1110 | handle->attest_it = | 1114 | handle->attest_it = |
1111 | GNUNET_RECLAIM_get_attestations_start (handle->idp, | 1115 | GNUNET_RECLAIM_get_attestations_start (idp, |
1112 | &handle->priv_key, | 1116 | &handle->priv_key, |
1113 | &oidc_iteration_error, | 1117 | &oidc_iteration_error, |
1114 | handle, | 1118 | handle, |
@@ -1125,9 +1129,6 @@ attr_in_claims_request (struct RequestHandle *handle, | |||
1125 | const char *attr_name, | 1129 | const char *attr_name, |
1126 | const char *claims_parameter) | 1130 | const char *claims_parameter) |
1127 | { | 1131 | { |
1128 | char *scope_variables; | ||
1129 | char *scope_variable; | ||
1130 | char delimiter[] = " "; | ||
1131 | int ret = GNUNET_NO; | 1132 | int ret = GNUNET_NO; |
1132 | json_t *root; | 1133 | json_t *root; |
1133 | json_error_t error; | 1134 | json_error_t error; |
@@ -1135,19 +1136,12 @@ attr_in_claims_request (struct RequestHandle *handle, | |||
1135 | const char *key; | 1136 | const char *key; |
1136 | json_t *value; | 1137 | json_t *value; |
1137 | 1138 | ||
1138 | scope_variables = GNUNET_strdup (handle->oidc->scope); | 1139 | /** Check if attribute is requested through standard scope **/ |
1139 | scope_variable = strtok (scope_variables, delimiter); | 1140 | if (GNUNET_YES == OIDC_check_scopes_for_claim_request (handle->oidc->scope, |
1140 | while (NULL != scope_variable) | 1141 | attr_name)) |
1141 | { | 1142 | return GNUNET_YES; |
1142 | if (0 == strcmp (attr_name, scope_variable)) | ||
1143 | break; | ||
1144 | scope_variable = strtok (NULL, delimiter); | ||
1145 | } | ||
1146 | if (NULL != scope_variable) | ||
1147 | ret = GNUNET_YES; | ||
1148 | GNUNET_free (scope_variables); | ||
1149 | 1143 | ||
1150 | /** Try claims parameter if no in scope */ | 1144 | /** Try claims parameter if not in scope */ |
1151 | if ((NULL != handle->oidc->claims) && | 1145 | if ((NULL != handle->oidc->claims) && |
1152 | (GNUNET_YES != ret)) | 1146 | (GNUNET_YES != ret)) |
1153 | { | 1147 | { |
@@ -1274,7 +1268,7 @@ code_redirect (void *cls) | |||
1274 | return; | 1268 | return; |
1275 | } | 1269 | } |
1276 | // iterate over egos and compare their public key | 1270 | // iterate over egos and compare their public key |
1277 | for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; | 1271 | for (handle->ego_entry = ego_head; NULL != handle->ego_entry; |
1278 | handle->ego_entry = handle->ego_entry->next) | 1272 | handle->ego_entry = handle->ego_entry->next) |
1279 | { | 1273 | { |
1280 | GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey); | 1274 | GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey); |
@@ -1282,13 +1276,12 @@ code_redirect (void *cls) | |||
1282 | { | 1276 | { |
1283 | handle->priv_key = | 1277 | handle->priv_key = |
1284 | *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); | 1278 | *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); |
1285 | handle->idp = GNUNET_RECLAIM_connect (cfg); | ||
1286 | handle->attr_idtoken_list = | 1279 | handle->attr_idtoken_list = |
1287 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); | 1280 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); |
1288 | handle->attr_userinfo_list = | 1281 | handle->attr_userinfo_list = |
1289 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); | 1282 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); |
1290 | handle->attr_it = | 1283 | handle->attr_it = |
1291 | GNUNET_RECLAIM_get_attributes_start (handle->idp, | 1284 | GNUNET_RECLAIM_get_attributes_start (idp, |
1292 | &handle->priv_key, | 1285 | &handle->priv_key, |
1293 | &oidc_iteration_error, | 1286 | &oidc_iteration_error, |
1294 | handle, | 1287 | handle, |
@@ -1433,7 +1426,7 @@ client_redirect (void *cls) | |||
1433 | 1426 | ||
1434 | /* Lookup client redirect uri to verify request */ | 1427 | /* Lookup client redirect uri to verify request */ |
1435 | handle->gns_op = | 1428 | handle->gns_op = |
1436 | GNUNET_GNS_lookup (handle->gns_handle, | 1429 | GNUNET_GNS_lookup (gns_handle, |
1437 | GNUNET_GNS_EMPTY_LABEL_AT, | 1430 | GNUNET_GNS_EMPTY_LABEL_AT, |
1438 | &handle->oidc->client_pkey, | 1431 | &handle->oidc->client_pkey, |
1439 | GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, | 1432 | GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, |
@@ -1448,6 +1441,7 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key) | |||
1448 | { | 1441 | { |
1449 | struct GNUNET_HashCode hc; | 1442 | struct GNUNET_HashCode hc; |
1450 | char *value; | 1443 | char *value; |
1444 | char *res; | ||
1451 | 1445 | ||
1452 | GNUNET_CRYPTO_hash (key, strlen (key), &hc); | 1446 | GNUNET_CRYPTO_hash (key, strlen (key), &hc); |
1453 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | 1447 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle |
@@ -1458,7 +1452,8 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key) | |||
1458 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc); | 1452 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc); |
1459 | if (NULL == value) | 1453 | if (NULL == value) |
1460 | return NULL; | 1454 | return NULL; |
1461 | return GNUNET_strdup (value); | 1455 | GNUNET_STRINGS_urldecode (value, strlen (value), &res); |
1456 | return res; | ||
1462 | } | 1457 | } |
1463 | 1458 | ||
1464 | 1459 | ||
@@ -1657,14 +1652,14 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1657 | 1652 | ||
1658 | // If we know this identity, translated the corresponding TLD | 1653 | // If we know this identity, translated the corresponding TLD |
1659 | // TODO: We might want to have a reverse lookup functionality for TLDs? | 1654 | // TODO: We might want to have a reverse lookup functionality for TLDs? |
1660 | for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) | 1655 | for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) |
1661 | { | 1656 | { |
1662 | priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego); | 1657 | priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego); |
1663 | GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey); | 1658 | GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey); |
1664 | if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) | 1659 | if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) |
1665 | { | 1660 | { |
1666 | handle->tld = GNUNET_strdup (tmp_ego->identifier); | 1661 | handle->tld = GNUNET_strdup (tmp_ego->identifier); |
1667 | handle->ego_entry = handle->ego_tail; | 1662 | handle->ego_entry = ego_tail; |
1668 | } | 1663 | } |
1669 | } | 1664 | } |
1670 | handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); | 1665 | handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); |
@@ -1749,16 +1744,16 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1749 | 1744 | ||
1750 | 1745 | ||
1751 | static int | 1746 | static int |
1752 | check_authorization (struct RequestHandle *handle, | 1747 | parse_credentials_basic_auth (struct RequestHandle *handle, |
1753 | struct GNUNET_CRYPTO_EcdsaPublicKey *cid) | 1748 | char **client_id, |
1749 | char **client_secret) | ||
1754 | { | 1750 | { |
1755 | struct GNUNET_HashCode cache_key; | 1751 | struct GNUNET_HashCode cache_key; |
1756 | char *authorization; | 1752 | char *authorization; |
1757 | char *credentials; | 1753 | char *credentials; |
1758 | char *basic_authorization; | 1754 | char *basic_authorization; |
1759 | char *client_id; | 1755 | char *client_id_tmp; |
1760 | char *pass; | 1756 | char *pass; |
1761 | char *expected_pass; | ||
1762 | 1757 | ||
1763 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, | 1758 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, |
1764 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), | 1759 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), |
@@ -1766,12 +1761,7 @@ check_authorization (struct RequestHandle *handle, | |||
1766 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | 1761 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle |
1767 | ->header_param_map, | 1762 | ->header_param_map, |
1768 | &cache_key)) | 1763 | &cache_key)) |
1769 | { | ||
1770 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1771 | handle->edesc = GNUNET_strdup ("missing authorization"); | ||
1772 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1773 | return GNUNET_SYSERR; | 1764 | return GNUNET_SYSERR; |
1774 | } | ||
1775 | authorization = | 1765 | authorization = |
1776 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, | 1766 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, |
1777 | &cache_key); | 1767 | &cache_key); |
@@ -1779,44 +1769,117 @@ check_authorization (struct RequestHandle *handle, | |||
1779 | // split header in "Basic" and [content] | 1769 | // split header in "Basic" and [content] |
1780 | credentials = strtok (authorization, " "); | 1770 | credentials = strtok (authorization, " "); |
1781 | if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) | 1771 | if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) |
1782 | { | ||
1783 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1784 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1785 | return GNUNET_SYSERR; | 1772 | return GNUNET_SYSERR; |
1786 | } | ||
1787 | credentials = strtok (NULL, " "); | 1773 | credentials = strtok (NULL, " "); |
1788 | if (NULL == credentials) | 1774 | if (NULL == credentials) |
1789 | { | ||
1790 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1791 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1792 | return GNUNET_SYSERR; | 1775 | return GNUNET_SYSERR; |
1793 | } | ||
1794 | GNUNET_STRINGS_base64_decode (credentials, | 1776 | GNUNET_STRINGS_base64_decode (credentials, |
1795 | strlen (credentials), | 1777 | strlen (credentials), |
1796 | (void **) &basic_authorization); | 1778 | (void **) &basic_authorization); |
1797 | 1779 | ||
1798 | if (NULL == basic_authorization) | 1780 | if (NULL == basic_authorization) |
1799 | { | ||
1800 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1801 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1802 | return GNUNET_SYSERR; | 1781 | return GNUNET_SYSERR; |
1803 | } | 1782 | client_id_tmp = strtok (basic_authorization, ":"); |
1804 | client_id = strtok (basic_authorization, ":"); | 1783 | if (NULL == client_id_tmp) |
1805 | if (NULL == client_id) | ||
1806 | { | 1784 | { |
1807 | GNUNET_free (basic_authorization); | 1785 | GNUNET_free (basic_authorization); |
1808 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1809 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1810 | return GNUNET_SYSERR; | 1786 | return GNUNET_SYSERR; |
1811 | } | 1787 | } |
1812 | pass = strtok (NULL, ":"); | 1788 | pass = strtok (NULL, ":"); |
1813 | if (NULL == pass) | 1789 | if (NULL == pass) |
1814 | { | 1790 | { |
1815 | GNUNET_free (basic_authorization); | 1791 | GNUNET_free (basic_authorization); |
1816 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1817 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1818 | return GNUNET_SYSERR; | 1792 | return GNUNET_SYSERR; |
1819 | } | 1793 | } |
1794 | *client_id = strdup (client_id_tmp); | ||
1795 | *client_secret = strdup (pass); | ||
1796 | GNUNET_free (basic_authorization); | ||
1797 | return GNUNET_OK; | ||
1798 | } | ||
1799 | |||
1800 | |||
1801 | static int | ||
1802 | parse_credentials_post_body (struct RequestHandle *handle, | ||
1803 | char **client_id, | ||
1804 | char **client_secret) | ||
1805 | { | ||
1806 | struct GNUNET_HashCode cache_key; | ||
1807 | char *client_id_tmp; | ||
1808 | char *pass; | ||
1809 | |||
1810 | GNUNET_CRYPTO_hash ("client_id", | ||
1811 | strlen ("client_id"), | ||
1812 | &cache_key); | ||
1813 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | ||
1814 | ->url_param_map, | ||
1815 | &cache_key)) | ||
1816 | return GNUNET_SYSERR; | ||
1817 | client_id_tmp = GNUNET_CONTAINER_multihashmap_get ( | ||
1818 | handle->rest_handle->url_param_map, | ||
1819 | &cache_key); | ||
1820 | if (NULL == client_id_tmp) | ||
1821 | return GNUNET_SYSERR; | ||
1822 | *client_id = strdup (client_id_tmp); | ||
1823 | GNUNET_CRYPTO_hash ("client_secret", | ||
1824 | strlen ("client_secret"), | ||
1825 | &cache_key); | ||
1826 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | ||
1827 | ->url_param_map, | ||
1828 | &cache_key)) | ||
1829 | return GNUNET_SYSERR; | ||
1830 | pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
1831 | &cache_key); | ||
1832 | if (NULL == pass) | ||
1833 | return GNUNET_SYSERR; | ||
1834 | *client_secret = strdup (pass); | ||
1835 | return GNUNET_OK; | ||
1836 | } | ||
1837 | |||
1838 | |||
1839 | static int | ||
1840 | check_authorization (struct RequestHandle *handle, | ||
1841 | struct GNUNET_CRYPTO_EcdsaPublicKey *cid) | ||
1842 | { | ||
1843 | char *expected_pass; | ||
1844 | char *received_cid; | ||
1845 | char *received_cpw; | ||
1846 | char *pkce_cv; | ||
1847 | |||
1848 | if (GNUNET_OK == parse_credentials_basic_auth (handle, | ||
1849 | &received_cid, | ||
1850 | &received_cpw)) | ||
1851 | { | ||
1852 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1853 | "Received client credentials in HTTP AuthZ header\n"); | ||
1854 | } | ||
1855 | else if (GNUNET_OK == parse_credentials_post_body (handle, | ||
1856 | &received_cid, | ||
1857 | &received_cpw)) | ||
1858 | { | ||
1859 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1860 | "Received client credentials in POST body\n"); | ||
1861 | } | ||
1862 | else | ||
1863 | { | ||
1864 | /** Allow public clients with PKCE **/ | ||
1865 | pkce_cv = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); | ||
1866 | if (NULL == pkce_cv) | ||
1867 | { | ||
1868 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1869 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1870 | return GNUNET_SYSERR; | ||
1871 | } | ||
1872 | handle->public_client = GNUNET_YES; | ||
1873 | GNUNET_free (pkce_cv); | ||
1874 | received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); | ||
1875 | GNUNET_STRINGS_string_to_data (received_cid, | ||
1876 | strlen (received_cid), | ||
1877 | cid, | ||
1878 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
1879 | GNUNET_free (received_cid); | ||
1880 | return GNUNET_OK; | ||
1881 | |||
1882 | } | ||
1820 | 1883 | ||
1821 | // check client password | 1884 | // check client password |
1822 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, | 1885 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -1824,9 +1887,8 @@ check_authorization (struct RequestHandle *handle, | |||
1824 | "OIDC_CLIENT_SECRET", | 1887 | "OIDC_CLIENT_SECRET", |
1825 | &expected_pass)) | 1888 | &expected_pass)) |
1826 | { | 1889 | { |
1827 | if (0 != strcmp (expected_pass, pass)) | 1890 | if (0 != strcmp (expected_pass, received_cpw)) |
1828 | { | 1891 | { |
1829 | GNUNET_free (basic_authorization); | ||
1830 | GNUNET_free (expected_pass); | 1892 | GNUNET_free (expected_pass); |
1831 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | 1893 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); |
1832 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 1894 | handle->response_code = MHD_HTTP_UNAUTHORIZED; |
@@ -1836,33 +1898,33 @@ check_authorization (struct RequestHandle *handle, | |||
1836 | } | 1898 | } |
1837 | else | 1899 | else |
1838 | { | 1900 | { |
1839 | GNUNET_free (basic_authorization); | ||
1840 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); | 1901 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); |
1841 | handle->edesc = GNUNET_strdup ("gnunet configuration failed"); | 1902 | handle->edesc = GNUNET_strdup ("gnunet configuration failed"); |
1842 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 1903 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; |
1843 | return GNUNET_SYSERR; | 1904 | return GNUNET_SYSERR; |
1844 | } | 1905 | } |
1845 | |||
1846 | // check client_id | 1906 | // check client_id |
1847 | for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; | 1907 | for (handle->ego_entry = ego_head; NULL != handle->ego_entry; |
1848 | handle->ego_entry = handle->ego_entry->next) | 1908 | handle->ego_entry = handle->ego_entry->next) |
1849 | { | 1909 | { |
1850 | if (0 == strcmp (handle->ego_entry->keystring, client_id)) | 1910 | if (0 == strcmp (handle->ego_entry->keystring, received_cid)) |
1851 | break; | 1911 | break; |
1852 | } | 1912 | } |
1853 | if (NULL == handle->ego_entry) | 1913 | if (NULL == handle->ego_entry) |
1854 | { | 1914 | { |
1855 | GNUNET_free (basic_authorization); | 1915 | GNUNET_free (received_cpw); |
1916 | GNUNET_free (received_cid); | ||
1856 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | 1917 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); |
1857 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 1918 | handle->response_code = MHD_HTTP_UNAUTHORIZED; |
1858 | return GNUNET_SYSERR; | 1919 | return GNUNET_SYSERR; |
1859 | } | 1920 | } |
1860 | GNUNET_STRINGS_string_to_data (client_id, | 1921 | GNUNET_STRINGS_string_to_data (received_cid, |
1861 | strlen (client_id), | 1922 | strlen (received_cid), |
1862 | cid, | 1923 | cid, |
1863 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); | 1924 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); |
1864 | 1925 | ||
1865 | GNUNET_free (basic_authorization); | 1926 | GNUNET_free (received_cpw); |
1927 | GNUNET_free (received_cid); | ||
1866 | return GNUNET_OK; | 1928 | return GNUNET_OK; |
1867 | } | 1929 | } |
1868 | 1930 | ||
@@ -1874,7 +1936,7 @@ find_ego (struct RequestHandle *handle, | |||
1874 | struct EgoEntry *ego_entry; | 1936 | struct EgoEntry *ego_entry; |
1875 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | 1937 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; |
1876 | 1938 | ||
1877 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 1939 | for (ego_entry = ego_head; NULL != ego_entry; |
1878 | ego_entry = ego_entry->next) | 1940 | ego_entry = ego_entry->next) |
1879 | { | 1941 | { |
1880 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key); | 1942 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key); |
@@ -1885,26 +1947,6 @@ find_ego (struct RequestHandle *handle, | |||
1885 | } | 1947 | } |
1886 | 1948 | ||
1887 | 1949 | ||
1888 | static void | ||
1889 | persist_access_token (const struct RequestHandle *handle, | ||
1890 | const char *access_token, | ||
1891 | const struct GNUNET_RECLAIM_Ticket *ticket) | ||
1892 | { | ||
1893 | struct GNUNET_HashCode hc; | ||
1894 | struct GNUNET_RECLAIM_Ticket *ticketbuf; | ||
1895 | |||
1896 | GNUNET_CRYPTO_hash (access_token, strlen (access_token), &hc); | ||
1897 | ticketbuf = GNUNET_new (struct GNUNET_RECLAIM_Ticket); | ||
1898 | *ticketbuf = *ticket; | ||
1899 | GNUNET_assert (GNUNET_SYSERR != | ||
1900 | GNUNET_CONTAINER_multihashmap_put ( | ||
1901 | OIDC_access_token_map, | ||
1902 | &hc, | ||
1903 | ticketbuf, | ||
1904 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1905 | } | ||
1906 | |||
1907 | |||
1908 | /** | 1950 | /** |
1909 | * Responds to token url-encoded POST request | 1951 | * Responds to token url-encoded POST request |
1910 | * | 1952 | * |
@@ -2008,7 +2050,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2008 | } | 2050 | } |
2009 | 2051 | ||
2010 | // decode code | 2052 | // decode code |
2011 | if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket, | 2053 | if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket, |
2012 | &cl, &al, &nonce)) | 2054 | &cl, &al, &nonce)) |
2013 | { | 2055 | { |
2014 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 2056 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
@@ -2046,20 +2088,19 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2046 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 2088 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
2047 | return; | 2089 | return; |
2048 | } | 2090 | } |
2049 | id_token = OIDC_id_token_new (&ticket.audience, | 2091 | id_token = OIDC_generate_id_token (&ticket.audience, |
2050 | &ticket.identity, | 2092 | &ticket.identity, |
2051 | cl, | 2093 | cl, |
2052 | al, | 2094 | al, |
2053 | &expiration_time, | 2095 | &expiration_time, |
2054 | (NULL != nonce) ? nonce : NULL, | 2096 | (NULL != nonce) ? nonce : NULL, |
2055 | jwt_secret); | 2097 | jwt_secret); |
2056 | access_token = OIDC_access_token_new (); | 2098 | access_token = OIDC_access_token_new (&ticket); |
2057 | OIDC_build_token_response (access_token, | 2099 | OIDC_build_token_response (access_token, |
2058 | id_token, | 2100 | id_token, |
2059 | &expiration_time, | 2101 | &expiration_time, |
2060 | &json_response); | 2102 | &json_response); |
2061 | 2103 | ||
2062 | persist_access_token (handle, access_token, &ticket); | ||
2063 | resp = GNUNET_REST_create_response (json_response); | 2104 | resp = GNUNET_REST_create_response (json_response); |
2064 | MHD_add_response_header (resp, "Cache-Control", "no-store"); | 2105 | MHD_add_response_header (resp, "Cache-Control", "no-store"); |
2065 | MHD_add_response_header (resp, "Pragma", "no-cache"); | 2106 | MHD_add_response_header (resp, "Pragma", "no-cache"); |
@@ -2084,83 +2125,56 @@ consume_ticket (void *cls, | |||
2084 | const struct GNUNET_RECLAIM_Attestation *attest) | 2125 | const struct GNUNET_RECLAIM_Attestation *attest) |
2085 | { | 2126 | { |
2086 | struct RequestHandle *handle = cls; | 2127 | struct RequestHandle *handle = cls; |
2128 | struct GNUNET_RECLAIM_AttributeListEntry *ale; | ||
2129 | struct GNUNET_RECLAIM_AttestationListEntry *atle; | ||
2130 | struct MHD_Response *resp; | ||
2131 | char *result_str; | ||
2087 | handle->idp_op = NULL; | 2132 | handle->idp_op = NULL; |
2088 | 2133 | ||
2134 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attr: %s\n", attr->name); | ||
2089 | if (NULL == identity) | 2135 | if (NULL == identity) |
2090 | { | 2136 | { |
2091 | GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); | 2137 | result_str = OIDC_generate_userinfo (&handle->ticket.identity, |
2138 | handle->attr_userinfo_list, | ||
2139 | handle->attests_list); | ||
2140 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Userinfo: %s\n", result_str); | ||
2141 | resp = GNUNET_REST_create_response (result_str); | ||
2142 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
2143 | GNUNET_free (result_str); | ||
2144 | cleanup_handle (handle); | ||
2092 | return; | 2145 | return; |
2093 | } | 2146 | } |
2094 | if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attr->attestation)) | 2147 | ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry); |
2148 | ale->attribute = GNUNET_RECLAIM_attribute_new (attr->name, | ||
2149 | &attr->attestation, | ||
2150 | attr->type, | ||
2151 | attr->data, | ||
2152 | attr->data_size); | ||
2153 | ale->attribute->id = attr->id; | ||
2154 | ale->attribute->flag = attr->flag; | ||
2155 | ale->attribute->attestation = attr->attestation; | ||
2156 | GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head, | ||
2157 | handle->attr_userinfo_list->list_tail, | ||
2158 | ale); | ||
2159 | for (atle = handle->attests_list->list_head; NULL != atle; atle = atle->next) | ||
2160 | { | ||
2161 | if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&atle->attestation->id, | ||
2162 | &attest->id)) | ||
2163 | continue; | ||
2164 | break; /** already in list **/ | ||
2165 | } | ||
2166 | if (NULL == atle) | ||
2095 | { | 2167 | { |
2096 | char *tmp_value; | 2168 | /** Attestation matches for attribute, add **/ |
2097 | json_t *value; | 2169 | atle = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry); |
2098 | tmp_value = GNUNET_RECLAIM_attribute_value_to_string (attr->type, | 2170 | atle->attestation = GNUNET_RECLAIM_attestation_new (attest->name, |
2099 | attr->data, | 2171 | attest->type, |
2100 | attr->data_size); | 2172 | attest->data, |
2101 | value = json_string (tmp_value); | 2173 | attest->data_size); |
2102 | json_object_set_new (handle->oidc->response, attr->name, value); | 2174 | GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head, |
2103 | GNUNET_free (tmp_value); | 2175 | handle->attests_list->list_tail, |
2104 | return; | 2176 | atle); |
2105 | } | 2177 | } |
2106 | json_t *claim_sources; | ||
2107 | json_t *claim_sources_jwt; | ||
2108 | json_t *claim_names; | ||
2109 | char *attest_val_str; | ||
2110 | claim_sources = json_object_get (handle->oidc->response,"_claim_sources"); | ||
2111 | claim_names = json_object_get (handle->oidc->response,"_claim_names"); | ||
2112 | attest_val_str = | ||
2113 | GNUNET_RECLAIM_attestation_value_to_string (attest->type, | ||
2114 | attest->data, | ||
2115 | attest->data_size); | ||
2116 | if ((NULL == claim_sources) && (NULL == claim_names) ) | ||
2117 | { | ||
2118 | claim_sources = json_object (); | ||
2119 | claim_names = json_object (); | ||
2120 | } | ||
2121 | char *source_name; | ||
2122 | int i = 0; | ||
2123 | GNUNET_asprintf (&source_name, "src%d", i); | ||
2124 | while (NULL != (claim_sources_jwt = json_object_get (claim_sources, | ||
2125 | source_name))) | ||
2126 | { | ||
2127 | if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt, | ||
2128 | "JWT")), | ||
2129 | attest_val_str)) | ||
2130 | { | ||
2131 | // Adapt only the claim names | ||
2132 | json_object_set_new (claim_names, attr->data, | ||
2133 | json_string (source_name)); | ||
2134 | json_object_set (handle->oidc->response, | ||
2135 | "_claim_names", claim_names); | ||
2136 | break; | ||
2137 | } | ||
2138 | i++; | ||
2139 | GNUNET_free (source_name); | ||
2140 | GNUNET_asprintf (&source_name, "src%d", i); | ||
2141 | } | ||
2142 | |||
2143 | // Create new one | ||
2144 | if (NULL == claim_sources_jwt) | ||
2145 | { | ||
2146 | claim_sources_jwt = json_object (); | ||
2147 | // Set the JWT for names | ||
2148 | json_object_set_new (claim_names, attr->data, | ||
2149 | json_string (source_name)); | ||
2150 | // Set the JWT for the inner source | ||
2151 | json_object_set_new (claim_sources_jwt, "JWT", | ||
2152 | json_string (attest_val_str)); | ||
2153 | // Set the JWT for the source | ||
2154 | json_object_set_new (claim_sources, source_name, claim_sources_jwt); | ||
2155 | // Set as claims | ||
2156 | json_object_set (handle->oidc->response, "_claim_names", claim_names); | ||
2157 | json_object_set (handle->oidc->response, "_claim_sources",claim_sources); | ||
2158 | } | ||
2159 | |||
2160 | json_decref (claim_sources); | ||
2161 | json_decref (claim_names); | ||
2162 | json_decref (claim_sources_jwt); | ||
2163 | GNUNET_free (attest_val_str); | ||
2164 | } | 2178 | } |
2165 | 2179 | ||
2166 | 2180 | ||
@@ -2178,15 +2192,16 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2178 | { | 2192 | { |
2179 | // TODO expiration time | 2193 | // TODO expiration time |
2180 | struct RequestHandle *handle = cls; | 2194 | struct RequestHandle *handle = cls; |
2195 | struct GNUNET_RECLAIM_Ticket *ticket; | ||
2181 | char delimiter[] = " "; | 2196 | char delimiter[] = " "; |
2182 | struct GNUNET_HashCode cache_key; | 2197 | struct GNUNET_HashCode cache_key; |
2183 | char *authorization; | 2198 | char *authorization; |
2184 | char *authorization_type; | 2199 | char *authorization_type; |
2185 | char *authorization_access_token; | 2200 | char *authorization_access_token; |
2186 | struct GNUNET_RECLAIM_Ticket *ticket; | 2201 | const struct EgoEntry *aud_ego; |
2187 | const struct EgoEntry *ego_entry; | ||
2188 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; | 2202 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; |
2189 | 2203 | ||
2204 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n"); | ||
2190 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, | 2205 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, |
2191 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), | 2206 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), |
2192 | &cache_key); | 2207 | &cache_key); |
@@ -2228,25 +2243,22 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2228 | return; | 2243 | return; |
2229 | } | 2244 | } |
2230 | 2245 | ||
2231 | GNUNET_CRYPTO_hash (authorization_access_token, | 2246 | if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token, |
2232 | strlen (authorization_access_token), | 2247 | &ticket)) |
2233 | &cache_key); | ||
2234 | if (GNUNET_NO == | ||
2235 | GNUNET_CONTAINER_multihashmap_contains (OIDC_access_token_map, | ||
2236 | &cache_key)) | ||
2237 | { | 2248 | { |
2238 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); | 2249 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); |
2239 | handle->edesc = GNUNET_strdup ("The access token expired"); | 2250 | handle->edesc = GNUNET_strdup ("The access token is invalid"); |
2240 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 2251 | handle->response_code = MHD_HTTP_UNAUTHORIZED; |
2241 | GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); | 2252 | GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); |
2242 | GNUNET_free (authorization); | 2253 | GNUNET_free (authorization); |
2243 | return; | 2254 | return; |
2255 | |||
2244 | } | 2256 | } |
2245 | ticket = | ||
2246 | GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key); | ||
2247 | GNUNET_assert (NULL != ticket); | 2257 | GNUNET_assert (NULL != ticket); |
2248 | ego_entry = find_ego (handle, &ticket->audience); | 2258 | handle->ticket = *ticket; |
2249 | if (NULL == ego_entry) | 2259 | GNUNET_free (ticket); |
2260 | aud_ego = find_ego (handle, &handle->ticket.audience); | ||
2261 | if (NULL == aud_ego) | ||
2250 | { | 2262 | { |
2251 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); | 2263 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); |
2252 | handle->edesc = GNUNET_strdup ("The access token expired"); | 2264 | handle->edesc = GNUNET_strdup ("The access token expired"); |
@@ -2255,53 +2267,23 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2255 | GNUNET_free (authorization); | 2267 | GNUNET_free (authorization); |
2256 | return; | 2268 | return; |
2257 | } | 2269 | } |
2270 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Consuming ticket\n"); | ||
2271 | privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); | ||
2272 | handle->attr_userinfo_list = | ||
2273 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); | ||
2274 | handle->attests_list = | ||
2275 | GNUNET_new (struct GNUNET_RECLAIM_AttestationList); | ||
2258 | 2276 | ||
2259 | handle->idp = GNUNET_RECLAIM_connect (cfg); | 2277 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, |
2260 | handle->oidc->response = json_object (); | ||
2261 | json_object_set_new (handle->oidc->response, | ||
2262 | "sub", | ||
2263 | json_string (ego_entry->keystring)); | ||
2264 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
2265 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, | ||
2266 | privkey, | 2278 | privkey, |
2267 | ticket, | 2279 | &handle->ticket, |
2268 | consume_ticket, | 2280 | &consume_ticket, |
2269 | handle); | 2281 | handle); |
2270 | GNUNET_free (authorization); | 2282 | GNUNET_free (authorization); |
2271 | } | 2283 | } |
2272 | 2284 | ||
2273 | 2285 | ||
2274 | /** | 2286 | /** |
2275 | * Handle rest request | ||
2276 | * | ||
2277 | * @param handle the request handle | ||
2278 | */ | ||
2279 | static void | ||
2280 | init_cont (struct RequestHandle *handle) | ||
2281 | { | ||
2282 | struct GNUNET_REST_RequestHandlerError err; | ||
2283 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
2284 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, | ||
2285 | { MHD_HTTP_METHOD_POST, | ||
2286 | GNUNET_REST_API_NS_AUTHORIZE, | ||
2287 | &authorize_endpoint }, // url-encoded | ||
2288 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont }, | ||
2289 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, | ||
2290 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, | ||
2291 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, | ||
2292 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, | ||
2293 | GNUNET_REST_HANDLER_END }; | ||
2294 | |||
2295 | if (GNUNET_NO == | ||
2296 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) | ||
2297 | { | ||
2298 | handle->response_code = err.error_code; | ||
2299 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
2300 | } | ||
2301 | } | ||
2302 | |||
2303 | |||
2304 | /** | ||
2305 | * If listing is enabled, prints information about the egos. | 2287 | * If listing is enabled, prints information about the egos. |
2306 | * | 2288 | * |
2307 | * This function is initially called for all egos and then again | 2289 | * This function is initially called for all egos and then again |
@@ -2340,18 +2322,16 @@ list_ego (void *cls, | |||
2340 | void **ctx, | 2322 | void **ctx, |
2341 | const char *identifier) | 2323 | const char *identifier) |
2342 | { | 2324 | { |
2343 | struct RequestHandle *handle = cls; | ||
2344 | struct EgoEntry *ego_entry; | 2325 | struct EgoEntry *ego_entry; |
2345 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | 2326 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; |
2346 | 2327 | ||
2347 | if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) | 2328 | if ((NULL == ego) && (ID_REST_STATE_INIT == state)) |
2348 | { | 2329 | { |
2349 | handle->state = ID_REST_STATE_POST_INIT; | 2330 | state = ID_REST_STATE_POST_INIT; |
2350 | init_cont (handle); | ||
2351 | return; | 2331 | return; |
2352 | } | 2332 | } |
2353 | GNUNET_assert (NULL != ego); | 2333 | GNUNET_assert (NULL != ego); |
2354 | if (ID_REST_STATE_INIT == handle->state) | 2334 | if (ID_REST_STATE_INIT == state) |
2355 | 2335 | ||
2356 | { | 2336 | { |
2357 | ego_entry = GNUNET_new (struct EgoEntry); | 2337 | ego_entry = GNUNET_new (struct EgoEntry); |
@@ -2359,15 +2339,15 @@ list_ego (void *cls, | |||
2359 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | 2339 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
2360 | ego_entry->ego = ego; | 2340 | ego_entry->ego = ego; |
2361 | ego_entry->identifier = GNUNET_strdup (identifier); | 2341 | ego_entry->identifier = GNUNET_strdup (identifier); |
2362 | GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, | 2342 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, |
2363 | handle->ego_tail, | 2343 | ego_tail, |
2364 | ego_entry); | 2344 | ego_entry); |
2365 | return; | 2345 | return; |
2366 | } | 2346 | } |
2367 | /* Ego renamed or added */ | 2347 | /* Ego renamed or added */ |
2368 | if (identifier != NULL) | 2348 | if (identifier != NULL) |
2369 | { | 2349 | { |
2370 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 2350 | for (ego_entry = ego_head; NULL != ego_entry; |
2371 | ego_entry = ego_entry->next) | 2351 | ego_entry = ego_entry->next) |
2372 | { | 2352 | { |
2373 | if (ego_entry->ego == ego) | 2353 | if (ego_entry->ego == ego) |
@@ -2386,15 +2366,15 @@ list_ego (void *cls, | |||
2386 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | 2366 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
2387 | ego_entry->ego = ego; | 2367 | ego_entry->ego = ego; |
2388 | ego_entry->identifier = GNUNET_strdup (identifier); | 2368 | ego_entry->identifier = GNUNET_strdup (identifier); |
2389 | GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, | 2369 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, |
2390 | handle->ego_tail, | 2370 | ego_tail, |
2391 | ego_entry); | 2371 | ego_entry); |
2392 | } | 2372 | } |
2393 | } | 2373 | } |
2394 | else | 2374 | else |
2395 | { | 2375 | { |
2396 | /* Delete */ | 2376 | /* Delete */ |
2397 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 2377 | for (ego_entry = ego_head; NULL != ego_entry; |
2398 | ego_entry = ego_entry->next) | 2378 | ego_entry = ego_entry->next) |
2399 | { | 2379 | { |
2400 | if (ego_entry->ego == ego) | 2380 | if (ego_entry->ego == ego) |
@@ -2403,8 +2383,8 @@ list_ego (void *cls, | |||
2403 | if (NULL == ego_entry) | 2383 | if (NULL == ego_entry) |
2404 | return; /* Not found */ | 2384 | return; /* Not found */ |
2405 | 2385 | ||
2406 | GNUNET_CONTAINER_DLL_remove (handle->ego_head, | 2386 | GNUNET_CONTAINER_DLL_remove (ego_head, |
2407 | handle->ego_tail, | 2387 | ego_tail, |
2408 | ego_entry); | 2388 | ego_entry); |
2409 | GNUNET_free (ego_entry->identifier); | 2389 | GNUNET_free (ego_entry->identifier); |
2410 | GNUNET_free (ego_entry->keystring); | 2390 | GNUNET_free (ego_entry->keystring); |
@@ -2415,36 +2395,153 @@ list_ego (void *cls, | |||
2415 | 2395 | ||
2416 | 2396 | ||
2417 | static void | 2397 | static void |
2398 | oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | ||
2399 | const char *url, | ||
2400 | void *cls) | ||
2401 | { | ||
2402 | json_t *oidc_config; | ||
2403 | json_t *auth_methods; | ||
2404 | json_t *sig_algs; | ||
2405 | json_t *scopes; | ||
2406 | json_t *response_types; | ||
2407 | json_t *sub_types; | ||
2408 | json_t *claim_types; | ||
2409 | char *oidc_config_str; | ||
2410 | struct MHD_Response *resp; | ||
2411 | struct RequestHandle *handle = cls; | ||
2412 | |||
2413 | oidc_config = json_object (); | ||
2414 | // FIXME get from config? | ||
2415 | json_object_set_new (oidc_config, | ||
2416 | "issuer", json_string ("http://localhost:7776")); | ||
2417 | json_object_set_new (oidc_config, | ||
2418 | "authorization_endpoint", | ||
2419 | json_string ("https://api.reclaim/openid/authorize")); | ||
2420 | json_object_set_new (oidc_config, | ||
2421 | "token_endpoint", | ||
2422 | json_string ("http://localhost:7776/openid/token")); | ||
2423 | auth_methods = json_array (); | ||
2424 | json_array_append_new (auth_methods, | ||
2425 | json_string ("client_secret_basic")); | ||
2426 | json_array_append_new (auth_methods, | ||
2427 | json_string ("client_secret_post")); | ||
2428 | json_object_set_new (oidc_config, | ||
2429 | "token_endpoint_auth_methods_supported", | ||
2430 | auth_methods); | ||
2431 | sig_algs = json_array (); | ||
2432 | json_array_append_new (sig_algs, | ||
2433 | json_string ("HS512")); | ||
2434 | json_object_set_new (oidc_config, | ||
2435 | "id_token_signing_alg_values_supported", | ||
2436 | sig_algs); | ||
2437 | json_object_set_new (oidc_config, | ||
2438 | "userinfo_endpoint", | ||
2439 | json_string ("http://localhost:7776/openid/userinfo")); | ||
2440 | scopes = json_array (); | ||
2441 | json_array_append_new (scopes, | ||
2442 | json_string ("openid")); | ||
2443 | json_array_append_new (scopes, | ||
2444 | json_string ("profile")); | ||
2445 | json_object_set_new (oidc_config, | ||
2446 | "scopes_supported", | ||
2447 | scopes); | ||
2448 | response_types = json_array (); | ||
2449 | json_array_append_new (response_types, | ||
2450 | json_string ("code")); | ||
2451 | json_object_set_new (oidc_config, | ||
2452 | "response_types_supported", | ||
2453 | response_types); | ||
2454 | sub_types = json_array (); | ||
2455 | json_array_append_new (sub_types, | ||
2456 | json_string ("public")); /* no pairwise suppport */ | ||
2457 | json_object_set_new (oidc_config, | ||
2458 | "subject_types_supported", | ||
2459 | sub_types); | ||
2460 | claim_types = json_array (); | ||
2461 | json_array_append_new (claim_types, | ||
2462 | json_string ("normal")); | ||
2463 | json_array_append_new (claim_types, | ||
2464 | json_string ("aggregated")); | ||
2465 | json_object_set_new (oidc_config, | ||
2466 | "claim_types_supported", | ||
2467 | claim_types); | ||
2468 | json_object_set_new (oidc_config, | ||
2469 | "claims_parameter_supported", | ||
2470 | json_boolean (1)); | ||
2471 | oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1)); | ||
2472 | resp = GNUNET_REST_create_response (oidc_config_str); | ||
2473 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
2474 | GNUNET_free (oidc_config_str); | ||
2475 | cleanup_handle (handle); | ||
2476 | } | ||
2477 | |||
2478 | |||
2479 | /** | ||
2480 | * Respond to OPTIONS request | ||
2481 | * | ||
2482 | * @param con_handle the connection handle | ||
2483 | * @param url the url | ||
2484 | * @param cls the RequestHandle | ||
2485 | */ | ||
2486 | static void | ||
2487 | oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, | ||
2488 | const char *url, | ||
2489 | void *cls) | ||
2490 | { | ||
2491 | struct MHD_Response *resp; | ||
2492 | struct RequestHandle *handle = cls; | ||
2493 | |||
2494 | // For now, independent of path return all options | ||
2495 | resp = GNUNET_REST_create_response (NULL); | ||
2496 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
2497 | MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*"); | ||
2498 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
2499 | cleanup_handle (handle); | ||
2500 | return; | ||
2501 | } | ||
2502 | |||
2503 | |||
2504 | static enum GNUNET_GenericReturnValue | ||
2418 | rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 2505 | rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, |
2419 | GNUNET_REST_ResultProcessor proc, | 2506 | GNUNET_REST_ResultProcessor proc, |
2420 | void *proc_cls) | 2507 | void *proc_cls) |
2421 | { | 2508 | { |
2422 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 2509 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
2510 | struct GNUNET_REST_RequestHandlerError err; | ||
2511 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
2512 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, | ||
2513 | { MHD_HTTP_METHOD_POST, | ||
2514 | GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, // url-encoded | ||
2515 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont }, | ||
2516 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, | ||
2517 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, | ||
2518 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, | ||
2519 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG, | ||
2520 | &oidc_config_endpoint }, | ||
2521 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG, | ||
2522 | &oidc_config_cors }, | ||
2523 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, | ||
2524 | GNUNET_REST_HANDLER_END }; | ||
2423 | 2525 | ||
2424 | handle->oidc = GNUNET_new (struct OIDC_Variables); | 2526 | handle->oidc = GNUNET_new (struct OIDC_Variables); |
2425 | if (NULL == OIDC_cookie_jar_map) | 2527 | if (NULL == OIDC_cookie_jar_map) |
2426 | OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10, | 2528 | OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10, |
2427 | GNUNET_NO); | 2529 | GNUNET_NO); |
2428 | if (NULL == OIDC_access_token_map) | ||
2429 | OIDC_access_token_map = | ||
2430 | GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | ||
2431 | handle->response_code = 0; | 2530 | handle->response_code = 0; |
2432 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 2531 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
2433 | handle->proc_cls = proc_cls; | 2532 | handle->proc_cls = proc_cls; |
2434 | handle->proc = proc; | 2533 | handle->proc = proc; |
2435 | handle->state = ID_REST_STATE_INIT; | ||
2436 | handle->rest_handle = rest_handle; | 2534 | handle->rest_handle = rest_handle; |
2437 | |||
2438 | handle->url = GNUNET_strdup (rest_handle->url); | 2535 | handle->url = GNUNET_strdup (rest_handle->url); |
2439 | if (handle->url[strlen (handle->url) - 1] == '/') | 2536 | if (handle->url[strlen (handle->url) - 1] == '/') |
2440 | handle->url[strlen (handle->url) - 1] = '\0'; | 2537 | handle->url[strlen (handle->url) - 1] = '\0'; |
2441 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | 2538 | if (GNUNET_NO == |
2442 | handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); | 2539 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) |
2443 | handle->gns_handle = GNUNET_GNS_connect (cfg); | 2540 | return GNUNET_NO; |
2444 | handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); | 2541 | |
2445 | handle->timeout_task = | 2542 | handle->timeout_task = |
2446 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); | 2543 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); |
2447 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | 2544 | return GNUNET_YES; |
2448 | } | 2545 | } |
2449 | 2546 | ||
2450 | 2547 | ||
@@ -2469,6 +2566,11 @@ libgnunet_plugin_rest_openid_connect_init (void *cls) | |||
2469 | api->cls = &plugin; | 2566 | api->cls = &plugin; |
2470 | api->name = GNUNET_REST_API_NS_OIDC; | 2567 | api->name = GNUNET_REST_API_NS_OIDC; |
2471 | api->process_request = &rest_identity_process_request; | 2568 | api->process_request = &rest_identity_process_request; |
2569 | identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); | ||
2570 | gns_handle = GNUNET_GNS_connect (cfg); | ||
2571 | idp = GNUNET_RECLAIM_connect (cfg); | ||
2572 | |||
2573 | state = ID_REST_STATE_INIT; | ||
2472 | GNUNET_asprintf (&allow_methods, | 2574 | GNUNET_asprintf (&allow_methods, |
2473 | "%s, %s, %s, %s, %s", | 2575 | "%s, %s, %s, %s, %s", |
2474 | MHD_HTTP_METHOD_GET, | 2576 | MHD_HTTP_METHOD_GET, |
@@ -2494,6 +2596,7 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) | |||
2494 | { | 2596 | { |
2495 | struct GNUNET_REST_Plugin *api = cls; | 2597 | struct GNUNET_REST_Plugin *api = cls; |
2496 | struct Plugin *plugin = api->cls; | 2598 | struct Plugin *plugin = api->cls; |
2599 | struct EgoEntry *ego_entry; | ||
2497 | 2600 | ||
2498 | plugin->cfg = NULL; | 2601 | plugin->cfg = NULL; |
2499 | 2602 | ||
@@ -2508,15 +2611,23 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) | |||
2508 | GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); | 2611 | GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); |
2509 | GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map); | 2612 | GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map); |
2510 | 2613 | ||
2511 | hashmap_it = | ||
2512 | GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_access_token_map); | ||
2513 | while (GNUNET_YES == | ||
2514 | GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, | ||
2515 | value)) | ||
2516 | GNUNET_free (value); | ||
2517 | GNUNET_CONTAINER_multihashmap_destroy (OIDC_access_token_map); | ||
2518 | GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); | 2614 | GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); |
2519 | GNUNET_free (allow_methods); | 2615 | GNUNET_free (allow_methods); |
2616 | if (NULL != gns_handle) | ||
2617 | GNUNET_GNS_disconnect (gns_handle); | ||
2618 | if (NULL != identity_handle) | ||
2619 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
2620 | if (NULL != idp) | ||
2621 | GNUNET_RECLAIM_disconnect (idp); | ||
2622 | while (NULL != (ego_entry = ego_head)) | ||
2623 | { | ||
2624 | GNUNET_CONTAINER_DLL_remove (ego_head, | ||
2625 | ego_tail, | ||
2626 | ego_entry); | ||
2627 | GNUNET_free (ego_entry->identifier); | ||
2628 | GNUNET_free (ego_entry->keystring); | ||
2629 | GNUNET_free (ego_entry); | ||
2630 | } | ||
2520 | GNUNET_free (api); | 2631 | GNUNET_free (api); |
2521 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2632 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2522 | "OpenID Connect REST plugin is finished\n"); | 2633 | "OpenID Connect REST plugin is finished\n"); |
diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index 10ee2f801..c2d14825e 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c | |||
@@ -88,6 +88,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
88 | static char *allow_methods; | 88 | static char *allow_methods; |
89 | 89 | ||
90 | /** | 90 | /** |
91 | * Ego list | ||
92 | */ | ||
93 | static struct EgoEntry *ego_head; | ||
94 | |||
95 | /** | ||
96 | * Ego list | ||
97 | */ | ||
98 | static struct EgoEntry *ego_tail; | ||
99 | |||
100 | /** | ||
101 | * The processing state | ||
102 | */ | ||
103 | static int state; | ||
104 | |||
105 | /** | ||
106 | * Handle to Identity service. | ||
107 | */ | ||
108 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
109 | |||
110 | /** | ||
111 | * Identity Provider | ||
112 | */ | ||
113 | static struct GNUNET_RECLAIM_Handle *idp; | ||
114 | |||
115 | /** | ||
91 | * @brief struct returned by the initialization function of the plugin | 116 | * @brief struct returned by the initialization function of the plugin |
92 | */ | 117 | */ |
93 | struct Plugin | 118 | struct Plugin |
@@ -129,15 +154,6 @@ struct EgoEntry | |||
129 | 154 | ||
130 | struct RequestHandle | 155 | struct RequestHandle |
131 | { | 156 | { |
132 | /** | ||
133 | * Ego list | ||
134 | */ | ||
135 | struct EgoEntry *ego_head; | ||
136 | |||
137 | /** | ||
138 | * Ego list | ||
139 | */ | ||
140 | struct EgoEntry *ego_tail; | ||
141 | 157 | ||
142 | /** | 158 | /** |
143 | * Selected ego | 159 | * Selected ego |
@@ -150,16 +166,6 @@ struct RequestHandle | |||
150 | struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; | 166 | struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; |
151 | 167 | ||
152 | /** | 168 | /** |
153 | * The processing state | ||
154 | */ | ||
155 | int state; | ||
156 | |||
157 | /** | ||
158 | * Handle to Identity service. | ||
159 | */ | ||
160 | struct GNUNET_IDENTITY_Handle *identity_handle; | ||
161 | |||
162 | /** | ||
163 | * Rest connection | 169 | * Rest connection |
164 | */ | 170 | */ |
165 | struct GNUNET_REST_RequestHandle *rest_handle; | 171 | struct GNUNET_REST_RequestHandle *rest_handle; |
@@ -175,11 +181,6 @@ struct RequestHandle | |||
175 | struct GNUNET_IDENTITY_Operation *op; | 181 | struct GNUNET_IDENTITY_Operation *op; |
176 | 182 | ||
177 | /** | 183 | /** |
178 | * Identity Provider | ||
179 | */ | ||
180 | struct GNUNET_RECLAIM_Handle *idp; | ||
181 | |||
182 | /** | ||
183 | * Idp Operation | 184 | * Idp Operation |
184 | */ | 185 | */ |
185 | struct GNUNET_RECLAIM_Operation *idp_op; | 186 | struct GNUNET_RECLAIM_Operation *idp_op; |
@@ -194,7 +195,6 @@ struct RequestHandle | |||
194 | */ | 195 | */ |
195 | struct GNUNET_RECLAIM_AttestationIterator *attest_it; | 196 | struct GNUNET_RECLAIM_AttestationIterator *attest_it; |
196 | 197 | ||
197 | |||
198 | /** | 198 | /** |
199 | * Ticket iterator | 199 | * Ticket iterator |
200 | */ | 200 | */ |
@@ -251,51 +251,31 @@ struct RequestHandle | |||
251 | * @param handle Handle to clean up | 251 | * @param handle Handle to clean up |
252 | */ | 252 | */ |
253 | static void | 253 | static void |
254 | cleanup_handle (struct RequestHandle *handle) | 254 | cleanup_handle (void *cls) |
255 | { | 255 | { |
256 | struct EgoEntry *ego_entry; | 256 | struct RequestHandle *handle = cls; |
257 | struct EgoEntry *ego_tmp; | ||
258 | 257 | ||
259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); | 258 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); |
260 | if (NULL != handle->resp_object) | 259 | if (NULL != handle->resp_object) |
261 | json_decref (handle->resp_object); | 260 | json_decref (handle->resp_object); |
262 | if (NULL != handle->timeout_task) | 261 | if (NULL != handle->timeout_task) |
263 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | 262 | GNUNET_SCHEDULER_cancel (handle->timeout_task); |
264 | if (NULL != handle->identity_handle) | ||
265 | GNUNET_IDENTITY_disconnect (handle->identity_handle); | ||
266 | if (NULL != handle->attr_it) | 263 | if (NULL != handle->attr_it) |
267 | GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); | 264 | GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); |
268 | if (NULL != handle->attest_it) | 265 | if (NULL != handle->attest_it) |
269 | GNUNET_RECLAIM_get_attestations_stop (handle->attest_it); | 266 | GNUNET_RECLAIM_get_attestations_stop (handle->attest_it); |
270 | if (NULL != handle->ticket_it) | 267 | if (NULL != handle->ticket_it) |
271 | GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); | 268 | GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); |
272 | if (NULL != handle->idp) | ||
273 | GNUNET_RECLAIM_disconnect (handle->idp); | ||
274 | if (NULL != handle->url) | 269 | if (NULL != handle->url) |
275 | GNUNET_free (handle->url); | 270 | GNUNET_free (handle->url); |
276 | if (NULL != handle->emsg) | 271 | if (NULL != handle->emsg) |
277 | GNUNET_free (handle->emsg); | 272 | GNUNET_free (handle->emsg); |
278 | if (NULL != handle->attr_list) | 273 | if (NULL != handle->attr_list) |
279 | GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list); | 274 | GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list); |
280 | for (ego_entry = handle->ego_head; NULL != ego_entry;) | ||
281 | { | ||
282 | ego_tmp = ego_entry; | ||
283 | ego_entry = ego_entry->next; | ||
284 | GNUNET_free (ego_tmp->identifier); | ||
285 | GNUNET_free (ego_tmp->keystring); | ||
286 | GNUNET_free (ego_tmp); | ||
287 | } | ||
288 | GNUNET_free (handle); | 275 | GNUNET_free (handle); |
289 | } | 276 | } |
290 | 277 | ||
291 | 278 | ||
292 | static void | ||
293 | cleanup_handle_delayed (void *cls) | ||
294 | { | ||
295 | cleanup_handle (cls); | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | 279 | /** |
300 | * Task run on error, sends error message. Cleans up everything. | 280 | * Task run on error, sends error message. Cleans up everything. |
301 | * | 281 | * |
@@ -316,7 +296,7 @@ do_error (void *cls) | |||
316 | resp = GNUNET_REST_create_response (json_error); | 296 | resp = GNUNET_REST_create_response (json_error); |
317 | MHD_add_response_header (resp, "Content-Type", "application/json"); | 297 | MHD_add_response_header (resp, "Content-Type", "application/json"); |
318 | handle->proc (handle->proc_cls, resp, handle->response_code); | 298 | handle->proc (handle->proc_cls, resp, handle->response_code); |
319 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 299 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
320 | GNUNET_free (json_error); | 300 | GNUNET_free (json_error); |
321 | } | 301 | } |
322 | 302 | ||
@@ -339,9 +319,7 @@ do_timeout (void *cls) | |||
339 | static void | 319 | static void |
340 | collect_error_cb (void *cls) | 320 | collect_error_cb (void *cls) |
341 | { | 321 | { |
342 | struct RequestHandle *handle = cls; | 322 | do_error (cls); |
343 | |||
344 | do_error (handle); | ||
345 | } | 323 | } |
346 | 324 | ||
347 | 325 | ||
@@ -353,13 +331,14 @@ finished_cont (void *cls, int32_t success, const char *emsg) | |||
353 | 331 | ||
354 | resp = GNUNET_REST_create_response (emsg); | 332 | resp = GNUNET_REST_create_response (emsg); |
355 | MHD_add_response_header (resp, "Content-Type", "application/json"); | 333 | MHD_add_response_header (resp, "Content-Type", "application/json"); |
334 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
356 | if (GNUNET_OK != success) | 335 | if (GNUNET_OK != success) |
357 | { | 336 | { |
358 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 337 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
359 | return; | 338 | return; |
360 | } | 339 | } |
361 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 340 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
362 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 341 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
363 | } | 342 | } |
364 | 343 | ||
365 | 344 | ||
@@ -370,13 +349,14 @@ delete_finished_cb (void *cls, int32_t success, const char *emsg) | |||
370 | struct MHD_Response *resp; | 349 | struct MHD_Response *resp; |
371 | 350 | ||
372 | resp = GNUNET_REST_create_response (emsg); | 351 | resp = GNUNET_REST_create_response (emsg); |
352 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
373 | if (GNUNET_OK != success) | 353 | if (GNUNET_OK != success) |
374 | { | 354 | { |
375 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 355 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
376 | return; | 356 | return; |
377 | } | 357 | } |
378 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 358 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
379 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 359 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
380 | } | 360 | } |
381 | 361 | ||
382 | 362 | ||
@@ -395,6 +375,7 @@ return_response (void *cls) | |||
395 | result_str = json_dumps (handle->resp_object, 0); | 375 | result_str = json_dumps (handle->resp_object, 0); |
396 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); | 376 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); |
397 | resp = GNUNET_REST_create_response (result_str); | 377 | resp = GNUNET_REST_create_response (result_str); |
378 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
398 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 379 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
399 | GNUNET_free (result_str); | 380 | GNUNET_free (result_str); |
400 | cleanup_handle (handle); | 381 | cleanup_handle (handle); |
@@ -485,7 +466,7 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
485 | identity = handle->url + strlen ( | 466 | identity = handle->url + strlen ( |
486 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; | 467 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; |
487 | 468 | ||
488 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 469 | for (ego_entry = ego_head; NULL != ego_entry; |
489 | ego_entry = ego_entry->next) | 470 | ego_entry = ego_entry->next) |
490 | if (0 == strcmp (identity, ego_entry->identifier)) | 471 | if (0 == strcmp (identity, ego_entry->identifier)) |
491 | break; | 472 | break; |
@@ -523,9 +504,8 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
523 | */ | 504 | */ |
524 | if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) | 505 | if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) |
525 | GNUNET_RECLAIM_id_generate (&attribute->id); | 506 | GNUNET_RECLAIM_id_generate (&attribute->id); |
526 | handle->idp = GNUNET_RECLAIM_connect (cfg); | ||
527 | exp = GNUNET_TIME_UNIT_HOURS; | 507 | exp = GNUNET_TIME_UNIT_HOURS; |
528 | handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp, | 508 | handle->idp_op = GNUNET_RECLAIM_attestation_store (idp, |
529 | identity_priv, | 509 | identity_priv, |
530 | attribute, | 510 | attribute, |
531 | &exp, | 511 | &exp, |
@@ -644,7 +624,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
644 | identity = handle->url + strlen ( | 624 | identity = handle->url + strlen ( |
645 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; | 625 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; |
646 | 626 | ||
647 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 627 | for (ego_entry = ego_head; NULL != ego_entry; |
648 | ego_entry = ego_entry->next) | 628 | ego_entry = ego_entry->next) |
649 | if (0 == strcmp (identity, ego_entry->identifier)) | 629 | if (0 == strcmp (identity, ego_entry->identifier)) |
650 | break; | 630 | break; |
@@ -659,8 +639,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
659 | return; | 639 | return; |
660 | } | 640 | } |
661 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 641 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
662 | handle->idp = GNUNET_RECLAIM_connect (cfg); | 642 | handle->attest_it = GNUNET_RECLAIM_get_attestations_start (idp, |
663 | handle->attest_it = GNUNET_RECLAIM_get_attestations_start (handle->idp, | ||
664 | priv_key, | 643 | priv_key, |
665 | &collect_error_cb, | 644 | &collect_error_cb, |
666 | handle, | 645 | handle, |
@@ -713,7 +692,7 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
713 | return; | 692 | return; |
714 | } | 693 | } |
715 | 694 | ||
716 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 695 | for (ego_entry = ego_head; NULL != ego_entry; |
717 | ego_entry = ego_entry->next) | 696 | ego_entry = ego_entry->next) |
718 | if (0 == strcmp (identity, ego_entry->identifier)) | 697 | if (0 == strcmp (identity, ego_entry->identifier)) |
719 | break; | 698 | break; |
@@ -727,11 +706,10 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
727 | return; | 706 | return; |
728 | } | 707 | } |
729 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 708 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
730 | handle->idp = GNUNET_RECLAIM_connect (cfg); | ||
731 | memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation)); | 709 | memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation)); |
732 | GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); | 710 | GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); |
733 | attr.name = ""; | 711 | attr.name = ""; |
734 | handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp, | 712 | handle->idp_op = GNUNET_RECLAIM_attestation_delete (idp, |
735 | priv_key, | 713 | priv_key, |
736 | &attr, | 714 | &attr, |
737 | &delete_finished_cb, | 715 | &delete_finished_cb, |
@@ -768,7 +746,7 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
768 | } | 746 | } |
769 | identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; | 747 | identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; |
770 | 748 | ||
771 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 749 | for (ego_entry = ego_head; NULL != ego_entry; |
772 | ego_entry = ego_entry->next) | 750 | ego_entry = ego_entry->next) |
773 | if (0 == strcmp (identity, ego_entry->identifier)) | 751 | if (0 == strcmp (identity, ego_entry->identifier)) |
774 | break; | 752 | break; |
@@ -782,9 +760,8 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
782 | return; | 760 | return; |
783 | } | 761 | } |
784 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 762 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
785 | handle->idp = GNUNET_RECLAIM_connect (cfg); | ||
786 | handle->ticket_it = | 763 | handle->ticket_it = |
787 | GNUNET_RECLAIM_ticket_iteration_start (handle->idp, | 764 | GNUNET_RECLAIM_ticket_iteration_start (idp, |
788 | priv_key, | 765 | priv_key, |
789 | &collect_error_cb, | 766 | &collect_error_cb, |
790 | handle, | 767 | handle, |
@@ -823,7 +800,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
823 | } | 800 | } |
824 | identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; | 801 | identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; |
825 | 802 | ||
826 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 803 | for (ego_entry = ego_head; NULL != ego_entry; |
827 | ego_entry = ego_entry->next) | 804 | ego_entry = ego_entry->next) |
828 | if (0 == strcmp (identity, ego_entry->identifier)) | 805 | if (0 == strcmp (identity, ego_entry->identifier)) |
829 | break; | 806 | break; |
@@ -862,9 +839,8 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
862 | */ | 839 | */ |
863 | if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) | 840 | if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) |
864 | GNUNET_RECLAIM_id_generate (&attribute->id); | 841 | GNUNET_RECLAIM_id_generate (&attribute->id); |
865 | handle->idp = GNUNET_RECLAIM_connect (cfg); | ||
866 | exp = GNUNET_TIME_UNIT_HOURS; | 842 | exp = GNUNET_TIME_UNIT_HOURS; |
867 | handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp, | 843 | handle->idp_op = GNUNET_RECLAIM_attribute_store (idp, |
868 | identity_priv, | 844 | identity_priv, |
869 | attribute, | 845 | attribute, |
870 | &exp, | 846 | &exp, |
@@ -1012,7 +988,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1012 | } | 988 | } |
1013 | identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; | 989 | identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; |
1014 | 990 | ||
1015 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 991 | for (ego_entry = ego_head; NULL != ego_entry; |
1016 | ego_entry = ego_entry->next) | 992 | ego_entry = ego_entry->next) |
1017 | if (0 == strcmp (identity, ego_entry->identifier)) | 993 | if (0 == strcmp (identity, ego_entry->identifier)) |
1018 | break; | 994 | break; |
@@ -1027,8 +1003,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1027 | return; | 1003 | return; |
1028 | } | 1004 | } |
1029 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 1005 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
1030 | handle->idp = GNUNET_RECLAIM_connect (cfg); | 1006 | handle->attr_it = GNUNET_RECLAIM_get_attributes_start (idp, |
1031 | handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp, | ||
1032 | priv_key, | 1007 | priv_key, |
1033 | &collect_error_cb, | 1008 | &collect_error_cb, |
1034 | handle, | 1009 | handle, |
@@ -1078,7 +1053,7 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1078 | return; | 1053 | return; |
1079 | } | 1054 | } |
1080 | 1055 | ||
1081 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 1056 | for (ego_entry = ego_head; NULL != ego_entry; |
1082 | ego_entry = ego_entry->next) | 1057 | ego_entry = ego_entry->next) |
1083 | if (0 == strcmp (identity, ego_entry->identifier)) | 1058 | if (0 == strcmp (identity, ego_entry->identifier)) |
1084 | break; | 1059 | break; |
@@ -1092,11 +1067,10 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1092 | return; | 1067 | return; |
1093 | } | 1068 | } |
1094 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 1069 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
1095 | handle->idp = GNUNET_RECLAIM_connect (cfg); | ||
1096 | memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute)); | 1070 | memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute)); |
1097 | GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); | 1071 | GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); |
1098 | attr.name = ""; | 1072 | attr.name = ""; |
1099 | handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp, | 1073 | handle->idp_op = GNUNET_RECLAIM_attribute_delete (idp, |
1100 | priv_key, | 1074 | priv_key, |
1101 | &attr, | 1075 | &attr, |
1102 | &delete_finished_cb, | 1076 | &delete_finished_cb, |
@@ -1152,7 +1126,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1152 | return; | 1126 | return; |
1153 | } | 1127 | } |
1154 | 1128 | ||
1155 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 1129 | for (ego_entry = ego_head; NULL != ego_entry; |
1156 | ego_entry = ego_entry->next) | 1130 | ego_entry = ego_entry->next) |
1157 | { | 1131 | { |
1158 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); | 1132 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); |
@@ -1169,8 +1143,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1169 | } | 1143 | } |
1170 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 1144 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
1171 | 1145 | ||
1172 | handle->idp = GNUNET_RECLAIM_connect (cfg); | 1146 | handle->idp_op = GNUNET_RECLAIM_ticket_revoke (idp, |
1173 | handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp, | ||
1174 | identity_priv, | 1147 | identity_priv, |
1175 | ticket, | 1148 | ticket, |
1176 | &finished_cont, | 1149 | &finished_cont, |
@@ -1256,7 +1229,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1256 | json_decref (data_json); | 1229 | json_decref (data_json); |
1257 | return; | 1230 | return; |
1258 | } | 1231 | } |
1259 | for (ego_entry = handle->ego_head; NULL != ego_entry; | 1232 | for (ego_entry = ego_head; NULL != ego_entry; |
1260 | ego_entry = ego_entry->next) | 1233 | ego_entry = ego_entry->next) |
1261 | { | 1234 | { |
1262 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); | 1235 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); |
@@ -1273,8 +1246,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1273 | } | 1246 | } |
1274 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 1247 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
1275 | handle->resp_object = json_object (); | 1248 | handle->resp_object = json_object (); |
1276 | handle->idp = GNUNET_RECLAIM_connect (cfg); | 1249 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, |
1277 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, | ||
1278 | identity_priv, | 1250 | identity_priv, |
1279 | ticket, | 1251 | ticket, |
1280 | &consume_cont, | 1252 | &consume_cont, |
@@ -1308,55 +1280,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1308 | 1280 | ||
1309 | 1281 | ||
1310 | /** | 1282 | /** |
1311 | * Handle rest request | ||
1312 | * | ||
1313 | * @param handle the request handle | ||
1314 | */ | ||
1315 | static void | ||
1316 | init_cont (struct RequestHandle *handle) | ||
1317 | { | ||
1318 | struct GNUNET_REST_RequestHandlerError err; | ||
1319 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
1320 | { { MHD_HTTP_METHOD_GET, | ||
1321 | GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, | ||
1322 | &list_attribute_cont }, | ||
1323 | { MHD_HTTP_METHOD_POST, | ||
1324 | GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, | ||
1325 | &add_attribute_cont }, | ||
1326 | { MHD_HTTP_METHOD_DELETE, | ||
1327 | GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, | ||
1328 | &delete_attribute_cont }, | ||
1329 | { MHD_HTTP_METHOD_GET, | ||
1330 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION, | ||
1331 | &list_attestation_cont }, | ||
1332 | { MHD_HTTP_METHOD_POST, | ||
1333 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION, | ||
1334 | &add_attestation_cont }, | ||
1335 | { MHD_HTTP_METHOD_DELETE, | ||
1336 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION, | ||
1337 | &delete_attestation_cont }, | ||
1338 | { MHD_HTTP_METHOD_GET, | ||
1339 | GNUNET_REST_API_NS_IDENTITY_TICKETS, | ||
1340 | &list_tickets_cont }, | ||
1341 | { MHD_HTTP_METHOD_POST, | ||
1342 | GNUNET_REST_API_NS_IDENTITY_REVOKE, | ||
1343 | &revoke_ticket_cont }, | ||
1344 | { MHD_HTTP_METHOD_POST, | ||
1345 | GNUNET_REST_API_NS_IDENTITY_CONSUME, | ||
1346 | &consume_ticket_cont }, | ||
1347 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont }, | ||
1348 | GNUNET_REST_HANDLER_END }; | ||
1349 | |||
1350 | if (GNUNET_NO == | ||
1351 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) | ||
1352 | { | ||
1353 | handle->response_code = err.error_code; | ||
1354 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | |||
1359 | /** | ||
1360 | * If listing is enabled, prints information about the egos. | 1283 | * If listing is enabled, prints information about the egos. |
1361 | * | 1284 | * |
1362 | * This function is initially called for all egos and then again | 1285 | * This function is initially called for all egos and then again |
@@ -1395,52 +1318,126 @@ list_ego (void *cls, | |||
1395 | void **ctx, | 1318 | void **ctx, |
1396 | const char *identifier) | 1319 | const char *identifier) |
1397 | { | 1320 | { |
1398 | struct RequestHandle *handle = cls; | ||
1399 | struct EgoEntry *ego_entry; | 1321 | struct EgoEntry *ego_entry; |
1400 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | 1322 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; |
1401 | 1323 | ||
1402 | if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) | 1324 | if ((NULL == ego) && (ID_REST_STATE_INIT == state)) |
1403 | { | 1325 | { |
1404 | handle->state = ID_REST_STATE_POST_INIT; | 1326 | state = ID_REST_STATE_POST_INIT; |
1405 | init_cont (handle); | ||
1406 | return; | 1327 | return; |
1407 | } | 1328 | } |
1408 | if (ID_REST_STATE_INIT == handle->state) | 1329 | if (ID_REST_STATE_INIT == state) |
1409 | { | 1330 | { |
1410 | ego_entry = GNUNET_new (struct EgoEntry); | 1331 | ego_entry = GNUNET_new (struct EgoEntry); |
1411 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | 1332 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); |
1412 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | 1333 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
1413 | ego_entry->ego = ego; | 1334 | ego_entry->ego = ego; |
1414 | ego_entry->identifier = GNUNET_strdup (identifier); | 1335 | ego_entry->identifier = GNUNET_strdup (identifier); |
1415 | GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, | 1336 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, |
1416 | handle->ego_tail, | 1337 | ego_tail, |
1417 | ego_entry); | 1338 | ego_entry); |
1418 | } | 1339 | } |
1340 | /* Ego renamed or added */ | ||
1341 | if (identifier != NULL) | ||
1342 | { | ||
1343 | for (ego_entry = ego_head; NULL != ego_entry; | ||
1344 | ego_entry = ego_entry->next) | ||
1345 | { | ||
1346 | if (ego_entry->ego == ego) | ||
1347 | { | ||
1348 | /* Rename */ | ||
1349 | GNUNET_free (ego_entry->identifier); | ||
1350 | ego_entry->identifier = GNUNET_strdup (identifier); | ||
1351 | break; | ||
1352 | } | ||
1353 | } | ||
1354 | if (NULL == ego_entry) | ||
1355 | { | ||
1356 | /* Add */ | ||
1357 | ego_entry = GNUNET_new (struct EgoEntry); | ||
1358 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | ||
1359 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | ||
1360 | ego_entry->ego = ego; | ||
1361 | ego_entry->identifier = GNUNET_strdup (identifier); | ||
1362 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, | ||
1363 | ego_tail, | ||
1364 | ego_entry); | ||
1365 | } | ||
1366 | } | ||
1367 | else | ||
1368 | { | ||
1369 | /* Delete */ | ||
1370 | for (ego_entry = ego_head; NULL != ego_entry; | ||
1371 | ego_entry = ego_entry->next) | ||
1372 | { | ||
1373 | if (ego_entry->ego == ego) | ||
1374 | break; | ||
1375 | } | ||
1376 | if (NULL == ego_entry) | ||
1377 | return; /* Not found */ | ||
1378 | |||
1379 | GNUNET_CONTAINER_DLL_remove (ego_head, | ||
1380 | ego_tail, | ||
1381 | ego_entry); | ||
1382 | GNUNET_free (ego_entry->identifier); | ||
1383 | GNUNET_free (ego_entry->keystring); | ||
1384 | GNUNET_free (ego_entry); | ||
1385 | return; | ||
1386 | } | ||
1387 | |||
1419 | } | 1388 | } |
1420 | 1389 | ||
1421 | 1390 | ||
1422 | static void | 1391 | static enum GNUNET_GenericReturnValue |
1423 | rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 1392 | rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, |
1424 | GNUNET_REST_ResultProcessor proc, | 1393 | GNUNET_REST_ResultProcessor proc, |
1425 | void *proc_cls) | 1394 | void *proc_cls) |
1426 | { | 1395 | { |
1427 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 1396 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
1397 | struct GNUNET_REST_RequestHandlerError err; | ||
1398 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
1399 | { { MHD_HTTP_METHOD_GET, | ||
1400 | GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont }, | ||
1401 | { MHD_HTTP_METHOD_POST, | ||
1402 | GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont }, | ||
1403 | { MHD_HTTP_METHOD_DELETE, | ||
1404 | GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &delete_attribute_cont }, | ||
1405 | { MHD_HTTP_METHOD_GET, | ||
1406 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &list_attestation_cont }, | ||
1407 | { MHD_HTTP_METHOD_POST, | ||
1408 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &add_attestation_cont }, | ||
1409 | { MHD_HTTP_METHOD_DELETE, | ||
1410 | GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &delete_attestation_cont }, | ||
1411 | { MHD_HTTP_METHOD_GET, | ||
1412 | GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont }, | ||
1413 | { MHD_HTTP_METHOD_POST, | ||
1414 | GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont }, | ||
1415 | { MHD_HTTP_METHOD_POST, | ||
1416 | GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont }, | ||
1417 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont }, | ||
1418 | GNUNET_REST_HANDLER_END | ||
1419 | }; | ||
1428 | 1420 | ||
1429 | handle->response_code = 0; | 1421 | handle->response_code = 0; |
1430 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 1422 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
1431 | handle->proc_cls = proc_cls; | 1423 | handle->proc_cls = proc_cls; |
1432 | handle->proc = proc; | 1424 | handle->proc = proc; |
1433 | handle->state = ID_REST_STATE_INIT; | 1425 | state = ID_REST_STATE_INIT; |
1434 | handle->rest_handle = rest_handle; | 1426 | handle->rest_handle = rest_handle; |
1435 | 1427 | ||
1436 | handle->url = GNUNET_strdup (rest_handle->url); | 1428 | handle->url = GNUNET_strdup (rest_handle->url); |
1437 | if (handle->url[strlen (handle->url) - 1] == '/') | 1429 | if (handle->url[strlen (handle->url) - 1] == '/') |
1438 | handle->url[strlen (handle->url) - 1] = '\0'; | 1430 | handle->url[strlen (handle->url) - 1] = '\0'; |
1439 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | 1431 | if (GNUNET_NO == |
1440 | handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); | 1432 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) |
1433 | { | ||
1434 | cleanup_handle (handle); | ||
1435 | return GNUNET_NO; | ||
1436 | } | ||
1437 | |||
1441 | handle->timeout_task = | 1438 | handle->timeout_task = |
1442 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); | 1439 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); |
1443 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | 1440 | return GNUNET_YES; |
1444 | } | 1441 | } |
1445 | 1442 | ||
1446 | 1443 | ||
@@ -1472,7 +1469,8 @@ libgnunet_plugin_rest_reclaim_init (void *cls) | |||
1472 | MHD_HTTP_METHOD_PUT, | 1469 | MHD_HTTP_METHOD_PUT, |
1473 | MHD_HTTP_METHOD_DELETE, | 1470 | MHD_HTTP_METHOD_DELETE, |
1474 | MHD_HTTP_METHOD_OPTIONS); | 1471 | MHD_HTTP_METHOD_OPTIONS); |
1475 | 1472 | identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); | |
1473 | idp = GNUNET_RECLAIM_connect (cfg); | ||
1476 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1474 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1477 | _ ("Identity Provider REST API initialized\n")); | 1475 | _ ("Identity Provider REST API initialized\n")); |
1478 | return api; | 1476 | return api; |
@@ -1490,8 +1488,22 @@ libgnunet_plugin_rest_reclaim_done (void *cls) | |||
1490 | { | 1488 | { |
1491 | struct GNUNET_REST_Plugin *api = cls; | 1489 | struct GNUNET_REST_Plugin *api = cls; |
1492 | struct Plugin *plugin = api->cls; | 1490 | struct Plugin *plugin = api->cls; |
1491 | struct EgoEntry *ego_entry; | ||
1492 | struct EgoEntry *ego_tmp; | ||
1493 | 1493 | ||
1494 | plugin->cfg = NULL; | 1494 | plugin->cfg = NULL; |
1495 | if (NULL != idp) | ||
1496 | GNUNET_RECLAIM_disconnect (idp); | ||
1497 | if (NULL != identity_handle) | ||
1498 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
1499 | for (ego_entry = ego_head; NULL != ego_entry;) | ||
1500 | { | ||
1501 | ego_tmp = ego_entry; | ||
1502 | ego_entry = ego_entry->next; | ||
1503 | GNUNET_free (ego_tmp->identifier); | ||
1504 | GNUNET_free (ego_tmp->keystring); | ||
1505 | GNUNET_free (ego_tmp); | ||
1506 | } | ||
1495 | 1507 | ||
1496 | GNUNET_free (allow_methods); | 1508 | GNUNET_free (allow_methods); |
1497 | GNUNET_free (api); | 1509 | GNUNET_free (api); |
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index ff549fa71..d73241a6f 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c | |||
@@ -1572,6 +1572,8 @@ GNUNET_RECLAIM_ticket_consume ( | |||
1572 | ctm->ticket = *ticket; | 1572 | ctm->ticket = *ticket; |
1573 | if (NULL != h->mq) | 1573 | if (NULL != h->mq) |
1574 | GNUNET_MQ_send_copy (h->mq, op->env); | 1574 | GNUNET_MQ_send_copy (h->mq, op->env); |
1575 | else | ||
1576 | reconnect(h); | ||
1575 | return op; | 1577 | return op; |
1576 | } | 1578 | } |
1577 | 1579 | ||
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c index 875509536..436b5b205 100644 --- a/src/rest/gnunet-rest-server.c +++ b/src/rest/gnunet-rest-server.c | |||
@@ -115,11 +115,6 @@ static struct MHD_Response *failure_response; | |||
115 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 115 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
116 | 116 | ||
117 | /** | 117 | /** |
118 | * Map of loaded plugins. | ||
119 | */ | ||
120 | static struct GNUNET_CONTAINER_MultiHashMap *plugin_map; | ||
121 | |||
122 | /** | ||
123 | * Echo request Origin in CORS | 118 | * Echo request Origin in CORS |
124 | */ | 119 | */ |
125 | static int echo_origin; | 120 | static int echo_origin; |
@@ -140,6 +135,38 @@ static char *allow_headers; | |||
140 | static char *allow_credentials; | 135 | static char *allow_credentials; |
141 | 136 | ||
142 | /** | 137 | /** |
138 | * Plugin list head | ||
139 | */ | ||
140 | static struct PluginListEntry *plugins_head; | ||
141 | |||
142 | /** | ||
143 | * Plugin list tail | ||
144 | */ | ||
145 | static struct PluginListEntry *plugins_tail; | ||
146 | |||
147 | /** | ||
148 | * A plugin list entry | ||
149 | */ | ||
150 | struct PluginListEntry | ||
151 | { | ||
152 | /* DLL */ | ||
153 | struct PluginListEntry *next; | ||
154 | |||
155 | /* DLL */ | ||
156 | struct PluginListEntry *prev; | ||
157 | |||
158 | /** | ||
159 | * libname (to cleanup) | ||
160 | */ | ||
161 | char *libname; | ||
162 | |||
163 | /** | ||
164 | * The plugin | ||
165 | */ | ||
166 | struct GNUNET_REST_Plugin *plugin; | ||
167 | }; | ||
168 | |||
169 | /** | ||
143 | * MHD Connection handle | 170 | * MHD Connection handle |
144 | */ | 171 | */ |
145 | struct MhdConnectionHandle | 172 | struct MhdConnectionHandle |
@@ -148,8 +175,6 @@ struct MhdConnectionHandle | |||
148 | 175 | ||
149 | struct MHD_Response *response; | 176 | struct MHD_Response *response; |
150 | 177 | ||
151 | struct GNUNET_REST_Plugin *plugin; | ||
152 | |||
153 | struct GNUNET_REST_RequestHandle *data_handle; | 178 | struct GNUNET_REST_RequestHandle *data_handle; |
154 | 179 | ||
155 | struct MHD_PostProcessor *pp; | 180 | struct MHD_PostProcessor *pp; |
@@ -159,6 +184,42 @@ struct MhdConnectionHandle | |||
159 | int state; | 184 | int state; |
160 | }; | 185 | }; |
161 | 186 | ||
187 | /** | ||
188 | * Accepted requests | ||
189 | */ | ||
190 | struct AcceptedRequest | ||
191 | { | ||
192 | /** | ||
193 | * DLL | ||
194 | */ | ||
195 | struct AcceptedRequest *next; | ||
196 | |||
197 | /** | ||
198 | * DLL | ||
199 | */ | ||
200 | struct AcceptedRequest *prev; | ||
201 | |||
202 | /** | ||
203 | * Socket | ||
204 | */ | ||
205 | struct GNUNET_NETWORK_Handle *sock; | ||
206 | |||
207 | /** | ||
208 | * Connection | ||
209 | */ | ||
210 | struct MhdConnectionHandle *con_handle; | ||
211 | }; | ||
212 | |||
213 | /** | ||
214 | * AcceptedRequest list head | ||
215 | */ | ||
216 | static struct AcceptedRequest *req_list_head; | ||
217 | |||
218 | /** | ||
219 | * AcceptedRequest list tail | ||
220 | */ | ||
221 | static struct AcceptedRequest *req_list_tail; | ||
222 | |||
162 | /* ************************* Global helpers ********************* */ | 223 | /* ************************* Global helpers ********************* */ |
163 | 224 | ||
164 | 225 | ||
@@ -213,7 +274,6 @@ cleanup_url_map (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
213 | return GNUNET_YES; | 274 | return GNUNET_YES; |
214 | } | 275 | } |
215 | 276 | ||
216 | |||
217 | static void | 277 | static void |
218 | cleanup_handle (struct MhdConnectionHandle *handle) | 278 | cleanup_handle (struct MhdConnectionHandle *handle) |
219 | { | 279 | { |
@@ -243,6 +303,19 @@ cleanup_handle (struct MhdConnectionHandle *handle) | |||
243 | GNUNET_free (handle); | 303 | GNUNET_free (handle); |
244 | } | 304 | } |
245 | 305 | ||
306 | static void | ||
307 | cleanup_ar (struct AcceptedRequest *ar) | ||
308 | { | ||
309 | if (NULL != ar->con_handle) | ||
310 | { | ||
311 | cleanup_handle (ar->con_handle); | ||
312 | } | ||
313 | GNUNET_NETWORK_socket_free_memory_only_ (ar->sock); | ||
314 | GNUNET_CONTAINER_DLL_remove (req_list_head, | ||
315 | req_list_tail, | ||
316 | ar); | ||
317 | GNUNET_free (ar); | ||
318 | } | ||
246 | 319 | ||
247 | static int | 320 | static int |
248 | header_iterator (void *cls, | 321 | header_iterator (void *cls, |
@@ -321,19 +394,24 @@ post_data_iter (void *cls, | |||
321 | return MHD_YES; | 394 | return MHD_YES; |
322 | 395 | ||
323 | GNUNET_CRYPTO_hash (key, strlen (key), &hkey); | 396 | GNUNET_CRYPTO_hash (key, strlen (key), &hkey); |
324 | GNUNET_asprintf (&val, "%s", data); | 397 | val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map, |
325 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( | 398 | &hkey); |
326 | handle->url_param_map, | 399 | if (NULL == val) |
327 | &hkey, | ||
328 | val, | ||
329 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
330 | { | 400 | { |
331 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 401 | val = GNUNET_malloc (65536); |
332 | "Could not load add url param '%s'=%s\n", | 402 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( |
333 | key, | 403 | handle->url_param_map, |
334 | data); | 404 | &hkey, |
335 | GNUNET_free (val); | 405 | val, |
406 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
407 | { | ||
408 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
409 | "Could not add url param '%s'\n", | ||
410 | key); | ||
411 | GNUNET_free (val); | ||
412 | } | ||
336 | } | 413 | } |
414 | memcpy (val + off, data, size); | ||
337 | return MHD_YES; | 415 | return MHD_YES; |
338 | } | 416 | } |
339 | 417 | ||
@@ -373,41 +451,30 @@ create_response (void *cls, | |||
373 | size_t *upload_data_size, | 451 | size_t *upload_data_size, |
374 | void **con_cls) | 452 | void **con_cls) |
375 | { | 453 | { |
376 | char *plugin_name; | ||
377 | char *origin; | 454 | char *origin; |
455 | struct AcceptedRequest *ar; | ||
378 | struct GNUNET_HashCode key; | 456 | struct GNUNET_HashCode key; |
379 | struct MhdConnectionHandle *con_handle; | 457 | struct MhdConnectionHandle *con_handle; |
380 | struct GNUNET_REST_RequestHandle *rest_conndata_handle; | 458 | struct GNUNET_REST_RequestHandle *rest_conndata_handle; |
459 | struct PluginListEntry *ple; | ||
381 | 460 | ||
382 | con_handle = *con_cls; | 461 | ar = *con_cls; |
462 | if (NULL == ar) | ||
463 | { | ||
464 | GNUNET_break (0); | ||
465 | return MHD_NO; | ||
466 | } | ||
383 | 467 | ||
384 | if (NULL == *con_cls) | 468 | if (NULL == ar->con_handle) |
385 | { | 469 | { |
386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); | 470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); |
387 | char tmp_url[strlen (url) + 1]; | ||
388 | strcpy (tmp_url, url); | ||
389 | con_handle = GNUNET_new (struct MhdConnectionHandle); | 471 | con_handle = GNUNET_new (struct MhdConnectionHandle); |
390 | con_handle->con = con; | 472 | con_handle->con = con; |
391 | con_handle->state = GN_REST_STATE_INIT; | 473 | con_handle->state = GN_REST_STATE_INIT; |
392 | *con_cls = con_handle; | 474 | ar->con_handle = con_handle; |
393 | |||
394 | plugin_name = strtok (tmp_url, "/"); | ||
395 | |||
396 | if (NULL != plugin_name) | ||
397 | { | ||
398 | GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key); | ||
399 | |||
400 | con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map, &key); | ||
401 | } | ||
402 | if (NULL == con_handle->plugin) | ||
403 | { | ||
404 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n"); | ||
405 | GNUNET_free (con_handle); | ||
406 | return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); | ||
407 | } | ||
408 | |||
409 | return MHD_YES; | 475 | return MHD_YES; |
410 | } | 476 | } |
477 | con_handle = ar->con_handle; | ||
411 | if (GN_REST_STATE_INIT == con_handle->state) | 478 | if (GN_REST_STATE_INIT == con_handle->state) |
412 | { | 479 | { |
413 | rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle); | 480 | rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle); |
@@ -428,6 +495,7 @@ create_response (void *cls, | |||
428 | MHD_HEADER_KIND, | 495 | MHD_HEADER_KIND, |
429 | (MHD_KeyValueIterator) & header_iterator, | 496 | (MHD_KeyValueIterator) & header_iterator, |
430 | rest_conndata_handle); | 497 | rest_conndata_handle); |
498 | |||
431 | con_handle->pp = MHD_create_post_processor (con, | 499 | con_handle->pp = MHD_create_post_processor (con, |
432 | 65536, | 500 | 65536, |
433 | &post_data_iter, | 501 | &post_data_iter, |
@@ -439,9 +507,18 @@ create_response (void *cls, | |||
439 | MHD_destroy_post_processor (con_handle->pp); | 507 | MHD_destroy_post_processor (con_handle->pp); |
440 | 508 | ||
441 | con_handle->state = GN_REST_STATE_PROCESSING; | 509 | con_handle->state = GN_REST_STATE_PROCESSING; |
442 | con_handle->plugin->process_request (rest_conndata_handle, | 510 | for (ple = plugins_head; NULL != ple; ple = ple->next) |
443 | &plugin_callback, | 511 | { |
444 | con_handle); | 512 | if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle, |
513 | &plugin_callback, | ||
514 | con_handle)) | ||
515 | break; /* Request handled */ | ||
516 | } | ||
517 | if (NULL == ple) | ||
518 | { | ||
519 | /** Request not handled **/ | ||
520 | MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); | ||
521 | } | ||
445 | *upload_data_size = 0; | 522 | *upload_data_size = 0; |
446 | run_mhd_now (); | 523 | run_mhd_now (); |
447 | return MHD_YES; | 524 | return MHD_YES; |
@@ -513,7 +590,7 @@ create_response (void *cls, | |||
513 | MHD_RESULT ret = MHD_queue_response (con, | 590 | MHD_RESULT ret = MHD_queue_response (con, |
514 | con_handle->status, | 591 | con_handle->status, |
515 | con_handle->response); | 592 | con_handle->response); |
516 | cleanup_handle (con_handle); | 593 | //cleanup_handle (con_handle); |
517 | return ret; | 594 | return ret; |
518 | } | 595 | } |
519 | } | 596 | } |
@@ -521,27 +598,6 @@ create_response (void *cls, | |||
521 | 598 | ||
522 | /* ******************** MHD HTTP setup and event loop ******************** */ | 599 | /* ******************** MHD HTTP setup and event loop ******************** */ |
523 | 600 | ||
524 | /** | ||
525 | * Function called when MHD decides that we are done with a connection. | ||
526 | * | ||
527 | * @param cls NULL | ||
528 | * @param connection connection handle | ||
529 | * @param con_cls value as set by the last call to | ||
530 | * the MHD_AccessHandlerCallback, should be our handle | ||
531 | * @param toe reason for request termination (ignored) | ||
532 | */ | ||
533 | static void | ||
534 | mhd_completed_cb (void *cls, | ||
535 | struct MHD_Connection *connection, | ||
536 | void **con_cls, | ||
537 | enum MHD_RequestTerminationCode toe) | ||
538 | { | ||
539 | if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) | ||
540 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
541 | "MHD encountered error handling request: %d\n", | ||
542 | toe); | ||
543 | } | ||
544 | |||
545 | 601 | ||
546 | /** | 602 | /** |
547 | * Kill the MHD daemon. | 603 | * Kill the MHD daemon. |
@@ -649,6 +705,135 @@ schedule_httpd () | |||
649 | GNUNET_NETWORK_fdset_destroy (wws); | 705 | GNUNET_NETWORK_fdset_destroy (wws); |
650 | } | 706 | } |
651 | 707 | ||
708 | /** | ||
709 | * Function called when MHD first processes an incoming connection. | ||
710 | * Gives us the respective URI information. | ||
711 | * | ||
712 | * We use this to associate the `struct MHD_Connection` with our | ||
713 | * internal `struct AcceptedRequest` data structure (by checking | ||
714 | * for matching sockets). | ||
715 | * | ||
716 | * @param cls the HTTP server handle (a `struct MhdHttpList`) | ||
717 | * @param url the URL that is being requested | ||
718 | * @param connection MHD connection object for the request | ||
719 | * @return the `struct Socks5Request` that this @a connection is for | ||
720 | */ | ||
721 | static void * | ||
722 | mhd_log_callback (void *cls, | ||
723 | const char *url, | ||
724 | struct MHD_Connection *connection) | ||
725 | { | ||
726 | struct AcceptedRequest *ar; | ||
727 | const union MHD_ConnectionInfo *ci; | ||
728 | |||
729 | ci = MHD_get_connection_info (connection, | ||
730 | MHD_CONNECTION_INFO_SOCKET_CONTEXT); | ||
731 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); | ||
732 | if (NULL == ci) | ||
733 | { | ||
734 | GNUNET_break (0); | ||
735 | return NULL; | ||
736 | } | ||
737 | ar = ci->socket_context; | ||
738 | return ar; | ||
739 | } | ||
740 | |||
741 | |||
742 | |||
743 | /** | ||
744 | * Function called when MHD decides that we are done with a connection. | ||
745 | * | ||
746 | * @param cls NULL | ||
747 | * @param connection connection handle | ||
748 | * @param con_cls value as set by the last call to | ||
749 | * the MHD_AccessHandlerCallback, should be our handle | ||
750 | * @param toe reason for request termination (ignored) | ||
751 | */ | ||
752 | static void | ||
753 | mhd_completed_cb (void *cls, | ||
754 | struct MHD_Connection *connection, | ||
755 | void **con_cls, | ||
756 | enum MHD_RequestTerminationCode toe) | ||
757 | { | ||
758 | struct AcceptedRequest *ar = *con_cls; | ||
759 | if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) | ||
760 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
761 | "MHD encountered error handling request: %d\n", | ||
762 | toe); | ||
763 | if (NULL == ar) | ||
764 | return; | ||
765 | if (NULL != ar->con_handle) | ||
766 | { | ||
767 | cleanup_handle (ar->con_handle); | ||
768 | ar->con_handle = NULL; | ||
769 | } | ||
770 | schedule_httpd (); | ||
771 | *con_cls = NULL; | ||
772 | } | ||
773 | |||
774 | /** | ||
775 | * Function called when MHD connection is opened or closed. | ||
776 | * | ||
777 | * @param cls NULL | ||
778 | * @param connection connection handle | ||
779 | * @param con_cls value as set by the last call to | ||
780 | * the MHD_AccessHandlerCallback, should be our `struct Socks5Request *` | ||
781 | * @param toe connection notification type | ||
782 | */ | ||
783 | static void | ||
784 | mhd_connection_cb (void *cls, | ||
785 | struct MHD_Connection *connection, | ||
786 | void **con_cls, | ||
787 | enum MHD_ConnectionNotificationCode cnc) | ||
788 | { | ||
789 | struct AcceptedRequest *ar; | ||
790 | const union MHD_ConnectionInfo *ci; | ||
791 | int sock; | ||
792 | |||
793 | switch (cnc) | ||
794 | { | ||
795 | case MHD_CONNECTION_NOTIFY_STARTED: | ||
796 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n"); | ||
797 | ci = MHD_get_connection_info (connection, | ||
798 | MHD_CONNECTION_INFO_CONNECTION_FD); | ||
799 | if (NULL == ci) | ||
800 | { | ||
801 | GNUNET_break (0); | ||
802 | return; | ||
803 | } | ||
804 | sock = ci->connect_fd; | ||
805 | for (ar = req_list_head; NULL != ar; ar = ar->next) | ||
806 | { | ||
807 | if (GNUNET_NETWORK_get_fd (ar->sock) == sock) | ||
808 | { | ||
809 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
810 | "Context set...\n"); | ||
811 | *con_cls = ar; | ||
812 | break; | ||
813 | } | ||
814 | } | ||
815 | break; | ||
816 | |||
817 | case MHD_CONNECTION_NOTIFY_CLOSED: | ||
818 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
819 | "Connection closed... cleaning up\n"); | ||
820 | ar = *con_cls; | ||
821 | if (NULL == ar) | ||
822 | { | ||
823 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
824 | "Connection stale!\n"); | ||
825 | return; | ||
826 | } | ||
827 | cleanup_ar (ar); | ||
828 | *con_cls = NULL; | ||
829 | break; | ||
830 | |||
831 | default: | ||
832 | GNUNET_break (0); | ||
833 | } | ||
834 | } | ||
835 | |||
836 | |||
652 | 837 | ||
653 | /** | 838 | /** |
654 | * Task run whenever HTTP server operations are pending. | 839 | * Task run whenever HTTP server operations are pending. |
@@ -674,7 +859,7 @@ static void | |||
674 | do_accept (void *cls) | 859 | do_accept (void *cls) |
675 | { | 860 | { |
676 | struct GNUNET_NETWORK_Handle *lsock = cls; | 861 | struct GNUNET_NETWORK_Handle *lsock = cls; |
677 | struct GNUNET_NETWORK_Handle *s; | 862 | struct AcceptedRequest *ar; |
678 | int fd; | 863 | int fd; |
679 | const struct sockaddr *addr; | 864 | const struct sockaddr *addr; |
680 | socklen_t len; | 865 | socklen_t len; |
@@ -696,24 +881,30 @@ do_accept (void *cls) | |||
696 | } | 881 | } |
697 | else | 882 | else |
698 | GNUNET_assert (0); | 883 | GNUNET_assert (0); |
699 | s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); | 884 | ar = GNUNET_new (struct AcceptedRequest); |
700 | if (NULL == s) | 885 | ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); |
886 | if (NULL == ar->sock) | ||
701 | { | 887 | { |
888 | GNUNET_free (ar); | ||
702 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); | 889 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); |
703 | return; | 890 | return; |
704 | } | 891 | } |
705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 892 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
706 | "Got an inbound connection, waiting for data\n"); | 893 | "Got an inbound connection, waiting for data\n"); |
707 | fd = GNUNET_NETWORK_get_fd (s); | 894 | fd = GNUNET_NETWORK_get_fd (ar->sock); |
708 | addr = GNUNET_NETWORK_get_addr (s); | 895 | addr = GNUNET_NETWORK_get_addr (ar->sock); |
709 | len = GNUNET_NETWORK_get_addrlen (s); | 896 | len = GNUNET_NETWORK_get_addrlen (ar->sock); |
897 | GNUNET_CONTAINER_DLL_insert (req_list_head, | ||
898 | req_list_tail, | ||
899 | ar); | ||
710 | if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) | 900 | if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) |
711 | { | 901 | { |
902 | GNUNET_NETWORK_socket_close (ar->sock); | ||
903 | GNUNET_free (ar); | ||
712 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 904 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
713 | _ ("Failed to pass client to MHD\n")); | 905 | _ ("Failed to pass client to MHD\n")); |
714 | return; | 906 | return; |
715 | } | 907 | } |
716 | GNUNET_free (s); | ||
717 | schedule_httpd (); | 908 | schedule_httpd (); |
718 | } | 909 | } |
719 | 910 | ||
@@ -726,6 +917,18 @@ do_accept (void *cls) | |||
726 | static void | 917 | static void |
727 | do_shutdown (void *cls) | 918 | do_shutdown (void *cls) |
728 | { | 919 | { |
920 | struct PluginListEntry *ple; | ||
921 | |||
922 | while (NULL != plugins_head) | ||
923 | { | ||
924 | ple = plugins_head; | ||
925 | GNUNET_CONTAINER_DLL_remove (plugins_head, | ||
926 | plugins_tail, | ||
927 | ple); | ||
928 | GNUNET_PLUGIN_unload (ple->libname, NULL); | ||
929 | GNUNET_free (ple->libname); | ||
930 | GNUNET_free (ple); | ||
931 | } | ||
729 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); | 932 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); |
730 | kill_httpd (); | 933 | kill_httpd (); |
731 | GNUNET_free (allow_credentials); | 934 | GNUNET_free (allow_credentials); |
@@ -814,7 +1017,7 @@ static void | |||
814 | load_plugin (void *cls, const char *libname, void *lib_ret) | 1017 | load_plugin (void *cls, const char *libname, void *lib_ret) |
815 | { | 1018 | { |
816 | struct GNUNET_REST_Plugin *plugin = lib_ret; | 1019 | struct GNUNET_REST_Plugin *plugin = lib_ret; |
817 | struct GNUNET_HashCode key; | 1020 | struct PluginListEntry *ple; |
818 | 1021 | ||
819 | if (NULL == lib_ret) | 1022 | if (NULL == lib_ret) |
820 | { | 1023 | { |
@@ -825,18 +1028,12 @@ load_plugin (void *cls, const char *libname, void *lib_ret) | |||
825 | } | 1028 | } |
826 | GNUNET_assert (1 < strlen (plugin->name)); | 1029 | GNUNET_assert (1 < strlen (plugin->name)); |
827 | GNUNET_assert ('/' == *plugin->name); | 1030 | GNUNET_assert ('/' == *plugin->name); |
828 | GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key); | 1031 | ple = GNUNET_new (struct PluginListEntry); |
829 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( | 1032 | ple->libname = GNUNET_strdup (libname); |
830 | plugin_map, | 1033 | ple->plugin = plugin; |
831 | &key, | 1034 | GNUNET_CONTAINER_DLL_insert (plugins_head, |
832 | plugin, | 1035 | plugins_tail, |
833 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | 1036 | ple); |
834 | { | ||
835 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
836 | "Could not load add plugin `%s'\n", | ||
837 | libname); | ||
838 | return; | ||
839 | } | ||
840 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); | 1037 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); |
841 | } | 1038 | } |
842 | 1039 | ||
@@ -858,8 +1055,8 @@ run (void *cls, | |||
858 | char *addr_str; | 1055 | char *addr_str; |
859 | 1056 | ||
860 | cfg = c; | 1057 | cfg = c; |
861 | plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | 1058 | plugins_head = NULL; |
862 | 1059 | plugins_tail = NULL; | |
863 | /* Get port to bind to */ | 1060 | /* Get port to bind to */ |
864 | if (GNUNET_OK != | 1061 | if (GNUNET_OK != |
865 | GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) | 1062 | GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) |
@@ -1004,6 +1201,12 @@ run (void *cls, | |||
1004 | NULL, | 1201 | NULL, |
1005 | MHD_OPTION_CONNECTION_TIMEOUT, | 1202 | MHD_OPTION_CONNECTION_TIMEOUT, |
1006 | (unsigned int) 16, | 1203 | (unsigned int) 16, |
1204 | MHD_OPTION_NOTIFY_CONNECTION, | ||
1205 | &mhd_connection_cb, | ||
1206 | NULL, | ||
1207 | MHD_OPTION_URI_LOG_CALLBACK, | ||
1208 | mhd_log_callback, | ||
1209 | NULL, | ||
1007 | MHD_OPTION_NOTIFY_COMPLETED, | 1210 | MHD_OPTION_NOTIFY_COMPLETED, |
1008 | &mhd_completed_cb, | 1211 | &mhd_completed_cb, |
1009 | NULL, | 1212 | NULL, |
diff --git a/src/rest/plugin_rest_config.c b/src/rest/plugin_rest_config.c index 43dea1b9f..d9ae57acd 100644 --- a/src/rest/plugin_rest_config.c +++ b/src/rest/plugin_rest_config.c | |||
@@ -347,7 +347,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
347 | * @param proc_cls closure for @a proc | 347 | * @param proc_cls closure for @a proc |
348 | * @return #GNUNET_OK if request accepted | 348 | * @return #GNUNET_OK if request accepted |
349 | */ | 349 | */ |
350 | static void | 350 | static enum GNUNET_GenericReturnValue |
351 | rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, | 351 | rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, |
352 | GNUNET_REST_ResultProcessor proc, | 352 | GNUNET_REST_ResultProcessor proc, |
353 | void *proc_cls) | 353 | void *proc_cls) |
@@ -371,9 +371,10 @@ rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, | |||
371 | if (GNUNET_NO == | 371 | if (GNUNET_NO == |
372 | GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle)) | 372 | GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle)) |
373 | { | 373 | { |
374 | handle->response_code = err.error_code; | 374 | cleanup_handle (handle); |
375 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 375 | return GNUNET_NO; |
376 | } | 376 | } |
377 | return GNUNET_YES; | ||
377 | } | 378 | } |
378 | 379 | ||
379 | 380 | ||
diff --git a/src/rest/plugin_rest_copying.c b/src/rest/plugin_rest_copying.c index e601e505e..1649da3bb 100644 --- a/src/rest/plugin_rest_copying.c +++ b/src/rest/plugin_rest_copying.c | |||
@@ -82,24 +82,6 @@ cleanup_handle (struct RequestHandle *handle) | |||
82 | 82 | ||
83 | 83 | ||
84 | /** | 84 | /** |
85 | * Task run on shutdown. Cleans up everything. | ||
86 | * | ||
87 | * @param cls unused | ||
88 | * @param tc scheduler context | ||
89 | */ | ||
90 | static void | ||
91 | do_error (void *cls) | ||
92 | { | ||
93 | struct RequestHandle *handle = cls; | ||
94 | struct MHD_Response *resp; | ||
95 | |||
96 | resp = GNUNET_REST_create_response (NULL); | ||
97 | handle->proc (handle->proc_cls, resp, handle->response_code); | ||
98 | cleanup_handle (handle); | ||
99 | } | ||
100 | |||
101 | |||
102 | /** | ||
103 | * Handle rest request | 85 | * Handle rest request |
104 | * | 86 | * |
105 | * @param handle the lookup handle | 87 | * @param handle the lookup handle |
@@ -155,7 +137,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
155 | * @param proc_cls closure for @a proc | 137 | * @param proc_cls closure for @a proc |
156 | * @return #GNUNET_OK if request accepted | 138 | * @return #GNUNET_OK if request accepted |
157 | */ | 139 | */ |
158 | static void | 140 | static enum GNUNET_GenericReturnValue |
159 | rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, | 141 | rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, |
160 | GNUNET_REST_ResultProcessor proc, | 142 | GNUNET_REST_ResultProcessor proc, |
161 | void *proc_cls) | 143 | void *proc_cls) |
@@ -172,14 +154,10 @@ rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, | |||
172 | handle->proc = proc; | 154 | handle->proc = proc; |
173 | handle->rest_handle = conndata_handle; | 155 | handle->rest_handle = conndata_handle; |
174 | 156 | ||
175 | if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle, | 157 | return GNUNET_REST_handle_request (conndata_handle, |
176 | handlers, | 158 | handlers, |
177 | &err, | 159 | &err, |
178 | handle)) | 160 | handle); |
179 | { | ||
180 | handle->response_code = err.error_code; | ||
181 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
182 | } | ||
183 | } | 161 | } |
184 | 162 | ||
185 | 163 | ||
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c index 0c85660dd..e194b0159 100644 --- a/src/transport/transport-testing2.c +++ b/src/transport/transport-testing2.c | |||
@@ -1023,11 +1023,7 @@ peerstore_start ( | |||
1023 | { | 1023 | { |
1024 | char *binary; | 1024 | char *binary; |
1025 | 1025 | ||
1026 | LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start\n"); | ||
1027 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-peerstore"); | 1026 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-peerstore"); |
1028 | LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start binary %s\n", | ||
1029 | binary); | ||
1030 | LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start 2\n"); | ||
1031 | tc_h->ps_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | 1027 | tc_h->ps_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
1032 | NULL, | 1028 | NULL, |
1033 | NULL, | 1029 | NULL, |
@@ -1037,7 +1033,6 @@ peerstore_start ( | |||
1037 | "-c", | 1033 | "-c", |
1038 | tc_h->cfg_filename, | 1034 | tc_h->cfg_filename, |
1039 | NULL); | 1035 | NULL); |
1040 | LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start 3\n"); | ||
1041 | if (NULL == tc_h->ps_proc) | 1036 | if (NULL == tc_h->ps_proc) |
1042 | { | 1037 | { |
1043 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start Peerstore!"); | 1038 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start Peerstore!"); |
@@ -1059,8 +1054,6 @@ nat_start ( | |||
1059 | 1054 | ||
1060 | LOG (GNUNET_ERROR_TYPE_DEBUG, "nat_start\n"); | 1055 | LOG (GNUNET_ERROR_TYPE_DEBUG, "nat_start\n"); |
1061 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-nat"); | 1056 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-nat"); |
1062 | LOG (GNUNET_ERROR_TYPE_DEBUG, "nat_start binary %s\n", | ||
1063 | binary); | ||
1064 | tc_h->nat_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR | 1057 | tc_h->nat_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR |
1065 | | GNUNET_OS_USE_PIPE_CONTROL, | 1058 | | GNUNET_OS_USE_PIPE_CONTROL, |
1066 | NULL, | 1059 | NULL, |
@@ -1158,8 +1151,6 @@ void | |||
1158 | GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( | 1151 | GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( |
1159 | struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h) | 1152 | struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h) |
1160 | { | 1153 | { |
1161 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1162 | "transport communicator service stop\n"); | ||
1163 | shutdown_communicator (tc_h->c_proc); | 1154 | shutdown_communicator (tc_h->c_proc); |
1164 | shutdown_service (tc_h->sh); | 1155 | shutdown_service (tc_h->sh); |
1165 | shutdown_nat (tc_h->nat_proc); | 1156 | shutdown_nat (tc_h->nat_proc); |
diff --git a/src/util/buffer.c b/src/util/buffer.c index 2af972413..662e4d0f2 100644 --- a/src/util/buffer.c +++ b/src/util/buffer.c | |||
@@ -32,7 +32,8 @@ | |||
32 | * @param capacity the capacity (in bytes) to allocate for @a buf | 32 | * @param capacity the capacity (in bytes) to allocate for @a buf |
33 | */ | 33 | */ |
34 | void | 34 | void |
35 | GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity) | 35 | GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, |
36 | size_t capacity) | ||
36 | { | 37 | { |
37 | /* Buffer should be zero-initialized */ | 38 | /* Buffer should be zero-initialized */ |
38 | GNUNET_assert (0 == buf->mem); | 39 | GNUNET_assert (0 == buf->mem); |
@@ -257,25 +258,25 @@ GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf, | |||
257 | * | 258 | * |
258 | * @param buf buffer to write to | 259 | * @param buf buffer to write to |
259 | * @param data data to read from | 260 | * @param data data to read from |
260 | * @param len number of bytes to copy from @a data to @a buf | 261 | * @param data_len number of bytes to copy from @a data to @a buf |
261 | */ | 262 | */ |
262 | void | 263 | void |
263 | GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, | 264 | GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, |
264 | const char *data, | 265 | const void *data, |
265 | size_t len) | 266 | size_t data_len) |
266 | { | 267 | { |
267 | size_t outlen = len * 8; | 268 | size_t outlen = data_len * 8; |
268 | char *p = buf->mem + buf->position; | ||
269 | 269 | ||
270 | if (outlen % 5 > 0) | 270 | if (outlen % 5 > 0) |
271 | outlen += 5 - outlen % 5; | 271 | outlen += 5 - outlen % 5; |
272 | outlen /= 5; | 272 | outlen /= 5; |
273 | 273 | GNUNET_buffer_ensure_remaining (buf, | |
274 | GNUNET_buffer_ensure_remaining (buf, outlen); | 274 | outlen); |
275 | GNUNET_assert (NULL != | 275 | GNUNET_assert (NULL != |
276 | GNUNET_STRINGS_data_to_string (data, | 276 | GNUNET_STRINGS_data_to_string (data, |
277 | len, | 277 | data_len, |
278 | p, | 278 | (buf->mem |
279 | + buf->position), | ||
279 | outlen)); | 280 | outlen)); |
280 | buf->position += outlen; | 281 | buf->position += outlen; |
281 | GNUNET_assert (buf->position <= buf->capacity); | 282 | GNUNET_assert (buf->position <= buf->capacity); |
diff --git a/src/util/strings.c b/src/util/strings.c index 41180dd71..9d6f4039e 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <iconv.h> | 29 | #include <iconv.h> |
30 | #endif | 30 | #endif |
31 | #include "gnunet_crypto_lib.h" | 31 | #include "gnunet_crypto_lib.h" |
32 | #include "gnunet_buffer_lib.h" | ||
32 | #include "gnunet_strings_lib.h" | 33 | #include "gnunet_strings_lib.h" |
33 | #include <unicase.h> | 34 | #include <unicase.h> |
34 | #include <unistr.h> | 35 | #include <unistr.h> |
@@ -2088,4 +2089,161 @@ GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out) | |||
2088 | } | 2089 | } |
2089 | 2090 | ||
2090 | 2091 | ||
2092 | /** | ||
2093 | * url/percent encode (RFC3986). | ||
2094 | * | ||
2095 | * @param data the data to encode | ||
2096 | * @param len the length of the input | ||
2097 | * @param output where to write the output (*output should be NULL, | ||
2098 | * is allocated) | ||
2099 | * @return the size of the output | ||
2100 | */ | ||
2101 | size_t | ||
2102 | GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out) | ||
2103 | { | ||
2104 | const char *rpos = data; | ||
2105 | *out = GNUNET_malloc (len + 1); /* output should always fit into input */ | ||
2106 | char *wpos = *out; | ||
2107 | size_t resl = 0; | ||
2108 | |||
2109 | while ('\0' != *rpos) | ||
2110 | { | ||
2111 | unsigned int num; | ||
2112 | switch (*rpos) | ||
2113 | { | ||
2114 | case '%': | ||
2115 | if (1 != sscanf (rpos + 1, "%2x", &num)) | ||
2116 | break; | ||
2117 | *wpos = (char) ((unsigned char) num); | ||
2118 | wpos++; | ||
2119 | resl++; | ||
2120 | rpos += 3; | ||
2121 | break; | ||
2122 | /* TODO: add bad sequence handling */ | ||
2123 | /* intentional fall through! */ | ||
2124 | default: | ||
2125 | *wpos = *rpos; | ||
2126 | wpos++; | ||
2127 | resl++; | ||
2128 | rpos++; | ||
2129 | } | ||
2130 | } | ||
2131 | *wpos = '\0'; /* add 0-terminator */ | ||
2132 | return resl; | ||
2133 | } | ||
2134 | |||
2135 | |||
2136 | /** | ||
2137 | * url/percent encode (RFC3986). | ||
2138 | * | ||
2139 | * @param data the data to decode | ||
2140 | * @param len the length of the input | ||
2141 | * @param output where to write the output (*output should be NULL, | ||
2142 | * is allocated) | ||
2143 | * @return the size of the output | ||
2144 | */ | ||
2145 | size_t | ||
2146 | GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out) | ||
2147 | { | ||
2148 | struct GNUNET_Buffer buf = { 0 }; | ||
2149 | const uint8_t *i8 = (uint8_t *) data; | ||
2150 | |||
2151 | while (0 != *i8) | ||
2152 | { | ||
2153 | if (0 == (0x80 & *i8)) | ||
2154 | { | ||
2155 | /* traditional ASCII */ | ||
2156 | if (isalnum (*i8) || (*i8 == '-') || (*i8 == '_') || (*i8 == '.') || | ||
2157 | (*i8 == '~') ) | ||
2158 | GNUNET_buffer_write (&buf, (const char*) i8, 1); | ||
2159 | else if (*i8 == ' ') | ||
2160 | GNUNET_buffer_write (&buf, "+", 1); | ||
2161 | else | ||
2162 | GNUNET_buffer_write_fstr (&buf, | ||
2163 | "%%%X%X", | ||
2164 | *i8 >> 4, | ||
2165 | *i8 & 15); | ||
2166 | i8++; | ||
2167 | continue; | ||
2168 | } | ||
2169 | if (0x80 + 0x40 == ((0x80 + 0x40 + 0x20) & *i8)) | ||
2170 | { | ||
2171 | /* 2-byte value, percent-encode */ | ||
2172 | GNUNET_buffer_write_fstr (&buf, | ||
2173 | "%%%X%X", | ||
2174 | *i8 >> 4, | ||
2175 | *i8 & 15); | ||
2176 | i8++; | ||
2177 | GNUNET_buffer_write_fstr (&buf, | ||
2178 | "%%%X%X", | ||
2179 | *i8 >> 4, | ||
2180 | *i8 & 15); | ||
2181 | i8++; | ||
2182 | continue; | ||
2183 | } | ||
2184 | if (0x80 + 0x40 + 0x20 == ((0x80 + 0x40 + 0x20 + 0x10) & *i8)) | ||
2185 | { | ||
2186 | /* 3-byte value, percent-encode */ | ||
2187 | for (unsigned int i = 0; i<3; i++) | ||
2188 | { | ||
2189 | GNUNET_buffer_write_fstr (&buf, | ||
2190 | "%%%X%X", | ||
2191 | *i8 >> 4, | ||
2192 | *i8 & 15); | ||
2193 | i8++; | ||
2194 | } | ||
2195 | continue; | ||
2196 | } | ||
2197 | if (0x80 + 0x40 + 0x20 + 0x10 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08) & *i8)) | ||
2198 | { | ||
2199 | /* 4-byte value, percent-encode */ | ||
2200 | for (unsigned int i = 0; i<4; i++) | ||
2201 | { | ||
2202 | GNUNET_buffer_write_fstr (&buf, | ||
2203 | "%%%X%X", | ||
2204 | *i8 >> 4, | ||
2205 | *i8 & 15); | ||
2206 | i8++; | ||
2207 | } | ||
2208 | continue; | ||
2209 | } | ||
2210 | if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08 | ||
2211 | + 0x04) & *i8)) | ||
2212 | { | ||
2213 | /* 5-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */ | ||
2214 | for (unsigned int i = 0; i<5; i++) | ||
2215 | { | ||
2216 | GNUNET_buffer_write_fstr (&buf, | ||
2217 | "%%%X%X", | ||
2218 | *i8 >> 4, | ||
2219 | *i8 & 15); | ||
2220 | i8++; | ||
2221 | } | ||
2222 | continue; | ||
2223 | } | ||
2224 | if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 + 0x04 == ((0x80 + 0x40 + 0x20 + 0x10 | ||
2225 | + 0x08 + 0x04 + 0x02) | ||
2226 | & *i8)) | ||
2227 | { | ||
2228 | /* 6-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */ | ||
2229 | for (unsigned int i = 0; i<6; i++) | ||
2230 | { | ||
2231 | GNUNET_buffer_write_fstr (&buf, | ||
2232 | "%%%X%X", | ||
2233 | *i8 >> 4, | ||
2234 | *i8 & 15); | ||
2235 | i8++; | ||
2236 | } | ||
2237 | continue; | ||
2238 | } | ||
2239 | /* really, really invalid UTF-8: fail */ | ||
2240 | GNUNET_break (0); | ||
2241 | GNUNET_buffer_clear (&buf); | ||
2242 | return 0; | ||
2243 | } | ||
2244 | *out = GNUNET_buffer_reap_str (&buf); | ||
2245 | return strlen (*out); | ||
2246 | } | ||
2247 | |||
2248 | |||
2091 | /* end of strings.c */ | 2249 | /* end of strings.c */ |
diff --git a/src/util/test_strings.c b/src/util/test_strings.c index 90d06a473..753ec6908 100644 --- a/src/util/test_strings.c +++ b/src/util/test_strings.c | |||
@@ -39,6 +39,10 @@ | |||
39 | #define WANTB(a, b, l) if (0 != memcmp (a, b, l)) { GNUNET_break (0); return 1; \ | 39 | #define WANTB(a, b, l) if (0 != memcmp (a, b, l)) { GNUNET_break (0); return 1; \ |
40 | } else { } | 40 | } else { } |
41 | 41 | ||
42 | #define URLENCODE_TEST_VECTOR_PLAIN "Asbjlaw=ljsdlasjd?人aslkdsa" | ||
43 | |||
44 | #define URLENCODE_TEST_VECTOR_ENCODED "Asbjlaw\%3Dljsdlasjd\%3F\%E4\%BA\%BAaslkdsa" | ||
45 | |||
42 | int | 46 | int |
43 | main (int argc, char *argv[]) | 47 | main (int argc, char *argv[]) |
44 | { | 48 | { |
@@ -137,6 +141,16 @@ main (int argc, char *argv[]) | |||
137 | GNUNET_STRINGS_fancy_time_to_relative ("15 m", &rtx)); | 141 | GNUNET_STRINGS_fancy_time_to_relative ("15 m", &rtx)); |
138 | GNUNET_assert (rt.rel_value_us == rtx.rel_value_us); | 142 | GNUNET_assert (rt.rel_value_us == rtx.rel_value_us); |
139 | 143 | ||
144 | GNUNET_assert (0 != GNUNET_STRINGS_urlencode (URLENCODE_TEST_VECTOR_PLAIN, | ||
145 | strlen (URLENCODE_TEST_VECTOR_PLAIN), | ||
146 | &b)); | ||
147 | WANT (URLENCODE_TEST_VECTOR_ENCODED, b); | ||
148 | GNUNET_free (b); | ||
149 | GNUNET_assert (0 != GNUNET_STRINGS_urldecode (URLENCODE_TEST_VECTOR_ENCODED, | ||
150 | strlen (URLENCODE_TEST_VECTOR_ENCODED), | ||
151 | &b)); | ||
152 | WANT (URLENCODE_TEST_VECTOR_PLAIN, b); | ||
153 | GNUNET_free (b); | ||
140 | return 0; | 154 | return 0; |
141 | } | 155 | } |
142 | 156 | ||