From 0def2d57eabbf00947ede47b0e968c0a395ace50 Mon Sep 17 00:00:00 2001 From: Markus Voggenreiter Date: Tue, 15 Oct 2019 09:32:16 +0200 Subject: [PATCH] Delete Attestation via Service --- src/include/gnunet_protocols.h | 2 + src/include/gnunet_reclaim_service.h | 19 ++++- src/reclaim/gnunet-service-reclaim.c | 114 ++++++++++++++++++++++++++- src/reclaim/plugin_rest_reclaim.c | 64 ++++++++++++++- src/reclaim/reclaim_api.c | 43 ++++++++++ 5 files changed, 234 insertions(+), 8 deletions(-) diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 8de779ad3..45b3c6728 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -2716,6 +2716,8 @@ extern "C" { #define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE 977 +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE 978 + /************************************************** * * ABD MESSAGE TYPES diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h index a9061d6e8..0f63b0c96 100644 --- a/src/include/gnunet_reclaim_service.h +++ b/src/include/gnunet_reclaim_service.h @@ -191,7 +191,24 @@ GNUNET_RECLAIM_attribute_delete ( const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls); - +/** + * Delete an attestation. Tickets used to share this attestation are updated + * accordingly. + * + * @param h handle to the re:claimID service + * @param pkey Private key of the identity to add an attribute to + * @param attr The attestation + * @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_delete ( + struct GNUNET_RECLAIM_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_RECLAIM_ATTESTATION_Claim *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 d6c93812f..7929d36d9 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -265,6 +265,11 @@ struct AttributeDeleteHandle */ struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; + /** + * The attestation to delete + */ + struct GNUNET_RECLAIM_ATTESTATION_Claim *attest; + /** * Tickets to update */ @@ -464,6 +469,8 @@ cleanup_adh (struct AttributeDeleteHandle *adh) GNUNET_free (adh->label); if (NULL != adh->claim) GNUNET_free (adh->claim); + if (NULL != adh->attest) + GNUNET_free (adh->attest); while (NULL != (le = adh->tickets_to_update_head)) { GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, @@ -1209,12 +1216,15 @@ ticket_iter (void *cls, for (int i = 0; i < rd_count; i++) { - if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) && + (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != 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; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Attribute to delete found (%s)\n", + "Attribute or Attestation to delete found (%s)\n", adh->label); has_changed = GNUNET_YES; break; @@ -1276,7 +1286,7 @@ update_tickets (void *cls) if (NULL == adh->tickets_to_update_head) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Finished updatding tickets, success\n"); + "Finished updating tickets, success\n"); send_delete_response (adh, GNUNET_OK); cleanup_adh (adh); return; @@ -1307,6 +1317,9 @@ update_tickets (void *cls) if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))) continue; + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type) + && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))) + continue; rd_new[j] = rd[i]; j++; } @@ -1466,6 +1479,97 @@ handle_attribute_delete_message (void *cls, adh); } +/** + * Attestation deleted callback + * + * @param cls our handle + * @param success success status + * @param emsg error message (NULL if success=GNUNET_OK) + */ +static void +attest_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 attestation %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); +} + +/** + * Check attestation delete message format + * + * @cls unused + * @dam message to check + */ +static int +check_attestation_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 attestation deletion + * + * @param cls our client + * @param dam deletion message + */ +static void +handle_attestation_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 ATTESTATION_DELETE message\n"); + + data_len = ntohs (dam->attr_len); + + adh = GNUNET_new (struct AttributeDeleteHandle); + adh->attest = GNUNET_RECLAIM_ATTESTATION_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->attest->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_store (nsh, + &adh->identity, + adh->label, + 0, + NULL, + &attest_delete_cont, + adh); +} + + + + + + /************************************************* * Attrubute iteration @@ -1890,6 +1994,10 @@ GNUNET_SERVICE_MAIN ( GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE, struct AttributeDeleteMessage, NULL), + GNUNET_MQ_hd_var_size (attestation_delete_message, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_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 9290925b8..b847b773c 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -546,15 +546,71 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } -/*WIP*/ +/** + * Deletes attestation from an identity + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ static void delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting Attestations not supported\n"); - GNUNET_SCHEDULER_add_now (&do_error, cls); - return; + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + struct RequestHandle *handle = cls; + struct GNUNET_RECLAIM_ATTESTATION_Claim attr; + struct EgoEntry *ego_entry; + char *identity_id_str; + char *identity; + char *id; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attestation.\n"); + 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_id_str = + strdup (handle->url + strlen ( + GNUNET_REST_API_NS_RECLAIM_ATTESTATION_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_free (identity_id_str); + 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) + { + // Done + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity); + GNUNET_free (identity_id_str); + 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); + memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)); + GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t)); + attr.name = ""; + handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp, + priv_key, + &attr, + &delete_finished_cb, + handle); + GNUNET_free (identity_id_str); } /** diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 988650450..ed07f78e1 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -972,6 +972,49 @@ GNUNET_RECLAIM_attestation_store ( return op; } +/** + * Delete an attestation. Tickets used to share this attestation are updated + * accordingly. + * + * @param h handle to the re:claimID service + * @param pkey Private key of the identity to add an attribute to + * @param attr The attestation + * @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_delete ( + struct GNUNET_RECLAIM_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_RECLAIM_ATTESTATION_Claim *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_serialize_get_size (attr); + op->env = GNUNET_MQ_msg_extra (dam, + attr_len, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE); + dam->identity = *pkey; + dam->id = htonl (op->r_id); + GNUNET_RECLAIM_ATTESTATION_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. * This MUST lock the `struct GNUNET_RECLAIM_Handle` -- 2.25.1