From b62682f35d3752eff4b9d7ff52d47e0bfbd6b6f5 Mon Sep 17 00:00:00 2001 From: Markus Voggenreiter Date: Sun, 27 Oct 2019 22:43:23 +0100 Subject: [PATCH] Deletion of Reference Type --- src/include/gnunet_protocols.h | 1 + src/include/gnunet_reclaim_service.h | 19 +++ src/reclaim/gnunet-service-reclaim.c | 198 ++++++++++++++++++++++++++- src/reclaim/plugin_rest_reclaim.c | 114 ++++++++++++++- src/reclaim/reclaim_api.c | 43 ++++++ 5 files changed, 366 insertions(+), 9 deletions(-) diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index f8d424359..367f6fd80 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -3309,6 +3309,7 @@ extern "C" { /** * Next available: 1500 */ +#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE 1500 /** diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h index eb6c1bc9e..f839123e5 100644 --- a/src/include/gnunet_reclaim_service.h +++ b/src/include/gnunet_reclaim_service.h @@ -210,6 +210,25 @@ GNUNET_RECLAIM_attestation_delete ( const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls); + +/** + * Delete an attestation reference. Tickets used to share this reference are updated + * accordingly. + * + * @param h handle to the re:claimID service + * @param pkey Private key of the identity to delete the reference from + * @param attr The reference + * @param cont Continuation to call when done + * @param cont_cls Closure for @a cont + * @return handle Used to to abort the request + */ +struct GNUNET_RECLAIM_Operation * +GNUNET_RECLAIM_attestation_reference_delete ( + struct GNUNET_RECLAIM_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr, + GNUNET_RECLAIM_ContinuationWithStatus cont, + void *cont_cls); /** * List all attributes for a local identity. * This MUST lock the `struct GNUNET_RECLAIM_Handle` diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index aea96e61e..1f320e196 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -270,6 +270,10 @@ struct AttributeDeleteHandle */ struct GNUNET_RECLAIM_ATTESTATION_Claim *attest; + /** + * The reference to delete + */ + struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference; /** * Tickets to update */ @@ -476,6 +480,8 @@ cleanup_adh (struct AttributeDeleteHandle *adh) GNUNET_free (adh->claim); if (NULL != adh->attest) GNUNET_free (adh->attest); + if (NULL != adh->reference) + GNUNET_free (adh->reference); while (NULL != (le = adh->tickets_to_update_head)) { GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, @@ -1192,6 +1198,21 @@ ref_error (void *cls) return; } +/** + * Error looking up potential reference value. Abort. + * + * @param cls our attribute delete handle + */ +static void +ref_del_error (void *cls) +{ + struct AttributeDeleteHandle *adh = cls; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to find Attestation entry for Attestation reference\n"); + cleanup_adh (adh); + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + return; +} /** * Reference store result handler * @@ -1306,8 +1327,9 @@ reference_store_task (void *cls) { if (0 == ash->reference->id_attest) { - ash->reference->id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, - UINT64_MAX); + ash->reference->id = GNUNET_CRYPTO_random_u64 ( + GNUNET_CRYPTO_QUALITY_STRONG, + UINT64_MAX); } else { @@ -1327,7 +1349,7 @@ reference_store_task (void *cls) ash, &ref_add_cb, ash); - GNUNET_free (label); + GNUNET_free (label); } /** @@ -1338,8 +1360,8 @@ reference_store_task (void *cls) */ static int check_reference_store_message (void *cls, - const struct - AttributeStoreMessage *sam) + const struct + AttributeStoreMessage *sam) { uint16_t size; @@ -1432,14 +1454,18 @@ ticket_iter (void *cls, for (int i = 0; i < rd_count; i++) { if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) && - (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type)) + (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) && + (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF != rd[i].record_type)) continue; if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))) continue; if (0 != memcmp (rd[i].data, (&adh->attest->id), sizeof(uint64_t))) continue; + if (0 != memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t))) + continue; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Attribute or Attestation to delete found (%s)\n", + "Attribute or Attestation/Reference to delete found (%s)\n", adh->label); has_changed = GNUNET_YES; break; @@ -1535,6 +1561,9 @@ update_tickets (void *cls) if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type) && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))) continue; + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF == rd[i].record_type) + && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))) + continue; rd_new[j] = rd[i]; j++; } @@ -1782,7 +1811,158 @@ handle_attestation_delete_message (void *cls, +/** +* Reference deleted callback +* +* @param cls our handle +* @param success success status +* @param emsg error message (NULL if success=GNUNET_OK) +*/ +static void +reference_delete_cont (void *cls, int32_t success, const char *emsg) +{ + struct AttributeDeleteHandle *adh = cls; + adh->ns_qe = NULL; + if (GNUNET_SYSERR == success) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error deleting reference %s\n", + adh->label); + send_delete_response (adh, GNUNET_SYSERR); + cleanup_adh (adh); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n"); + GNUNET_SCHEDULER_add_now (&start_ticket_update, adh); +} + +static void +ref_del_cb (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + + struct AttributeDeleteHandle *adh = cls; + char *data_tmp; + struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1]; + struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref; + size_t attr_len; + + if (0 == rd_count ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to find Attestation entry for Attestation reference\n"); + cleanup_adh (adh); + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + return; + } + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Intended Reference location is not an attestation\n"); + cleanup_adh (adh); + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + return; + } + rd_new[0] = rd[0]; + int i; + int j = 1; + for (i = 1; idata_size); + ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len); + if (NULL == ref ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse attestation reference from %s\n", + data_tmp); + rd_new[j] = rd[i]; + j += 1; + continue; + } + if ((strcmp (adh->reference->name,ref->name) == 0)&& + (strcmp (adh->reference->reference_value,ref->reference_value)==0) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Found reference to delete.\n"); + } + else + { + rd_new[j] = rd[i]; + j += 1; + } + GNUNET_free (data_tmp); + } + adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, + &adh->identity, + label, + j, + rd_new, + &reference_delete_cont, + adh); +} + +/** + * Check an attestation reference delete message + * + * @param cls unused + * @param sam the message to check + */ +static int +check_reference_delete_message (void *cls, + const struct AttributeDeleteMessage *dam) +{ + uint16_t size; + + size = ntohs (dam->header.size); + if (size <= sizeof(struct AttributeDeleteMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + +/** + * Handle reference deletion + * + * @param cls our client + * @param dam deletion message + */ +static void +handle_reference_delete_message (void *cls, + const struct AttributeDeleteMessage *dam) +{ + struct AttributeDeleteHandle *adh; + struct IdpClient *idp = cls; + size_t data_len; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n"); + data_len = ntohs (dam->attr_len); + adh = GNUNET_new (struct AttributeDeleteHandle); + adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &dam[1], + data_len); + adh->r_id = ntohl (dam->id); + adh->identity = dam->identity; + adh->label + = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->id, + sizeof(uint64_t)); + GNUNET_SERVICE_client_continue (idp->client); + adh->client = idp; + GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh); + adh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, + &adh->identity, + adh->label, + &ref_del_error, + adh, + &ref_del_cb, + adh); +} @@ -2238,6 +2418,10 @@ GNUNET_SERVICE_MAIN ( GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE, struct AttributeStoreMessage, NULL), + GNUNET_MQ_hd_var_size (reference_delete_message, + GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE, + struct AttributeDeleteMessage, + NULL), GNUNET_MQ_hd_fixed_size ( iteration_start, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index b52cf9650..5066eef58 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -483,7 +483,8 @@ add_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } identity = handle->url + strlen ( - GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/") + 1; + GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/") + + 1; for (ego_entry = handle->ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) @@ -733,6 +734,102 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, handle); } +/** + * Deletes reference from an identity + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ +static void +delete_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char *url, + void *cls) +{ + struct RequestHandle *handle = cls; + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr; + struct EgoEntry *ego_entry; + char *identity; + char *identity_id_str; + char *id; + 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_ref (&attr), + GNUNET_JSON_spec_end () }; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Deleting attestation reference.\n"); + if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ( + "reference/") + 1 >= strlen ( + handle->url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + identity_id_str = strdup (handle->url + strlen ( + GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + + strlen ("reference/") + + 1); + identity = strtok (identity_id_str, "/"); + id = strtok (NULL, "/"); + + if ((NULL == identity) || (NULL == id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + 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) + { + 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); + 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 == attr) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse attestation reference from %s\n", + term_data); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + GNUNET_STRINGS_string_to_data (id, strlen (id), &attr->id, sizeof(uint64_t)); + + handle->idp = GNUNET_RECLAIM_connect (cfg); + handle->idp_op = GNUNET_RECLAIM_attestation_reference_delete (handle->idp, + priv_key, + attr, + & + delete_finished_cb, + handle); + GNUNET_JSON_parse_free (attrspec); +} + + /** * Deletes attestation from an identity * @@ -745,8 +842,21 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; struct RequestHandle *handle = cls; + /* Check for substring "reference" */ + if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen ( + handle->url)) + { + if ( strncmp ("reference", (handle->url + strlen ( + GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + + 1), strlen ( + "reference")) == 0) + { + delete_attestation_ref_cont (con_handle,url,cls); + return; + } + } + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; struct GNUNET_RECLAIM_ATTESTATION_Claim attr; struct EgoEntry *ego_entry; char *identity_id_str; diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index a6ff0237d..7c7261522 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -1163,6 +1163,49 @@ GNUNET_RECLAIM_attestation_reference_store ( return op; } +/** + * Delete an attestation reference. Tickets used to share this reference are updated + * accordingly. + * + * @param h handle to the re:claimID service + * @param pkey Private key of the identity to delete the reference from + * @param attr The reference + * @param cont Continuation to call when done + * @param cont_cls Closure for @a cont + * @return handle Used to to abort the request + */ +struct GNUNET_RECLAIM_Operation * +GNUNET_RECLAIM_attestation_reference_delete ( + struct GNUNET_RECLAIM_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr, + GNUNET_RECLAIM_ContinuationWithStatus cont, + void *cont_cls) +{ + + struct GNUNET_RECLAIM_Operation *op; + struct AttributeDeleteMessage *dam; + size_t attr_len; + + op = GNUNET_new (struct GNUNET_RECLAIM_Operation); + op->h = h; + op->as_cb = cont; + op->cls = cont_cls; + op->r_id = h->r_id_gen++; + GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); + attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr); + op->env = GNUNET_MQ_msg_extra (dam, + attr_len, + GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE); + dam->identity = *pkey; + dam->id = htonl (op->r_id); + GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &dam[1]); + + dam->attr_len = htons (attr_len); + if (NULL != h->mq) + GNUNET_MQ_send_copy (h->mq, op->env); + return op; +} /** * List all attributes for a local identity. -- 2.25.1