From e29f90c0ad27e49f7cd464d93fff8197d10b324f Mon Sep 17 00:00:00 2001 From: Markus Voggenreiter Date: Sat, 12 Oct 2019 14:47:51 +0200 Subject: [PATCH] Fixed direct Namestore Access --- .../plugin_reclaim_attribute_gnuid.c | 9 +- src/reclaim/plugin_rest_reclaim.c | 265 +++++++++++++++++- 2 files changed, 266 insertions(+), 8 deletions(-) diff --git a/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c b/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c index b06f98f66..b00d206f1 100644 --- a/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c +++ b/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c @@ -160,15 +160,14 @@ static struct { NULL, UINT32_MAX } }; /** - * Mapping of attribute type numbers to human-readable - * attribute type names. - */ + * Mapping of attestation type numbers to human-readable + * attestation type names. + */ static struct { const char *name; uint32_t number; -} gnuid_attest_name_map[] = { { "STRING", - GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING }, +} gnuid_attest_name_map[] = { { "JWT", GNUNET_RECLAIM_ATTESTATION_TYPE_JWT }, { NULL, UINT32_MAX } }; /** diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index d7cfd393a..b476a1ea2 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -241,6 +241,143 @@ struct RequestHandle json_t *resp_object; }; +/** + * Handle for attribute store request + */ +struct AttributeStoreHandle +{ + /** + * DLL + */ + struct AttributeStoreHandle *next; + + /** + * DLL + */ + struct AttributeStoreHandle *prev; + + /** + * Client connection + */ + struct IdpClient *client; + + /** + * Identity + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + + /** + * Identity pubkey + */ + struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey; + + /** + * QueueEntry + */ + struct GNUNET_NAMESTORE_QueueEntry *ns_qe; + + /** + * The attribute to store + */ + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; + + /** + * The attestation to store + */ + struct GNUNET_RECLAIM_ATTESTATION_Claim *attest; + + /** + * The attribute expiration interval + */ + struct GNUNET_TIME_Relative exp; + + /** + * request id + */ + uint32_t r_id; +}; + +/** + * Handle to the service. + */ +struct GNUNET_RECLAIM_Handle +{ + /** + * Configuration to use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Socket (if available). + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Closure for 'cb'. + */ + void *cb_cls; + + /** + * Head of active operations. + */ + struct GNUNET_RECLAIM_Operation *op_head; + + /** + * Tail of active operations. + */ + struct GNUNET_RECLAIM_Operation *op_tail; + + /** + * Head of active iterations + */ + struct GNUNET_RECLAIM_AttributeIterator *it_head; + + /** + * Tail of active iterations + */ + struct GNUNET_RECLAIM_AttributeIterator *it_tail; + + /** + * Head of active iterations + */ + struct GNUNET_RECLAIM_TicketIterator *ticket_it_head; + + /** + * Tail of active iterations + */ + struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail; + + /** + * Currently pending transmission request, or NULL for none. + */ + struct GNUNET_CLIENT_TransmitHandle *th; + + /** + * Task doing exponential back-off trying to reconnect. + */ + struct GNUNET_SCHEDULER_Task *reconnect_task; + + /** + * Time for next connect retry. + */ + struct GNUNET_TIME_Relative reconnect_backoff; + + /** + * Connection to service (if available). + */ + struct GNUNET_MQ_Handle *mq; + + /** + * Request Id generator. Incremented by one for each request. + */ + uint32_t r_id_gen; + + /** + * Are we polling for incoming messages right now? + */ + int in_receive; +}; + /** * Cleanup lookup handle * @param handle Handle to clean up @@ -439,9 +576,131 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding Attestations not supported\n"); - GNUNET_SCHEDULER_add_now (&do_error, cls); - return; + const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + const char *identity; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute; + struct GNUNET_TIME_Relative exp; + char term_data[handle->rest_handle->data_size + 1]; + json_t *data_json; + json_error_t err; + struct GNUNET_JSON_Specification attrspec[] = + { GNUNET_RECLAIM_JSON_spec_claim_attest (&attribute), + GNUNET_JSON_spec_end () }; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Adding an attestation 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; + + if (NULL == ego_entry) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity); + return; + } + identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + + if (0 >= handle->rest_handle->data_size) + { + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + term_data[handle->rest_handle->data_size] = '\0'; + GNUNET_memcpy (term_data, + handle->rest_handle->data, + handle->rest_handle->data_size); + data_json = json_loads (term_data, JSON_DECODE_ANY, &err); + GNUNET_assert (GNUNET_OK == + GNUNET_JSON_parse (data_json, attrspec, NULL, NULL)); + json_decref (data_json); + if (NULL == attribute) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse attestation from %s\n", + term_data); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + /** + * New ID for attribute + */ + if (0 == attribute->id) + attribute->id = + GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); + handle->idp = GNUNET_RECLAIM_connect (cfg); + exp = GNUNET_TIME_UNIT_HOURS; + /*New */ + struct GNUNET_RECLAIM_Handle *h = handle->idp; + struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey = identity_priv; + /*struct GNUNET_RECLAIM_ATTESTATION_Claim *attr = attribute;*/ + struct GNUNET_TIME_Relative *exp_interval = &exp; + /*GNUNET_RECLAIM_ContinuationWithStatus cont = &finished_cont;*/ + void *cont_cls = handle; + + struct AttributeStoreHandle *ash; + struct GNUNET_GNSRECORD_Data rd[1]; + char *buf; + char *label; + size_t buf_size; + struct IdpClient *idp = cont_cls; + struct GNUNET_NAMESTORE_Handle *nsh; + nsh = GNUNET_NAMESTORE_connect (cfg); + if (NULL == nsh) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "error connecting to namestore"); + } + ash = GNUNET_new (struct AttributeStoreHandle); + ash->identity = *pkey; + ash->r_id = h->r_id_gen++; + ash->exp.rel_value_us = exp_interval->rel_value_us; + ash->attest = attribute; + ash->client = idp; + /*GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Type:%u\n", type); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ID:%s\n", id_str); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Size:%u\n", data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data:%s\n", data);*/ + buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest); + buf = GNUNET_malloc (buf_size); + // Give the ash a new id if unset + if (0 == ash->attest->id) + ash->attest->id + = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); + GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf); + label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id, + sizeof(uint64_t)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label); + + rd[0].data_size = buf_size; + rd[0].data = buf; + rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR; + rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; + rd[0].expiration_time = ash->exp.rel_value_us; + ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh, + &ash->identity, + label, + 1, + rd, + &finished_cont, + ash); + GNUNET_free (buf); + GNUNET_free (label); + GNUNET_JSON_parse_free (attrspec); } /*Placeholder*/ static void -- 2.25.1