From cc838240da0d28fa1fc6d7a97da2808a7a622365 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 6 Oct 2017 16:50:32 +0200 Subject: -remove deprecated --- .../plugin_rest_identity_provider.c | 1216 -------------------- 1 file changed, 1216 deletions(-) delete mode 100644 src/identity-provider/plugin_rest_identity_provider.c (limited to 'src/identity-provider/plugin_rest_identity_provider.c') diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c deleted file mode 100644 index dfb935f5b..000000000 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ /dev/null @@ -1,1216 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012-2015 GNUnet e.V. - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ -/** - * @author Martin Schanzenbach - * @file identity/plugin_rest_identity.c - * @brief GNUnet Namestore REST plugin - * - */ - -#include "platform.h" -#include "gnunet_rest_plugin.h" -#include "gnunet_identity_service.h" -#include "gnunet_gns_service.h" -#include "gnunet_gnsrecord_lib.h" -#include "gnunet_namestore_service.h" -#include "gnunet_rest_lib.h" -#include "gnunet_jsonapi_lib.h" -#include "gnunet_jsonapi_util.h" -#include "microhttpd.h" -#include -#include -#include "gnunet_signatures.h" -#include "gnunet_identity_provider_service.h" - -/** - * REST root namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_PROVIDER "/idp" - -/** - * Issue namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE "/idp/issue" - -/** - * Check namespace TODO - */ -#define GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK "/idp/check" - -/** - * Token namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN "/idp/token" - -/** - * The parameter name in which the ticket must be provided - */ -#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET "ticket" - -/** - * The parameter name in which the expected nonce must be provided - */ -#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE "expected_nonce" - -/** - * The parameter name in which the ticket must be provided - */ -#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN "token" - -/** - * The URL parameter name in which the nonce must be provided - */ -#define GNUNET_IDENTITY_TOKEN_REQUEST_NONCE "nonce" - -/** - * State while collecting all egos - */ -#define ID_REST_STATE_INIT 0 - -/** - * Done collecting egos - */ -#define ID_REST_STATE_POST_INIT 1 - -/** - * Resource type - */ -#define GNUNET_REST_JSONAPI_IDENTITY_TOKEN "token" - -/** - * URL parameter to create a GNUid token for a specific audience - */ -#define GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST "audience" - -/** - * URL parameter to create a GNUid token for a specific issuer (EGO) - */ -#define GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST "issuer" - -/** - * Attributes passed to issue request - */ -#define GNUNET_IDENTITY_TOKEN_ATTR_LIST "requested_attrs" - -/** - * Attributes passed to issue request - */ -#define GNUNET_IDENTITY_TOKEN_V_ATTR_LIST "requested_verified_attrs" - - -/** - * Token expiration string - */ -#define GNUNET_IDENTITY_TOKEN_EXP_STRING "expiration" - -/** - * Error messages - */ -#define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid" -#define GNUNET_REST_ERROR_NO_DATA "No data" - -/** - * GNUid token lifetime - */ -#define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000 - -/** - * The configuration handle - */ -const struct GNUNET_CONFIGURATION_Handle *cfg; - -/** - * HTTP methods allows for this plugin - */ -static char* allow_methods; - -/** - * @brief struct returned by the initialization function of the plugin - */ -struct Plugin -{ - const struct GNUNET_CONFIGURATION_Handle *cfg; -}; - -/** - * The ego list - */ -struct EgoEntry -{ - /** - * DLL - */ - struct EgoEntry *next; - - /** - * DLL - */ - struct EgoEntry *prev; - - /** - * Ego Identifier - */ - char *identifier; - - /** - * Public key string - */ - char *keystring; - - /** - * The Ego - */ - struct GNUNET_IDENTITY_Ego *ego; -}; - - -struct RequestHandle -{ - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - - /** - * Selected ego - */ - struct EgoEntry *ego_entry; - - /** - * Ptr to current ego private key - */ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - - /** - * Handle to the rest connection - */ - struct GNUNET_REST_RequestHandle *conndata_handle; - - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - - /** - * IDENTITY Operation - */ - struct GNUNET_IDENTITY_Operation *op; - - /** - * Identity Provider - */ - struct GNUNET_IDENTITY_PROVIDER_Handle *idp; - - /** - * Idp Operation - */ - struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op; - - /** - * Handle to NS service - */ - struct GNUNET_NAMESTORE_Handle *ns_handle; - - /** - * NS iterator - */ - struct GNUNET_NAMESTORE_ZoneIterator *ns_it; - - /** - * NS Handle - */ - struct GNUNET_NAMESTORE_QueueEntry *ns_qe; - - /** - * Desired timeout for the lookup (default is no timeout). - */ - struct GNUNET_TIME_Relative timeout; - - /** - * ID of a task associated with the resolution process. - */ - struct GNUNET_SCHEDULER_Task *timeout_task; - - /** - * The plugin result processor - */ - GNUNET_REST_ResultProcessor proc; - - /** - * The closure of the result processor - */ - void *proc_cls; - - /** - * The url - */ - char *url; - - /** - * Error response message - */ - char *emsg; - - /** - * Reponse code - */ - int response_code; - - /** - * Response object - */ - struct GNUNET_JSONAPI_Document *resp_object; - -}; - - -/** - * Cleanup lookup handle - * @param handle Handle to clean up - */ -static void -cleanup_handle (struct RequestHandle *handle) -{ - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cleaning up\n"); - if (NULL != handle->resp_object) - GNUNET_JSONAPI_document_delete (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->idp) - GNUNET_IDENTITY_PROVIDER_disconnect (handle->idp); - if (NULL != handle->ns_it) - GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it); - if (NULL != handle->ns_qe) - GNUNET_NAMESTORE_cancel (handle->ns_qe); - if (NULL != handle->ns_handle) - GNUNET_NAMESTORE_disconnect (handle->ns_handle); - if (NULL != handle->url) - GNUNET_free (handle->url); - if (NULL != handle->emsg) - GNUNET_free (handle->emsg); - 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); -} - - -/** - * Task run on error, sends error message. Cleans up everything. - * - * @param cls the `struct RequestHandle` - */ -static void -do_error (void *cls) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - char *json_error; - - GNUNET_asprintf (&json_error, - "{Error while processing request: %s}", - handle->emsg); - resp = GNUNET_REST_create_response (json_error); - handle->proc (handle->proc_cls, resp, handle->response_code); - cleanup_handle (handle); - GNUNET_free (json_error); -} - -/** - * Task run on timeout, sends error message. Cleans up everything. - * - * @param cls the `struct RequestHandle` - */ -static void -do_timeout (void *cls) -{ - struct RequestHandle *handle = cls; - - handle->timeout_task = NULL; - do_error (handle); -} - - -/** - * Task run on shutdown. Cleans up everything. - * - * @param cls unused - */ -static void -do_cleanup_handle_delayed (void *cls) -{ - struct RequestHandle *handle = cls; - - cleanup_handle (handle); -} - - -/** - * Get a ticket for identity - * @param cls the handle - * @param ticket the ticket returned from the idp - */ -static void -token_creat_cont (void *cls, - const char *label, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, - const struct GNUNET_IDENTITY_PROVIDER_Token *token) -{ - struct GNUNET_JSONAPI_Resource *json_resource; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - json_t *ticket_json; - json_t *token_json; - char *ticket_str; - char *token_str; - char *result_str; - - handle->idp_op = NULL; - - if (NULL == ticket) - { - handle->emsg = GNUNET_strdup ("Error in token issue"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - handle->resp_object = GNUNET_JSONAPI_document_new (); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, - label); - ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); - token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token); - ticket_json = json_string (ticket_str); - token_json = json_string (token_str); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, - ticket_json); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN, - token_json); - GNUNET_free (ticket_str); - GNUNET_free (token_str); - json_decref (ticket_json); - json_decref (token_json); - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - - GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle); -} - - -/** - * Continueationf for token issue request - * - * @param con the Rest handle - * @param url the requested url - * @param cls the request handle - */ -static void -issue_token_cont (struct GNUNET_REST_RequestHandle *con, - const char *url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - const char *egoname; - - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct GNUNET_HashCode key; - struct MHD_Response *resp; - struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; - struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; - struct GNUNET_TIME_Relative etime_rel; - struct GNUNET_TIME_Absolute exp_time; - char *ego_val; - char *audience; - char *exp_str; - char *nonce_str; - char *scopes; - char *vattrs; - uint64_t time; - uint64_t nonce; - - if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, - GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "URL invalid: %s\n", handle->url); - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); - cleanup_handle (handle); - return; - } - egoname = NULL; - ego_entry = NULL; - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, - strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST), - &key); - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer not found\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - if (NULL == ego_val) - { - GNUNET_SCHEDULER_add_now (&do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ego invalid: %s\n", - ego_val); - return; - } - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - { - if (0 != strcmp (ego_val, ego_entry->identifier)) - continue; - egoname = ego_entry->identifier; - break; - } - if ( (NULL == egoname) || - (NULL == ego_entry) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ego not found: %s\n", - ego_val); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Ego to issue token for: %s\n", - egoname); - - - //Meta info - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_ATTR_LIST, - strlen (GNUNET_IDENTITY_TOKEN_ATTR_LIST), - &key); - - scopes = NULL; - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("Scopes missing!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - - //vattrs - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST, - strlen (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST), - &key); - - vattrs = NULL; - if ( GNUNET_YES == - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - vattrs = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - } - - - - //Token audience - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST, - strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST), - &key); - audience = NULL; - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Audience missing!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Audience to issue token for: %s\n", - audience); - - priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, - &pub_key); - GNUNET_STRINGS_string_to_data (audience, - strlen (audience), - &aud_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - //Remote nonce - nonce_str = NULL; - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE, - strlen (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE), - &key); - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("Request nonce missing!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_assert (NULL != nonce_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Request nonce: %s\n", - nonce_str); - GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce)); - - //Get expiration for token from URL parameter - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING, - strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING), - &key); - - exp_str = NULL; - if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key)) - { - exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - } - if (NULL == exp_str) { - handle->emsg = GNUNET_strdup ("No expiration given!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - if (GNUNET_OK != - GNUNET_STRINGS_fancy_time_to_relative (exp_str, - &etime_rel)) - { - handle->emsg = GNUNET_strdup ("Expiration invalid!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - time = GNUNET_TIME_absolute_get().abs_value_us; - exp_time.abs_value_us = time + etime_rel.rel_value_us; - - handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); - handle->idp_op = GNUNET_IDENTITY_PROVIDER_issue_token (handle->idp, - priv_key, - &aud_key, - scopes, - vattrs, - exp_time, - nonce, - &token_creat_cont, - handle); - -} - - -/** - * Build a GNUid token for identity - * - * @param cls the request handle - */ -static void -return_token_list (void *cls) -{ - char* result_str; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - cleanup_handle (handle); -} - - -static void -token_collect_error_cb (void *cls) -{ - struct RequestHandle *handle = cls; - - do_error (handle); -} - - -/** - * Collect all tokens for an ego - * - * TODO move this into the identity-provider service - * - */ -static void -token_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd); - - -static void -token_collect_finished_cb (void *cls) -{ - struct RequestHandle *handle = cls; - struct EgoEntry *ego_tmp; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - - ego_tmp = handle->ego_head; - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - ego_tmp); - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - - if (NULL == handle->ego_head) - { - //Done - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token END\n"); - handle->ns_it = NULL; - GNUNET_SCHEDULER_add_now (&return_token_list, handle); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Next ego: %s\n", - handle->ego_head->identifier); - priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); - handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, - priv_key, - &token_collect_error_cb, - handle, - &token_collect, - handle, - &token_collect_finished_cb, - handle); -} - - -/** - * Collect all tokens for an ego - * - * TODO move this into the identity-provider service - * - */ -static void -token_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - struct RequestHandle *handle = cls; - int i; - char* data; - struct GNUNET_JSONAPI_Resource *json_resource; - json_t *issuer; - json_t *token; - - for (i = 0; i < rd_count; i++) - { - if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN) - { - data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, - rd[i].data, - rd[i].data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN, - label); - issuer = json_string (handle->ego_head->identifier); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, - issuer); - json_decref (issuer); - token = json_string (data); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_TOKEN, - token); - json_decref (token); - - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - GNUNET_free (data); - } - } - - GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); -} - - - -/** - * Respond to OPTIONS request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -list_token_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - char* ego_val; - struct GNUNET_HashCode key; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; - - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, - strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST), - &key); - - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No issuer given.\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_assert (NULL != ego_val); - //Remove non-matching egos - for (ego_entry = handle->ego_head; - NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - if (0 != strcmp (ego_val, ego_tmp->identifier)) - { - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - ego_tmp); - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } - } - handle->resp_object = GNUNET_JSONAPI_document_new (); - if (NULL == handle->ego_head) - { - //Done - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No results.\n"); - GNUNET_SCHEDULER_add_now (&return_token_list, handle); - return; - } - priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); - handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); - handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, - priv_key, - &token_collect_error_cb, - handle, - &token_collect, - handle, - &token_collect_finished_cb, - handle); - -} - -/** - * Return token to requestor - * - * @param cls request handle - * @param token the token - */ -static void -exchange_cont (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Token *token, - uint64_t ticket_nonce) -{ - json_t *root; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - struct GNUNET_HashCode key; - char* result; - char* token_str; - char* nonce_str; - uint64_t expected_nonce; - - //Get nonce - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE, - strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE), - &key); - - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("No nonce given."); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_assert (NULL != nonce_str); - GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &expected_nonce)); - - if (ticket_nonce != expected_nonce) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ticket nonce %"SCNu64" does not match expected nonce %"SCNu64"\n", - ticket_nonce, expected_nonce); - handle->emsg = GNUNET_strdup ("Ticket nonce does not match expected nonce\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - root = json_object (); - token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token); - json_object_set_new (root, "token", json_string (token_str)); - json_object_set_new (root, "token_type", json_string ("jwt")); - GNUNET_free (token_str); - - result = json_dumps (root, JSON_INDENT(1)); - resp = GNUNET_REST_create_response (result); - GNUNET_free (result); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - cleanup_handle (handle); - json_decref (root); -} - - -/** - * - * Callback called when identity for token exchange has been found - * - * @param cls request handle - * @param ego the identity to use as issuer - * @param ctx user context - * @param name identity name - * - */ -static void -exchange_token_ticket_cb (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *name) -{ - struct RequestHandle *handle = cls; - struct GNUNET_HashCode key; - struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket; - char* ticket_str; - - handle->op = NULL; - - if (NULL == ego) - { - handle->emsg = GNUNET_strdup ("No identity found."); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - //Get ticket - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, - strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET), - &key); - - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("No ticket given."); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - ticket_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego); - GNUNET_IDENTITY_PROVIDER_string_to_ticket (ticket_str, - &ticket); - - handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); - handle->idp_op = GNUNET_IDENTITY_PROVIDER_exchange_ticket (handle->idp, - ticket, - handle->priv_key, - &exchange_cont, - handle); - GNUNET_IDENTITY_PROVIDER_ticket_destroy (ticket); - -} - - - -/** - * Respond to issue request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -exchange_token_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - struct RequestHandle *handle = cls; - - //Get token from GNS - handle->op = GNUNET_IDENTITY_get (handle->identity_handle, - "gns-master", - &exchange_token_ticket_cb, - handle); -} - -/** - * Respond to OPTIONS request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -options_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - struct MHD_Response *resp; - struct RequestHandle *handle = cls; - - //For now, independent of path return all options - resp = GNUNET_REST_create_response (NULL); - MHD_add_response_header (resp, - "Access-Control-Allow-Methods", - allow_methods); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - cleanup_handle (handle); - return; -} - -/** - * 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_TOKEN_ISSUE, &issue_token_cont}, - //{MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK, &check_token_cont}, - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &list_token_cont}, - {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &options_cont}, - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN, &exchange_token_ticket_cont}, - GNUNET_REST_HANDLER_END - }; - - if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_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 -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)) - { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); - return; - } - if (ID_REST_STATE_INIT == handle->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, ego_entry); - } - -} - -/** - * Function processing the REST call - * - * @param method HTTP method - * @param url URL of the HTTP request - * @param data body of the HTTP request (optional) - * @param data_size length of the body - * @param proc callback function for the result - * @param proc_cls closure for callback function - * @return GNUNET_OK if request accepted - */ -static void -rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, - GNUNET_REST_ResultProcessor proc, - void *proc_cls) -{ - struct RequestHandle *handle = GNUNET_new (struct RequestHandle); - - handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; - handle->proc_cls = proc_cls; - handle->proc = proc; - handle->state = ID_REST_STATE_INIT; - handle->conndata_handle = conndata_handle; - - - handle->url = GNUNET_strdup (conndata_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->timeout_task = - GNUNET_SCHEDULER_add_delayed (handle->timeout, - &do_timeout, - handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected\n"); -} - -/** - * Entry point for the plugin. - * - * @param cls Config info - * @return NULL on error, otherwise the plugin context - */ -void * -libgnunet_plugin_rest_identity_provider_init (void *cls) -{ - static struct Plugin plugin; - struct GNUNET_REST_Plugin *api; - - cfg = cls; - if (NULL != plugin.cfg) - return NULL; /* can only initialize once! */ - memset (&plugin, 0, sizeof (struct Plugin)); - plugin.cfg = cfg; - api = GNUNET_new (struct GNUNET_REST_Plugin); - api->cls = &plugin; - api->name = GNUNET_REST_API_NS_IDENTITY_PROVIDER; - api->process_request = &rest_identity_process_request; - GNUNET_asprintf (&allow_methods, - "%s, %s, %s, %s, %s", - MHD_HTTP_METHOD_GET, - MHD_HTTP_METHOD_POST, - MHD_HTTP_METHOD_PUT, - MHD_HTTP_METHOD_DELETE, - MHD_HTTP_METHOD_OPTIONS); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Identity Token REST API initialized\n")); - return api; -} - - -/** - * Exit point from the plugin. - * - * @param cls the plugin context (as returned by "init") - * @return always NULL - */ -void * -libgnunet_plugin_rest_identity_provider_done (void *cls) -{ - struct GNUNET_REST_Plugin *api = cls; - struct Plugin *plugin = api->cls; - - plugin->cfg = NULL; - GNUNET_free_non_null (allow_methods); - GNUNET_free (api); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Identity Token REST plugin is finished\n"); - return NULL; -} - -/* end of plugin_rest_gns.c */ -- cgit v1.2.3