From 494af3383d2a5d3402e1f03209cb574af86079a8 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Sun, 14 Apr 2019 15:23:44 +0200 Subject: RECLAIM: bugfixes; add delete attribute API --- src/reclaim/gnunet-reclaim.c | 61 ++++- src/reclaim/gnunet-service-reclaim.c | 356 +++++++++++++++++++++++---- src/reclaim/gnunet-service-reclaim_tickets.c | 126 +++++----- src/reclaim/gnunet-service-reclaim_tickets.h | 37 ++- src/reclaim/reclaim.h | 54 ++-- src/reclaim/reclaim_api.c | 58 ++++- 6 files changed, 550 insertions(+), 142 deletions(-) (limited to 'src/reclaim') diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c index 1c3b4174d..a9d6f67d2 100644 --- a/src/reclaim/gnunet-reclaim.c +++ b/src/reclaim/gnunet-reclaim.c @@ -157,6 +157,16 @@ static struct GNUNET_SCHEDULER_Task *cleanup_task; */ struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; +/** + * Claim to delete + */ +static char *attr_delete; + +/** + * Claim object to delete + */ +static struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr_to_delete; + static void do_cleanup (void *cls) { @@ -177,6 +187,8 @@ do_cleanup (void *cls) GNUNET_free (abe_key); if (NULL != attr_list) GNUNET_free (attr_list); + if (NULL != attr_to_delete) + GNUNET_free (attr_to_delete); } static void @@ -208,6 +220,7 @@ process_attrs (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) { char *value_str; + char *id; const char *attr_type; if (NULL == identity) { @@ -222,8 +235,10 @@ process_attrs (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, value_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, attr->data, attr->data_size); attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type); - fprintf (stdout, "%s: %s [%s,v%u,id=%" PRIu64 "]\n", attr->name, value_str, - attr_type, attr->version, attr->id); + id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t)); + fprintf (stdout, "Name: %s; Value: %s (%s); Version %u; ID: %s\n", attr->name, + value_str, attr_type, attr->version, id); + GNUNET_free (id); } static void @@ -284,6 +299,19 @@ process_rvk (void *cls, int success, const char *msg) cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); } + +static void +process_delete (void *cls, int success, const char *msg) +{ + reclaim_op = NULL; + if (GNUNET_OK != success) { + fprintf (stderr, "Deletion failed.\n"); + ret = 1; + } + cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); +} + + static void iter_finished (void *cls) { @@ -315,6 +343,15 @@ iter_finished (void *cls) &process_rvk, NULL); return; } + if (attr_delete) { + if (NULL == attr_to_delete) { + fprintf (stdout, "No such attribute ``%s''\n", attr_delete); + return; + } + reclaim_op = GNUNET_RECLAIM_attribute_delete ( + reclaim_handle, pkey, attr_to_delete, &process_delete, NULL); + return; + } if (attr_name) { if (NULL == type_str) type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING; @@ -348,6 +385,8 @@ iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; char *attrs_tmp; char *attr_str; + char *label; + char *id; const char *attr_type; if ((NULL != attr_name) && (NULL != claim)) { @@ -373,12 +412,22 @@ iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, break; } GNUNET_free (attrs_tmp); + } else if (attr_delete && (NULL == attr_to_delete)) { + label = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t)); + if (0 == strcasecmp (attr_delete, label)) { + attr_to_delete = GNUNET_RECLAIM_ATTRIBUTE_claim_new ( + attr->name, attr->type, attr->data, attr->data_size); + attr_to_delete->id = attr->id; + } + GNUNET_free (label); } else if (list) { attr_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, attr->data, attr->data_size); attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type); - fprintf (stdout, "%s: %s [%s,v%u,id=%" PRIu64 "]\n", attr->name, attr_str, - attr_type, attr->version, attr->id); + id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t)); + fprintf (stdout, "Name: %s; Value: %s (%s); Version %u; ID: %s\n", + attr->name, attr_str, attr_type, attr->version, id); + GNUNET_free (id); } GNUNET_RECLAIM_get_attributes_next (attr_iterator); } @@ -474,7 +523,9 @@ main (int argc, char *const argv[]) GNUNET_GETOPT_option_string ('a', "add", "NAME", gettext_noop ("Add an attribute NAME"), &attr_name), - + GNUNET_GETOPT_option_string ('d', "delete", "ID", + gettext_noop ("Add an attribute with ID"), + &attr_delete), GNUNET_GETOPT_option_string ('V', "value", "VALUE", gettext_noop ("The attribute VALUE"), &attr_value), diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index 2bb4f5a74..5deb482e9 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -34,7 +34,7 @@ #include "gnunet_namestore_service.h" #include "gnunet_protocols.h" #include "gnunet_reclaim_attribute_lib.h" -#include "gnunet_reclaim_plugin.h" +#include "gnunet_reclaim_service.h" #include "gnunet_signatures.h" #include "reclaim.h" @@ -63,16 +63,6 @@ */ static struct GNUNET_IDENTITY_Handle *identity_handle; -/** - * Database handle - */ -static struct GNUNET_RECLAIM_PluginFunctions *TKT_database; - -/** - * Name of DB plugin - */ -static char *db_lib_name; - /** * Token expiration interval */ @@ -106,7 +96,8 @@ struct IdpClient; /** * A ticket iteration operation. */ -struct TicketIteration { +struct TicketIteration +{ /** * DLL */ @@ -136,7 +127,8 @@ struct TicketIteration { /** * An attribute iteration operation. */ -struct AttributeIterator { +struct AttributeIterator +{ /** * Next element in the DLL */ @@ -171,7 +163,8 @@ struct AttributeIterator { /** * An idp client */ -struct IdpClient { +struct IdpClient +{ /** * The client @@ -246,9 +239,80 @@ struct IdpClient { * Tail of DLL of attribute store ops */ struct AttributeStoreHandle *store_op_tail; + /** + * Head of DLL of attribute delete ops + */ + struct AttributeDeleteHandle *delete_op_head; + + /** + * Tail of DLL of attribute delete ops + */ + struct AttributeDeleteHandle *delete_op_tail; +}; + + +struct AttributeDeleteHandle +{ + /** + * DLL + */ + struct AttributeDeleteHandle *next; + + /** + * DLL + */ + struct AttributeDeleteHandle *prev; + + /** + * Client connection + */ + struct IdpClient *client; + + /** + * Identity + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + + + /** + * QueueEntry + */ + struct GNUNET_NAMESTORE_QueueEntry *ns_qe; + + /** + * Iterator + */ + struct GNUNET_NAMESTORE_ZoneIterator *ns_it; + + /** + * The attribute to delete + */ + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; + + /** + * Tickets to update + */ + struct TicketRecordsEntry *tickets_to_update_head; + + /** + * Tickets to update + */ + struct TicketRecordsEntry *tickets_to_update_tail; + + /** + * Attribute label + */ + char *label; + + /** + * request id + */ + uint32_t r_id; }; -struct AttributeStoreHandle { + +struct AttributeStoreHandle +{ /** * DLL */ @@ -295,7 +359,8 @@ struct AttributeStoreHandle { uint32_t r_id; }; -struct ConsumeTicketOperation { +struct ConsumeTicketOperation +{ /** * DLL */ @@ -325,7 +390,8 @@ struct ConsumeTicketOperation { /** * Updated attribute IDs */ -struct TicketAttributeUpdateEntry { +struct TicketAttributeUpdateEntry +{ /** * DLL */ @@ -350,7 +416,8 @@ struct TicketAttributeUpdateEntry { /** * Ticket revocation request handle */ -struct TicketRevocationOperation { +struct TicketRevocationOperation +{ /** * DLL */ @@ -380,7 +447,8 @@ struct TicketRevocationOperation { /** * Ticket issue operation handle */ -struct TicketIssueOperation { +struct TicketIssueOperation +{ /** * DLL */ @@ -407,7 +475,8 @@ struct TicketIssueOperation { * map in json_t format * */ -struct EgoEntry { +struct EgoEntry +{ /** * DLL */ @@ -438,9 +507,6 @@ cleanup () GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); RECLAIM_TICKETS_deinit (); - GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, TKT_database)); - GNUNET_free (db_lib_name); - db_lib_name = NULL; if (NULL != timeout_task) GNUNET_SCHEDULER_cancel (timeout_task); if (NULL != update_task) @@ -673,7 +739,7 @@ attr_store_cont (void *cls, int32_t success, const char *emsg) { struct AttributeStoreHandle *ash = cls; struct GNUNET_MQ_Envelope *env; - struct AttributeStoreResultMessage *acr_msg; + struct SuccessResultMessage *acr_msg; ash->ns_qe = NULL; GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head, @@ -687,10 +753,8 @@ attr_store_cont (void *cls, int32_t success, const char *emsg) return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending ATTRIBUTE_STORE_RESPONSE message\n"); - env = GNUNET_MQ_msg (acr_msg, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n"); + env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE); acr_msg->id = htonl (ash->r_id); acr_msg->op_result = htonl (GNUNET_OK); GNUNET_MQ_send (ash->client->mq, env); @@ -771,6 +835,220 @@ handle_attribute_store_message (void *cls, GNUNET_SCHEDULER_add_now (&attr_store_task, ash); } + +static void +cleanup_adh (struct AttributeDeleteHandle *adh) +{ + struct TicketRecordsEntry *le; + if (NULL != adh->ns_it) + GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it); + if (NULL != adh->ns_qe) + GNUNET_NAMESTORE_cancel (adh->ns_qe); + if (NULL != adh->label) + GNUNET_free (adh->label); + if (NULL != adh->claim) + GNUNET_free (adh->claim); + while (NULL != (le = adh->tickets_to_update_head)) { + GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, + adh->tickets_to_update_tail, le); + if (NULL != le->label) + GNUNET_free (le->label); + if (NULL != le->data) + GNUNET_free (le->data); + GNUNET_free (le); + } + GNUNET_free (adh); +} + + +static void +send_delete_response (struct AttributeDeleteHandle *adh, int32_t success) +{ + struct GNUNET_MQ_Envelope *env; + struct SuccessResultMessage *acr_msg; + + GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head, + adh->client->delete_op_tail, adh); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n"); + env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE); + acr_msg->id = htonl (adh->r_id); + acr_msg->op_result = htonl (success); + GNUNET_MQ_send (adh->client->mq, env); +} + + +static void +ticket_iter (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; + struct TicketRecordsEntry *le; + int has_changed = GNUNET_NO; + + for (int i = 0; i < rd_count; i++) { + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) + continue; + if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t))) + continue; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute to delete found (%s)\n", + adh->label); + has_changed = GNUNET_YES; + break; + } + if (GNUNET_YES == has_changed) { + le = GNUNET_new (struct TicketRecordsEntry); + le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd); + le->data = GNUNET_malloc (le->data_size); + le->rd_count = rd_count; + le->label = GNUNET_strdup (label); + GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data); + GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head, + adh->tickets_to_update_tail, le); + } + GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1); +} + + +static void +update_tickets (void *cls); + + +static void +ticket_updated (void *cls, int32_t success, const char *emsg) +{ + struct AttributeDeleteHandle *adh = cls; + adh->ns_qe = NULL; + GNUNET_SCHEDULER_add_now (&update_tickets, adh); +} + +static void +update_tickets (void *cls) +{ + struct AttributeDeleteHandle *adh = cls; + struct TicketRecordsEntry *le; + if (NULL == adh->tickets_to_update_head) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Finished updatding tickets, success\n"); + send_delete_response (adh, GNUNET_OK); + cleanup_adh (adh); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating %s\n", + adh->tickets_to_update_head->label); + le = adh->tickets_to_update_head; + GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, + adh->tickets_to_update_tail, le); + struct GNUNET_GNSRECORD_Data rd[le->rd_count]; + struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1]; + GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count, + rd); + int j = 0; + for (int i = 0; i < le->rd_count; i++) { + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) && + (0 == memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t)))) + continue; + rd_new[j] = rd[i]; + j++; + } + adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &adh->identity, le->label, + j, rd_new, &ticket_updated, adh); + GNUNET_free (le->label); + GNUNET_free (le->data); + GNUNET_free (le); +} + + +static void +ticket_iter_fin (void *cls) +{ + struct AttributeDeleteHandle *adh = cls; + adh->ns_it = NULL; + GNUNET_SCHEDULER_add_now (&update_tickets, adh); +} + + +static void +ticket_iter_err (void *cls) +{ + struct AttributeDeleteHandle *adh = cls; + adh->ns_it = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Namestore error on delete %s\n", + adh->label); + send_delete_response (adh, GNUNET_SYSERR); + cleanup_adh (adh); +} + + +static void +start_ticket_update (void *cls) +{ + struct AttributeDeleteHandle *adh = cls; + adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start ( + nsh, &adh->identity, &ticket_iter_err, adh, &ticket_iter, adh, + &ticket_iter_fin, adh); +} + + +static void +attr_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 attribute %s (%s)\n", + adh->claim->name, adh->label); + send_delete_response (adh, GNUNET_SYSERR); + cleanup_adh (adh); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating tickets...\n"); + GNUNET_SCHEDULER_add_now (&start_ticket_update, adh); +} + + +static int +check_attribute_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; +} + + +static void +handle_attribute_delete_message (void *cls, + const struct AttributeDeleteMessage *dam) +{ + struct AttributeDeleteHandle *adh; + struct IdpClient *idp = cls; + size_t data_len; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received ATTRIBUTE_DELETE message\n"); + + data_len = ntohs (dam->attr_len); + + adh = GNUNET_new (struct AttributeDeleteHandle); + adh->claim = GNUNET_RECLAIM_ATTRIBUTE_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->claim->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, &attr_delete_cont, adh); +} + + /************************************************* * Attrubute iteration *************************************************/ @@ -1013,7 +1291,6 @@ static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *server) { - char *database; cfg = c; if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) { @@ -1030,19 +1307,6 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, } identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL); - /* Loading DB plugin */ - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string ( - cfg, "reclaim", "database", &database)) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n"); - GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_reclaim_%s", database); - TKT_database = GNUNET_PLUGIN_load (db_lib_name, (void *)cfg); - GNUNET_free (database); - if (NULL == TKT_database) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not load database backend `%s'\n", db_lib_name); - GNUNET_SCHEDULER_shutdown (); - return; - } if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time ( cfg, "reclaim", "TOKEN_EXPIRATION_INTERVAL", @@ -1075,6 +1339,7 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct TicketIssueOperation *iss; struct ConsumeTicketOperation *ct; struct AttributeStoreHandle *as; + struct AttributeDeleteHandle *adh; // TODO other operations @@ -1095,6 +1360,10 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as); cleanup_as_handle (as); } + while (NULL != (adh = idp->delete_op_head)) { + GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh); + cleanup_adh (adh); + } while (NULL != (ai = idp->attr_iter_head)) { GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai); @@ -1143,6 +1412,9 @@ GNUNET_SERVICE_MAIN ( GNUNET_MQ_hd_var_size (attribute_store_message, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE, struct AttributeStoreMessage, NULL), + GNUNET_MQ_hd_var_size (attribute_delete_message, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE, + struct AttributeDeleteMessage, NULL), GNUNET_MQ_hd_fixed_size ( iteration_start, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, struct AttributeIterationStartMessage, NULL), diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c index 549ea8c34..1cdd4268d 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/reclaim/gnunet-service-reclaim_tickets.c @@ -30,6 +30,34 @@ struct ParallelLookup; + +/** + * A reference to a ticket stored in GNS + */ +struct TicketReference +{ + /** + * DLL + */ + struct TicketReference *next; + + /** + * DLL + */ + struct TicketReference *prev; + + /** + * Attributes + */ + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; + + /** + * Tickets + */ + struct GNUNET_RECLAIM_Ticket ticket; +}; + + struct RECLAIM_TICKETS_ConsumeHandle { /** @@ -115,33 +143,6 @@ struct ParallelLookup }; -/** - * A reference to a ticket stored in GNS - */ -struct TicketReference -{ - /** - * DLL - */ - struct TicketReference *next; - - /** - * DLL - */ - struct TicketReference *prev; - - /** - * Attributes - */ - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; - - /** - * Tickets - */ - struct GNUNET_RECLAIM_Ticket ticket; -}; - - /** * Ticket issue request handle */ @@ -224,39 +225,6 @@ struct RevokedAttributeEntry }; -struct TicketRecordsEntry -{ - /** - * DLL - */ - struct TicketRecordsEntry *next; - - /** - * DLL - */ - struct TicketRecordsEntry *prev; - - /** - * Record count - */ - unsigned int rd_count; - - /** - * Data - */ - char *data; - - /** - * Data size - */ - size_t data_size; - - /** - * Label - */ - char *label; -}; - /** * Ticket revocation request handle */ @@ -414,8 +382,11 @@ rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_GNSRECORD_Data *rd) { struct RECLAIM_TICKETS_RevokeHandle *rvk = cls; + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; + struct GNUNET_GNSRECORD_Data new_rd; struct RevokedAttributeEntry *le; char *new_label; + char *attr_data; rvk->ns_qe = NULL; if (0 == rd_count) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -430,12 +401,24 @@ rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, /** find a new place for this attribute **/ rvk->move_attr->new_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); + new_rd = *rd; + claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Attribute to update: Name=%s, ID=%" PRIu64 "\n", claim->name, + claim->id); + claim->id = rvk->move_attr->new_id; + new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim); + attr_data = GNUNET_malloc (rd->data_size); + new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data); + new_rd.data = attr_data; new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof (uint64_t)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label); - rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, new_label, - 1, rd, &move_attr_finished, rvk); + rvk->ns_qe = GNUNET_NAMESTORE_records_store ( + nsh, &rvk->identity, new_label, 1, &new_rd, &move_attr_finished, rvk); GNUNET_free (new_label); + GNUNET_free (claim); + GNUNET_free (attr_data); } @@ -703,7 +686,7 @@ process_parallel_lookup_result (void *cls, uint32_t rd_count, struct ParallelLookup *parallel_lookup = cls; struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle; struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Parallel lookup finished (count=%u)\n", rd_count); GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head, @@ -777,8 +760,10 @@ lookup_authz_cb (void *cls, uint32_t rd_count, GNUNET_YES); for (int i = 0; i < rd_count; i++) { + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) + continue; lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute ref found %s\n", lbl); parallel_lookup = GNUNET_new (struct ParallelLookup); parallel_lookup->handle = cth; parallel_lookup->label = lbl; @@ -790,9 +775,14 @@ lookup_authz_cb (void *cls, uint32_t rd_count, GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head, cth->parallel_lookups_tail, parallel_lookup); } - cth->kill_task = GNUNET_SCHEDULER_add_delayed ( - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3), - &abort_parallel_lookups, cth); + if (NULL != cth->parallel_lookups_head) { + cth->kill_task = GNUNET_SCHEDULER_add_delayed ( + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3), + &abort_parallel_lookups, cth); + return; + } + cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL); + cleanup_cth (cth); } @@ -813,7 +803,7 @@ RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id, cth->cb_cls = cb_cls; label = GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for AuthZ info under %s\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for AuthZ info under %s\n", label); cth->lookup_start_time = GNUNET_TIME_absolute_get (); cth->lookup_request = GNUNET_GNS_lookup ( diff --git a/src/reclaim/gnunet-service-reclaim_tickets.h b/src/reclaim/gnunet-service-reclaim_tickets.h index d2b614c46..6e704243d 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.h +++ b/src/reclaim/gnunet-service-reclaim_tickets.h @@ -38,7 +38,7 @@ #include "gnunet_namestore_service.h" #include "gnunet_protocols.h" #include "gnunet_reclaim_attribute_lib.h" -#include "gnunet_reclaim_plugin.h" +#include "gnunet_reclaim_service.h" #include "gnunet_signatures.h" #include "gnunet_statistics_service.h" #include "reclaim.h" @@ -47,6 +47,41 @@ struct RECLAIM_TICKETS_Iterator; struct RECLAIM_TICKETS_ConsumeHandle; struct RECLAIM_TICKETS_RevokeHandle; + +struct TicketRecordsEntry +{ + /** + * DLL + */ + struct TicketRecordsEntry *next; + + /** + * DLL + */ + struct TicketRecordsEntry *prev; + + /** + * Record count + */ + unsigned int rd_count; + + /** + * Data + */ + char *data; + + /** + * Data size + */ + size_t data_size; + + /** + * Label + */ + char *label; +}; + + /** * Continuation called with ticket. * diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h index c29902ab1..982cd8ae4 100644 --- a/src/reclaim/reclaim.h +++ b/src/reclaim/reclaim.h @@ -33,6 +33,7 @@ GNUNET_NETWORK_STRUCT_BEGIN + /** * Use to store an identity attribute */ @@ -64,13 +65,42 @@ struct AttributeStoreMessage struct GNUNET_CRYPTO_EcdsaPrivateKey identity; /* followed by the serialized attribute */ +}; + + +/** + * Use to delete an identity attribute + */ +struct AttributeDeleteMessage +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this request (for key collisions). + */ + uint32_t id GNUNET_PACKED; + + /** + * The length of the attribute + */ + uint32_t attr_len GNUNET_PACKED; + + /** + * Identity + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + /* followed by the serialized attribute */ }; + /** - * Attribute store response message + * Attribute store/delete response message */ -struct AttributeStoreResultMessage +struct SuccessResultMessage { /** * Message header @@ -86,7 +116,6 @@ struct AttributeStoreResultMessage * #GNUNET_SYSERR on failure, #GNUNET_OK on success */ int32_t op_result GNUNET_PACKED; - }; /** @@ -99,7 +128,7 @@ struct AttributeResultMessage */ struct GNUNET_MessageHeader header; - /** + /** * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; @@ -144,7 +173,6 @@ struct AttributeIterationStartMessage * Identity. */ struct GNUNET_CRYPTO_EcdsaPrivateKey identity; - }; @@ -162,7 +190,6 @@ struct AttributeIterationNextMessage * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; - }; @@ -180,7 +207,6 @@ struct AttributeIterationStopMessage * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; - }; /** @@ -202,7 +228,6 @@ struct TicketIterationStartMessage * Identity. */ struct GNUNET_CRYPTO_EcdsaPrivateKey identity; - }; @@ -220,7 +245,6 @@ struct TicketIterationNextMessage * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; - }; @@ -238,11 +262,9 @@ struct TicketIterationStopMessage * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; - }; - /** * Ticket issue message */ @@ -273,7 +295,7 @@ struct IssueTicketMessage */ uint32_t attr_len GNUNET_PACKED; - //Followed by a serialized attribute list + // Followed by a serialized attribute list }; /** @@ -301,7 +323,7 @@ struct RevokeTicketMessage */ uint32_t attrs_len GNUNET_PACKED; - //Followed by a ticket and serialized attribute list + // Followed by a ticket and serialized attribute list }; /** @@ -340,7 +362,6 @@ struct TicketResultMessage * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; - }; /** @@ -363,7 +384,7 @@ struct ConsumeTicketMessage */ struct GNUNET_CRYPTO_EcdsaPrivateKey identity; - //Followed by a serialized ticket + // Followed by a serialized ticket }; /** @@ -376,7 +397,7 @@ struct ConsumeTicketResultMessage */ struct GNUNET_MessageHeader header; - /** + /** * Unique identifier for this request (for key collisions). */ uint32_t id GNUNET_PACKED; @@ -407,7 +428,6 @@ struct ConsumeTicketResultMessage }; - GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 0edae76c2..e0ca9adf3 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -407,14 +407,13 @@ mq_error_handler (void *cls, enum GNUNET_MQ_Error error) /** * Handle an incoming message of type - * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE + * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE * * @param cls * @param msg the message we received */ static void -handle_attribute_store_response (void *cls, - const struct AttributeStoreResultMessage *msg) +handle_success_response (void *cls, const struct SuccessResultMessage *msg) { struct GNUNET_RECLAIM_Handle *h = cls; struct GNUNET_RECLAIM_Operation *op; @@ -429,8 +428,8 @@ handle_attribute_store_response (void *cls, return; res = ntohl (msg->op_result); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received ATTRIBUTE_STORE_RESPONSE with result %d\n", res); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Received SUCCESS_RESPONSE with result %d\n", + res); /* TODO: add actual error message to response... */ if (GNUNET_SYSERR == res) @@ -735,10 +734,9 @@ static void reconnect (struct GNUNET_RECLAIM_Handle *h) { struct GNUNET_MQ_MessageHandler handlers[] = { - GNUNET_MQ_hd_fixed_size ( - attribute_store_response, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE, - struct AttributeStoreResultMessage, h), + GNUNET_MQ_hd_fixed_size (success_response, + GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE, + struct SuccessResultMessage, h), GNUNET_MQ_hd_var_size (attribute_result, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT, struct AttributeResultMessage, h), @@ -873,6 +871,48 @@ GNUNET_RECLAIM_attribute_store ( } +/** + * Delete an attribute. Tickets used to share this attribute 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 attribute + * @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_attribute_delete ( + struct GNUNET_RECLAIM_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_RECLAIM_ATTRIBUTE_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_ATTRIBUTE_serialize_get_size (attr); + op->env = GNUNET_MQ_msg_extra (dam, attr_len, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE); + dam->identity = *pkey; + dam->id = htonl (op->r_id); + GNUNET_RECLAIM_ATTRIBUTE_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` -- cgit v1.2.3