X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Freclaim%2Fgnunet-service-reclaim.c;h=a83ea05a645f94d3a5fffc38fbda1652c190d553;hb=a140ff725af20d55f80463969a415bbd85ff63bc;hp=c8ae8a2385958011f4886ba198504ca9f8241c39;hpb=7a923f1b2d38d55ca921abb57980ccfd1340f634;p=oweals%2Fgnunet.git diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index c8ae8a238..a83ea05a6 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -16,7 +16,7 @@ along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later - */ + */ /** * @author Martin Schanzenbach * @file src/reclaim/gnunet-service-reclaim.c @@ -25,56 +25,15 @@ */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet-service-reclaim_tickets.h" #include "gnunet_constants.h" -#include "gnunet_protocols.h" -#include "gnunet_identity_service.h" #include "gnunet_gnsrecord_lib.h" -#include "gnunet_namestore_service.h" -#include "gnunet_reclaim_plugin.h" +#include "gnunet_protocols.h" #include "gnunet_reclaim_attribute_lib.h" +#include "gnunet_reclaim_service.h" #include "gnunet_signatures.h" -#include "gnunet-service-reclaim_tickets.h" #include "reclaim.h" -/** - * First pass state - */ -#define STATE_INIT 0 - -/** - * Normal operation state - */ -#define STATE_POST_INIT 1 - -/** - * Minimum interval between updates - */ -#define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES - -/** - * Standard token expiration time - */ -#define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS - -/** - * Identity handle - */ -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 - */ -static struct GNUNET_TIME_Relative token_expiration_interval; /** * Namestore handle @@ -86,12 +45,6 @@ static struct GNUNET_NAMESTORE_Handle *nsh; */ static struct GNUNET_SCHEDULER_Task *timeout_task; -/** - * Update task - */ -static struct GNUNET_SCHEDULER_Task *update_task; - - /** * Our configuration. */ @@ -168,16 +121,23 @@ struct AttributeIterator * The operation id fot the zone iteration in the response for the client */ uint32_t request_id; - }; - /** * An idp client */ struct IdpClient { + /** + * DLL + */ + struct IdpClient *prev; + + /** + * DLL + */ + struct IdpClient *next; /** * The client @@ -216,12 +176,12 @@ struct IdpClient /** * Head of DLL of ticket revocation ops */ - struct TicketRevocationHandle *revoke_op_head; + struct TicketRevocationOperation *revoke_op_head; /** * Tail of DLL of ticket revocation ops */ - struct TicketRevocationHandle *revoke_op_tail; + struct TicketRevocationOperation *revoke_op_tail; /** * Head of DLL of ticket issue ops @@ -252,20 +212,32 @@ 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 AttributeStoreHandle + +/** + * Handle for attribute deletion request + */ +struct AttributeDeleteHandle { /** * DLL */ - struct AttributeStoreHandle *next; + struct AttributeDeleteHandle *next; /** * DLL */ - struct AttributeStoreHandle *prev; + struct AttributeDeleteHandle *prev; /** * Client connection @@ -277,10 +249,6 @@ struct AttributeStoreHandle */ struct GNUNET_CRYPTO_EcdsaPrivateKey identity; - /** - * Identity pubkey - */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey; /** * QueueEntry @@ -288,14 +256,29 @@ struct AttributeStoreHandle struct GNUNET_NAMESTORE_QueueEntry *ns_qe; /** - * The attribute to store + * Iterator + */ + struct GNUNET_NAMESTORE_ZoneIterator *ns_it; + + /** + * The attribute to delete */ struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; /** - * The attribute expiration interval + * Tickets to update */ - struct GNUNET_TIME_Relative exp; + struct TicketRecordsEntry *tickets_to_update_head; + + /** + * Tickets to update + */ + struct TicketRecordsEntry *tickets_to_update_tail; + + /** + * Attribute label + */ + char *label; /** * request id @@ -304,17 +287,20 @@ struct AttributeStoreHandle }; -struct ConsumeTicketOperation +/** + * Handle for attribute store request + */ +struct AttributeStoreHandle { /** * DLL */ - struct ConsumeTicketOperation *next; + struct AttributeStoreHandle *next; /** * DLL */ - struct ConsumeTicketOperation *prev; + struct AttributeStoreHandle *prev; /** * Client connection @@ -322,67 +308,51 @@ struct ConsumeTicketOperation struct IdpClient *client; /** - * request id + * Identity */ - uint32_t r_id; + struct GNUNET_CRYPTO_EcdsaPrivateKey identity; /** - * Ticket consume handle + * Identity pubkey */ - struct RECLAIM_TICKETS_ConsumeHandle *ch; -}; - + struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey; -/** - * Updated attribute IDs - */ -struct TicketAttributeUpdateEntry -{ /** - * DLL + * QueueEntry */ - struct TicketAttributeUpdateEntry *next; + struct GNUNET_NAMESTORE_QueueEntry *ns_qe; /** - * DLL + * The attribute to store */ - struct TicketAttributeUpdateEntry *prev; + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; /** - * The old ID + * The attribute expiration interval */ - uint64_t old_id; + struct GNUNET_TIME_Relative exp; /** - * The new ID + * request id */ - uint64_t new_id; + uint32_t r_id; }; + /** - * Ticket revocation request handle + * Handle for ticket consume request */ -struct TicketRevocationHandle +struct ConsumeTicketOperation { /** * DLL */ - struct TicketRevocationHandle *prev; + struct ConsumeTicketOperation *next; /** * DLL */ - struct TicketRevocationHandle *next; - - /** - * Attribute updates - */ - struct TicketAttributeUpdateEntry *attr_updates_head; - - /** - * Attribute updates - */ - struct TicketAttributeUpdateEntry *attr_updates_tail; + struct ConsumeTicketOperation *prev; /** * Client connection @@ -390,39 +360,41 @@ struct TicketRevocationHandle struct IdpClient *client; /** - * Attributes to reissue + * request id */ - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; + uint32_t r_id; /** - * Attributes to revoke + * Ticket consume handle */ - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *rvk_attrs; + struct RECLAIM_TICKETS_ConsumeHandle *ch; +}; - /** - * Issuer Key - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; +/** + * Ticket revocation request handle + */ +struct TicketRevocationOperation +{ /** - * Ticket to issue + * DLL */ - struct GNUNET_RECLAIM_Ticket ticket; + struct TicketRevocationOperation *prev; /** - * QueueEntry + * DLL */ - struct GNUNET_NAMESTORE_QueueEntry *ns_qe; + struct TicketRevocationOperation *next; /** - * Namestore iterator + * Client connection */ - struct GNUNET_NAMESTORE_ZoneIterator *ns_it; + struct IdpClient *client; /** - * Offset + * Revocation handle */ - uint32_t offset; + struct RECLAIM_TICKETS_RevokeHandle *rh; /** * request id @@ -431,7 +403,6 @@ struct TicketRevocationHandle }; - /** * Ticket issue operation handle */ @@ -460,58 +431,156 @@ struct TicketIssueOperation /** - * DLL for ego handles to egos containing the RECLAIM_ATTRS in a - * map in json_t format + * Client list + */ +static struct IdpClient *client_list_head = NULL; + +/** + * Client list + */ +static struct IdpClient *client_list_tail = NULL; + + +/** + * Cleanup attribute delete handle * + * @param adh the attribute to cleanup */ -struct EgoEntry +static void +cleanup_adh (struct AttributeDeleteHandle *adh) { - /** - * DLL - */ - struct EgoEntry *next; + 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); +} - /** - * DLL - */ - struct EgoEntry *prev; - /** - * Ego handle - */ - struct GNUNET_IDENTITY_Ego *ego; +/** + * Cleanup attribute store handle + * + * @param handle handle to clean up + */ +static void +cleanup_as_handle (struct AttributeStoreHandle *ash) +{ + if (NULL != ash->ns_qe) + GNUNET_NAMESTORE_cancel (ash->ns_qe); + if (NULL != ash->claim) + GNUNET_free (ash->claim); + GNUNET_free (ash); +} - /** - * Attribute map. Contains the attributes as json_t - */ - struct GNUNET_CONTAINER_MultiHashMap *attr_map; -}; +/** + * Cleanup client + * + * @param idp the client to clean up + */ +static void +cleanup_client (struct IdpClient *idp) +{ + struct AttributeIterator *ai; + struct TicketIteration *ti; + struct TicketRevocationOperation *rop; + struct TicketIssueOperation *iss; + struct ConsumeTicketOperation *ct; + struct AttributeStoreHandle *as; + struct AttributeDeleteHandle *adh; + + while (NULL != (iss = idp->issue_op_head)) + { + GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss); + GNUNET_free (iss); + } + while (NULL != (ct = idp->consume_op_head)) + { + GNUNET_CONTAINER_DLL_remove (idp->consume_op_head, + idp->consume_op_tail, + ct); + if (NULL != ct->ch) + RECLAIM_TICKETS_consume_cancel (ct->ch); + GNUNET_free (ct); + } + while (NULL != (as = idp->store_op_head)) + { + 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); + GNUNET_free (ai); + } + while (NULL != (rop = idp->revoke_op_head)) + { + GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop); + if (NULL != rop->rh) + RECLAIM_TICKETS_revoke_cancel (rop->rh); + GNUNET_free (rop); + } + while (NULL != (ti = idp->ticket_iter_head)) + { + GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head, + idp->ticket_iter_tail, + ti); + if (NULL != ti->iter) + RECLAIM_TICKETS_iteration_stop (ti->iter); + GNUNET_free (ti); + } + GNUNET_free (idp); +} + /** * Cleanup task */ static void -cleanup() +cleanup () { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cleaning up\n"); + struct IdpClient *cl; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); + + while (NULL != (cl = client_list_head)) + { + GNUNET_CONTAINER_DLL_remove (client_list_head, + client_list_tail, + cl); + cleanup_client (cl); + } 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) - GNUNET_SCHEDULER_cancel (update_task); - if (NULL != identity_handle) - GNUNET_IDENTITY_disconnect (identity_handle); if (NULL != nsh) GNUNET_NAMESTORE_disconnect (nsh); } + /** * Shutdown task * @@ -520,36 +589,19 @@ cleanup() static void do_shutdown (void *cls) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Shutting down...\n"); - cleanup(); -} - - -static int -create_sym_key_from_ecdh (const struct GNUNET_HashCode *new_key_hash, - struct GNUNET_CRYPTO_SymmetricSessionKey *skey, - struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) -{ - struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; - - GNUNET_CRYPTO_hash_to_enc (new_key_hash, - &new_key_hash_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); - static const char ctx_key[] = "gnuid-aes-ctx-key"; - GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), - new_key_hash, sizeof (struct GNUNET_HashCode), - ctx_key, strlen (ctx_key), - NULL, 0); - static const char ctx_iv[] = "gnuid-aes-ctx-iv"; - GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), - new_key_hash, sizeof (struct GNUNET_HashCode), - ctx_iv, strlen (ctx_iv), - NULL, 0); - return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); + cleanup (); } +/** + * Sends a ticket result message to the client + * + * @param client the client to send to + * @param r_id the request message ID to reply to + * @param ticket the ticket to include (may be NULL) + * @param success the success status of the request + */ static void send_ticket_result (const struct IdpClient *client, uint32_t r_id, @@ -558,66 +610,68 @@ send_ticket_result (const struct IdpClient *client, { struct TicketResultMessage *irm; struct GNUNET_MQ_Envelope *env; - struct GNUNET_RECLAIM_Ticket *ticket_buf; + env = GNUNET_MQ_msg (irm, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); if (NULL != ticket) { - env = GNUNET_MQ_msg_extra (irm, - sizeof (struct GNUNET_RECLAIM_Ticket), - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); - ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1]; - *ticket_buf = *ticket; - } else { - env = GNUNET_MQ_msg (irm, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); + irm->ticket = *ticket; } - //TODO add success member + // TODO add success member irm->id = htonl (r_id); - GNUNET_MQ_send (client->mq, - env); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n"); + GNUNET_MQ_send (client->mq, env); } +/** + * Issue ticket result + * + * @param cls out ticket issue operation handle + * @param ticket the issued ticket + * @param success issue success status (GNUNET_OK if successful) + * @param emsg error message (NULL of success is GNUNET_OK) + */ static void issue_ticket_result_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket, - uint32_t success, - const char* emsg) + int32_t success, + const char *emsg) { struct TicketIssueOperation *tio = cls; + if (GNUNET_OK != success) { - send_ticket_result (tio->client, - tio->r_id, - NULL, - GNUNET_SYSERR); + send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR); GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head, tio->client->issue_op_tail, tio); GNUNET_free (tio); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error issuing ticket: %s\n", - emsg); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg); return; } - send_ticket_result (tio->client, - tio->r_id, - ticket, - GNUNET_SYSERR); + send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR); GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head, tio->client->issue_op_tail, tio); GNUNET_free (tio); } + +/** + * Check issue ticket message + * + * @cls unused + * @im message to check + * @return GNUNET_OK if message is ok + */ static int -check_issue_ticket_message (void *cls, - const struct IssueTicketMessage *im) +check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im) { uint16_t size; size = ntohs (im->header.size); - if (size <= sizeof (struct IssueTicketMessage)) + if (size <= sizeof(struct IssueTicketMessage)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -625,23 +679,29 @@ check_issue_ticket_message (void *cls, return GNUNET_OK; } + +/** + * Handle ticket issue message + * + * @param cls our client + * @param im the message + */ static void -handle_issue_ticket_message (void *cls, - const struct IssueTicketMessage *im) +handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im) { struct TicketIssueOperation *tio; struct IdpClient *idp = cls; struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; size_t attrs_len; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n"); tio = GNUNET_new (struct TicketIssueOperation); attrs_len = ntohs (im->attr_len); - attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len); + attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &im[1], + attrs_len); tio->r_id = ntohl (im->id); tio->client = idp; - GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, - idp->issue_op_tail, - tio); + GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio); RECLAIM_TICKETS_issue (&im->identity, attrs, &im->rp, @@ -651,505 +711,52 @@ handle_issue_ticket_message (void *cls, GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs); } + /********************************************************** - * Revocation - **********************************************************/ +* Revocation +**********************************************************/ /** - * Cleanup revoke handle + * Handles revocation result * - * @param rh the ticket revocation handle + * @param cls our revocation operation handle + * @param success revocation result (GNUNET_OK if successful) */ static void -cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh) +revoke_result_cb (void *cls, int32_t success) { - if (NULL != rh->attrs) - GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs); - if (NULL != rh->rvk_attrs) - GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs); - if (NULL != rh->ns_qe) - GNUNET_NAMESTORE_cancel (rh->ns_qe); - if (NULL != rh->ns_it) - GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it); - GNUNET_free (rh); + struct TicketRevocationOperation *rop = cls; + struct GNUNET_MQ_Envelope *env; + struct RevokeTicketResultMessage *trm; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending REVOKE_TICKET_RESULT message\n"); + rop->rh = NULL; + env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT); + trm->id = htonl (rop->r_id); + trm->success = htonl (success); + GNUNET_MQ_send (rop->client->mq, env); + GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head, + rop->client->revoke_op_tail, + rop); + GNUNET_free (rop); } + +/** + * Check revocation message format + * + * @param cls unused + * @param im the message to check + * @return GNUNET_OK if message is ok + */ static int -serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, - struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, - char **result) -{ - struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; - struct GNUNET_CRYPTO_SymmetricSessionKey skey; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - struct GNUNET_HashCode new_key_hash; - ssize_t enc_size; - char *enc_keyinfo; - char *buf; - char *write_ptr; - char attrs_str_len; - char* label; - - GNUNET_assert (NULL != attrs->list_head); - attrs_str_len = 0; - for (le = attrs->list_head; NULL != le; le = le->next) { - attrs_str_len += 15 + 1; //TODO propery calculate - } - buf = GNUNET_malloc (attrs_str_len); - write_ptr = buf; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Writing attributes\n"); - for (le = attrs->list_head; NULL != le; le = le->next) { - label = GNUNET_STRINGS_data_to_string_alloc (&le->claim->id, - sizeof (uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Adding attribute to record: %s\n", label); - - GNUNET_memcpy (write_ptr, - label, - strlen (label)); - write_ptr[strlen (label)] = ','; - write_ptr += strlen (label) + 1; - GNUNET_free (label); - } - write_ptr--; - write_ptr[0] = '\0'; //replace last , with a 0-terminator - // ECDH keypair E = eG - *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create(); - GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, - &ecdh_pubkey); - enc_keyinfo = GNUNET_malloc (attrs_str_len); - // Derived key K = H(eB) - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, - &ticket->audience, - &new_key_hash)); - create_sym_key_from_ecdh (&new_key_hash, &skey, &iv); - enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf, - attrs_str_len, - &skey, &iv, - enc_keyinfo); - *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+ - enc_size); - GNUNET_memcpy (*result, - &ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), - enc_keyinfo, - enc_size); - GNUNET_free (enc_keyinfo); - GNUNET_free (buf); - return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size; -} - - -/** - * Send revocation result - * - * @param rh ticket revocation handle - * @param success GNUNET_OK if successful result - */ -static void -send_revocation_finished (struct TicketRevocationHandle *rh, - uint32_t success) -{ - struct GNUNET_MQ_Envelope *env; - struct RevokeTicketResultMessage *trm; - - GNUNET_break(TKT_database->delete_ticket (TKT_database->cls, - &rh->ticket)); - - env = GNUNET_MQ_msg (trm, - GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT); - trm->id = htonl (rh->r_id); - trm->success = htonl (success); - GNUNET_MQ_send (rh->client->mq, - env); - GNUNET_CONTAINER_DLL_remove (rh->client->revoke_op_head, - rh->client->revoke_op_tail, - rh); -} - - -/** - * Process ticket from database - * - * @param cls struct TicketIterationProcResult - * @param ticket the ticket - * @param attrs the attributes - */ -static void -ticket_reissue_proc (void *cls, - const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs); - -static void -revocation_reissue_tickets (struct TicketRevocationHandle *rh); - - -static void reissue_next (void *cls) -{ - struct TicketRevocationHandle *rh = cls; - revocation_reissue_tickets (rh); -} - - -static void -reissue_ticket_cont (void *cls, - int32_t success, - const char *emsg) -{ - struct TicketRevocationHandle *rh = cls; - - rh->ns_qe = NULL; - if (GNUNET_SYSERR == success) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", - "Unknown Error\n"); - send_revocation_finished (rh, GNUNET_SYSERR); - cleanup_revoke_ticket_handle (rh); - return; - } - rh->offset++; - GNUNET_SCHEDULER_add_now (&reissue_next, rh); -} - - -/** - * Process ticket from database - * - * @param cls struct TicketIterationProcResult - * @param ticket the ticket - * @param attrs the attributes - */ -static void -ticket_reissue_proc (void *cls, - const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) -{ - struct TicketRevocationHandle *rh = cls; - struct TicketAttributeUpdateEntry *tue; - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; - struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; - struct GNUNET_GNSRECORD_Data code_record[1]; - int reissue_ticket; - size_t authz_record_len; - char *authz_record_data; - char *label; - - - if (NULL == ticket) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Iteration done\n"); - return; - } - - if (0 == memcmp (&ticket->audience, - &rh->ticket.audience, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Do not reissue for this identity.!\n"); - label = GNUNET_STRINGS_data_to_string_alloc (&rh->ticket.rnd, - sizeof (uint64_t)); - //Delete record - rh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, - &rh->identity, - label, - 0, - NULL, - &reissue_ticket_cont, - rh); - - GNUNET_free (label); - return; - } - - /* - * Check if any attribute of this ticket intersects with a rollover attribute - */ - reissue_ticket = GNUNET_NO; - for (le = attrs->list_head; NULL != le; le = le->next) - { - for (tue = rh->attr_updates_head; - NULL != tue; - tue = tue->next) - { - if (tue->old_id == le->claim->id) - { - reissue_ticket = GNUNET_YES; - le->claim->id = tue->new_id; - } - } - } - - if (GNUNET_NO == reissue_ticket) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Skipping ticket.\n"); - - rh->offset++; - GNUNET_SCHEDULER_add_now (&reissue_next, rh); - return; - } - - //Create new ABE key for RP - - /* If this is the RP we want to revoke attributes of, the do so */ - - //TODO rename function - authz_record_len = serialize_authz_record (ticket, - attrs, - &ecdhe_privkey, - &authz_record_data); - code_record[0].data = authz_record_data; - code_record[0].data_size = authz_record_len; - code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; - code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ; - code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; - - label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, - sizeof (uint64_t)); - //Publish record - rh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, - &rh->identity, - label, - 1, - code_record, - &reissue_ticket_cont, - rh); - GNUNET_free (ecdhe_privkey); - GNUNET_free (label); - GNUNET_free (authz_record_data); -} - - -/* Prototype for below function */ -static void -attr_reenc_cont (void *cls, - int32_t success, - const char *emsg); - -static void -revocation_reissue_tickets (struct TicketRevocationHandle *rh) -{ - int ret; - /* Done, issue new keys */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Revocation Phase III: Reissuing Tickets\n"); - if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls, - &rh->ticket.identity, - GNUNET_NO, - rh->offset, - &ticket_reissue_proc, - rh))) - { - GNUNET_break (0); - } - if (GNUNET_NO == ret) - { - send_revocation_finished (rh, GNUNET_OK); - cleanup_revoke_ticket_handle (rh); - return; - } -} - -/** - * Failed to check for attribute - */ -static void -check_attr_error (void *cls) -{ - struct TicketRevocationHandle *rh = cls; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to check for existing attribute\n"); - rh->ns_qe = NULL; - send_revocation_finished (rh, GNUNET_SYSERR); - cleanup_revoke_ticket_handle (rh); -} - - -/** - * Revoke next attribte by reencryption with - * new ABE master - */ -static void -reenc_next_attribute (void *cls); - -/** - * Check for existing attribute and overwrite - */ -static void -check_attr_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd_old) -{ - struct TicketRevocationHandle *rh = cls; - struct TicketAttributeUpdateEntry *tue; - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; - struct GNUNET_GNSRECORD_Data rd[1]; - char* buf; - size_t buf_size; - char* new_label; - - rh->ns_qe = NULL; - if (1 != rd_count) { - le = rh->attrs->list_head; - GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, - rh->attrs->list_tail, - le); - GNUNET_assert (NULL != rh->rvk_attrs); - GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head, - rh->rvk_attrs->list_tail, - le); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Re-encrypting next attribute\n"); - GNUNET_SCHEDULER_add_now (&reenc_next_attribute, - rh); - return; - } - - buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim); - buf = GNUNET_malloc (buf_size); - rh->attrs->list_head->claim->version++; - GNUNET_RECLAIM_ATTRIBUTE_serialize (rh->attrs->list_head->claim, - buf); - tue = GNUNET_new (struct TicketAttributeUpdateEntry); - tue->old_id = rh->attrs->list_head->claim->id; - tue->new_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, - UINT64_MAX); - GNUNET_CONTAINER_DLL_insert (rh->attr_updates_head, - rh->attr_updates_tail, - tue); - rh->attrs->list_head->claim->id = tue->new_id; - new_label = GNUNET_STRINGS_data_to_string_alloc (&tue->new_id, - sizeof (uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "New attr id %s\n", new_label); - rd[0].data_size = buf_size; - rd[0].data = buf; - rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR; - rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; - rd[0].expiration_time = rd_old[0].expiration_time; - rh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, - &rh->identity, - new_label, - 1, - rd, - &attr_reenc_cont, - rh); -} - - -/** - * Revoke next attribte by reencryption with - * new ABE master - */ -static void -reenc_next_attribute (void *cls) -{ - struct TicketRevocationHandle *rh = cls; - char *label; - if (NULL == rh->attrs->list_head) - { - revocation_reissue_tickets (rh); - return; - } - /* First check if attribute still exists */ - label = GNUNET_STRINGS_data_to_string_alloc (&rh->attrs->list_head->claim->id, - sizeof (uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ID: %lu\n", rh->attrs->list_head->claim->id); - rh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, - &rh->identity, - label, - &check_attr_error, - rh, - &check_attr_cb, - rh); - GNUNET_free (label); -} - - -/** - * Namestore callback after revoked attribute - * is stored - */ -static void -attr_reenc_cont (void *cls, - int32_t success, - const char *emsg) -{ - struct TicketRevocationHandle *rh = cls; - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; - - rh->ns_qe = NULL; - if (GNUNET_SYSERR == success) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to reencrypt attribute %s\n", - emsg); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; - } - if (NULL == rh->attrs->list_head) - { - revocation_reissue_tickets (rh); - return; - } - le = rh->attrs->list_head; - GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, - rh->attrs->list_tail, - le); - GNUNET_assert (NULL != rh->rvk_attrs); - GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head, - rh->rvk_attrs->list_tail, - le); - - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Re-encrypting next attribute\n"); - reenc_next_attribute (rh); -} - - -static void -process_attributes_to_update (void *cls, - const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) -{ - struct TicketRevocationHandle *rh = cls; - - rh->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Revocation Phase I: Collecting attributes\n"); - /* Reencrypt all attributes with new key */ - if (NULL == rh->attrs->list_head) - { - /* No attributes to reencrypt */ - send_revocation_finished (rh, GNUNET_OK); - cleanup_revoke_ticket_handle (rh); - return; - } else { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Revocation Phase II: Re-encrypting attributes\n"); - reenc_next_attribute (rh); - } - -} - - -static int -check_revoke_ticket_message(void *cls, - const struct RevokeTicketMessage *im) +check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im) { uint16_t size; size = ntohs (im->header.size); - if (size <= sizeof (struct RevokeTicketMessage)) + if (size != sizeof(struct RevokeTicketMessage)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -1157,57 +764,45 @@ check_revoke_ticket_message(void *cls, return GNUNET_OK; } + +/** + * Handle a revocation message to a ticket. + * + * @param cls our client + * @param rm the message to handle + */ static void -handle_revoke_ticket_message (void *cls, - const struct RevokeTicketMessage *rm) +handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm) { - struct TicketRevocationHandle *rh; + struct TicketRevocationOperation *rop; struct IdpClient *idp = cls; - struct GNUNET_RECLAIM_Ticket *ticket; - - rh = GNUNET_new (struct TicketRevocationHandle); - ticket = (struct GNUNET_RECLAIM_Ticket*)&rm[1]; - rh->rvk_attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); - rh->ticket = *ticket; - rh->r_id = ntohl (rm->id); - rh->client = idp; - rh->identity = rm->identity; - GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity, - &rh->ticket.identity); - GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, - idp->revoke_op_tail, - rh); - /** - * TODO replace with GNS storage - */ - TKT_database->get_ticket_attributes (TKT_database->cls, - &rh->ticket, - &process_attributes_to_update, - rh); - GNUNET_SERVICE_client_continue (idp->client); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n"); + rop = GNUNET_new (struct TicketRevocationOperation); + rop->r_id = ntohl (rm->id); + rop->client = idp; + GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop); + rop->rh + = RECLAIM_TICKETS_revoke (&rm->ticket, &rm->identity, &revoke_result_cb, + rop); + GNUNET_SERVICE_client_continue (idp->client); } -static int -check_consume_ticket_message (void *cls, - const struct ConsumeTicketMessage *cm) -{ - uint16_t size; - - size = ntohs (cm->header.size); - if (size <= sizeof (struct ConsumeTicketMessage)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} +/** + * Handle a ticket consume result + * + * @param cls our consume ticket operation handle + * @param identity the attribute authority + * @param attrs the attribute/claim list + * @param success GNUNET_OK if successful + * @param emsg error message (NULL if success=GNUNET_OK) + */ static void consume_result_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, - uint32_t success, + int32_t success, const char *emsg) { struct ConsumeTicketOperation *cop = cls; @@ -1215,13 +810,14 @@ consume_result_cb (void *cls, struct GNUNET_MQ_Envelope *env; char *data_tmp; size_t attrs_len; + if (GNUNET_OK != success) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error consuming ticket: %s\n", - emsg); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg); } attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending CONSUME_TICKET_RESULT message\n"); env = GNUNET_MQ_msg_extra (crm, attrs_len, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT); @@ -1230,65 +826,78 @@ consume_result_cb (void *cls, crm->identity = *identity; crm->result = htonl (success); data_tmp = (char *) &crm[1]; - GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, - data_tmp); + GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, data_tmp); GNUNET_MQ_send (cop->client->mq, env); GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head, cop->client->consume_op_tail, cop); GNUNET_free (cop); +} + +/** + * Check a consume ticket message + * + * @param cls unused + * @param cm the message to handle + */ +static int +check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm) +{ + uint16_t size; + + size = ntohs (cm->header.size); + if (size != sizeof(struct ConsumeTicketMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; } + +/** + * Handle a consume ticket message + * + * @param cls our client handle + * @cm the message to handle + */ static void -handle_consume_ticket_message (void *cls, - const struct ConsumeTicketMessage *cm) +handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm) { struct ConsumeTicketOperation *cop; - struct GNUNET_RECLAIM_Ticket *ticket; struct IdpClient *idp = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n"); cop = GNUNET_new (struct ConsumeTicketOperation); cop->r_id = ntohl (cm->id); cop->client = idp; - ticket = (struct GNUNET_RECLAIM_Ticket*)&cm[1]; - cop->ch = RECLAIM_TICKETS_consume (&cm->identity, - ticket, - &consume_result_cb, - cop); - GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, - idp->consume_op_tail, + cop->ch + = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb, cop); + GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop); GNUNET_SERVICE_client_continue (idp->client); } + /***************************************** - * Attribute store - *****************************************/ +* Attribute store +*****************************************/ + /** - * Cleanup attribute store handle + * Attribute store result handler * - * @param handle handle to clean up + * @param cls our attribute store handle + * @param success GNUNET_OK if successful + * @param emsg error message (NULL if success=GNUNET_OK) */ static void -cleanup_as_handle (struct AttributeStoreHandle *ash) -{ - if (NULL != ash->ns_qe) - GNUNET_NAMESTORE_cancel (ash->ns_qe); - if (NULL != ash->claim) - GNUNET_free (ash->claim); - GNUNET_free (ash); -} - -static void -attr_store_cont (void *cls, - int32_t success, - const char *emsg) +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, @@ -1305,19 +914,17 @@ attr_store_cont (void *cls, 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); + GNUNET_MQ_send (ash->client->mq, env); cleanup_as_handle (ash); } + /** - * Adds a new attribute + * Add a new attribute * * @param cls the AttributeStoreHandle */ @@ -1326,23 +933,21 @@ attr_store_task (void *cls) { struct AttributeStoreHandle *ash = cls; struct GNUNET_GNSRECORD_Data rd[1]; - char* buf; - char* label; + char *buf; + char *label; size_t buf_size; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Storing attribute\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n"); buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (ash->claim); buf = GNUNET_malloc (buf_size); - //Give the ash a new id - ash->claim->id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, - UINT64_MAX); - GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, - buf); - label = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id, - sizeof (uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Encrypting with label %s\n", label); + // Give the ash a new id if unset + if (0 == ash->claim->id) + ash->claim->id + = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); + GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, buf); + label + = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->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; @@ -1357,17 +962,24 @@ attr_store_task (void *cls) &attr_store_cont, ash); GNUNET_free (buf); + GNUNET_free (label); } +/** + * Check an attribute store message + * + * @param cls unused + * @param sam the message to check + */ static int -check_attribute_store_message(void *cls, - const struct AttributeStoreMessage *sam) +check_attribute_store_message (void *cls, + const struct AttributeStoreMessage *sam) { uint16_t size; size = ntohs (sam->header.size); - if (size <= sizeof (struct AttributeStoreMessage)) + if (size <= sizeof(struct AttributeStoreMessage)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -1376,6 +988,12 @@ check_attribute_store_message(void *cls, } +/** + * Handle an attribute store message + * + * @param cls our client + * @param sam the message to handle + */ static void handle_attribute_store_message (void *cls, const struct AttributeStoreMessage *sam) @@ -1383,52 +1001,342 @@ handle_attribute_store_message (void *cls, struct AttributeStoreHandle *ash; struct IdpClient *idp = cls; size_t data_len; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received ATTRIBUTE_STORE message\n"); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n"); data_len = ntohs (sam->attr_len); ash = GNUNET_new (struct AttributeStoreHandle); - ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&sam[1], + ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &sam[1], data_len); ash->r_id = ntohl (sam->id); ash->identity = sam->identity; ash->exp.rel_value_us = GNUNET_ntohll (sam->exp); - GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, - &ash->identity_pkey); + GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey); GNUNET_SERVICE_client_continue (idp->client); ash->client = idp; - GNUNET_CONTAINER_DLL_insert (idp->store_op_head, - idp->store_op_tail, - ash); + GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash); GNUNET_SCHEDULER_add_now (&attr_store_task, ash); } -/************************************************* - * Attrubute iteration - *************************************************/ +/** + * Send a deletion success response + * + * @param adh our attribute deletion handle + * @param success the success status + */ static void -cleanup_attribute_iter_handle (struct AttributeIterator *ai) +send_delete_response (struct AttributeDeleteHandle *adh, int32_t success) { - GNUNET_free (ai); + 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); } + +/** + * Namestore iteration within attribute deletion. + * We need to reissue tickets with the deleted attribute removed. + * + * @param cls our attribute deletion handle + * @param zone the private key of the ticket issuer + * @param label the label of the record + * @param rd_count number of records + * @param rd record data + */ static void -attr_iter_error (void *cls) +ticket_iter (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) { - struct AttributeIterator *ai = cls; + 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); +} + + +/** + * Recursion prototype for function + * @param cls our deletion handle + */ +static void +update_tickets (void *cls); + + +/** + * Callback called when a ticket was updated + * + * @param cls our attribute deletion handle + * @param success GNUNET_OK if successful + * @param emsg error message (NULL if success=GNUNET_OK) + */ +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); +} + + +/** + * Update tickets: Remove shared attribute which has just been deleted. + * This method is called recursively until all tickets are processed. + * Eventually, the updated tickets are stored using ``update_tickets''. + * + * @param cls our attribute deletion handle + */ +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, - "Failed to iterate over attributes\n"); - GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head, - ai->client->attr_iter_tail, - ai); - cleanup_attribute_iter_handle (ai); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + "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]; + if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size, + le->data, + le->rd_count, + rd)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to deserialize record data!\n"); + send_delete_response (adh, GNUNET_SYSERR); + cleanup_adh (adh); + return; + } + 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); +} + + +/** + * Done collecting affected tickets, start updating. + * + * @param cls our attribute deletion handle + */ +static void +ticket_iter_fin (void *cls) +{ + struct AttributeDeleteHandle *adh = cls; + + adh->ns_it = NULL; + GNUNET_SCHEDULER_add_now (&update_tickets, adh); } + +/** + * Error collecting affected tickets. Abort. + * + * @param cls our attribute deletion handle + */ +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); +} + + +/** + * Start processing tickets which may still contain reference to deleted + * attribute. + * + * @param cls attribute deletion handle + */ +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); +} + + +/** + * Attribute deleted callback + * + * @param cls our handle + * @param success success status + * @param emsg error message (NULL if success=GNUNET_OK) + */ +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\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 attribute delete message format + * + * @cls unused + * @dam message to check + */ +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; +} + + +/** + * Handle attribute deletion + * + * @param cls our client + * @param dam deletion message + */ +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_DEBUG, "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 +*************************************************/ + + +/** + * Done iterating over attributes + * + * @param cls our iterator handle + */ static void attr_iter_finished (void *cls) { @@ -1436,17 +1344,42 @@ attr_iter_finished (void *cls) struct GNUNET_MQ_Envelope *env; struct AttributeResultMessage *arm; - env = GNUNET_MQ_msg (arm, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n"); + env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); arm->id = htonl (ai->request_id); arm->attr_len = htons (0); GNUNET_MQ_send (ai->client->mq, env); GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head, ai->client->attr_iter_tail, ai); - cleanup_attribute_iter_handle (ai); + GNUNET_free (ai); } + +/** + * Error iterating over attributes. Abort. + * + * @param cls our attribute iteration handle + */ +static void +attr_iter_error (void *cls) +{ + struct AttributeIterator *ai = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n"); + attr_iter_finished (ai); +} + + +/** + * Got record. Return if it is an attribute. + * + * @param cls our attribute iterator + * @param zone zone we are iterating + * @param label label of the records + * @param rd_count record count + * @param rd records + */ static void attr_iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, @@ -1457,38 +1390,39 @@ attr_iter_cb (void *cls, struct AttributeIterator *ai = cls; struct AttributeResultMessage *arm; struct GNUNET_MQ_Envelope *env; - char* data_tmp; + char *data_tmp; if (rd_count != 1) { - GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, - 1); + GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); return; } if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type) { - GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, - 1); + 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, "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); + GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); data_tmp = (char *) &arm[1]; - GNUNET_memcpy (data_tmp, - rd->data, - rd->data_size); + GNUNET_memcpy (data_tmp, rd->data, rd->data_size); GNUNET_MQ_send (ai->client->mq, env); } +/** + * Iterate over zone to get attributes + * + * @param cls our client + * @param ais_msg the iteration message to start + */ static void handle_iteration_start (void *cls, const struct AttributeIterationStartMessage *ais_msg) @@ -1503,9 +1437,7 @@ handle_iteration_start (void *cls, ai->client = idp; ai->identity = ais_msg->identity; - GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, - idp->attr_iter_tail, - ai); + GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai); ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh, &ai->identity, &attr_iter_error, @@ -1518,6 +1450,12 @@ handle_iteration_start (void *cls, } +/** + * Handle iteration stop message from client + * + * @param cls the client + * @param ais_msg the stop message + */ static void handle_iteration_stop (void *cls, const struct AttributeIterationStopMessage *ais_msg) @@ -1539,14 +1477,18 @@ handle_iteration_stop (void *cls, GNUNET_SERVICE_client_drop (idp->client); return; } - GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, - idp->attr_iter_tail, - ai); + GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai); GNUNET_free (ai); GNUNET_SERVICE_client_continue (idp->client); } +/** + * Client requests next attribute from iterator + * + * @param cls the client + * @param ais_msg the message + */ static void handle_iteration_next (void *cls, const struct AttributeIterationNextMessage *ais_msg) @@ -1567,46 +1509,58 @@ handle_iteration_next (void *cls, GNUNET_SERVICE_client_drop (idp->client); return; } - GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, - 1); + GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); GNUNET_SERVICE_client_continue (idp->client); } + /****************************************************** - * Ticket iteration - ******************************************************/ +* Ticket iteration +******************************************************/ +/** + * Got a ticket. Return to client + * + * @param cls our ticket iterator + * @param ticket the ticket + */ static void -ticket_iter_cb (void *cls, - struct GNUNET_RECLAIM_Ticket *ticket) +ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket) { struct TicketIteration *ti = cls; struct GNUNET_MQ_Envelope *env; struct TicketResultMessage *trm; + env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); if (NULL == ticket) { /* send empty response to indicate end of list */ - env = GNUNET_MQ_msg (trm, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head, ti->client->ticket_iter_tail, ti); - } else { - env = GNUNET_MQ_msg_extra (trm, - sizeof (struct GNUNET_RECLAIM_Ticket), - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); + } + else + { + trm->ticket = *ticket; } trm->id = htonl (ti->r_id); - GNUNET_MQ_send (ti->client->mq, - env); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n"); + GNUNET_MQ_send (ti->client->mq, env); if (NULL == ticket) GNUNET_free (ti); } + +/** + * Client requests a ticket iteration + * + * @param cls the client + * @param tis_msg the iteration request message + */ static void -handle_ticket_iteration_start (void *cls, - const struct TicketIterationStartMessage *tis_msg) +handle_ticket_iteration_start ( + void *cls, + const struct TicketIterationStartMessage *tis_msg) { struct IdpClient *client = cls; struct TicketIteration *ti; @@ -1620,13 +1574,18 @@ handle_ticket_iteration_start (void *cls, GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head, client->ticket_iter_tail, ti); - ti->iter = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, - &ticket_iter_cb, - ti); + ti->iter + = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti); GNUNET_SERVICE_client_continue (client->client); } +/** + * Client has had enough tickets + * + * @param cls the client + * @param tis_msg the stop message + */ static void handle_ticket_iteration_stop (void *cls, const struct TicketIterationStopMessage *tis_msg) @@ -1657,6 +1616,12 @@ handle_ticket_iteration_stop (void *cls, } +/** + * Client requests next result. + * + * @param cls the client + * @param tis_msg the message + */ static void handle_ticket_iteration_next (void *cls, const struct TicketIterationNextMessage *tis_msg) @@ -1682,8 +1647,6 @@ handle_ticket_iteration_next (void *cls, } - - /** * Main function that will be run * @@ -1696,67 +1659,27 @@ 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)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to initialized TICKETS subsystem.\n"); + "Unable to initialize TICKETS subsystem.\n"); GNUNET_SCHEDULER_shutdown (); return; } - //Connect to identity and namestore services + // Connect to identity and namestore services nsh = GNUNET_NAMESTORE_connect (cfg); if (NULL == nsh) { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore"); - } - - 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", - &token_expiration_interval)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Time window for zone iteration: %s\n", - GNUNET_STRINGS_relative_time_to_string (token_expiration_interval, - GNUNET_YES)); - } else { - token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL; + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "error connecting to namestore"); } GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); } + /** * Called whenever a client is disconnected. * @@ -1770,65 +1693,12 @@ client_disconnect_cb (void *cls, void *app_ctx) { struct IdpClient *idp = app_ctx; - struct AttributeIterator *ai; - struct TicketIteration *ti; - struct TicketRevocationHandle *rh; - struct TicketIssueOperation *iss; - struct ConsumeTicketOperation *ct; - struct AttributeStoreHandle *as; - - //TODO other operations - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client %p disconnected\n", - client); - - while (NULL != (iss = idp->issue_op_head)) - { - GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, - idp->issue_op_tail, - iss); - GNUNET_free (iss); - } - while (NULL != (ct = idp->consume_op_head)) - { - GNUNET_CONTAINER_DLL_remove (idp->consume_op_head, - idp->consume_op_tail, - ct); - if (NULL != ct->ch) - RECLAIM_TICKETS_consume_cancel (ct->ch); - GNUNET_free (ct); - } - while (NULL != (as = idp->store_op_head)) - { - GNUNET_CONTAINER_DLL_remove (idp->store_op_head, - idp->store_op_tail, - as); - cleanup_as_handle (as); - } - while (NULL != (ai = idp->attr_iter_head)) - { - GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, - idp->attr_iter_tail, - ai); - cleanup_attribute_iter_handle (ai); - } - while (NULL != (rh = idp->revoke_op_head)) - { - GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, - idp->revoke_op_tail, - rh); - cleanup_revoke_ticket_handle (rh); - } - while (NULL != (ti = idp->ticket_iter_head)) - { - GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head, - idp->ticket_iter_tail, - ti); - GNUNET_free (ti); - } - GNUNET_free (idp); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); + GNUNET_CONTAINER_DLL_remove (client_list_head, + client_list_tail, + idp); + cleanup_client (idp); } @@ -1846,66 +1716,72 @@ client_connect_cb (void *cls, struct GNUNET_MQ_Handle *mq) { struct IdpClient *idp; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client %p connected\n", - client); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client); idp = GNUNET_new (struct IdpClient); idp->client = client; idp->mq = mq; + GNUNET_CONTAINER_DLL_insert (client_list_head, + client_list_tail, + idp); return idp; } - /** * Define "main" method using service macro. */ -GNUNET_SERVICE_MAIN -("reclaim", - GNUNET_SERVICE_OPTION_NONE, - &run, - &client_connect_cb, - &client_disconnect_cb, - NULL, - GNUNET_MQ_hd_var_size (attribute_store_message, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE, - struct AttributeStoreMessage, - NULL), - GNUNET_MQ_hd_fixed_size (iteration_start, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, - struct AttributeIterationStartMessage, - NULL), - GNUNET_MQ_hd_fixed_size (iteration_next, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT, - struct AttributeIterationNextMessage, - NULL), - GNUNET_MQ_hd_fixed_size (iteration_stop, - GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP, - struct AttributeIterationStopMessage, - NULL), - GNUNET_MQ_hd_var_size (issue_ticket_message, - GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET, - struct IssueTicketMessage, - NULL), - GNUNET_MQ_hd_var_size (consume_ticket_message, - GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET, - struct ConsumeTicketMessage, - NULL), - GNUNET_MQ_hd_fixed_size (ticket_iteration_start, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START, - struct TicketIterationStartMessage, - NULL), - GNUNET_MQ_hd_fixed_size (ticket_iteration_next, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT, - struct TicketIterationNextMessage, - NULL), - GNUNET_MQ_hd_fixed_size (ticket_iteration_stop, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP, - struct TicketIterationStopMessage, - NULL), - GNUNET_MQ_hd_var_size (revoke_ticket_message, - GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET, - struct RevokeTicketMessage, - NULL), - GNUNET_MQ_handler_end()); +GNUNET_SERVICE_MAIN ( + "reclaim", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + 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), + GNUNET_MQ_hd_fixed_size (iteration_next, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT, + struct AttributeIterationNextMessage, + NULL), + GNUNET_MQ_hd_fixed_size (iteration_stop, + GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP, + struct AttributeIterationStopMessage, + NULL), + GNUNET_MQ_hd_var_size (issue_ticket_message, + GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET, + struct IssueTicketMessage, + NULL), + GNUNET_MQ_hd_var_size (consume_ticket_message, + GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET, + struct ConsumeTicketMessage, + NULL), + GNUNET_MQ_hd_fixed_size (ticket_iteration_start, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START, + struct TicketIterationStartMessage, + NULL), + GNUNET_MQ_hd_fixed_size (ticket_iteration_next, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT, + struct TicketIterationNextMessage, + NULL), + GNUNET_MQ_hd_fixed_size (ticket_iteration_stop, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP, + struct TicketIterationStopMessage, + NULL), + GNUNET_MQ_hd_var_size (revoke_ticket_message, + GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET, + struct RevokeTicketMessage, + NULL), + GNUNET_MQ_handler_end ()); /* end of gnunet-service-reclaim.c */