2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @author Martin Schanzenbach
22 * @file src/reclaim/gnunet-service-reclaim.c
23 * @brief reclaim Service
27 #include "gnunet_util_lib.h"
28 #include "gnunet-service-reclaim_tickets.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_gnsrecord_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_reclaim_attribute_lib.h"
33 #include "gnunet_reclaim_service.h"
34 #include "gnunet_signatures.h"
41 static struct GNUNET_NAMESTORE_Handle *nsh;
46 static struct GNUNET_SCHEDULER_Task *timeout_task;
51 static const struct GNUNET_CONFIGURATION_Handle *cfg;
59 * A ticket iteration operation.
61 struct TicketIteration
66 struct TicketIteration *next;
71 struct TicketIteration *prev;
74 * Client which intiated this zone iteration
76 struct IdpClient *client;
79 * The operation id fot the iteration in the response for the client
86 struct RECLAIM_TICKETS_Iterator *iter;
91 * An attribute iteration operation.
93 struct AttributeIterator
96 * Next element in the DLL
98 struct AttributeIterator *next;
101 * Previous element in the DLL
103 struct AttributeIterator *prev;
106 * IDP client which intiated this zone iteration
108 struct IdpClient *client;
111 * Key of the zone we are iterating over.
113 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
118 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
121 * The operation id fot the zone iteration in the response for the client
135 struct IdpClient *prev;
140 struct IdpClient *next;
145 struct GNUNET_SERVICE_Client *client;
148 * Message queue for transmission to @e client
150 struct GNUNET_MQ_Handle *mq;
154 * Attribute iteration operations in
155 * progress initiated by this client
157 struct AttributeIterator *attr_iter_head;
161 * Attribute iteration operations
162 * in progress initiated by this client
164 struct AttributeIterator *attr_iter_tail;
167 * Head of DLL of ticket iteration ops
169 struct TicketIteration *ticket_iter_head;
172 * Tail of DLL of ticket iteration ops
174 struct TicketIteration *ticket_iter_tail;
177 * Head of DLL of ticket revocation ops
179 struct TicketRevocationOperation *revoke_op_head;
182 * Tail of DLL of ticket revocation ops
184 struct TicketRevocationOperation *revoke_op_tail;
187 * Head of DLL of ticket issue ops
189 struct TicketIssueOperation *issue_op_head;
192 * Tail of DLL of ticket issue ops
194 struct TicketIssueOperation *issue_op_tail;
197 * Head of DLL of ticket consume ops
199 struct ConsumeTicketOperation *consume_op_head;
202 * Tail of DLL of ticket consume ops
204 struct ConsumeTicketOperation *consume_op_tail;
207 * Head of DLL of attribute store ops
209 struct AttributeStoreHandle *store_op_head;
212 * Tail of DLL of attribute store ops
214 struct AttributeStoreHandle *store_op_tail;
216 * Head of DLL of attribute delete ops
218 struct AttributeDeleteHandle *delete_op_head;
221 * Tail of DLL of attribute delete ops
223 struct AttributeDeleteHandle *delete_op_tail;
228 * Handle for attribute deletion request
230 struct AttributeDeleteHandle
235 struct AttributeDeleteHandle *next;
240 struct AttributeDeleteHandle *prev;
245 struct IdpClient *client;
250 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
256 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
261 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
264 * The attribute to delete
266 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
269 * The attestation to delete
271 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
274 * The reference to delete
276 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
280 struct TicketRecordsEntry *tickets_to_update_head;
285 struct TicketRecordsEntry *tickets_to_update_tail;
300 * Handle for attribute store request
302 struct AttributeStoreHandle
307 struct AttributeStoreHandle *next;
312 struct AttributeStoreHandle *prev;
317 struct IdpClient *client;
322 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
327 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
332 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
335 * The attribute to store
337 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
340 * The attestation to store
342 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
345 * The reference to store
347 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
350 * The attribute expiration interval
352 struct GNUNET_TIME_Relative exp;
362 * Handle for ticket consume request
364 struct ConsumeTicketOperation
369 struct ConsumeTicketOperation *next;
374 struct ConsumeTicketOperation *prev;
379 struct IdpClient *client;
387 * Ticket consume handle
389 struct RECLAIM_TICKETS_ConsumeHandle *ch;
394 * Ticket revocation request handle
396 struct TicketRevocationOperation
401 struct TicketRevocationOperation *prev;
406 struct TicketRevocationOperation *next;
411 struct IdpClient *client;
416 struct RECLAIM_TICKETS_RevokeHandle *rh;
426 * Ticket issue operation handle
428 struct TicketIssueOperation
433 struct TicketIssueOperation *prev;
438 struct TicketIssueOperation *next;
443 struct IdpClient *client;
455 static struct IdpClient *client_list_head = NULL;
460 static struct IdpClient *client_list_tail = NULL;
464 * Cleanup attribute delete handle
466 * @param adh the attribute to cleanup
469 cleanup_adh (struct AttributeDeleteHandle *adh)
471 struct TicketRecordsEntry *le;
473 if (NULL != adh->ns_it)
474 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
475 if (NULL != adh->ns_qe)
476 GNUNET_NAMESTORE_cancel (adh->ns_qe);
477 if (NULL != adh->label)
478 GNUNET_free (adh->label);
479 if (NULL != adh->claim)
480 GNUNET_free (adh->claim);
481 if (NULL != adh->attest)
482 GNUNET_free (adh->attest);
483 if (NULL != adh->reference)
484 GNUNET_free (adh->reference);
485 while (NULL != (le = adh->tickets_to_update_head))
487 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
488 adh->tickets_to_update_tail,
490 if (NULL != le->label)
491 GNUNET_free (le->label);
492 if (NULL != le->data)
493 GNUNET_free (le->data);
501 * Cleanup attribute store handle
503 * @param handle handle to clean up
506 cleanup_as_handle (struct AttributeStoreHandle *ash)
508 if (NULL != ash->ns_qe)
509 GNUNET_NAMESTORE_cancel (ash->ns_qe);
510 if (NULL != ash->claim)
511 GNUNET_free (ash->claim);
512 if (NULL != ash->attest)
513 GNUNET_free (ash->attest);
514 if (NULL != ash->reference)
515 GNUNET_free (ash->reference);
523 * @param idp the client to clean up
526 cleanup_client (struct IdpClient *idp)
528 struct AttributeIterator *ai;
529 struct TicketIteration *ti;
530 struct TicketRevocationOperation *rop;
531 struct TicketIssueOperation *iss;
532 struct ConsumeTicketOperation *ct;
533 struct AttributeStoreHandle *as;
534 struct AttributeDeleteHandle *adh;
536 while (NULL != (iss = idp->issue_op_head))
538 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
541 while (NULL != (ct = idp->consume_op_head))
543 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
544 idp->consume_op_tail,
547 RECLAIM_TICKETS_consume_cancel (ct->ch);
550 while (NULL != (as = idp->store_op_head))
552 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
553 cleanup_as_handle (as);
555 while (NULL != (adh = idp->delete_op_head))
557 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
561 while (NULL != (ai = idp->attr_iter_head))
563 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
566 while (NULL != (rop = idp->revoke_op_head))
568 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
570 RECLAIM_TICKETS_revoke_cancel (rop->rh);
573 while (NULL != (ti = idp->ticket_iter_head))
575 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
576 idp->ticket_iter_tail,
578 if (NULL != ti->iter)
579 RECLAIM_TICKETS_iteration_stop (ti->iter);
592 struct IdpClient *cl;
594 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
596 while (NULL != (cl = client_list_head))
598 GNUNET_CONTAINER_DLL_remove (client_list_head,
603 RECLAIM_TICKETS_deinit ();
604 if (NULL != timeout_task)
605 GNUNET_SCHEDULER_cancel (timeout_task);
607 GNUNET_NAMESTORE_disconnect (nsh);
617 do_shutdown (void *cls)
619 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
625 * Sends a ticket result message to the client
627 * @param client the client to send to
628 * @param r_id the request message ID to reply to
629 * @param ticket the ticket to include (may be NULL)
630 * @param success the success status of the request
633 send_ticket_result (const struct IdpClient *client,
635 const struct GNUNET_RECLAIM_Ticket *ticket,
638 struct TicketResultMessage *irm;
639 struct GNUNET_MQ_Envelope *env;
641 env = GNUNET_MQ_msg (irm,
642 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
645 irm->ticket = *ticket;
647 // TODO add success member
648 irm->id = htonl (r_id);
649 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
650 GNUNET_MQ_send (client->mq, env);
655 * Issue ticket result
657 * @param cls out ticket issue operation handle
658 * @param ticket the issued ticket
659 * @param success issue success status (GNUNET_OK if successful)
660 * @param emsg error message (NULL of success is GNUNET_OK)
663 issue_ticket_result_cb (void *cls,
664 struct GNUNET_RECLAIM_Ticket *ticket,
668 struct TicketIssueOperation *tio = cls;
670 if (GNUNET_OK != success)
672 send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR);
673 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
674 tio->client->issue_op_tail,
677 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
680 send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR);
681 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
682 tio->client->issue_op_tail,
689 * Check issue ticket message
692 * @im message to check
693 * @return GNUNET_OK if message is ok
696 check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
700 size = ntohs (im->header.size);
701 if (size <= sizeof(struct IssueTicketMessage))
704 return GNUNET_SYSERR;
711 * Handle ticket issue message
713 * @param cls our client
714 * @param im the message
717 handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
719 struct TicketIssueOperation *tio;
720 struct IdpClient *idp = cls;
721 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
724 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n");
725 tio = GNUNET_new (struct TicketIssueOperation);
726 attrs_len = ntohs (im->attr_len);
727 attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &im[1],
729 tio->r_id = ntohl (im->id);
731 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
732 RECLAIM_TICKETS_issue (&im->identity,
735 &issue_ticket_result_cb,
737 GNUNET_SERVICE_client_continue (idp->client);
738 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
742 /**********************************************************
744 **********************************************************/
747 * Handles revocation result
749 * @param cls our revocation operation handle
750 * @param success revocation result (GNUNET_OK if successful)
753 revoke_result_cb (void *cls, int32_t success)
755 struct TicketRevocationOperation *rop = cls;
756 struct GNUNET_MQ_Envelope *env;
757 struct RevokeTicketResultMessage *trm;
759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
760 "Sending REVOKE_TICKET_RESULT message\n");
762 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
763 trm->id = htonl (rop->r_id);
764 trm->success = htonl (success);
765 GNUNET_MQ_send (rop->client->mq, env);
766 GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
767 rop->client->revoke_op_tail,
774 * Check revocation message format
777 * @param im the message to check
778 * @return GNUNET_OK if message is ok
781 check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
785 size = ntohs (im->header.size);
786 if (size != sizeof(struct RevokeTicketMessage))
789 return GNUNET_SYSERR;
796 * Handle a revocation message to a ticket.
798 * @param cls our client
799 * @param rm the message to handle
802 handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
804 struct TicketRevocationOperation *rop;
805 struct IdpClient *idp = cls;
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n");
808 rop = GNUNET_new (struct TicketRevocationOperation);
809 rop->r_id = ntohl (rm->id);
811 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
813 = RECLAIM_TICKETS_revoke (&rm->ticket, &rm->identity, &revoke_result_cb,
815 GNUNET_SERVICE_client_continue (idp->client);
820 * Handle a ticket consume result
822 * @param cls our consume ticket operation handle
823 * @param identity the attribute authority
824 * @param attrs the attribute/claim list
825 * @param success GNUNET_OK if successful
826 * @param emsg error message (NULL if success=GNUNET_OK)
829 consume_result_cb (void *cls,
830 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
831 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
835 struct ConsumeTicketOperation *cop = cls;
836 struct ConsumeTicketResultMessage *crm;
837 struct GNUNET_MQ_Envelope *env;
841 if (GNUNET_OK != success)
843 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
845 attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
847 "Sending CONSUME_TICKET_RESULT message\n");
848 env = GNUNET_MQ_msg_extra (crm,
850 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
851 crm->id = htonl (cop->r_id);
852 crm->attrs_len = htons (attrs_len);
853 crm->identity = *identity;
854 crm->result = htonl (success);
855 data_tmp = (char *) &crm[1];
856 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, data_tmp);
857 GNUNET_MQ_send (cop->client->mq, env);
858 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
859 cop->client->consume_op_tail,
866 * Check a consume ticket message
869 * @param cm the message to handle
872 check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
876 size = ntohs (cm->header.size);
877 if (size != sizeof(struct ConsumeTicketMessage))
880 return GNUNET_SYSERR;
887 * Handle a consume ticket message
889 * @param cls our client handle
890 * @cm the message to handle
893 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
895 struct ConsumeTicketOperation *cop;
896 struct IdpClient *idp = cls;
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
899 cop = GNUNET_new (struct ConsumeTicketOperation);
900 cop->r_id = ntohl (cm->id);
903 = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb,
905 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
906 GNUNET_SERVICE_client_continue (idp->client);
910 /*****************************************
912 *****************************************/
916 * Attribute store result handler
918 * @param cls our attribute store handle
919 * @param success GNUNET_OK if successful
920 * @param emsg error message (NULL if success=GNUNET_OK)
923 attr_store_cont (void *cls, int32_t success, const char *emsg)
925 struct AttributeStoreHandle *ash = cls;
926 struct GNUNET_MQ_Envelope *env;
927 struct SuccessResultMessage *acr_msg;
930 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
931 ash->client->store_op_tail,
934 if (GNUNET_SYSERR == success)
936 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
937 "Failed to store attribute %s\n",
939 cleanup_as_handle (ash);
940 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
944 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
945 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
946 acr_msg->id = htonl (ash->r_id);
947 acr_msg->op_result = htonl (GNUNET_OK);
948 GNUNET_MQ_send (ash->client->mq, env);
949 cleanup_as_handle (ash);
954 * Add a new attribute
956 * @param cls the AttributeStoreHandle
959 attr_store_task (void *cls)
961 struct AttributeStoreHandle *ash = cls;
962 struct GNUNET_GNSRECORD_Data rd[1];
967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
968 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (ash->claim);
969 buf = GNUNET_malloc (buf_size);
970 // Give the ash a new id if unset
971 if (0 == ash->claim->id)
973 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
974 GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, buf);
976 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id, sizeof(uint64_t));
977 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
979 rd[0].data_size = buf_size;
981 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR;
982 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
983 rd[0].expiration_time = ash->exp.rel_value_us;
984 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
997 * Check an attribute store message
1000 * @param sam the message to check
1003 check_attribute_store_message (void *cls,
1004 const struct AttributeStoreMessage *sam)
1008 size = ntohs (sam->header.size);
1009 if (size <= sizeof(struct AttributeStoreMessage))
1012 return GNUNET_SYSERR;
1019 * Handle an attribute store message
1021 * @param cls our client
1022 * @param sam the message to handle
1025 handle_attribute_store_message (void *cls,
1026 const struct AttributeStoreMessage *sam)
1028 struct AttributeStoreHandle *ash;
1029 struct IdpClient *idp = cls;
1032 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
1034 data_len = ntohs (sam->attr_len);
1036 ash = GNUNET_new (struct AttributeStoreHandle);
1037 ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &sam[1],
1040 ash->r_id = ntohl (sam->id);
1041 ash->identity = sam->identity;
1042 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1043 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1045 GNUNET_SERVICE_client_continue (idp->client);
1047 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1048 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1053 * Attestation store result handler
1055 * @param cls our attribute store handle
1056 * @param success GNUNET_OK if successful
1057 * @param emsg error message (NULL if success=GNUNET_OK)
1060 attest_store_cont (void *cls, int32_t success, const char *emsg)
1062 struct AttributeStoreHandle *ash = cls;
1063 struct GNUNET_MQ_Envelope *env;
1064 struct SuccessResultMessage *acr_msg;
1067 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1068 ash->client->store_op_tail,
1071 if (GNUNET_SYSERR == success)
1073 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1074 "Failed to store attestation %s\n",
1076 cleanup_as_handle (ash);
1077 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1082 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1083 acr_msg->id = htonl (ash->r_id);
1084 acr_msg->op_result = htonl (GNUNET_OK);
1085 GNUNET_MQ_send (ash->client->mq, env);
1086 cleanup_as_handle (ash);
1090 * Send a reference error response
1092 * @param ash our attribute store handle
1093 * @param success the success status
1096 send_ref_error (struct AttributeStoreHandle *ash)
1098 struct GNUNET_MQ_Envelope *env;
1099 struct SuccessResultMessage *acr_msg;
1102 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1103 ash->client->store_op_tail,
1106 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1107 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1108 acr_msg->id = htonl (ash->r_id);
1109 acr_msg->op_result = htonl (GNUNET_SYSERR);
1110 GNUNET_MQ_send (ash->client->mq, env);
1111 cleanup_as_handle (ash);
1115 * Error looking up potential attestation. Abort.
1117 * @param cls our attribute store handle
1120 attest_error (void *cls)
1122 struct AttributeStoreHandle *ash = cls;
1123 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1124 "Failed to check for existing Attestation\n");
1125 cleanup_as_handle (ash);
1126 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1131 * Check for existing record before storing reference
1133 * @param cls our attribute store handle
1134 * @param zone zone we are iterating
1135 * @param label label of the records
1136 * @param rd_count record count
1140 attest_add_cb (void *cls,
1141 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1143 unsigned int rd_count,
1144 const struct GNUNET_GNSRECORD_Data *rd)
1146 struct AttributeStoreHandle *ash = cls;
1149 buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
1150 buf = GNUNET_malloc (buf_size);
1151 GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1155 "Storing new Attestation\n");
1156 struct GNUNET_GNSRECORD_Data rd_new[1];
1157 rd_new[0].data_size = buf_size;
1158 rd_new[0].data = buf;
1159 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
1160 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1161 rd_new[0].expiration_time = ash->exp.rel_value_us;
1162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1163 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1173 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1176 "Existing Attestation location is not an Attestation\n");
1177 send_ref_error (ash);
1180 struct GNUNET_GNSRECORD_Data rd_new[rd_count];
1181 for (int i = 0; i<rd_count; i++)
1185 rd_new[0].data_size = buf_size;
1186 rd_new[0].data = buf;
1187 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
1188 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1189 rd_new[0].expiration_time = ash->exp.rel_value_us;
1190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1191 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1202 * Add a new attestation
1204 * @param cls the AttributeStoreHandle
1207 attest_store_task (void *cls)
1209 struct AttributeStoreHandle *ash = cls;
1212 // Give the ash a new id if unset
1213 if (0 == ash->attest->id)
1215 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
1216 label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
1218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219 "Looking up existing data under label %s\n", label);
1220 // Test for the content of the existing ID
1221 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1228 GNUNET_free (label);
1232 * Check an attestation store message
1235 * @param sam the message to check
1238 check_attestation_store_message (void *cls,
1239 const struct AttributeStoreMessage *sam)
1243 size = ntohs (sam->header.size);
1244 if (size <= sizeof(struct AttributeStoreMessage))
1247 return GNUNET_SYSERR;
1253 * Handle an attestation store message
1255 * @param cls our client
1256 * @param sam the message to handle
1259 handle_attestation_store_message (void *cls,
1260 const struct AttributeStoreMessage *sam)
1262 struct AttributeStoreHandle *ash;
1263 struct IdpClient *idp = cls;
1266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
1268 data_len = ntohs (sam->attr_len);
1270 ash = GNUNET_new (struct AttributeStoreHandle);
1271 ash->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &sam[1],
1274 ash->r_id = ntohl (sam->id);
1275 ash->identity = sam->identity;
1276 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1277 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1279 GNUNET_SERVICE_client_continue (idp->client);
1281 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1282 GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
1286 * Error looking up potential reference value. Abort.
1288 * @param cls our attribute store handle
1291 ref_error (void *cls)
1293 struct AttributeStoreHandle *ash = cls;
1294 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1295 "Failed to find Attestation entry for Attestation reference\n");
1296 cleanup_as_handle (ash);
1297 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1302 * Error looking up potential reference value. Abort.
1304 * @param cls our attribute delete handle
1307 ref_del_error (void *cls)
1309 struct AttributeDeleteHandle *adh = cls;
1310 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1311 "Failed to find Attestation entry for Attestation reference\n");
1313 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1317 * Reference store result handler
1319 * @param cls our attribute store handle
1320 * @param success GNUNET_OK if successful
1321 * @param emsg error message (NULL if success=GNUNET_OK)
1324 reference_store_cont (void *cls, int32_t success, const char *emsg)
1326 struct AttributeStoreHandle *ash = cls;
1327 struct GNUNET_MQ_Envelope *env;
1328 struct SuccessResultMessage *acr_msg;
1331 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1332 ash->client->store_op_tail,
1335 if (GNUNET_SYSERR == success)
1337 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1338 "Failed to store reference %s\n",
1340 cleanup_as_handle (ash);
1341 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1346 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1347 acr_msg->id = htonl (ash->r_id);
1348 acr_msg->op_result = htonl (GNUNET_OK);
1349 GNUNET_MQ_send (ash->client->mq, env);
1350 cleanup_as_handle (ash);
1355 * Check for existing record before storing reference
1357 * @param cls our attribute store handle
1358 * @param zone zone we are iterating
1359 * @param label label of the records
1360 * @param rd_count record count
1364 ref_add_cb (void *cls,
1365 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1367 unsigned int rd_count,
1368 const struct GNUNET_GNSRECORD_Data *rd)
1370 struct AttributeStoreHandle *ash = cls;
1373 buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (ash->reference);
1374 buf = GNUNET_malloc (buf_size);
1375 GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf);
1376 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
1380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1381 "Failed to find Attestation entry for Attestation reference\n");
1382 send_ref_error (ash);
1385 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1388 "Intended Reference storage location is not an attestation\n");
1389 send_ref_error (ash);
1392 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
1394 for (i = 0; i<rd_count; i++)
1396 data_tmp = GNUNET_malloc (rd[i].data_size);
1397 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
1398 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, htons (
1401 if ((strcmp (ash->reference->name,ref->name) == 0)&&
1402 (strcmp (ash->reference->reference_value,ref->reference_value)==0) )
1404 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1405 "Reference already stored\n");
1406 reference_store_cont (ash,GNUNET_OK, NULL);
1410 rd_new[rd_count].data_size = buf_size;
1411 rd_new[rd_count].data = buf;
1412 rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE;
1413 rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1414 rd_new[rd_count].expiration_time = ash->exp.rel_value_us;
1415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1416 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1421 &reference_store_cont,
1427 * Add a new reference
1429 * @param cls the AttributeStoreHandle
1432 reference_store_task (void *cls)
1434 struct AttributeStoreHandle *ash = cls;
1437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing reference\n");
1439 // Give the ash a new id if unset
1440 if (0 == ash->reference->id)
1442 if (0 == ash->reference->id_attest)
1444 ash->reference->id = GNUNET_CRYPTO_random_u64 (
1445 GNUNET_CRYPTO_QUALITY_STRONG,
1450 ash->reference->id = ash->reference->id_attest;
1454 label = GNUNET_STRINGS_data_to_string_alloc (&ash->reference->id,
1456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1457 "Looking up existing data under label %s\n", label);
1458 // Test for the content of the existing ID
1460 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1467 GNUNET_free (label);
1471 * Check an attestation reference store message
1474 * @param sam the message to check
1477 check_reference_store_message (void *cls,
1479 AttributeStoreMessage *sam)
1483 size = ntohs (sam->header.size);
1484 if (size <= sizeof(struct AttributeStoreMessage))
1487 return GNUNET_SYSERR;
1494 * Handle an attestation reference store message
1496 * @param cls our client
1497 * @param sam the message to handle
1500 handle_reference_store_message (void *cls,
1501 const struct AttributeStoreMessage *sam)
1503 struct AttributeStoreHandle *ash;
1504 struct IdpClient *idp = cls;
1507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_STORE message\n");
1509 data_len = ntohs (sam->attr_len);
1510 ash = GNUNET_new (struct AttributeStoreHandle);
1511 ash->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &sam[1],
1513 ash->r_id = ntohl (sam->id);
1514 ash->identity = sam->identity;
1515 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1516 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1519 GNUNET_SERVICE_client_continue (idp->client);
1521 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1522 GNUNET_SCHEDULER_add_now (&reference_store_task, ash);
1525 * Send a deletion success response
1527 * @param adh our attribute deletion handle
1528 * @param success the success status
1531 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1533 struct GNUNET_MQ_Envelope *env;
1534 struct SuccessResultMessage *acr_msg;
1536 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
1537 adh->client->delete_op_tail,
1540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1541 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1542 acr_msg->id = htonl (adh->r_id);
1543 acr_msg->op_result = htonl (success);
1544 GNUNET_MQ_send (adh->client->mq, env);
1549 * Namestore iteration within attribute deletion.
1550 * We need to reissue tickets with the deleted attribute removed.
1552 * @param cls our attribute deletion handle
1553 * @param zone the private key of the ticket issuer
1554 * @param label the label of the record
1555 * @param rd_count number of records
1556 * @param rd record data
1559 ticket_iter (void *cls,
1560 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1562 unsigned int rd_count,
1563 const struct GNUNET_GNSRECORD_Data *rd)
1565 struct AttributeDeleteHandle *adh = cls;
1566 struct TicketRecordsEntry *le;
1567 int has_changed = GNUNET_NO;
1568 for (int i = 0; i < rd_count; i++)
1570 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
1572 if (adh->claim != NULL)
1573 if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
1575 if (adh->attest != NULL)
1576 if (0 != memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))
1578 if (adh->reference != NULL)
1579 if (0 != memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))
1581 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1582 "Attribute or Attestation/Reference to delete found (%s)\n",
1584 has_changed = GNUNET_YES;
1587 if (GNUNET_YES == has_changed)
1589 le = GNUNET_new (struct TicketRecordsEntry);
1590 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1591 le->data = GNUNET_malloc (le->data_size);
1592 le->rd_count = rd_count;
1593 le->label = GNUNET_strdup (label);
1594 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
1595 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
1596 adh->tickets_to_update_tail,
1599 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
1604 * Recursion prototype for function
1605 * @param cls our deletion handle
1608 update_tickets (void *cls);
1612 * Callback called when a ticket was updated
1614 * @param cls our attribute deletion handle
1615 * @param success GNUNET_OK if successful
1616 * @param emsg error message (NULL if success=GNUNET_OK)
1619 ticket_updated (void *cls, int32_t success, const char *emsg)
1621 struct AttributeDeleteHandle *adh = cls;
1624 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1629 * Update tickets: Remove shared attribute which has just been deleted.
1630 * This method is called recursively until all tickets are processed.
1631 * Eventually, the updated tickets are stored using ``update_tickets''.
1633 * @param cls our attribute deletion handle
1636 update_tickets (void *cls)
1638 struct AttributeDeleteHandle *adh = cls;
1639 struct TicketRecordsEntry *le;
1641 if (NULL == adh->tickets_to_update_head)
1643 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1644 "Finished updating tickets, success\n");
1645 send_delete_response (adh, GNUNET_OK);
1649 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1651 adh->tickets_to_update_head->label);
1652 le = adh->tickets_to_update_head;
1653 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1654 adh->tickets_to_update_tail,
1656 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
1657 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
1658 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
1663 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1664 "Unable to deserialize record data!\n");
1665 send_delete_response (adh, GNUNET_SYSERR);
1670 for (int i = 0; i < le->rd_count; i++)
1672 if (adh->claim != NULL)
1673 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1674 && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
1676 if (adh->attest != NULL)
1677 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1678 && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t))))
1680 if (adh->reference != NULL)
1681 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1682 && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t))))
1687 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1694 GNUNET_free (le->label);
1695 GNUNET_free (le->data);
1701 * Done collecting affected tickets, start updating.
1703 * @param cls our attribute deletion handle
1706 ticket_iter_fin (void *cls)
1708 struct AttributeDeleteHandle *adh = cls;
1710 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1715 * Error collecting affected tickets. Abort.
1717 * @param cls our attribute deletion handle
1720 ticket_iter_err (void *cls)
1722 struct AttributeDeleteHandle *adh = cls;
1725 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1726 "Namestore error on delete %s\n",
1728 send_delete_response (adh, GNUNET_SYSERR);
1734 * Start processing tickets which may still contain reference to deleted
1737 * @param cls attribute deletion handle
1740 start_ticket_update (void *cls)
1742 struct AttributeDeleteHandle *adh = cls;
1744 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1756 * Attribute deleted callback
1758 * @param cls our handle
1759 * @param success success status
1760 * @param emsg error message (NULL if success=GNUNET_OK)
1763 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1765 struct AttributeDeleteHandle *adh = cls;
1768 if (GNUNET_SYSERR == success)
1770 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1771 "Error deleting attribute %s\n",
1773 send_delete_response (adh, GNUNET_SYSERR);
1777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1778 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1783 * Check attribute delete message format
1786 * @dam message to check
1789 check_attribute_delete_message (void *cls,
1790 const struct AttributeDeleteMessage *dam)
1794 size = ntohs (dam->header.size);
1795 if (size <= sizeof(struct AttributeDeleteMessage))
1798 return GNUNET_SYSERR;
1805 * Handle attribute deletion
1807 * @param cls our client
1808 * @param dam deletion message
1811 handle_attribute_delete_message (void *cls,
1812 const struct AttributeDeleteMessage *dam)
1814 struct AttributeDeleteHandle *adh;
1815 struct IdpClient *idp = cls;
1818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1820 data_len = ntohs (dam->attr_len);
1822 adh = GNUNET_new (struct AttributeDeleteHandle);
1823 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &dam[1],
1825 adh->reference = NULL;
1828 adh->r_id = ntohl (dam->id);
1829 adh->identity = dam->identity;
1831 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id, sizeof(uint64_t));
1832 GNUNET_SERVICE_client_continue (idp->client);
1834 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1835 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1845 * Attestation deleted callback
1847 * @param cls our handle
1848 * @param success success status
1849 * @param emsg error message (NULL if success=GNUNET_OK)
1852 attest_delete_cont (void *cls, int32_t success, const char *emsg)
1854 struct AttributeDeleteHandle *adh = cls;
1857 if (GNUNET_SYSERR == success)
1859 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1860 "Error deleting attestation %s\n",
1862 send_delete_response (adh, GNUNET_SYSERR);
1866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1867 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1871 * Check attestation delete message format
1874 * @dam message to check
1877 check_attestation_delete_message (void *cls,
1878 const struct AttributeDeleteMessage *dam)
1882 size = ntohs (dam->header.size);
1883 if (size <= sizeof(struct AttributeDeleteMessage))
1886 return GNUNET_SYSERR;
1893 * Handle attestation deletion
1895 * @param cls our client
1896 * @param dam deletion message
1899 handle_attestation_delete_message (void *cls,
1900 const struct AttributeDeleteMessage *dam)
1902 struct AttributeDeleteHandle *adh;
1903 struct IdpClient *idp = cls;
1906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
1908 data_len = ntohs (dam->attr_len);
1910 adh = GNUNET_new (struct AttributeDeleteHandle);
1911 adh->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &dam[1],
1913 adh->reference = NULL;
1916 adh->r_id = ntohl (dam->id);
1917 adh->identity = dam->identity;
1919 = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id, sizeof(uint64_t));
1920 GNUNET_SERVICE_client_continue (idp->client);
1922 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1923 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1928 &attest_delete_cont,
1935 * Reference deleted callback
1937 * @param cls our handle
1938 * @param success success status
1939 * @param emsg error message (NULL if success=GNUNET_OK)
1942 reference_delete_cont (void *cls, int32_t success, const char *emsg)
1944 struct AttributeDeleteHandle *adh = cls;
1947 if (GNUNET_SYSERR == success)
1949 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1950 "Error deleting reference %s\n",
1952 send_delete_response (adh, GNUNET_SYSERR);
1956 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1957 //GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1958 send_delete_response (adh, GNUNET_OK);
1964 ref_del_cb (void *cls,
1965 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1967 unsigned int rd_count,
1968 const struct GNUNET_GNSRECORD_Data *rd)
1971 struct AttributeDeleteHandle *adh = cls;
1973 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
1974 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
1979 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1980 "Failed to find Attestation entry for Attestation reference\n");
1982 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1985 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1987 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1988 "Intended Reference location is not an attestation\n");
1990 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1996 for (i = 1; i<rd_count; i++)
1998 data_tmp = GNUNET_malloc (rd[i].data_size);
1999 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2000 attr_len = htons (rd[i].data_size);
2001 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
2004 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2005 "Unable to parse attestation reference from %s\n",
2011 if ((strcmp (adh->reference->name,ref->name) == 0)&&
2012 (strcmp (adh->reference->reference_value,ref->reference_value)==0) )
2014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2015 "Found reference to delete.\n");
2022 GNUNET_free (data_tmp);
2024 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
2029 &reference_delete_cont,
2034 * Check an attestation reference delete message
2037 * @param sam the message to check
2040 check_reference_delete_message (void *cls,
2041 const struct AttributeDeleteMessage *dam)
2045 size = ntohs (dam->header.size);
2046 if (size <= sizeof(struct AttributeDeleteMessage))
2049 return GNUNET_SYSERR;
2055 * Handle reference deletion
2057 * @param cls our client
2058 * @param dam deletion message
2061 handle_reference_delete_message (void *cls,
2062 const struct AttributeDeleteMessage *dam)
2064 struct AttributeDeleteHandle *adh;
2065 struct IdpClient *idp = cls;
2068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n");
2069 data_len = ntohs (dam->attr_len);
2070 adh = GNUNET_new (struct AttributeDeleteHandle);
2071 adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &dam[1],
2076 adh->r_id = ntohl (dam->id);
2077 adh->identity = dam->identity;
2079 = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->id,
2081 GNUNET_SERVICE_client_continue (idp->client);
2083 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
2084 adh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
2095 /*************************************************
2096 * Attrubute iteration
2097 *************************************************/
2101 * Done iterating over attributes
2103 * @param cls our iterator handle
2106 attr_iter_finished (void *cls)
2108 struct AttributeIterator *ai = cls;
2109 struct GNUNET_MQ_Envelope *env;
2110 struct AttributeResultMessage *arm;
2112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
2113 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2114 arm->id = htonl (ai->request_id);
2115 arm->attr_len = htons (0);
2116 GNUNET_MQ_send (ai->client->mq, env);
2117 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
2118 ai->client->attr_iter_tail,
2125 * Error iterating over attributes. Abort.
2127 * @param cls our attribute iteration handle
2130 attr_iter_error (void *cls)
2132 struct AttributeIterator *ai = cls;
2134 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
2135 attr_iter_finished (ai);
2140 * Got record. Return if it is an attribute or attestation/reference.
2142 * @param cls our attribute iterator
2143 * @param zone zone we are iterating
2144 * @param label label of the records
2145 * @param rd_count record count
2149 attr_iter_cb (void *cls,
2150 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
2152 unsigned int rd_count,
2153 const struct GNUNET_GNSRECORD_Data *rd)
2155 struct AttributeIterator *ai = cls;
2156 struct GNUNET_MQ_Envelope *env;
2161 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2166 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[0].record_type)
2168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2169 "Found Ticket. Ignoring.\n");
2170 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2173 else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
2175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2176 "Non-Attestation record with multiple entries found: %u\n",
2178 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2183 for (int i = 0; i<rd_count; i++)
2185 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd[i].record_type) &&
2186 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) &&
2187 (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE != rd[i].record_type))
2189 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2193 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type )
2195 struct AttributeResultMessage *arm;
2196 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
2198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2199 "Sending ATTRIBUTE_RESULT message\n");
2200 env = GNUNET_MQ_msg_extra (arm,
2202 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2203 arm->id = htonl (ai->request_id);
2204 arm->attr_len = htons (rd[i].data_size);
2205 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
2206 data_tmp = (char *) &arm[1];
2207 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2208 GNUNET_MQ_send (ai->client->mq, env);
2212 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type )
2214 struct AttributeResultMessage *arm;
2215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
2217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2218 "Sending ATTESTATION_RESULT message\n");
2219 env = GNUNET_MQ_msg_extra (arm,
2221 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
2222 arm->id = htonl (ai->request_id);
2223 arm->attr_len = htons (rd[i].data_size);
2224 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
2225 data_tmp = (char *) &arm[1];
2226 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2227 GNUNET_MQ_send (ai->client->mq, env);
2231 struct ReferenceResultMessage *rrm;
2232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reference under: %s\n",
2234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2235 "Sending REFERENCE_RESULT message\n");
2236 env = GNUNET_MQ_msg_extra (rrm,
2237 rd[i].data_size + rd[0].data_size,
2238 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT);
2239 rrm->id = htonl (ai->request_id);
2240 rrm->attest_len = htons (rd[0].data_size);
2241 rrm->ref_len = htons (rd[i].data_size);
2242 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &rrm->identity);
2243 data_tmp = (char *) &rrm[1];
2244 GNUNET_memcpy (data_tmp, rd[0].data, rd[0].data_size);
2245 data_tmp += rd[0].data_size;
2246 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2247 GNUNET_MQ_send (ai->client->mq, env);
2254 * Iterate over zone to get attributes
2256 * @param cls our client
2257 * @param ais_msg the iteration message to start
2260 handle_iteration_start (void *cls,
2261 const struct AttributeIterationStartMessage *ais_msg)
2263 struct IdpClient *idp = cls;
2264 struct AttributeIterator *ai;
2266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2267 "Received ATTRIBUTE_ITERATION_START message\n");
2268 ai = GNUNET_new (struct AttributeIterator);
2269 ai->request_id = ntohl (ais_msg->id);
2271 ai->identity = ais_msg->identity;
2273 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
2274 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
2280 &attr_iter_finished,
2282 GNUNET_SERVICE_client_continue (idp->client);
2287 * Handle iteration stop message from client
2289 * @param cls the client
2290 * @param ais_msg the stop message
2293 handle_iteration_stop (void *cls,
2294 const struct AttributeIterationStopMessage *ais_msg)
2296 struct IdpClient *idp = cls;
2297 struct AttributeIterator *ai;
2300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2301 "Received `%s' message\n",
2302 "ATTRIBUTE_ITERATION_STOP");
2303 rid = ntohl (ais_msg->id);
2304 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2305 if (ai->request_id == rid)
2310 GNUNET_SERVICE_client_drop (idp->client);
2313 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
2315 GNUNET_SERVICE_client_continue (idp->client);
2320 * Client requests next attribute from iterator
2322 * @param cls the client
2323 * @param ais_msg the message
2326 handle_iteration_next (void *cls,
2327 const struct AttributeIterationNextMessage *ais_msg)
2329 struct IdpClient *idp = cls;
2330 struct AttributeIterator *ai;
2333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2334 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2335 rid = ntohl (ais_msg->id);
2336 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2337 if (ai->request_id == rid)
2342 GNUNET_SERVICE_client_drop (idp->client);
2345 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2346 GNUNET_SERVICE_client_continue (idp->client);
2350 /******************************************************
2352 ******************************************************/
2355 * Got a ticket. Return to client
2357 * @param cls our ticket iterator
2358 * @param ticket the ticket
2361 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
2363 struct TicketIteration *ti = cls;
2364 struct GNUNET_MQ_Envelope *env;
2365 struct TicketResultMessage *trm;
2367 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2370 /* send empty response to indicate end of list */
2371 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2372 ti->client->ticket_iter_tail,
2377 trm->ticket = *ticket;
2379 trm->id = htonl (ti->r_id);
2380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
2381 GNUNET_MQ_send (ti->client->mq, env);
2388 * Client requests a ticket iteration
2390 * @param cls the client
2391 * @param tis_msg the iteration request message
2394 handle_ticket_iteration_start (
2396 const struct TicketIterationStartMessage *tis_msg)
2398 struct IdpClient *client = cls;
2399 struct TicketIteration *ti;
2401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2402 "Received TICKET_ITERATION_START message\n");
2403 ti = GNUNET_new (struct TicketIteration);
2404 ti->r_id = ntohl (tis_msg->id);
2405 ti->client = client;
2407 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2408 client->ticket_iter_tail,
2411 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
2412 GNUNET_SERVICE_client_continue (client->client);
2417 * Client has had enough tickets
2419 * @param cls the client
2420 * @param tis_msg the stop message
2423 handle_ticket_iteration_stop (void *cls,
2424 const struct TicketIterationStopMessage *tis_msg)
2426 struct IdpClient *client = cls;
2427 struct TicketIteration *ti;
2430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2431 "Received `%s' message\n",
2432 "TICKET_ITERATION_STOP");
2433 rid = ntohl (tis_msg->id);
2434 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2435 if (ti->r_id == rid)
2440 GNUNET_SERVICE_client_drop (client->client);
2443 RECLAIM_TICKETS_iteration_stop (ti->iter);
2444 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2445 client->ticket_iter_tail,
2448 GNUNET_SERVICE_client_continue (client->client);
2453 * Client requests next result.
2455 * @param cls the client
2456 * @param tis_msg the message
2459 handle_ticket_iteration_next (void *cls,
2460 const struct TicketIterationNextMessage *tis_msg)
2462 struct IdpClient *client = cls;
2463 struct TicketIteration *ti;
2466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2467 "Received TICKET_ITERATION_NEXT message\n");
2468 rid = ntohl (tis_msg->id);
2469 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2470 if (ti->r_id == rid)
2475 GNUNET_SERVICE_client_drop (client->client);
2478 RECLAIM_TICKETS_iteration_next (ti->iter);
2479 GNUNET_SERVICE_client_continue (client->client);
2484 * Main function that will be run
2486 * @param cls closure
2487 * @param c the configuration used
2488 * @param server the service handle
2492 const struct GNUNET_CONFIGURATION_Handle *c,
2493 struct GNUNET_SERVICE_Handle *server)
2497 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
2499 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2500 "Unable to initialize TICKETS subsystem.\n");
2501 GNUNET_SCHEDULER_shutdown ();
2504 // Connect to identity and namestore services
2505 nsh = GNUNET_NAMESTORE_connect (cfg);
2508 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2509 "error connecting to namestore");
2512 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2517 * Called whenever a client is disconnected.
2519 * @param cls closure
2520 * @param client identification of the client
2521 * @param app_ctx @a client
2524 client_disconnect_cb (void *cls,
2525 struct GNUNET_SERVICE_Client *client,
2528 struct IdpClient *idp = app_ctx;
2530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
2531 GNUNET_CONTAINER_DLL_remove (client_list_head,
2534 cleanup_client (idp);
2539 * Add a client to our list of active clients.
2542 * @param client client to add
2543 * @param mq message queue for @a client
2544 * @return internal namestore client structure for this client
2547 client_connect_cb (void *cls,
2548 struct GNUNET_SERVICE_Client *client,
2549 struct GNUNET_MQ_Handle *mq)
2551 struct IdpClient *idp;
2553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
2554 idp = GNUNET_new (struct IdpClient);
2555 idp->client = client;
2557 GNUNET_CONTAINER_DLL_insert (client_list_head,
2565 * Define "main" method using service macro.
2567 GNUNET_SERVICE_MAIN (
2569 GNUNET_SERVICE_OPTION_NONE,
2572 &client_disconnect_cb,
2574 GNUNET_MQ_hd_var_size (attribute_store_message,
2575 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2576 struct AttributeStoreMessage,
2578 GNUNET_MQ_hd_var_size (attestation_store_message,
2579 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
2580 struct AttributeStoreMessage,
2582 GNUNET_MQ_hd_var_size (attribute_delete_message,
2583 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2584 struct AttributeDeleteMessage,
2586 GNUNET_MQ_hd_var_size (attestation_delete_message,
2587 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
2588 struct AttributeDeleteMessage,
2590 GNUNET_MQ_hd_var_size (reference_store_message,
2591 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE,
2592 struct AttributeStoreMessage,
2594 GNUNET_MQ_hd_var_size (reference_delete_message,
2595 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE,
2596 struct AttributeDeleteMessage,
2598 GNUNET_MQ_hd_fixed_size (
2600 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2601 struct AttributeIterationStartMessage,
2603 GNUNET_MQ_hd_fixed_size (iteration_next,
2604 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2605 struct AttributeIterationNextMessage,
2607 GNUNET_MQ_hd_fixed_size (iteration_stop,
2608 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2609 struct AttributeIterationStopMessage,
2611 GNUNET_MQ_hd_var_size (issue_ticket_message,
2612 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2613 struct IssueTicketMessage,
2615 GNUNET_MQ_hd_var_size (consume_ticket_message,
2616 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2617 struct ConsumeTicketMessage,
2619 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2620 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2621 struct TicketIterationStartMessage,
2623 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2624 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2625 struct TicketIterationNextMessage,
2627 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2628 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2629 struct TicketIterationStopMessage,
2631 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2632 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2633 struct RevokeTicketMessage,
2635 GNUNET_MQ_handler_end ());
2636 /* end of gnunet-service-reclaim.c */