From 815ded19f106990a37bbacec83546b1b897491f6 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Tue, 4 Aug 2020 19:40:23 +0200 Subject: rest: fix #6462 --- src/gns/plugin_rest_gns.c | 65 +++---- src/identity/plugin_rest_identity.c | 290 ++++++++++++++---------------- src/include/gnunet_rest_plugin.h | 8 +- src/namestore/plugin_rest_namestore.c | 242 ++++++++++++------------- src/peerinfo-tool/plugin_rest_peerinfo.c | 66 +++---- src/reclaim/plugin_rest_openid_connect.c | 241 ++++++++++++------------- src/reclaim/plugin_rest_reclaim.c | 293 ++++++++++++++++--------------- src/rest/gnunet-rest-server.c | 120 +++++++------ src/rest/plugin_rest_config.c | 7 +- src/rest/plugin_rest_copying.c | 32 +--- 10 files changed, 645 insertions(+), 719 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 @@ -62,6 +62,11 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Connection to GNS + */ +static struct GNUNET_GNS_Handle *gns; + /** * @brief struct returned by the initialization function of the plugin */ @@ -75,11 +80,6 @@ struct Plugin */ struct RequestHandle { - /** - * Connection to GNS - */ - struct GNUNET_GNS_Handle *gns; - /** * Active GNS lookup */ @@ -153,12 +153,6 @@ cleanup_handle (void *cls) GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup); handle->gns_lookup = NULL; } - if (NULL != handle->gns) - { - GNUNET_GNS_disconnect (handle->gns); - handle->gns = NULL; - } - if (NULL != handle->timeout_task) { GNUNET_SCHEDULER_cancel (handle->timeout_task); @@ -318,7 +312,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle, handle->record_type = GNUNET_GNSRECORD_TYPE_ANY; } - handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns, + handle->gns_lookup = GNUNET_GNS_lookup_with_tld (gns, handle->name, handle->record_type, GNUNET_GNS_LO_DEFAULT, @@ -351,29 +345,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * Function processing the REST call * @@ -385,12 +356,17 @@ init_cont (struct RequestHandle *handle) * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont }, + GNUNET_REST_HANDLER_END }; handle->response_code = 0; handle->timeout = @@ -402,14 +378,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->gns = GNUNET_GNS_connect (cfg); - init_cont (handle); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -441,6 +420,7 @@ libgnunet_plugin_rest_gns_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + gns = GNUNET_GNS_connect (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n")); return api; @@ -460,6 +440,9 @@ libgnunet_plugin_rest_gns_done (void *cls) struct Plugin *plugin = api->cls; plugin->cfg = NULL; + if (NULL != gns) + GNUNET_GNS_disconnect (gns); + GNUNET_free (allow_methods); 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 @@ -126,6 +126,26 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + /** * @brief struct returned by the initialization function of the plugin */ @@ -185,27 +205,6 @@ struct RequestHandle */ size_t data_size; - - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - /** * IDENTITY Operation */ @@ -260,8 +259,6 @@ static void cleanup_handle (void *cls) { struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->timeout_task) @@ -276,17 +273,6 @@ cleanup_handle (void *cls) GNUNET_free (handle->emsg); if (NULL != handle->name) GNUNET_free (handle->name); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); - - for (ego_entry = handle->ego_head; NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } GNUNET_free (handle); } @@ -338,7 +324,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name) if (NULL != pubkey) { - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 != strcasecmp (pubkey, ego_entry->keystring)) @@ -348,7 +334,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name) } if (NULL != name) { - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 != strcasecmp (name, ego_entry->identifier)) @@ -438,7 +424,7 @@ ego_get_subsystem (struct GNUNET_REST_RequestHandle *con_handle, // requested default identity of subsystem GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem); - handle->op = GNUNET_IDENTITY_get (handle->identity_handle, + handle->op = GNUNET_IDENTITY_get (identity_handle, subsystem, &ego_get_for_subsystem, handle); @@ -476,7 +462,7 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle, json_root = json_array (); // Return ego/egos - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { json_ego = json_object (); @@ -766,7 +752,7 @@ ego_edit (struct RequestHandle *handle, struct EgoEntry *ego_entry) json_decref (data_js); return; } - handle->op = GNUNET_IDENTITY_rename (handle->identity_handle, + handle->op = GNUNET_IDENTITY_rename (identity_handle, ego_entry->identifier, newname, &do_finished, @@ -956,7 +942,7 @@ ego_edit_subsystem (struct GNUNET_REST_RequestHandle *con_handle, } handle->response_code = MHD_HTTP_NO_CONTENT; - handle->op = GNUNET_IDENTITY_set (handle->identity_handle, + handle->op = GNUNET_IDENTITY_set (identity_handle, newsubsys, ego_entry->ego, &do_finished, @@ -1047,7 +1033,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, return; } GNUNET_STRINGS_utf8_tolower (egoname, egoname); - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 == strcasecmp (egoname, ego_entry->identifier)) @@ -1073,7 +1059,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, pk_ptr = NULL; json_decref (data_js); handle->response_code = MHD_HTTP_CREATED; - handle->op = GNUNET_IDENTITY_create (handle->identity_handle, + handle->op = GNUNET_IDENTITY_create (identity_handle, handle->name, pk_ptr, &do_finished_create, @@ -1118,7 +1104,7 @@ ego_delete_pubkey (struct GNUNET_REST_RequestHandle *con_handle, } handle->response_code = MHD_HTTP_NO_CONTENT; - handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, + handle->op = GNUNET_IDENTITY_delete (identity_handle, ego_entry->identifier, &do_finished, handle); @@ -1162,7 +1148,7 @@ ego_delete_name (struct GNUNET_REST_RequestHandle *con_handle, } handle->response_code = MHD_HTTP_NO_CONTENT; - handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, + handle->op = GNUNET_IDENTITY_delete (identity_handle, ego_entry->identifier, &do_finished, handle); @@ -1193,144 +1179,78 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all }, - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, - &ego_get_pubkey }, - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name }, - { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, - &ego_get_subsystem }, - { MHD_HTTP_METHOD_PUT, - GNUNET_REST_API_NS_IDENTITY_PUBKEY, - &ego_edit_pubkey }, - { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name }, - { MHD_HTTP_METHOD_PUT, - GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, - &ego_edit_subsystem }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_IDENTITY_PUBKEY, - &ego_delete_pubkey }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_IDENTITY_NAME, - &ego_delete_name }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - -/** - * If listing is enabled, prints information about the egos. - * - * This function is initially called for all egos and then again - * whenever a ego's identifier changes or if it is deleted. At the - * end of the initial pass over all egos, the function is once called - * with 'NULL' for 'ego'. That does NOT mean that the callback won't - * be invoked in the future or that there was an error. - * - * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', - * this function is only called ONCE, and 'NULL' being passed in - * 'ego' does indicate an error (i.e. name is taken or no default - * value is known). If 'ego' is non-NULL and if '*ctx' - * is set in those callbacks, the value WILL be passed to a subsequent - * call to the identity callback of 'GNUNET_IDENTITY_connect' (if - * that one was not NULL). - * - * When an identity is renamed, this function is called with the - * (known) ego but the NEW identifier. - * - * When an identity is deleted, this function is called with the - * (known) ego and "NULL" for the 'identifier'. In this case, - * the 'ego' is henceforth invalid (and the 'ctx' should also be - * cleaned up). - * - * @param cls closure - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param identifier identifier assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ static void -init_egos (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *identifier) +list_ego (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); - return; } - // Check if ego exists - for (ego_entry = handle->ego_head; NULL != ego_entry;) + /* Ego renamed or added */ + if (identifier != NULL) { - struct EgoEntry *tmp = ego_entry; - ego_entry = ego_entry->next; - if (ego != tmp->ego) - continue; - // Deleted - if (NULL == identifier) + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) { - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - tmp); - GNUNET_free (tmp->keystring); - GNUNET_free (tmp->identifier); - GNUNET_free (tmp); + if (ego_entry->ego == ego) + { + /* Rename */ + GNUNET_free (ego_entry->identifier); + ego_entry->identifier = GNUNET_strdup (identifier); + break; + } } - else + if (NULL == ego_entry) { - // Renamed - GNUNET_free (tmp->identifier); - tmp->identifier = GNUNET_strdup (identifier); + /* Add */ + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, + ego_entry); } + } + else + { + /* Delete */ + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + break; + } + if (NULL == ego_entry) + return; /* Not found */ + + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); return; } - // New ego - ego_entry = GNUNET_new (struct EgoEntry); - GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); - ego_entry->ego = ego; - GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, - ego_entry); } @@ -1346,12 +1266,38 @@ init_egos (void *cls, * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, + &ego_get_pubkey }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name }, + { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, + &ego_get_subsystem }, + { MHD_HTTP_METHOD_PUT, + GNUNET_REST_API_NS_IDENTITY_PUBKEY, + &ego_edit_pubkey }, + { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name }, + { MHD_HTTP_METHOD_PUT, + GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, + &ego_edit_subsystem }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_IDENTITY_PUBKEY, + &ego_delete_pubkey }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_IDENTITY_NAME, + &ego_delete_name }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, + GNUNET_REST_HANDLER_END }; + handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; @@ -1365,13 +1311,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -1403,6 +1353,7 @@ libgnunet_plugin_rest_identity_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n")); return api; @@ -1420,8 +1371,21 @@ libgnunet_plugin_rest_identity_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; plugin->cfg = NULL; + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + + for (ego_entry = ego_head; NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } GNUNET_free (allow_methods); GNUNET_free (api); 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 * @param data_size the length of the data * @param proc the callback for result * @param proc_cls closure for callback + * @return GNUNET_YES if the request was processed */ - void (*process_request) (struct GNUNET_REST_RequestHandle *handle, - GNUNET_REST_ResultProcessor proc, - void *proc_cls); + enum GNUNET_GenericReturnValue (*process_request)( + struct GNUNET_REST_RequestHandle *handle, + GNUNET_REST_ResultProcessor proc, + void *proc_cls); }; 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 @@ -84,6 +84,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to NAMESTORE + */ +static struct GNUNET_NAMESTORE_Handle *ns_handle; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + /** * @brief struct returned by the initialization function of the plugin */ @@ -170,15 +195,6 @@ struct RequestHandle */ json_t *resp_object; - /** - * The processing state - */ - int state; - - /** - * Handle to NAMESTORE - */ - struct GNUNET_NAMESTORE_Handle *ns_handle; /** * Handle to NAMESTORE it @@ -195,26 +211,11 @@ struct RequestHandle */ struct EgoEntry *ego_entry; - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - /** * IDENTITY Operation */ struct GNUNET_IDENTITY_Operation *op; - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - /** * Rest connection */ @@ -264,8 +265,6 @@ static void cleanup_handle (void *cls) { struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->timeout_task) @@ -294,21 +293,6 @@ cleanup_handle (void *cls) GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it); if (NULL != handle->ns_qe) GNUNET_NAMESTORE_cancel (handle->ns_qe); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); - if (NULL != handle->ns_handle) - { - GNUNET_NAMESTORE_disconnect (handle->ns_handle); - } - - for (ego_entry = handle->ego_head; NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } if (NULL != handle->resp_object) { @@ -368,7 +352,7 @@ get_egoentry_namestore (struct RequestHandle *handle, char *name) if (NULL == name) return NULL; tmp = strtok (copy, "/"); - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 != strcasecmp (tmp, ego_entry->identifier)) @@ -647,7 +631,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, if (1 >= strlen (labelname)) { handle->list_it = - GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, + GNUNET_NAMESTORE_zone_iteration_start (ns_handle, handle->zone_pkey, &namestore_iteration_error, handle, @@ -664,7 +648,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, return; } handle->record_name = GNUNET_strdup (labelname + 1); - handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, handle->zone_pkey, handle->record_name, &ns_lookup_error_cb, @@ -699,7 +683,7 @@ ns_lookup_cb (void *cls, } for (j = 0; j < handle->rd_count; j++) rd_new[i + j] = handle->rd[j]; - handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, handle->zone_pkey, handle->record_name, i + j, @@ -791,7 +775,7 @@ namestore_add_or_update (struct GNUNET_REST_RequestHandle *con_handle, return; } handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, handle->zone_pkey, handle->record_name, &ns_lookup_error_cb, @@ -892,7 +876,7 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle, } handle->record_name = GNUNET_strdup (labelname + 1); - handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, handle->zone_pkey, handle->record_name, 0, @@ -932,90 +916,79 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add }, - { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update }, - { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - -/** - * This function is initially called for all egos and then again - * whenever a ego's identifier changes or if it is deleted. At the - * end of the initial pass over all egos, the function is once called - * with 'NULL' for 'ego'. That does NOT mean that the callback won't - * be invoked in the future or that there was an error. - * - * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', - * this function is only called ONCE, and 'NULL' being passed in - * 'ego' does indicate an error (i.e. name is taken or no default - * value is known). If 'ego' is non-NULL and if '*ctx' - * is set in those callbacks, the value WILL be passed to a subsequent - * call to the identity callback of 'GNUNET_IDENTITY_connect' (if - * that one was not NULL). - * - * When an identity is renamed, this function is called with the - * (known) ego but the NEW identifier. - * - * When an identity is deleted, this function is called with the - * (known) ego and "NULL" for the 'identifier'. In this case, - * the 'ego' is henceforth invalid (and the 'ctx' should also be - * cleaned up). - * - * @param cls closure - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param name identifier assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ static void -id_connect_cb (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *name) +list_ego (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; - GNUNET_asprintf (&ego_entry->identifier, "%s", name); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); } + /* Ego renamed or added */ + if (identifier != NULL) + { + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + { + /* Rename */ + GNUNET_free (ego_entry->identifier); + ego_entry->identifier = GNUNET_strdup (identifier); + break; + } + } + if (NULL == ego_entry) + { + /* Add */ + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, + ego_entry); + } + } + else + { + /* Delete */ + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + break; + } + if (NULL == ego_entry) + return; /* Not found */ + + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); + return; + } + } @@ -1030,12 +1003,20 @@ id_connect_cb (void *cls, * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add }, + { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update }, + { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont }, + GNUNET_REST_HANDLER_END }; handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; @@ -1048,14 +1029,18 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } - handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); - handle->identity_handle = - GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle); handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -1087,6 +1072,8 @@ libgnunet_plugin_rest_namestore_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + ns_handle = GNUNET_NAMESTORE_connect (cfg); + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n")); return api; @@ -1104,8 +1091,23 @@ libgnunet_plugin_rest_namestore_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; plugin->cfg = NULL; + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + if (NULL != ns_handle) + GNUNET_NAMESTORE_disconnect (ns_handle); + + for (ego_entry = ego_head; NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } GNUNET_free (allow_methods); 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; /** * HTTP methods allows for this plugin */ -static char*allow_methods; +static char *allow_methods; + +/** + * Handle to PEERINFO + */ +static struct GNUNET_PEERINFO_Handle *peerinfo_handle; /** * @brief struct returned by the initialization function of the plugin @@ -204,10 +209,6 @@ struct RequestHandle */ struct GNUNET_PEERINFO_IteratorContext *list_it; - /** - * Handle to PEERINFO - */ - struct GNUNET_PEERINFO_Handle *peerinfo_handle; /** * Rest connection @@ -294,10 +295,10 @@ cleanup_handle (void *cls) GNUNET_PEERINFO_iterate_cancel (handle->list_it); handle->list_it = NULL; } - if (NULL != handle->peerinfo_handle) + if (NULL != peerinfo_handle) { - GNUNET_PEERINFO_disconnect (handle->peerinfo_handle); - handle->peerinfo_handle = NULL; + GNUNET_PEERINFO_disconnect (peerinfo_handle); + peerinfo_handle = NULL; } GNUNET_free (handle); @@ -664,7 +665,7 @@ peerinfo_get (struct GNUNET_REST_RequestHandle *con_handle, // specific_peer = GNUNET_PEER_resolve2(peer_id); } - handle->list_it = GNUNET_PEERINFO_iterate (handle->peerinfo_handle, + handle->list_it = GNUNET_PEERINFO_iterate (peerinfo_handle, include_friend_only, specific_peer, &peerinfo_list_iteration, @@ -698,32 +699,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = { - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont }, - GNUNET_REST_HANDLER_END - }; - - if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * Function processing the REST call * @@ -735,12 +710,18 @@ init_cont (struct RequestHandle *handle) * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = { + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont }, + GNUNET_REST_HANDLER_END + }; handle->response_code = 0; handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, @@ -753,14 +734,20 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->peerinfo_handle = GNUNET_PEERINFO_connect (cfg); - init_cont (handle); + if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, + handlers, + &err, + handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -792,6 +779,7 @@ libgnunet_plugin_rest_peerinfo_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + peerinfo_handle = GNUNET_PEERINFO_connect (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Peerinfo REST API initialized\n")); diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index eb602a08f..64782fb72 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -248,6 +248,36 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + +/** + * GNS handle + */ +static struct GNUNET_GNS_Handle *gns_handle; + +/** + * Identity Provider + */ +static struct GNUNET_RECLAIM_Handle *idp; + /** * @brief struct returned by the initialization function of the plugin */ @@ -361,15 +391,6 @@ struct EgoEntry struct RequestHandle { - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; /** * Selected ego @@ -386,40 +407,15 @@ struct RequestHandle */ struct OIDC_Variables *oidc; - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - - /** - * Rest connection - */ - struct GNUNET_REST_RequestHandle *rest_handle; - - /** - * GNS handle - */ - struct GNUNET_GNS_Handle *gns_handle; - /** * GNS lookup op */ struct GNUNET_GNS_LookupRequest *gns_op; /** - * Handle to NAMESTORE - */ - struct GNUNET_NAMESTORE_Handle *namestore_handle; - - /** - * Iterator for NAMESTORE + * Rest connection */ - struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; + struct GNUNET_REST_RequestHandle *rest_handle; /** * Attribute claim list for id_token @@ -442,10 +438,6 @@ struct RequestHandle */ struct GNUNET_IDENTITY_Operation *op; - /** - * Identity Provider - */ - struct GNUNET_RECLAIM_Handle *idp; /** * Idp Operation @@ -529,6 +521,7 @@ struct RequestHandle int response_code; }; + /** * Cleanup lookup handle * @param handle Handle to clean up @@ -536,13 +529,10 @@ struct RequestHandle static void cleanup_handle (struct RequestHandle *handle) { - struct EgoEntry *ego_entry; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->timeout_task) GNUNET_SCHEDULER_cancel (handle->timeout_task); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); if (NULL != handle->attr_it) GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); if (NULL != handle->attest_it) @@ -551,8 +541,6 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); if (NULL != handle->idp_op) GNUNET_RECLAIM_cancel (handle->idp_op); - if (NULL != handle->idp) - GNUNET_RECLAIM_disconnect (handle->idp); GNUNET_free (handle->url); GNUNET_free (handle->tld); GNUNET_free (handle->redirect_prefix); @@ -561,11 +549,6 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_free (handle->edesc); if (NULL != handle->gns_op) GNUNET_GNS_lookup_cancel (handle->gns_op); - if (NULL != handle->gns_handle) - GNUNET_GNS_disconnect (handle->gns_handle); - - if (NULL != handle->namestore_handle) - GNUNET_NAMESTORE_disconnect (handle->namestore_handle); if (NULL != handle->oidc) { GNUNET_free (handle->oidc->client_id); @@ -585,15 +568,6 @@ cleanup_handle (struct RequestHandle *handle) if (NULL!=handle->attests_list) GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list); - while (NULL != (ego_entry = handle->ego_head)) - { - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - ego_entry); - GNUNET_free (ego_entry->identifier); - GNUNET_free (ego_entry->keystring); - GNUNET_free (ego_entry); - } GNUNET_free (handle); } @@ -993,7 +967,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) handle->redirect_prefix, handle->tld, handle->redirect_suffix, - (NULL == strchr(handle->redirect_suffix, '?') ? "?" : "&"), + (NULL == strchr (handle->redirect_suffix, '?') ? "?" : + "&"), handle->oidc->response_type, code_string, handle->oidc->state); @@ -1003,7 +978,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) GNUNET_asprintf (&redirect_uri, "%s%s%s=%s&state=%s", handle->oidc->redirect_uri, - (NULL == strchr(handle->oidc->redirect_uri, '?') ? "?" : "&"), + (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" : + "&"), handle->oidc->response_type, code_string, handle->oidc->state); @@ -1082,7 +1058,7 @@ oidc_attest_collect_finished_cb (void *cls) handle->attest_it = NULL; merged_list = attribute_list_merge (handle->attr_idtoken_list, handle->attr_userinfo_list); - handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, &handle->priv_key, &handle->oidc->client_pkey, merged_list, @@ -1149,7 +1125,7 @@ oidc_attr_collect_finished_cb (void *cls) } handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList); handle->attest_it = - GNUNET_RECLAIM_get_attestations_start (handle->idp, + GNUNET_RECLAIM_get_attestations_start (idp, &handle->priv_key, &oidc_iteration_error, handle, @@ -1315,7 +1291,7 @@ code_redirect (void *cls) return; } // iterate over egos and compare their public key - for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; + for (handle->ego_entry = ego_head; NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey); @@ -1323,13 +1299,12 @@ code_redirect (void *cls) { handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); handle->attr_idtoken_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); handle->attr_userinfo_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); handle->attr_it = - GNUNET_RECLAIM_get_attributes_start (handle->idp, + GNUNET_RECLAIM_get_attributes_start (idp, &handle->priv_key, &oidc_iteration_error, handle, @@ -1474,7 +1449,7 @@ client_redirect (void *cls) /* Lookup client redirect uri to verify request */ handle->gns_op = - GNUNET_GNS_lookup (handle->gns_handle, + GNUNET_GNS_lookup (gns_handle, GNUNET_GNS_EMPTY_LABEL_AT, &handle->oidc->client_pkey, GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, @@ -1700,14 +1675,14 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, // If we know this identity, translated the corresponding TLD // TODO: We might want to have a reverse lookup functionality for TLDs? - for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) + for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) { priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego); GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey); if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) { handle->tld = GNUNET_strdup (tmp_ego->identifier); - handle->ego_entry = handle->ego_tail; + handle->ego_entry = ego_tail; } } handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); @@ -1790,6 +1765,7 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); } + static int parse_credentials_basic_auth (struct RequestHandle *handle, char **client_id, @@ -1847,8 +1823,8 @@ parse_credentials_basic_auth (struct RequestHandle *handle, static int parse_credentials_post_body (struct RequestHandle *handle, - char **client_id, - char **client_secret) + char **client_id, + char **client_secret) { struct GNUNET_HashCode cache_key; char *client_id_tmp; @@ -1861,8 +1837,9 @@ parse_credentials_post_body (struct RequestHandle *handle, ->url_param_map, &cache_key)) return GNUNET_SYSERR; - client_id_tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, - &cache_key); + client_id_tmp = GNUNET_CONTAINER_multihashmap_get ( + handle->rest_handle->url_param_map, + &cache_key); if (NULL == client_id_tmp) return GNUNET_SYSERR; *client_id = strdup (client_id_tmp); @@ -1896,13 +1873,16 @@ check_authorization (struct RequestHandle *handle, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received client credentials in HTTP AuthZ header\n"); - } else if (GNUNET_OK == parse_credentials_post_body (handle, - &received_cid, - &received_cpw)) + } + else if (GNUNET_OK == parse_credentials_post_body (handle, + &received_cid, + &received_cpw)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received client credentials in POST body\n"); - } else { + } + else + { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; @@ -1931,7 +1911,7 @@ check_authorization (struct RequestHandle *handle, return GNUNET_SYSERR; } // check client_id - for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; + for (handle->ego_entry = ego_head; NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) { if (0 == strcmp (handle->ego_entry->keystring, received_cid)) @@ -1963,7 +1943,7 @@ find_ego (struct RequestHandle *handle, struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key); @@ -2321,14 +2301,13 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, return; } - handle->idp = GNUNET_RECLAIM_connect (cfg); handle->oidc->response = json_object (); json_object_set_new (handle->oidc->response, "sub", json_string (iss_ego->keystring)); privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); - handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, privkey, ticket, consume_ticket, @@ -2337,36 +2316,6 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_AUTHORIZE, - &authorize_endpoint }, // url-encoded - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * If listing is enabled, prints information about the egos. * @@ -2406,18 +2355,16 @@ list_ego (void *cls, void **ctx, const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } GNUNET_assert (NULL != ego); - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); @@ -2425,15 +2372,15 @@ list_ego (void *cls, ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); return; } /* Ego renamed or added */ if (identifier != NULL) { - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (ego_entry->ego == ego) @@ -2452,15 +2399,15 @@ list_ego (void *cls, ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); } } else { /* Delete */ - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (ego_entry->ego == ego) @@ -2469,8 +2416,8 @@ list_ego (void *cls, if (NULL == ego_entry) return; /* Not found */ - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, ego_entry); GNUNET_free (ego_entry->identifier); GNUNET_free (ego_entry->keystring); @@ -2480,12 +2427,23 @@ list_ego (void *cls, } -static void +static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, // url-encoded + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, + GNUNET_REST_HANDLER_END }; handle->oidc = GNUNET_new (struct OIDC_Variables); if (NULL == OIDC_cookie_jar_map) @@ -2495,19 +2453,17 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; handle->proc_cls = proc_cls; handle->proc = proc; - handle->state = ID_REST_STATE_INIT; handle->rest_handle = rest_handle; - handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); - handle->gns_handle = GNUNET_GNS_connect (cfg); - handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + return GNUNET_NO; + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -2532,6 +2488,11 @@ libgnunet_plugin_rest_openid_connect_init (void *cls) api->cls = &plugin; api->name = GNUNET_REST_API_NS_OIDC; api->process_request = &rest_identity_process_request; + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); + gns_handle = GNUNET_GNS_connect (cfg); + idp = GNUNET_RECLAIM_connect (cfg); + + state = ID_REST_STATE_INIT; GNUNET_asprintf (&allow_methods, "%s, %s, %s, %s, %s", MHD_HTTP_METHOD_GET, @@ -2557,6 +2518,7 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; plugin->cfg = NULL; @@ -2573,6 +2535,21 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); GNUNET_free (allow_methods); + if (NULL != gns_handle) + GNUNET_GNS_disconnect (gns_handle); + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + if (NULL != idp) + GNUNET_RECLAIM_disconnect (idp); + while (NULL != (ego_entry = ego_head)) + { + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); + } GNUNET_free (api); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "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..eb442bc3b 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -87,6 +87,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + +/** + * Identity Provider + */ +static struct GNUNET_RECLAIM_Handle *idp; + /** * @brief struct returned by the initialization function of the plugin */ @@ -129,15 +154,6 @@ struct EgoEntry struct RequestHandle { - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; /** * Selected ego @@ -149,16 +165,6 @@ struct RequestHandle */ struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - /** * Rest connection */ @@ -174,11 +180,6 @@ struct RequestHandle */ struct GNUNET_IDENTITY_Operation *op; - /** - * Identity Provider - */ - struct GNUNET_RECLAIM_Handle *idp; - /** * Idp Operation */ @@ -194,7 +195,6 @@ struct RequestHandle */ struct GNUNET_RECLAIM_AttestationIterator *attest_it; - /** * Ticket iterator */ @@ -251,51 +251,31 @@ struct RequestHandle * @param handle Handle to clean up */ static void -cleanup_handle (struct RequestHandle *handle) +cleanup_handle (void *cls) { - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; + struct RequestHandle *handle = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->resp_object) json_decref (handle->resp_object); if (NULL != handle->timeout_task) GNUNET_SCHEDULER_cancel (handle->timeout_task); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); if (NULL != handle->attr_it) GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); if (NULL != handle->attest_it) GNUNET_RECLAIM_get_attestations_stop (handle->attest_it); if (NULL != handle->ticket_it) GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); - if (NULL != handle->idp) - GNUNET_RECLAIM_disconnect (handle->idp); if (NULL != handle->url) GNUNET_free (handle->url); if (NULL != handle->emsg) GNUNET_free (handle->emsg); if (NULL != handle->attr_list) GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list); - for (ego_entry = handle->ego_head; NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } GNUNET_free (handle); } -static void -cleanup_handle_delayed (void *cls) -{ - cleanup_handle (cls); -} - - /** * Task run on error, sends error message. Cleans up everything. * @@ -316,7 +296,7 @@ do_error (void *cls) resp = GNUNET_REST_create_response (json_error); MHD_add_response_header (resp, "Content-Type", "application/json"); handle->proc (handle->proc_cls, resp, handle->response_code); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); GNUNET_free (json_error); } @@ -339,9 +319,7 @@ do_timeout (void *cls) static void collect_error_cb (void *cls) { - struct RequestHandle *handle = cls; - - do_error (handle); + do_error (cls); } @@ -359,7 +337,7 @@ finished_cont (void *cls, int32_t success, const char *emsg) return; } handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); } @@ -376,7 +354,7 @@ delete_finished_cb (void *cls, int32_t success, const char *emsg) return; } handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); } @@ -485,7 +463,7 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, identity = handle->url + strlen ( GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -523,9 +501,8 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, */ if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) GNUNET_RECLAIM_id_generate (&attribute->id); - handle->idp = GNUNET_RECLAIM_connect (cfg); exp = GNUNET_TIME_UNIT_HOURS; - handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attestation_store (idp, identity_priv, attribute, &exp, @@ -644,7 +621,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, identity = handle->url + strlen ( GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -659,8 +636,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->attest_it = GNUNET_RECLAIM_get_attestations_start (handle->idp, + handle->attest_it = GNUNET_RECLAIM_get_attestations_start (idp, priv_key, &collect_error_cb, handle, @@ -713,7 +689,7 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -727,11 +703,10 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation)); GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); attr.name = ""; - handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attestation_delete (idp, priv_key, &attr, &delete_finished_cb, @@ -768,7 +743,7 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -782,9 +757,8 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); handle->ticket_it = - GNUNET_RECLAIM_ticket_iteration_start (handle->idp, + GNUNET_RECLAIM_ticket_iteration_start (idp, priv_key, &collect_error_cb, handle, @@ -823,7 +797,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -862,9 +836,8 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, */ if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) GNUNET_RECLAIM_id_generate (&attribute->id); - handle->idp = GNUNET_RECLAIM_connect (cfg); exp = GNUNET_TIME_UNIT_HOURS; - handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attribute_store (idp, identity_priv, attribute, &exp, @@ -1012,7 +985,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -1027,8 +1000,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp, + handle->attr_it = GNUNET_RECLAIM_get_attributes_start (idp, priv_key, &collect_error_cb, handle, @@ -1078,7 +1050,7 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -1092,11 +1064,10 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute)); GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); attr.name = ""; - handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attribute_delete (idp, priv_key, &attr, &delete_finished_cb, @@ -1152,7 +1123,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); @@ -1169,8 +1140,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_revoke (idp, identity_priv, ticket, &finished_cont, @@ -1256,7 +1226,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, json_decref (data_json); return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); @@ -1273,8 +1243,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); handle->resp_object = json_object (); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, identity_priv, ticket, &consume_cont, @@ -1307,55 +1276,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, - &list_attribute_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, - &add_attribute_cont }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, - &delete_attribute_cont }, - { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_RECLAIM_ATTESTATION, - &list_attestation_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_RECLAIM_ATTESTATION, - &add_attestation_cont }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_RECLAIM_ATTESTATION, - &delete_attestation_cont }, - { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_IDENTITY_TICKETS, - &list_tickets_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_IDENTITY_REVOKE, - &revoke_ticket_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_IDENTITY_CONSUME, - &consume_ticket_cont }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * If listing is enabled, prints information about the egos. * @@ -1395,52 +1315,126 @@ list_ego (void *cls, void **ctx, const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); } + /* Ego renamed or added */ + if (identifier != NULL) + { + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + { + /* Rename */ + GNUNET_free (ego_entry->identifier); + ego_entry->identifier = GNUNET_strdup (identifier); + break; + } + } + if (NULL == ego_entry) + { + /* Add */ + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, + ego_entry); + } + } + else + { + /* Delete */ + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + break; + } + if (NULL == ego_entry) + return; /* Not found */ + + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); + return; + } + } -static void +static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &delete_attribute_cont }, + { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &list_attestation_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &add_attestation_cont }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &delete_attestation_cont }, + { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont }, + GNUNET_REST_HANDLER_END + }; handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; handle->proc_cls = proc_cls; handle->proc = proc; - handle->state = ID_REST_STATE_INIT; + state = ID_REST_STATE_INIT; handle->rest_handle = rest_handle; handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -1472,7 +1466,8 @@ libgnunet_plugin_rest_reclaim_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); - + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); + idp = GNUNET_RECLAIM_connect (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity Provider REST API initialized\n")); return api; @@ -1490,8 +1485,22 @@ libgnunet_plugin_rest_reclaim_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; plugin->cfg = NULL; + if (NULL != idp) + GNUNET_RECLAIM_disconnect (idp); + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + for (ego_entry = ego_head; NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } GNUNET_free (allow_methods); GNUNET_free (api); diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c index 519a27515..44d4f345e 100644 --- a/src/rest/gnunet-rest-server.c +++ b/src/rest/gnunet-rest-server.c @@ -114,11 +114,6 @@ static struct MHD_Response *failure_response; */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Map of loaded plugins. - */ -static struct GNUNET_CONTAINER_MultiHashMap *plugin_map; - /** * Echo request Origin in CORS */ @@ -139,6 +134,38 @@ static char *allow_headers; */ static char *allow_credentials; +/** + * Plugin list head + */ +static struct PluginListEntry *plugins_head; + +/** + * Plugin list tail + */ +static struct PluginListEntry *plugins_tail; + +/** + * A plugin list entry + */ +struct PluginListEntry +{ + /* DLL */ + struct PluginListEntry *next; + + /* DLL */ + struct PluginListEntry *prev; + + /** + * libname (to cleanup) + */ + char *libname; + + /** + * The plugin + */ + struct GNUNET_REST_Plugin *plugin; +}; + /** * MHD Connection handle */ @@ -148,8 +175,6 @@ struct MhdConnectionHandle struct MHD_Response *response; - struct GNUNET_REST_Plugin *plugin; - struct GNUNET_REST_RequestHandle *data_handle; struct MHD_PostProcessor *pp; @@ -322,15 +347,15 @@ post_data_iter (void *cls, GNUNET_CRYPTO_hash (key, strlen (key), &hkey); val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map, - &hkey); + &hkey); if (NULL == val) { val = GNUNET_malloc (65536); if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( - handle->url_param_map, - &hkey, - val, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + handle->url_param_map, + &hkey, + val, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not add url param '%s'\n", @@ -378,39 +403,21 @@ create_response (void *cls, size_t *upload_data_size, void **con_cls) { - char *plugin_name; char *origin; struct GNUNET_HashCode key; struct MhdConnectionHandle *con_handle; struct GNUNET_REST_RequestHandle *rest_conndata_handle; + struct PluginListEntry *ple; con_handle = *con_cls; if (NULL == *con_cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); - char tmp_url[strlen (url) + 1]; - strcpy (tmp_url, url); con_handle = GNUNET_new (struct MhdConnectionHandle); con_handle->con = con; con_handle->state = GN_REST_STATE_INIT; *con_cls = con_handle; - - plugin_name = strtok (tmp_url, "/"); - - if (NULL != plugin_name) - { - GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key); - - con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map, &key); - } - if (NULL == con_handle->plugin) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n"); - GNUNET_free (con_handle); - return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); - } - return MHD_YES; } if (GN_REST_STATE_INIT == con_handle->state) @@ -445,9 +452,18 @@ create_response (void *cls, MHD_destroy_post_processor (con_handle->pp); con_handle->state = GN_REST_STATE_PROCESSING; - con_handle->plugin->process_request (rest_conndata_handle, - &plugin_callback, - con_handle); + for (ple = plugins_head; NULL != ple; ple = ple->next) + { + if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle, + &plugin_callback, + con_handle)) + break; /* Request handled */ + } + if (NULL == ple) + { + /** Request not handled **/ + MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); + } *upload_data_size = 0; run_mhd_now (); return MHD_YES; @@ -732,6 +748,18 @@ do_accept (void *cls) static void do_shutdown (void *cls) { + struct PluginListEntry *ple; + + while (NULL != plugins_head) + { + ple = plugins_head; + GNUNET_CONTAINER_DLL_remove (plugins_head, + plugins_tail, + ple); + GNUNET_PLUGIN_unload (ple->libname, NULL); + GNUNET_free (ple->libname); + GNUNET_free (ple); + } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); kill_httpd (); GNUNET_free (allow_credentials); @@ -820,7 +848,7 @@ static void load_plugin (void *cls, const char *libname, void *lib_ret) { struct GNUNET_REST_Plugin *plugin = lib_ret; - struct GNUNET_HashCode key; + struct PluginListEntry *ple; if (NULL == lib_ret) { @@ -831,18 +859,12 @@ load_plugin (void *cls, const char *libname, void *lib_ret) } GNUNET_assert (1 < strlen (plugin->name)); GNUNET_assert ('/' == *plugin->name); - GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key); - if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( - plugin_map, - &key, - plugin, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Could not load add plugin `%s'\n", - libname); - return; - } + ple = GNUNET_new (struct PluginListEntry); + ple->libname = GNUNET_strdup (libname); + ple->plugin = plugin; + GNUNET_CONTAINER_DLL_insert (plugins_head, + plugins_tail, + ple); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); } @@ -864,8 +886,8 @@ run (void *cls, char *addr_str; cfg = c; - plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); - + plugins_head = NULL; + plugins_tail = NULL; /* Get port to bind to */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) 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, * @param proc_cls closure for @a proc * @return #GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) @@ -371,9 +371,10 @@ rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle)) { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); + cleanup_handle (handle); + return GNUNET_NO; } + return GNUNET_YES; } 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 @@ -81,24 +81,6 @@ cleanup_handle (struct RequestHandle *handle) } -/** - * Task run on shutdown. Cleans up everything. - * - * @param cls unused - * @param tc scheduler context - */ -static void -do_error (void *cls) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, handle->response_code); - cleanup_handle (handle); -} - - /** * Handle rest request * @@ -155,7 +137,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, * @param proc_cls closure for @a proc * @return #GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) @@ -172,14 +154,10 @@ rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, handle->proc = proc; handle->rest_handle = conndata_handle; - if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } + return GNUNET_REST_handle_request (conndata_handle, + handlers, + &err, + handle); } -- cgit v1.2.3