From 9bb775312552270404b90e0a0603cbbadb1145c1 Mon Sep 17 00:00:00 2001 From: Markus Voggenreiter Date: Sat, 19 Oct 2019 11:30:24 +0200 Subject: [PATCH] Listing Attestations through service --- src/include/gnunet_protocols.h | 2 + src/include/gnunet_reclaim_attribute_lib.h | 4 +- src/reclaim-attribute/reclaim_attribute.c | 5 +- src/reclaim/gnunet-service-reclaim.c | 47 ++++++--- src/reclaim/plugin_rest_reclaim.c | 111 ++++++++++++++++++++- src/reclaim/reclaim_api.c | 102 +++++++++++++++++++ 6 files changed, 248 insertions(+), 23 deletions(-) diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 45b3c6728..f1dc74462 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -2718,6 +2718,8 @@ extern "C" { #define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE 978 +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT 979 + /************************************************** * * ABD MESSAGE TYPES diff --git a/src/include/gnunet_reclaim_attribute_lib.h b/src/include/gnunet_reclaim_attribute_lib.h index c23b39383..34429da51 100644 --- a/src/include/gnunet_reclaim_attribute_lib.h +++ b/src/include/gnunet_reclaim_attribute_lib.h @@ -53,12 +53,12 @@ extern "C" { /** * No value attestation. */ -#define GNUNET_RECLAIM_ATTESTATION_TYPE_NONE 0 +#define GNUNET_RECLAIM_ATTESTATION_TYPE_NONE 10 /** * A JSON Web Token attestation. */ -#define GNUNET_RECLAIM_ATTESTATION_TYPE_JWT 1 +#define GNUNET_RECLAIM_ATTESTATION_TYPE_JWT 11 /** * An attribute. diff --git a/src/reclaim-attribute/reclaim_attribute.c b/src/reclaim-attribute/reclaim_attribute.c index 43767d063..2cc0827a7 100644 --- a/src/reclaim-attribute/reclaim_attribute.c +++ b/src/reclaim-attribute/reclaim_attribute.c @@ -229,7 +229,6 @@ GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename) unsigned int i; struct Plugin *plugin; uint32_t ret; - init (); for (i = 0; i < num_plugins; i++) { @@ -699,8 +698,8 @@ GNUNET_RECLAIM_ATTESTATION_serialize ( attr_ser = (struct Attestation *) result; attr_ser->attestation_type = htons (attr->type); - attr_ser->attestation_type = htonl (attr->version); - attr_ser->attestation_type = GNUNET_htonll (attr->id); + attr_ser->attestation_version = htonl (attr->version); + attr_ser->attestation_id = GNUNET_htonll (attr->id); name_len = strlen (attr->name); attr_ser->name_len = htons (name_len); write_ptr = (char *) &attr_ser[1]; diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index c183b4b78..dcd5d3410 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -1615,7 +1615,7 @@ attr_iter_error (void *cls) /** - * Got record. Return if it is an attribute. + * Got record. Return if it is an attribute or attestation. * * @param cls our attribute iterator * @param zone zone we are iterating @@ -1641,22 +1641,43 @@ attr_iter_cb (void *cls, return; } - if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type) + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type) && + (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd->record_type) ) { GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n"); - env = GNUNET_MQ_msg_extra (arm, - rd->data_size, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); - arm->id = htonl (ai->request_id); - arm->attr_len = htons (rd->data_size); - GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); - data_tmp = (char *) &arm[1]; - GNUNET_memcpy (data_tmp, rd->data, rd->data_size); - GNUNET_MQ_send (ai->client->mq, env); + + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd->record_type ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n", + label); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending ATTESTATION_RESULT message\n"); + env = GNUNET_MQ_msg_extra (arm, + rd->data_size, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT); + arm->id = htonl (ai->request_id); + arm->attr_len = htons (rd->data_size); + GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); + data_tmp = (char *) &arm[1]; + GNUNET_memcpy (data_tmp, rd->data, rd->data_size); + GNUNET_MQ_send (ai->client->mq, env); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n"); + env = GNUNET_MQ_msg_extra (arm, + rd->data_size, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); + arm->id = htonl (ai->request_id); + arm->attr_len = htons (rd->data_size); + GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); + data_tmp = (char *) &arm[1]; + GNUNET_memcpy (data_tmp, rd->data, rd->data_size); + GNUNET_MQ_send (ai->client->mq, env); + } } diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index 4e5914f78..f126c0fb1 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -532,15 +532,110 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, handle); GNUNET_JSON_parse_free (attrspec); } -/*Placeholder*/ + + +/** + * Collect all attestations for an ego + * + */ +static void +attest_collect (void *cls, + const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, + const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest) +{ + struct RequestHandle *handle = cls; + json_t *attr_obj; + const char *type; + char *tmp_value; + char *id_str; + + if (NULL == attest) + { + GNUNET_RECLAIM_get_attributes_next (handle->attr_it); + return; + } + + if ((NULL == attest->name) || (NULL == attest->data)) + { + GNUNET_RECLAIM_get_attributes_next (handle->attr_it); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation: %s\n", + attest->name); + + tmp_value = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type, + attest->data, + attest->data_size); + attr_obj = json_object (); + json_object_set_new (attr_obj, "value", json_string (tmp_value)); + json_object_set_new (attr_obj, "name", json_string (attest->name)); + type = GNUNET_RECLAIM_ATTESTATION_number_to_typename (attest->type); + json_object_set_new (attr_obj, "type", json_string (type)); + id_str = GNUNET_STRINGS_data_to_string_alloc (&attest->id, sizeof(uint64_t)); + json_object_set_new (attr_obj, "id", json_string (id_str)); + json_array_append (handle->resp_object, attr_obj); + json_decref (attr_obj); + GNUNET_free (tmp_value); + GNUNET_RECLAIM_get_attributes_next (handle->attr_it); +} + + +/** + * Lists attestation for identity request + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ static void list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Listing Attestations not supported\n"); - GNUNET_SCHEDULER_add_now (&do_error, cls); - return; + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + char *identity; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Getting attestations for %s.\n", + handle->url); + if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen ( + handle->url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + identity = handle->url + strlen ( + GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1; + + for (ego_entry = handle->ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + if (0 == strcmp (identity, ego_entry->identifier)) + break; + handle->resp_object = json_array (); + + + if (NULL == ego_entry) + { + // Done + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity); + GNUNET_SCHEDULER_add_now (&return_response, 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, + priv_key, + &collect_error_cb, + handle, + &attest_collect, + handle, + &collect_finished_cb, + handle); } /** @@ -761,6 +856,12 @@ attr_collect (void *cls, char *tmp_value; char *id_str; + if (NULL == attr) + { + GNUNET_RECLAIM_get_attributes_next (handle->attr_it); + return; + } + if ((NULL == attr->name) || (NULL == attr->data)) { GNUNET_RECLAIM_get_attributes_next (handle->attr_it); @@ -984,7 +1085,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, static void consume_cont (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, + const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest) { struct RequestHandle *handle = cls; diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 7bbcf9a65..bb0a5e3a8 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -622,6 +622,104 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg) GNUNET_assert (0); } +/** + * Handle an incoming message of type + * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT + * + * @param cls + * @param msg the message we received + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +static int +check_attestation_result (void *cls, const struct AttributeResultMessage *msg) +{ + size_t msg_len; + size_t attr_len; + + msg_len = ntohs (msg->header.size); + attr_len = ntohs (msg->attr_len); + if (msg_len != sizeof(struct AttributeResultMessage) + attr_len) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Handle an incoming message of type + * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT + * + * @param cls + * @param msg the message we received + */ +static void +handle_attestation_result (void *cls, const struct AttributeResultMessage *msg) +{ + static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; + struct GNUNET_RECLAIM_Handle *h = cls; + struct GNUNET_RECLAIM_AttributeIterator *it; + struct GNUNET_RECLAIM_Operation *op; + size_t attr_len; + uint32_t r_id = ntohl (msg->id); + + attr_len = ntohs (msg->attr_len); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n"); + + + for (it = h->it_head; NULL != it; it = it->next) + if (it->r_id == r_id) + break; + for (op = h->op_head; NULL != op; op = op->next) + if (op->r_id == r_id) + break; + if ((NULL == it) && (NULL == op)) + return; + + if ((0 == + (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy))))) + { + if ((NULL == it) && (NULL == op)) + { + GNUNET_break (0); + force_reconnect (h); + return; + } + if (NULL != it) + { + if (NULL != it->finish_cb) + it->finish_cb (it->finish_cb_cls); + free_it (it); + } + if (NULL != op) + { + if (NULL != op->ar_cb) + op->ar_cb (op->cls, NULL, NULL, NULL); + GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); + free_op (op); + } + return; + } + + { + struct GNUNET_RECLAIM_ATTESTATION_Claim *attr; + attr = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1], attr_len); + if (NULL != it) + { + if (NULL != it->proc) + it->proc (it->proc_cls, &msg->identity, NULL, attr); + } + else if (NULL != op) + { + if (NULL != op->ar_cb) + op->ar_cb (op->cls, &msg->identity, NULL, attr); + } + GNUNET_free (attr); + return; + } + GNUNET_assert (0); +} /** * Handle an incoming message of type @@ -741,6 +839,10 @@ reconnect (struct GNUNET_RECLAIM_Handle *h) GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT, struct AttributeResultMessage, h), + GNUNET_MQ_hd_var_size (attestation_result, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT, + struct AttributeResultMessage, + h), GNUNET_MQ_hd_fixed_size (ticket_result, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT, struct TicketResultMessage, -- 2.25.1