From aea518e4e5fc23c0778823f4a09d3de04628bf79 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Thu, 27 Sep 2018 17:20:45 +0200 Subject: actually fix ftbfs --- src/credential/Makefile.am | 20 - src/credential/plugin_rest_credential.c | 1150 ----------------------------- src/rest-plugins/Makefile.am | 18 +- src/rest-plugins/plugin_rest_credential.c | 1150 +++++++++++++++++++++++++++++ 4 files changed, 1167 insertions(+), 1171 deletions(-) delete mode 100644 src/credential/plugin_rest_credential.c create mode 100644 src/rest-plugins/plugin_rest_credential.c diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am index ca11c5e4f..90479eed1 100644 --- a/src/credential/Makefile.am +++ b/src/credential/Makefile.am @@ -35,13 +35,6 @@ plugin_LTLIBRARIES = \ libgnunet_plugin_gnsrecord_credential.la -if HAVE_MHD -if HAVE_JSON -plugin_LTLIBRARIES += libgnunet_plugin_rest_credential.la -endif -endif - - gnunet_credential_SOURCES = \ gnunet-credential.c gnunet_credential_LDADD = \ @@ -84,19 +77,6 @@ libgnunetcredential_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) -libgnunet_plugin_rest_credential_la_SOURCES = \ - plugin_rest_credential.c -libgnunet_plugin_rest_credential_la_LIBADD = \ - libgnunetcredential.la \ - $(top_builddir)/src/rest/libgnunetrest.la \ - $(top_builddir)/src/identity/libgnunetidentity.la \ - $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ - $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ - $(LTLIBINTL) -ljansson -lmicrohttpd -libgnunet_plugin_rest_credential_la_LDFLAGS = \ - $(GN_PLUGIN_LDFLAGS) - check_SCRIPTS = \ test_credential_issue.sh \ diff --git a/src/credential/plugin_rest_credential.c b/src/credential/plugin_rest_credential.c deleted file mode 100644 index 253378dfc..000000000 --- a/src/credential/plugin_rest_credential.c +++ /dev/null @@ -1,1150 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012-2016 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ -/** - * @author Martin Schanzenbach - * @file credential/plugin_rest_credential.c - * @brief GNUnet CREDENTIAL REST plugin - * - */ - -#include "platform.h" -#include "gnunet_rest_plugin.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define GNUNET_REST_API_NS_CREDENTIAL "/credential" - -#define GNUNET_REST_API_NS_CREDENTIAL_ISSUE "/credential/issue" - -#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify" - -#define GNUNET_REST_API_NS_CREDENTIAL_COLLECT "/credential/collect" - -#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration" - -#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key" - -#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO "subject" - -#define GNUNET_REST_JSONAPI_CREDENTIAL "credential" - -#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential" - -#define GNUNET_REST_JSONAPI_DELEGATIONS "delegations" - -#define GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR "attribute" - -#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR "credential" - -/** - * @brief struct returned by the initialization function of the plugin - */ -struct Plugin -{ - const struct GNUNET_CONFIGURATION_Handle *cfg; -}; - -const struct GNUNET_CONFIGURATION_Handle *cfg; - -struct RequestHandle -{ - /** - * Handle to Credential service. - */ - struct GNUNET_CREDENTIAL_Handle *credential; - - /** - * Handle to lookup request - */ - struct GNUNET_CREDENTIAL_Request *verify_request; - - /** - * Handle to issue request - */ - struct GNUNET_CREDENTIAL_Request *issue_request; - - /** - * Handle to identity - */ - struct GNUNET_IDENTITY_Handle *identity; - - /** - * Handle to identity operation - */ - struct GNUNET_IDENTITY_Operation *id_op; - - /** - * Handle to ego lookup - */ - struct GNUNET_IDENTITY_EgoLookup *ego_lookup; - - /** - * Handle to rest request - */ - struct GNUNET_REST_RequestHandle *rest_handle; - - /** - * ID of a task associated with the resolution process. - */ - struct GNUNET_SCHEDULER_Task * timeout_task; - - /** - * The root of the received JSON or NULL - */ - json_t *json_root; - - /** - * The plugin result processor - */ - GNUNET_REST_ResultProcessor proc; - - /** - * The closure of the result processor - */ - void *proc_cls; - - /** - * The issuer attribute to verify - */ - char *issuer_attr; - - /** - * The subject attribute - */ - char *subject_attr; - - /** - * The public key of the issuer - */ - struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; - - /** - * The public key of the subject - */ - struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; - - /** - * HTTP response code - */ - int response_code; - - /** - * Timeout - */ - struct GNUNET_TIME_Relative timeout; - -}; - - -/** - * Cleanup lookup handle. - * - * @param handle Handle to clean up - */ -static void -cleanup_handle (struct RequestHandle *handle) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cleaning up\n"); - if (NULL != handle->json_root) - json_decref (handle->json_root); - - if (NULL != handle->issuer_attr) - GNUNET_free (handle->issuer_attr); - if (NULL != handle->subject_attr) - GNUNET_free (handle->subject_attr); - if (NULL != handle->verify_request) - GNUNET_CREDENTIAL_request_cancel (handle->verify_request); - if (NULL != handle->credential) - GNUNET_CREDENTIAL_disconnect (handle->credential); - if (NULL != handle->id_op) - GNUNET_IDENTITY_cancel (handle->id_op); - if (NULL != handle->ego_lookup) - GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup); - if (NULL != handle->identity) - GNUNET_IDENTITY_disconnect (handle->identity); - if (NULL != handle->timeout_task) - { - GNUNET_SCHEDULER_cancel (handle->timeout_task); - } - GNUNET_free (handle); -} - - -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); -} - -/** - * Attribute delegation to JSON - * - * @param delegation_chain_entry the DSE - * @return JSON, NULL if failed - */ -static json_t* -attribute_delegation_to_json (struct GNUNET_CREDENTIAL_Delegation *delegation_chain_entry) -{ - char *subject; - char *issuer; - json_t *attr_obj; - - issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->issuer_key); - if (NULL == issuer) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer in delegation malformed\n"); - return NULL; - } - subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->subject_key); - if (NULL == subject) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Subject in credential malformed\n"); - GNUNET_free (issuer); - return NULL; - } - attr_obj = json_object (); - - json_object_set_new (attr_obj, "issuer", json_string (issuer)); - json_object_set_new (attr_obj, "issuer_attribute", - json_string (delegation_chain_entry->issuer_attribute)); - - json_object_set_new (attr_obj, "subject", json_string (subject)); - if (0 < delegation_chain_entry->subject_attribute_len) - { - json_object_set_new (attr_obj, "subject_attribute", - json_string (delegation_chain_entry->subject_attribute)); - } - GNUNET_free (issuer); - GNUNET_free (subject); - return attr_obj; -} - -/** - * JSONAPI resource to Credential - * - * @param res the JSONAPI resource - * @return the resulting credential, NULL if failed - */ -static struct GNUNET_CREDENTIAL_Credential* -json_to_credential (json_t *res) -{ - struct GNUNET_CREDENTIAL_Credential *cred; - json_t *tmp; - const char *attribute; - const char *signature; - char *sig; - - tmp = json_object_get (res, "attribute"); - if (0 == json_is_string (tmp)) - { - return NULL; - } - attribute = json_string_value (tmp); - cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) - + strlen (attribute)); - cred->issuer_attribute = attribute; - cred->issuer_attribute_len = strlen (attribute); - tmp = json_object_get (res, "issuer"); - if (0 == json_is_string (tmp)) - { - GNUNET_free (cred); - return NULL; - } - - GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp), - strlen (json_string_value(tmp)), - &cred->issuer_key); - tmp = json_object_get (res, "subject"); - if (0 == json_is_string (tmp)) - { - GNUNET_free (cred); - return NULL; - } - GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp), - strlen (json_string_value(tmp)), - &cred->subject_key); - - tmp = json_object_get (res, "signature"); - if (0 == json_is_string (tmp)) - { - GNUNET_free (cred); - return NULL; - } - signature = json_string_value (tmp); - GNUNET_STRINGS_base64_decode (signature, - strlen (signature), - (char**)&sig); - GNUNET_memcpy (&cred->signature, - sig, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); - GNUNET_free (sig); - - tmp = json_object_get (res, "expiration"); - if (0 == json_is_integer (tmp)) - { - GNUNET_free (cred); - return NULL; - } - cred->expiration.abs_value_us = json_integer_value (tmp); - return cred; -} - - -/** - * Credential to JSON - * - * @param cred the credential - * @return the resulting json, NULL if failed - */ -static json_t* -credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred) -{ - char *issuer; - char *subject; - char *signature; - char attribute[cred->issuer_attribute_len + 1]; - json_t *cred_obj; - - issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); - if (NULL == issuer) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer in credential malformed\n"); - return NULL; - } - subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); - if (NULL == subject) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Subject in credential malformed\n"); - GNUNET_free (issuer); - return NULL; - } - GNUNET_STRINGS_base64_encode ((char*)&cred->signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature), - &signature); - GNUNET_memcpy (attribute, - cred->issuer_attribute, - cred->issuer_attribute_len); - attribute[cred->issuer_attribute_len] = '\0'; - cred_obj = json_object (); - json_object_set_new (cred_obj, "issuer", json_string (issuer)); - json_object_set_new (cred_obj, "subject", json_string (subject)); - json_object_set_new (cred_obj, "attribute", json_string (attribute)); - json_object_set_new (cred_obj, "signature", json_string (signature)); - json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us)); - GNUNET_free (issuer); - GNUNET_free (subject); - GNUNET_free (signature); - return cred_obj; -} - -static void -handle_collect_response (void *cls, - unsigned int d_count, - struct GNUNET_CREDENTIAL_Delegation *delegation_chain, - unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cred) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - struct GNUNET_JSONAPI_Document *json_document; - struct GNUNET_JSONAPI_Resource *json_resource; - json_t *cred_obj; - json_t *cred_array; - char *result; - char *issuer; - char *id; - uint32_t i; - - handle->verify_request = NULL; - if (NULL == cred) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Verify failed.\n"); - handle->response_code = MHD_HTTP_NOT_FOUND; - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key); - if (NULL == issuer) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer in delegation malformed\n"); - return; - } - GNUNET_asprintf (&id, - "%s.%s", - issuer, - handle->issuer_attr); - GNUNET_free (issuer); - json_document = GNUNET_JSONAPI_document_new (); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, - id); - GNUNET_free (id); - cred_array = json_array (); - for (i=0;iproc (handle->proc_cls, resp, MHD_HTTP_OK); - cleanup_handle (handle); -} - -static void -subject_ego_lookup (void *cls, - const struct GNUNET_IDENTITY_Ego *ego) -{ - struct RequestHandle *handle = cls; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key; - handle->ego_lookup = NULL; - - if (NULL == ego) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Subject not found\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - sub_key = GNUNET_IDENTITY_ego_get_private_key (ego); - handle->verify_request = GNUNET_CREDENTIAL_collect (handle->credential, - &handle->issuer_key, - handle->issuer_attr, - sub_key, - &handle_collect_response, - handle); -} - - - -static void -handle_verify_response (void *cls, - unsigned int d_count, - struct GNUNET_CREDENTIAL_Delegation *delegation_chain, - unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cred) -{ - - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - struct GNUNET_JSONAPI_Document *json_document; - struct GNUNET_JSONAPI_Resource *json_resource; - json_t *cred_obj; - json_t *attr_obj; - json_t *cred_array; - json_t *attr_array; - char *result; - char *issuer; - char *id; - uint32_t i; - - handle->verify_request = NULL; - if (NULL == cred) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Verify failed.\n"); - handle->response_code = MHD_HTTP_NOT_FOUND; - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key); - if (NULL == issuer) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer in delegation malformed\n"); - return; - } - GNUNET_asprintf (&id, - "%s.%s", - issuer, - handle->issuer_attr); - GNUNET_free (issuer); - json_document = GNUNET_JSONAPI_document_new (); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, - id); - GNUNET_free (id); - attr_array = json_array (); - for (i = 0; i < d_count; i++) - { - attr_obj = attribute_delegation_to_json (&delegation_chain[i]); - json_array_append_new (attr_array, attr_obj); - } - cred_array = json_array (); - for (i=0;iproc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result); - cleanup_handle (handle); -} - -static void -collect_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, - const char* url, - void *cls) -{ - struct RequestHandle *handle = cls; - struct GNUNET_HashCode key; - char *tmp; - char *entity_attr; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting...\n"); - handle->credential = GNUNET_CREDENTIAL_connect (cfg); - handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, - &do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected\n"); - if (NULL == handle->credential) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Connecting to CREDENTIAL failed\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing issuer attribute\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, - &key); - entity_attr = GNUNET_strdup (tmp); - tmp = strtok(entity_attr, "."); - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed issuer or attribute\n"); - GNUNET_free (entity_attr); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, - strlen (tmp), - &handle->issuer_key)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed issuer key\n"); - GNUNET_free (entity_attr); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = strtok (NULL, "."); //Issuer attribute - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed attribute\n"); - GNUNET_free (entity_attr); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - handle->issuer_attr = GNUNET_strdup (tmp); - GNUNET_free (entity_attr); - - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing subject\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, - &key); - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed subject\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, - tmp, - &subject_ego_lookup, - handle); -} - - - -static void -verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, - const char* url, - void *cls) -{ - struct RequestHandle *handle = cls; - struct GNUNET_HashCode key; - struct GNUNET_JSONAPI_Document *json_obj; - struct GNUNET_JSONAPI_Resource *res; - struct GNUNET_CREDENTIAL_Credential *cred; - char *tmp; - char *entity_attr; - int i; - uint32_t credential_count; - uint32_t resource_count; - json_t *cred_json; - json_t *data_js; - json_error_t err; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting...\n"); - handle->credential = GNUNET_CREDENTIAL_connect (cfg); - handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, - &do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected\n"); - if (NULL == handle->credential) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Connecting to CREDENTIAL failed\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing issuer attribute\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, - &key); - entity_attr = GNUNET_strdup (tmp); - tmp = strtok(entity_attr, "."); - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed issuer or attribute\n"); - GNUNET_free (entity_attr); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, - strlen (tmp), - &handle->issuer_key)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed issuer key\n"); - GNUNET_free (entity_attr); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = strtok (NULL, "."); //Issuer attribute - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed attribute\n"); - GNUNET_free (entity_attr); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - handle->issuer_attr = GNUNET_strdup (tmp); - GNUNET_free (entity_attr); - - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing subject key\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, - &key); - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed subject\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, - strlen (tmp), - &handle->subject_key)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed subject key\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - if (0 >= handle->rest_handle->data_size) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing credentials\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - struct GNUNET_JSON_Specification docspec[] = { - GNUNET_JSON_spec_jsonapi_document (&json_obj), - GNUNET_JSON_spec_end() - }; - char term_data[handle->rest_handle->data_size+1]; - term_data[handle->rest_handle->data_size] = '\0'; - credential_count = 0; - GNUNET_memcpy (term_data, - handle->rest_handle->data, - handle->rest_handle->data_size); - data_js = json_loads (term_data, - JSON_DECODE_ANY, - &err); - GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, docspec, - NULL, NULL)); - json_decref (data_js); - if (NULL == json_obj) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to parse JSONAPI Object from %s\n", - term_data); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - resource_count = GNUNET_JSONAPI_document_resource_count(json_obj); - GNUNET_assert (1 == resource_count); - res = (GNUNET_JSONAPI_document_get_resource(json_obj, 0)); - if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type(res, - GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Resource not a credential!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to parse JSONAPI Object from %s\n", - term_data); - GNUNET_JSONAPI_document_delete (json_obj); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - cred_json = GNUNET_JSONAPI_resource_read_attr (res, - GNUNET_REST_JSONAPI_CREDENTIAL); - - GNUNET_assert (json_is_array (cred_json)); - - credential_count = json_array_size(cred_json); - - struct GNUNET_CREDENTIAL_Credential credentials[credential_count]; - for (i=0;iissuer_attribute); - GNUNET_free (cred); - } - GNUNET_JSONAPI_document_delete(json_obj); - handle->verify_request = GNUNET_CREDENTIAL_verify (handle->credential, - &handle->issuer_key, - handle->issuer_attr, - &handle->subject_key, - credential_count, - credentials, - &handle_verify_response, - handle); - for (i=0;iissuer_key); - if (NULL == issuer) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Subject malformed\n"); - GNUNET_free (issuer); - return; - } - GNUNET_asprintf (&id, - "%s.%s", - issuer, - (char*)&cred[1]); - subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); - if (NULL == subject) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Subject malformed\n"); - GNUNET_free (id); - GNUNET_free (issuer); - return; - } - GNUNET_STRINGS_base64_encode ((char*)&cred->signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature), - &signature); - json_document = GNUNET_JSONAPI_document_new (); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, - id); - GNUNET_free (id); - cred_obj = json_object(); - json_object_set_new (cred_obj, "issuer", json_string (issuer)); - json_object_set_new (cred_obj, "subject", json_string (subject)); - json_object_set_new (cred_obj, "expiration", json_integer( cred->expiration.abs_value_us)); - json_object_set_new (cred_obj, "signature", json_string (signature)); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_CREDENTIAL, - cred_obj); - GNUNET_JSONAPI_document_resource_add (json_document, json_resource); - GNUNET_JSONAPI_document_serialize (json_document, &result); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Result %s\n", - result); - json_decref (cred_obj); - GNUNET_JSONAPI_document_delete (json_document); - resp = GNUNET_REST_create_response (result); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result); - GNUNET_free (signature); - GNUNET_free (issuer); - GNUNET_free (subject); - cleanup_handle (handle); -} - -void -get_cred_issuer_cb (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *name) -{ - struct RequestHandle *handle = cls; - struct GNUNET_TIME_Absolute etime_abs; - struct GNUNET_TIME_Relative etime_rel; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer_key; - struct GNUNET_HashCode key; - struct GNUNET_CREDENTIAL_Credential *cred; - char* expiration_str; - char* tmp; - - handle->id_op = NULL; - - if (NULL == name) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer not configured!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting to credential service...\n"); - handle->credential = GNUNET_CREDENTIAL_connect (cfg); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected\n"); - if (NULL == handle->credential) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Connecting to CREDENTIAL failed\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing expiration\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - expiration_str = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, - &key); - if ( NULL == expiration_str ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Expiration malformed\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str, - &etime_rel)) - { - etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel); - } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str, - &etime_abs)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed expiration: %s\n", expiration_str); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing issuer attribute\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - handle->issuer_attr = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get - (handle->rest_handle->url_param_map, - &key)); - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY, - strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY), - &key); - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Missing subject\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, - &key); - if (NULL == tmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed subject\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, - strlen (tmp), - &handle->subject_key)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed subject key\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego); - cred = GNUNET_CREDENTIAL_credential_issue (issuer_key, - &handle->subject_key, - handle->issuer_attr, - &etime_abs); - if (NULL == cred) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to create credential\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - send_cred_response (handle, cred); -} - - -static void -issue_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, - const char* url, - void *cls) -{ - struct RequestHandle *handle = cls; - - handle->identity = GNUNET_IDENTITY_connect (cfg, - NULL, - NULL); - handle->id_op = GNUNET_IDENTITY_get(handle->identity, - "credential-issuer", - &get_cred_issuer_cb, - handle); - handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, - &do_error, - handle); -} - -static void -options_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - struct MHD_Response *resp; - struct RequestHandle *handle = cls; - - //For GNS, independent of path return all options - resp = GNUNET_REST_create_response (NULL); - MHD_add_response_header (resp, - "Access-Control-Allow-Methods", - MHD_HTTP_METHOD_GET); - handle->proc (handle->proc_cls, - resp, - MHD_HTTP_OK); - cleanup_handle (handle); -} - - -static void -rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, - GNUNET_REST_ResultProcessor proc, - void *proc_cls) -{ - struct RequestHandle *handle = GNUNET_new (struct RequestHandle); - struct GNUNET_REST_RequestHandlerError err; - - handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; - handle->proc_cls = proc_cls; - handle->proc = proc; - handle->rest_handle = conndata_handle; - - static const struct GNUNET_REST_RequestHandler handlers[] = { - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont}, - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_COLLECT, &collect_cred_cont}, - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont}, - {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont}, - GNUNET_REST_HANDLER_END - }; - - if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - -/** - * Entry point for the plugin. - * - * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*" - * @return NULL on error, otherwise the plugin context - */ -void * -libgnunet_plugin_rest_credential_init (void *cls) -{ - static struct Plugin plugin; - cfg = cls; - struct GNUNET_REST_Plugin *api; - - 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_CREDENTIAL; - api->process_request = &rest_credential_process_request; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("GNS 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_credential_done (void *cls) -{ - struct GNUNET_REST_Plugin *api = cls; - struct Plugin *plugin = api->cls; - - plugin->cfg = NULL; - GNUNET_free (api); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS REST plugin is finished\n"); - return NULL; -} - -/* end of plugin_rest_gns.c */ diff --git a/src/rest-plugins/Makefile.am b/src/rest-plugins/Makefile.am index 486692b72..484dceaba 100644 --- a/src/rest-plugins/Makefile.am +++ b/src/rest-plugins/Makefile.am @@ -22,11 +22,27 @@ plugin_LTLIBRARIES = \ libgnunet_plugin_rest_peerinfo.la \ libgnunet_plugin_rest_identity.la \ libgnunet_plugin_rest_namestore.la \ - libgnunet_plugin_rest_gns.la + libgnunet_plugin_rest_gns.la \ + libgnunet_plugin_rest_credential.la if HAVE_ABE plugin_LTLIBRARIES += libgnunet_plugin_rest_openid_connect.la endif +libgnunet_plugin_rest_credential_la_SOURCES = \ + plugin_rest_credential.c +libgnunet_plugin_rest_credential_la_LIBADD = \ + $(top_builddir)/src/credential/libgnunetcredential.la \ + $(top_builddir)/src/rest/libgnunetrest.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ + $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \ + $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ + $(LTLIBINTL) -ljansson -lmicrohttpd +libgnunet_plugin_rest_credential_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) + + + libgnunet_plugin_rest_copying_la_SOURCES = \ plugin_rest_copying.c diff --git a/src/rest-plugins/plugin_rest_credential.c b/src/rest-plugins/plugin_rest_credential.c new file mode 100644 index 000000000..253378dfc --- /dev/null +++ b/src/rest-plugins/plugin_rest_credential.c @@ -0,0 +1,1150 @@ +/* + This file is part of GNUnet. + Copyright (C) 2012-2016 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +/** + * @author Martin Schanzenbach + * @file credential/plugin_rest_credential.c + * @brief GNUnet CREDENTIAL REST plugin + * + */ + +#include "platform.h" +#include "gnunet_rest_plugin.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define GNUNET_REST_API_NS_CREDENTIAL "/credential" + +#define GNUNET_REST_API_NS_CREDENTIAL_ISSUE "/credential/issue" + +#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify" + +#define GNUNET_REST_API_NS_CREDENTIAL_COLLECT "/credential/collect" + +#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration" + +#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key" + +#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO "subject" + +#define GNUNET_REST_JSONAPI_CREDENTIAL "credential" + +#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential" + +#define GNUNET_REST_JSONAPI_DELEGATIONS "delegations" + +#define GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR "attribute" + +#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR "credential" + +/** + * @brief struct returned by the initialization function of the plugin + */ +struct Plugin +{ + const struct GNUNET_CONFIGURATION_Handle *cfg; +}; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +struct RequestHandle +{ + /** + * Handle to Credential service. + */ + struct GNUNET_CREDENTIAL_Handle *credential; + + /** + * Handle to lookup request + */ + struct GNUNET_CREDENTIAL_Request *verify_request; + + /** + * Handle to issue request + */ + struct GNUNET_CREDENTIAL_Request *issue_request; + + /** + * Handle to identity + */ + struct GNUNET_IDENTITY_Handle *identity; + + /** + * Handle to identity operation + */ + struct GNUNET_IDENTITY_Operation *id_op; + + /** + * Handle to ego lookup + */ + struct GNUNET_IDENTITY_EgoLookup *ego_lookup; + + /** + * Handle to rest request + */ + struct GNUNET_REST_RequestHandle *rest_handle; + + /** + * ID of a task associated with the resolution process. + */ + struct GNUNET_SCHEDULER_Task * timeout_task; + + /** + * The root of the received JSON or NULL + */ + json_t *json_root; + + /** + * The plugin result processor + */ + GNUNET_REST_ResultProcessor proc; + + /** + * The closure of the result processor + */ + void *proc_cls; + + /** + * The issuer attribute to verify + */ + char *issuer_attr; + + /** + * The subject attribute + */ + char *subject_attr; + + /** + * The public key of the issuer + */ + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; + + /** + * The public key of the subject + */ + struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; + + /** + * HTTP response code + */ + int response_code; + + /** + * Timeout + */ + struct GNUNET_TIME_Relative timeout; + +}; + + +/** + * Cleanup lookup handle. + * + * @param handle Handle to clean up + */ +static void +cleanup_handle (struct RequestHandle *handle) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Cleaning up\n"); + if (NULL != handle->json_root) + json_decref (handle->json_root); + + if (NULL != handle->issuer_attr) + GNUNET_free (handle->issuer_attr); + if (NULL != handle->subject_attr) + GNUNET_free (handle->subject_attr); + if (NULL != handle->verify_request) + GNUNET_CREDENTIAL_request_cancel (handle->verify_request); + if (NULL != handle->credential) + GNUNET_CREDENTIAL_disconnect (handle->credential); + if (NULL != handle->id_op) + GNUNET_IDENTITY_cancel (handle->id_op); + if (NULL != handle->ego_lookup) + GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup); + if (NULL != handle->identity) + GNUNET_IDENTITY_disconnect (handle->identity); + if (NULL != handle->timeout_task) + { + GNUNET_SCHEDULER_cancel (handle->timeout_task); + } + GNUNET_free (handle); +} + + +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); +} + +/** + * Attribute delegation to JSON + * + * @param delegation_chain_entry the DSE + * @return JSON, NULL if failed + */ +static json_t* +attribute_delegation_to_json (struct GNUNET_CREDENTIAL_Delegation *delegation_chain_entry) +{ + char *subject; + char *issuer; + json_t *attr_obj; + + issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->issuer_key); + if (NULL == issuer) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Issuer in delegation malformed\n"); + return NULL; + } + subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->subject_key); + if (NULL == subject) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Subject in credential malformed\n"); + GNUNET_free (issuer); + return NULL; + } + attr_obj = json_object (); + + json_object_set_new (attr_obj, "issuer", json_string (issuer)); + json_object_set_new (attr_obj, "issuer_attribute", + json_string (delegation_chain_entry->issuer_attribute)); + + json_object_set_new (attr_obj, "subject", json_string (subject)); + if (0 < delegation_chain_entry->subject_attribute_len) + { + json_object_set_new (attr_obj, "subject_attribute", + json_string (delegation_chain_entry->subject_attribute)); + } + GNUNET_free (issuer); + GNUNET_free (subject); + return attr_obj; +} + +/** + * JSONAPI resource to Credential + * + * @param res the JSONAPI resource + * @return the resulting credential, NULL if failed + */ +static struct GNUNET_CREDENTIAL_Credential* +json_to_credential (json_t *res) +{ + struct GNUNET_CREDENTIAL_Credential *cred; + json_t *tmp; + const char *attribute; + const char *signature; + char *sig; + + tmp = json_object_get (res, "attribute"); + if (0 == json_is_string (tmp)) + { + return NULL; + } + attribute = json_string_value (tmp); + cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + + strlen (attribute)); + cred->issuer_attribute = attribute; + cred->issuer_attribute_len = strlen (attribute); + tmp = json_object_get (res, "issuer"); + if (0 == json_is_string (tmp)) + { + GNUNET_free (cred); + return NULL; + } + + GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp), + strlen (json_string_value(tmp)), + &cred->issuer_key); + tmp = json_object_get (res, "subject"); + if (0 == json_is_string (tmp)) + { + GNUNET_free (cred); + return NULL; + } + GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp), + strlen (json_string_value(tmp)), + &cred->subject_key); + + tmp = json_object_get (res, "signature"); + if (0 == json_is_string (tmp)) + { + GNUNET_free (cred); + return NULL; + } + signature = json_string_value (tmp); + GNUNET_STRINGS_base64_decode (signature, + strlen (signature), + (char**)&sig); + GNUNET_memcpy (&cred->signature, + sig, + sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); + GNUNET_free (sig); + + tmp = json_object_get (res, "expiration"); + if (0 == json_is_integer (tmp)) + { + GNUNET_free (cred); + return NULL; + } + cred->expiration.abs_value_us = json_integer_value (tmp); + return cred; +} + + +/** + * Credential to JSON + * + * @param cred the credential + * @return the resulting json, NULL if failed + */ +static json_t* +credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred) +{ + char *issuer; + char *subject; + char *signature; + char attribute[cred->issuer_attribute_len + 1]; + json_t *cred_obj; + + issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); + if (NULL == issuer) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Issuer in credential malformed\n"); + return NULL; + } + subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); + if (NULL == subject) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Subject in credential malformed\n"); + GNUNET_free (issuer); + return NULL; + } + GNUNET_STRINGS_base64_encode ((char*)&cred->signature, + sizeof (struct GNUNET_CRYPTO_EcdsaSignature), + &signature); + GNUNET_memcpy (attribute, + cred->issuer_attribute, + cred->issuer_attribute_len); + attribute[cred->issuer_attribute_len] = '\0'; + cred_obj = json_object (); + json_object_set_new (cred_obj, "issuer", json_string (issuer)); + json_object_set_new (cred_obj, "subject", json_string (subject)); + json_object_set_new (cred_obj, "attribute", json_string (attribute)); + json_object_set_new (cred_obj, "signature", json_string (signature)); + json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us)); + GNUNET_free (issuer); + GNUNET_free (subject); + GNUNET_free (signature); + return cred_obj; +} + +static void +handle_collect_response (void *cls, + unsigned int d_count, + struct GNUNET_CREDENTIAL_Delegation *delegation_chain, + unsigned int c_count, + struct GNUNET_CREDENTIAL_Credential *cred) +{ + struct RequestHandle *handle = cls; + struct MHD_Response *resp; + struct GNUNET_JSONAPI_Document *json_document; + struct GNUNET_JSONAPI_Resource *json_resource; + json_t *cred_obj; + json_t *cred_array; + char *result; + char *issuer; + char *id; + uint32_t i; + + handle->verify_request = NULL; + if (NULL == cred) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Verify failed.\n"); + handle->response_code = MHD_HTTP_NOT_FOUND; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key); + if (NULL == issuer) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Issuer in delegation malformed\n"); + return; + } + GNUNET_asprintf (&id, + "%s.%s", + issuer, + handle->issuer_attr); + GNUNET_free (issuer); + json_document = GNUNET_JSONAPI_document_new (); + json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, + id); + GNUNET_free (id); + cred_array = json_array (); + for (i=0;iproc (handle->proc_cls, resp, MHD_HTTP_OK); + cleanup_handle (handle); +} + +static void +subject_ego_lookup (void *cls, + const struct GNUNET_IDENTITY_Ego *ego) +{ + struct RequestHandle *handle = cls; + const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key; + handle->ego_lookup = NULL; + + if (NULL == ego) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Subject not found\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + sub_key = GNUNET_IDENTITY_ego_get_private_key (ego); + handle->verify_request = GNUNET_CREDENTIAL_collect (handle->credential, + &handle->issuer_key, + handle->issuer_attr, + sub_key, + &handle_collect_response, + handle); +} + + + +static void +handle_verify_response (void *cls, + unsigned int d_count, + struct GNUNET_CREDENTIAL_Delegation *delegation_chain, + unsigned int c_count, + struct GNUNET_CREDENTIAL_Credential *cred) +{ + + struct RequestHandle *handle = cls; + struct MHD_Response *resp; + struct GNUNET_JSONAPI_Document *json_document; + struct GNUNET_JSONAPI_Resource *json_resource; + json_t *cred_obj; + json_t *attr_obj; + json_t *cred_array; + json_t *attr_array; + char *result; + char *issuer; + char *id; + uint32_t i; + + handle->verify_request = NULL; + if (NULL == cred) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Verify failed.\n"); + handle->response_code = MHD_HTTP_NOT_FOUND; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key); + if (NULL == issuer) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Issuer in delegation malformed\n"); + return; + } + GNUNET_asprintf (&id, + "%s.%s", + issuer, + handle->issuer_attr); + GNUNET_free (issuer); + json_document = GNUNET_JSONAPI_document_new (); + json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, + id); + GNUNET_free (id); + attr_array = json_array (); + for (i = 0; i < d_count; i++) + { + attr_obj = attribute_delegation_to_json (&delegation_chain[i]); + json_array_append_new (attr_array, attr_obj); + } + cred_array = json_array (); + for (i=0;iproc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_free (result); + cleanup_handle (handle); +} + +static void +collect_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, + const char* url, + void *cls) +{ + struct RequestHandle *handle = cls; + struct GNUNET_HashCode key; + char *tmp; + char *entity_attr; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connecting...\n"); + handle->credential = GNUNET_CREDENTIAL_connect (cfg); + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, + &do_error, handle); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connected\n"); + if (NULL == handle->credential) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Connecting to CREDENTIAL failed\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing issuer attribute\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, + &key); + entity_attr = GNUNET_strdup (tmp); + tmp = strtok(entity_attr, "."); + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed issuer or attribute\n"); + GNUNET_free (entity_attr); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, + strlen (tmp), + &handle->issuer_key)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed issuer key\n"); + GNUNET_free (entity_attr); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = strtok (NULL, "."); //Issuer attribute + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed attribute\n"); + GNUNET_free (entity_attr); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + handle->issuer_attr = GNUNET_strdup (tmp); + GNUNET_free (entity_attr); + + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing subject\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, + &key); + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed subject\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, + tmp, + &subject_ego_lookup, + handle); +} + + + +static void +verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, + const char* url, + void *cls) +{ + struct RequestHandle *handle = cls; + struct GNUNET_HashCode key; + struct GNUNET_JSONAPI_Document *json_obj; + struct GNUNET_JSONAPI_Resource *res; + struct GNUNET_CREDENTIAL_Credential *cred; + char *tmp; + char *entity_attr; + int i; + uint32_t credential_count; + uint32_t resource_count; + json_t *cred_json; + json_t *data_js; + json_error_t err; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connecting...\n"); + handle->credential = GNUNET_CREDENTIAL_connect (cfg); + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, + &do_error, handle); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connected\n"); + if (NULL == handle->credential) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Connecting to CREDENTIAL failed\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing issuer attribute\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, + &key); + entity_attr = GNUNET_strdup (tmp); + tmp = strtok(entity_attr, "."); + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed issuer or attribute\n"); + GNUNET_free (entity_attr); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, + strlen (tmp), + &handle->issuer_key)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed issuer key\n"); + GNUNET_free (entity_attr); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = strtok (NULL, "."); //Issuer attribute + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed attribute\n"); + GNUNET_free (entity_attr); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + handle->issuer_attr = GNUNET_strdup (tmp); + GNUNET_free (entity_attr); + + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing subject key\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, + &key); + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed subject\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, + strlen (tmp), + &handle->subject_key)) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed subject key\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + if (0 >= handle->rest_handle->data_size) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing credentials\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + struct GNUNET_JSON_Specification docspec[] = { + GNUNET_JSON_spec_jsonapi_document (&json_obj), + GNUNET_JSON_spec_end() + }; + char term_data[handle->rest_handle->data_size+1]; + term_data[handle->rest_handle->data_size] = '\0'; + credential_count = 0; + GNUNET_memcpy (term_data, + handle->rest_handle->data, + handle->rest_handle->data_size); + data_js = json_loads (term_data, + JSON_DECODE_ANY, + &err); + GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, docspec, + NULL, NULL)); + json_decref (data_js); + if (NULL == json_obj) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse JSONAPI Object from %s\n", + term_data); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + resource_count = GNUNET_JSONAPI_document_resource_count(json_obj); + GNUNET_assert (1 == resource_count); + res = (GNUNET_JSONAPI_document_get_resource(json_obj, 0)); + if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type(res, + GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Resource not a credential!\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse JSONAPI Object from %s\n", + term_data); + GNUNET_JSONAPI_document_delete (json_obj); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + cred_json = GNUNET_JSONAPI_resource_read_attr (res, + GNUNET_REST_JSONAPI_CREDENTIAL); + + GNUNET_assert (json_is_array (cred_json)); + + credential_count = json_array_size(cred_json); + + struct GNUNET_CREDENTIAL_Credential credentials[credential_count]; + for (i=0;iissuer_attribute); + GNUNET_free (cred); + } + GNUNET_JSONAPI_document_delete(json_obj); + handle->verify_request = GNUNET_CREDENTIAL_verify (handle->credential, + &handle->issuer_key, + handle->issuer_attr, + &handle->subject_key, + credential_count, + credentials, + &handle_verify_response, + handle); + for (i=0;iissuer_key); + if (NULL == issuer) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Subject malformed\n"); + GNUNET_free (issuer); + return; + } + GNUNET_asprintf (&id, + "%s.%s", + issuer, + (char*)&cred[1]); + subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); + if (NULL == subject) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Subject malformed\n"); + GNUNET_free (id); + GNUNET_free (issuer); + return; + } + GNUNET_STRINGS_base64_encode ((char*)&cred->signature, + sizeof (struct GNUNET_CRYPTO_EcdsaSignature), + &signature); + json_document = GNUNET_JSONAPI_document_new (); + json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, + id); + GNUNET_free (id); + cred_obj = json_object(); + json_object_set_new (cred_obj, "issuer", json_string (issuer)); + json_object_set_new (cred_obj, "subject", json_string (subject)); + json_object_set_new (cred_obj, "expiration", json_integer( cred->expiration.abs_value_us)); + json_object_set_new (cred_obj, "signature", json_string (signature)); + GNUNET_JSONAPI_resource_add_attr (json_resource, + GNUNET_REST_JSONAPI_CREDENTIAL, + cred_obj); + GNUNET_JSONAPI_document_resource_add (json_document, json_resource); + GNUNET_JSONAPI_document_serialize (json_document, &result); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Result %s\n", + result); + json_decref (cred_obj); + GNUNET_JSONAPI_document_delete (json_document); + resp = GNUNET_REST_create_response (result); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_free (result); + GNUNET_free (signature); + GNUNET_free (issuer); + GNUNET_free (subject); + cleanup_handle (handle); +} + +void +get_cred_issuer_cb (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *name) +{ + struct RequestHandle *handle = cls; + struct GNUNET_TIME_Absolute etime_abs; + struct GNUNET_TIME_Relative etime_rel; + const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer_key; + struct GNUNET_HashCode key; + struct GNUNET_CREDENTIAL_Credential *cred; + char* expiration_str; + char* tmp; + + handle->id_op = NULL; + + if (NULL == name) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Issuer not configured!\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connecting to credential service...\n"); + handle->credential = GNUNET_CREDENTIAL_connect (cfg); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connected\n"); + if (NULL == handle->credential) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Connecting to CREDENTIAL failed\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing expiration\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + expiration_str = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, + &key); + if ( NULL == expiration_str ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expiration malformed\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str, + &etime_rel)) + { + etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel); + } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str, + &etime_abs)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed expiration: %s\n", expiration_str); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing issuer attribute\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + handle->issuer_attr = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get + (handle->rest_handle->url_param_map, + &key)); + GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY, + strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY), + &key); + if ( GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, + &key) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Missing subject\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, + &key); + if (NULL == tmp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed subject\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, + strlen (tmp), + &handle->subject_key)) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed subject key\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego); + cred = GNUNET_CREDENTIAL_credential_issue (issuer_key, + &handle->subject_key, + handle->issuer_attr, + &etime_abs); + if (NULL == cred) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to create credential\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + send_cred_response (handle, cred); +} + + +static void +issue_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, + const char* url, + void *cls) +{ + struct RequestHandle *handle = cls; + + handle->identity = GNUNET_IDENTITY_connect (cfg, + NULL, + NULL); + handle->id_op = GNUNET_IDENTITY_get(handle->identity, + "credential-issuer", + &get_cred_issuer_cb, + handle); + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, + &do_error, + handle); +} + +static void +options_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + + //For GNS, independent of path return all options + resp = GNUNET_REST_create_response (NULL); + MHD_add_response_header (resp, + "Access-Control-Allow-Methods", + MHD_HTTP_METHOD_GET); + handle->proc (handle->proc_cls, + resp, + MHD_HTTP_OK); + cleanup_handle (handle); +} + + +static void +rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, + GNUNET_REST_ResultProcessor proc, + void *proc_cls) +{ + struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + + handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; + handle->proc_cls = proc_cls; + handle->proc = proc; + handle->rest_handle = conndata_handle; + + static const struct GNUNET_REST_RequestHandler handlers[] = { + {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont}, + {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_COLLECT, &collect_cred_cont}, + {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont}, + {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont}, + GNUNET_REST_HANDLER_END + }; + + if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle, + handlers, + &err, + handle)) + { + handle->response_code = err.error_code; + GNUNET_SCHEDULER_add_now (&do_error, handle); + } +} + + +/** + * Entry point for the plugin. + * + * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*" + * @return NULL on error, otherwise the plugin context + */ +void * +libgnunet_plugin_rest_credential_init (void *cls) +{ + static struct Plugin plugin; + cfg = cls; + struct GNUNET_REST_Plugin *api; + + 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_CREDENTIAL; + api->process_request = &rest_credential_process_request; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("GNS 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_credential_done (void *cls) +{ + struct GNUNET_REST_Plugin *api = cls; + struct Plugin *plugin = api->cls; + + plugin->cfg = NULL; + GNUNET_free (api); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS REST plugin is finished\n"); + return NULL; +} + +/* end of plugin_rest_gns.c */ -- cgit v1.2.3