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 (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->claim->id))
972 GNUNET_RECLAIM_id_generate (&ash->claim->id);
973 GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, buf);
975 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id,
976 sizeof (ash->reference->id));
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);
1091 * Send a reference error response
1093 * @param ash our attribute store handle
1094 * @param success the success status
1097 send_ref_error (struct AttributeStoreHandle *ash)
1099 struct GNUNET_MQ_Envelope *env;
1100 struct SuccessResultMessage *acr_msg;
1103 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1104 ash->client->store_op_tail,
1107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1108 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1109 acr_msg->id = htonl (ash->r_id);
1110 acr_msg->op_result = htonl (GNUNET_SYSERR);
1111 GNUNET_MQ_send (ash->client->mq, env);
1112 cleanup_as_handle (ash);
1117 * Error looking up potential attestation. Abort.
1119 * @param cls our attribute store handle
1122 attest_error (void *cls)
1124 struct AttributeStoreHandle *ash = cls;
1125 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1126 "Failed to check for existing Attestation\n");
1127 cleanup_as_handle (ash);
1128 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1134 * Check for existing record before storing reference
1136 * @param cls our attribute store handle
1137 * @param zone zone we are iterating
1138 * @param label label of the records
1139 * @param rd_count record count
1143 attest_add_cb (void *cls,
1144 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1146 unsigned int rd_count,
1147 const struct GNUNET_GNSRECORD_Data *rd)
1149 struct AttributeStoreHandle *ash = cls;
1152 buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
1153 buf = GNUNET_malloc (buf_size);
1154 GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
1157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1158 "Storing new Attestation\n");
1159 struct GNUNET_GNSRECORD_Data rd_new[1];
1160 rd_new[0].data_size = buf_size;
1161 rd_new[0].data = buf;
1162 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
1163 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1164 rd_new[0].expiration_time = ash->exp.rel_value_us;
1165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1166 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1176 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1178 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1179 "Existing Attestation location is not an Attestation\n");
1180 send_ref_error (ash);
1183 struct GNUNET_GNSRECORD_Data rd_new[rd_count];
1184 for (int i = 0; i<rd_count; i++)
1188 rd_new[0].data_size = buf_size;
1189 rd_new[0].data = buf;
1190 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
1191 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1192 rd_new[0].expiration_time = ash->exp.rel_value_us;
1193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1194 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1206 * Add a new attestation
1208 * @param cls the AttributeStoreHandle
1211 attest_store_task (void *cls)
1213 struct AttributeStoreHandle *ash = cls;
1216 // Give the ash a new id if unset
1217 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->attest->id))
1218 GNUNET_RECLAIM_id_generate (&ash->attest->id);
1219 label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
1220 sizeof (ash->attest->id));
1221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1222 "Looking up existing data under label %s\n", label);
1223 // Test for the content of the existing ID
1224 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1231 GNUNET_free (label);
1236 * Check an attestation store message
1239 * @param sam the message to check
1242 check_attestation_store_message (void *cls,
1243 const struct AttributeStoreMessage *sam)
1247 size = ntohs (sam->header.size);
1248 if (size <= sizeof(struct AttributeStoreMessage))
1251 return GNUNET_SYSERR;
1258 * Handle an attestation store message
1260 * @param cls our client
1261 * @param sam the message to handle
1264 handle_attestation_store_message (void *cls,
1265 const struct AttributeStoreMessage *sam)
1267 struct AttributeStoreHandle *ash;
1268 struct IdpClient *idp = cls;
1271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
1273 data_len = ntohs (sam->attr_len);
1275 ash = GNUNET_new (struct AttributeStoreHandle);
1276 ash->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &sam[1],
1279 ash->r_id = ntohl (sam->id);
1280 ash->identity = sam->identity;
1281 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1282 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1284 GNUNET_SERVICE_client_continue (idp->client);
1286 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1287 GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
1292 * Error looking up potential reference value. Abort.
1294 * @param cls our attribute store handle
1297 ref_error (void *cls)
1299 struct AttributeStoreHandle *ash = cls;
1300 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1301 "Failed to find Attestation entry for Attestation reference\n");
1302 cleanup_as_handle (ash);
1303 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1309 * Error looking up potential reference value. Abort.
1311 * @param cls our attribute delete handle
1314 ref_del_error (void *cls)
1316 struct AttributeDeleteHandle *adh = cls;
1317 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1318 "Failed to find Attestation entry for Attestation reference\n");
1320 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1326 * Reference store result handler
1328 * @param cls our attribute store handle
1329 * @param success GNUNET_OK if successful
1330 * @param emsg error message (NULL if success=GNUNET_OK)
1333 reference_store_cont (void *cls, int32_t success, const char *emsg)
1335 struct AttributeStoreHandle *ash = cls;
1336 struct GNUNET_MQ_Envelope *env;
1337 struct SuccessResultMessage *acr_msg;
1340 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1341 ash->client->store_op_tail,
1344 if (GNUNET_SYSERR == success)
1346 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1347 "Failed to store reference %s\n",
1349 cleanup_as_handle (ash);
1350 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1355 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1356 acr_msg->id = htonl (ash->r_id);
1357 acr_msg->op_result = htonl (GNUNET_OK);
1358 GNUNET_MQ_send (ash->client->mq, env);
1359 cleanup_as_handle (ash);
1364 * Check for existing record before storing reference
1366 * @param cls our attribute store handle
1367 * @param zone zone we are iterating
1368 * @param label label of the records
1369 * @param rd_count record count
1373 ref_add_cb (void *cls,
1374 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1376 unsigned int rd_count,
1377 const struct GNUNET_GNSRECORD_Data *rd)
1379 struct AttributeStoreHandle *ash = cls;
1382 buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (ash->reference);
1383 buf = GNUNET_malloc (buf_size);
1384 GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf);
1385 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
1389 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1390 "Failed to find Attestation entry for Attestation reference\n");
1391 send_ref_error (ash);
1394 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1397 "Intended Reference storage location is not an attestation\n");
1398 send_ref_error (ash);
1401 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
1403 for (i = 0; i<rd_count; i++)
1405 data_tmp = GNUNET_malloc (rd[i].data_size);
1406 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
1407 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, htons (
1410 if ((strcmp (ash->reference->name,ref->name) == 0) &&
1411 (strcmp (ash->reference->reference_value,ref->reference_value)==0) )
1413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1414 "Reference already stored\n");
1415 reference_store_cont (ash,GNUNET_OK, NULL);
1419 rd_new[rd_count].data_size = buf_size;
1420 rd_new[rd_count].data = buf;
1421 rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE;
1422 rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1423 rd_new[rd_count].expiration_time = ash->exp.rel_value_us;
1424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1425 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1430 &reference_store_cont,
1437 * Add a new reference
1439 * @param cls the AttributeStoreHandle
1442 reference_store_task (void *cls)
1444 struct AttributeStoreHandle *ash = cls;
1447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing reference\n");
1449 // Give the ash a new id if unset
1450 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->reference->id))
1452 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->reference->id_attest))
1454 GNUNET_RECLAIM_id_generate (&ash->reference->id);
1458 ash->reference->id = ash->reference->id_attest;
1462 label = GNUNET_STRINGS_data_to_string_alloc (&ash->reference->id,
1463 sizeof (ash->reference->id));
1464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1465 "Looking up existing data under label %s\n", label);
1466 // Test for the content of the existing ID
1468 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1475 GNUNET_free (label);
1480 * Check an attestation reference store message
1483 * @param sam the message to check
1486 check_reference_store_message (void *cls,
1488 AttributeStoreMessage *sam)
1492 size = ntohs (sam->header.size);
1493 if (size <= sizeof(struct AttributeStoreMessage))
1496 return GNUNET_SYSERR;
1503 * Handle an attestation reference store message
1505 * @param cls our client
1506 * @param sam the message to handle
1509 handle_reference_store_message (void *cls,
1510 const struct AttributeStoreMessage *sam)
1512 struct AttributeStoreHandle *ash;
1513 struct IdpClient *idp = cls;
1516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_STORE message\n");
1518 data_len = ntohs (sam->attr_len);
1519 ash = GNUNET_new (struct AttributeStoreHandle);
1520 ash->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &sam[1],
1522 ash->r_id = ntohl (sam->id);
1523 ash->identity = sam->identity;
1524 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1525 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1528 GNUNET_SERVICE_client_continue (idp->client);
1530 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1531 GNUNET_SCHEDULER_add_now (&reference_store_task, ash);
1536 * Send a deletion success response
1538 * @param adh our attribute deletion handle
1539 * @param success the success status
1542 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1544 struct GNUNET_MQ_Envelope *env;
1545 struct SuccessResultMessage *acr_msg;
1547 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
1548 adh->client->delete_op_tail,
1551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1552 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1553 acr_msg->id = htonl (adh->r_id);
1554 acr_msg->op_result = htonl (success);
1555 GNUNET_MQ_send (adh->client->mq, env);
1560 * Namestore iteration within attribute deletion.
1561 * We need to reissue tickets with the deleted attribute removed.
1563 * @param cls our attribute deletion handle
1564 * @param zone the private key of the ticket issuer
1565 * @param label the label of the record
1566 * @param rd_count number of records
1567 * @param rd record data
1570 ticket_iter (void *cls,
1571 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1573 unsigned int rd_count,
1574 const struct GNUNET_GNSRECORD_Data *rd)
1576 struct AttributeDeleteHandle *adh = cls;
1577 struct TicketRecordsEntry *le;
1578 int has_changed = GNUNET_NO;
1579 for (int i = 0; i < rd_count; i++)
1581 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
1583 if (adh->claim != NULL)
1584 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1587 if (adh->attest != NULL)
1588 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1591 if (adh->reference != NULL)
1592 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1593 &adh->reference->id))
1595 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1596 "Attribute or Attestation/Reference to delete found (%s)\n",
1598 has_changed = GNUNET_YES;
1601 if (GNUNET_YES == has_changed)
1603 le = GNUNET_new (struct TicketRecordsEntry);
1604 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1605 le->data = GNUNET_malloc (le->data_size);
1606 le->rd_count = rd_count;
1607 le->label = GNUNET_strdup (label);
1608 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
1609 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
1610 adh->tickets_to_update_tail,
1613 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
1618 * Recursion prototype for function
1619 * @param cls our deletion handle
1622 update_tickets (void *cls);
1626 * Callback called when a ticket was updated
1628 * @param cls our attribute deletion handle
1629 * @param success GNUNET_OK if successful
1630 * @param emsg error message (NULL if success=GNUNET_OK)
1633 ticket_updated (void *cls, int32_t success, const char *emsg)
1635 struct AttributeDeleteHandle *adh = cls;
1638 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1643 * Update tickets: Remove shared attribute which has just been deleted.
1644 * This method is called recursively until all tickets are processed.
1645 * Eventually, the updated tickets are stored using ``update_tickets''.
1647 * @param cls our attribute deletion handle
1650 update_tickets (void *cls)
1652 struct AttributeDeleteHandle *adh = cls;
1653 struct TicketRecordsEntry *le;
1655 if (NULL == adh->tickets_to_update_head)
1657 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1658 "Finished updating tickets, success\n");
1659 send_delete_response (adh, GNUNET_OK);
1663 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1665 adh->tickets_to_update_head->label);
1666 le = adh->tickets_to_update_head;
1667 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1668 adh->tickets_to_update_tail,
1670 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
1671 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
1672 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
1677 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1678 "Unable to deserialize record data!\n");
1679 send_delete_response (adh, GNUNET_SYSERR);
1684 for (int i = 0; i < le->rd_count; i++)
1686 if (adh->claim != NULL)
1687 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1688 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1691 if (adh->attest != NULL)
1692 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1693 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1696 if (adh->reference != NULL)
1697 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1698 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1699 &adh->reference->id)))
1704 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1711 GNUNET_free (le->label);
1712 GNUNET_free (le->data);
1718 * Done collecting affected tickets, start updating.
1720 * @param cls our attribute deletion handle
1723 ticket_iter_fin (void *cls)
1725 struct AttributeDeleteHandle *adh = cls;
1727 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1732 * Error collecting affected tickets. Abort.
1734 * @param cls our attribute deletion handle
1737 ticket_iter_err (void *cls)
1739 struct AttributeDeleteHandle *adh = cls;
1742 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1743 "Namestore error on delete %s\n",
1745 send_delete_response (adh, GNUNET_SYSERR);
1751 * Start processing tickets which may still contain reference to deleted
1754 * @param cls attribute deletion handle
1757 start_ticket_update (void *cls)
1759 struct AttributeDeleteHandle *adh = cls;
1761 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1773 * Attribute deleted callback
1775 * @param cls our handle
1776 * @param success success status
1777 * @param emsg error message (NULL if success=GNUNET_OK)
1780 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1782 struct AttributeDeleteHandle *adh = cls;
1785 if (GNUNET_SYSERR == success)
1787 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1788 "Error deleting attribute %s\n",
1790 send_delete_response (adh, GNUNET_SYSERR);
1794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1795 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1800 * Check attribute delete message format
1803 * @dam message to check
1806 check_attribute_delete_message (void *cls,
1807 const struct AttributeDeleteMessage *dam)
1811 size = ntohs (dam->header.size);
1812 if (size <= sizeof(struct AttributeDeleteMessage))
1815 return GNUNET_SYSERR;
1822 * Handle attribute deletion
1824 * @param cls our client
1825 * @param dam deletion message
1828 handle_attribute_delete_message (void *cls,
1829 const struct AttributeDeleteMessage *dam)
1831 struct AttributeDeleteHandle *adh;
1832 struct IdpClient *idp = cls;
1835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1837 data_len = ntohs (dam->attr_len);
1839 adh = GNUNET_new (struct AttributeDeleteHandle);
1840 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &dam[1],
1842 adh->reference = NULL;
1845 adh->r_id = ntohl (dam->id);
1846 adh->identity = dam->identity;
1848 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id,
1849 sizeof(adh->claim->id));
1850 GNUNET_SERVICE_client_continue (idp->client);
1852 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1853 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1864 * Attestation deleted callback
1866 * @param cls our handle
1867 * @param success success status
1868 * @param emsg error message (NULL if success=GNUNET_OK)
1871 attest_delete_cont (void *cls, int32_t success, const char *emsg)
1873 struct AttributeDeleteHandle *adh = cls;
1876 if (GNUNET_SYSERR == success)
1878 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1879 "Error deleting attestation %s\n",
1881 send_delete_response (adh, GNUNET_SYSERR);
1885 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1886 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1891 * Check attestation delete message format
1894 * @dam message to check
1897 check_attestation_delete_message (void *cls,
1898 const struct AttributeDeleteMessage *dam)
1902 size = ntohs (dam->header.size);
1903 if (size <= sizeof(struct AttributeDeleteMessage))
1906 return GNUNET_SYSERR;
1913 * Handle attestation deletion
1915 * @param cls our client
1916 * @param dam deletion message
1919 handle_attestation_delete_message (void *cls,
1920 const struct AttributeDeleteMessage *dam)
1922 struct AttributeDeleteHandle *adh;
1923 struct IdpClient *idp = cls;
1926 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
1928 data_len = ntohs (dam->attr_len);
1930 adh = GNUNET_new (struct AttributeDeleteHandle);
1931 adh->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &dam[1],
1933 adh->reference = NULL;
1936 adh->r_id = ntohl (dam->id);
1937 adh->identity = dam->identity;
1939 = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id,
1940 sizeof(adh->attest->id));
1941 GNUNET_SERVICE_client_continue (idp->client);
1943 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1944 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1949 &attest_delete_cont,
1955 * Reference deleted callback
1957 * @param cls our handle
1958 * @param success success status
1959 * @param emsg error message (NULL if success=GNUNET_OK)
1962 reference_delete_cont (void *cls, int32_t success, const char *emsg)
1964 struct AttributeDeleteHandle *adh = cls;
1967 if (GNUNET_SYSERR == success)
1969 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1970 "Error deleting reference %s\n",
1972 send_delete_response (adh, GNUNET_SYSERR);
1976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1977 // GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1978 send_delete_response (adh, GNUNET_OK);
1985 ref_del_cb (void *cls,
1986 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1988 unsigned int rd_count,
1989 const struct GNUNET_GNSRECORD_Data *rd)
1992 struct AttributeDeleteHandle *adh = cls;
1994 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
1995 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
2000 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2001 "Failed to find Attestation entry for Attestation reference\n");
2003 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2006 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
2008 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2009 "Intended Reference location is not an attestation\n");
2011 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2017 for (i = 1; i<rd_count; i++)
2019 data_tmp = GNUNET_malloc (rd[i].data_size);
2020 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2021 attr_len = htons (rd[i].data_size);
2022 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
2025 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2026 "Unable to parse attestation reference from %s\n",
2032 if ((strcmp (adh->reference->name,ref->name) == 0) &&
2033 (strcmp (adh->reference->reference_value,ref->reference_value)==0) )
2035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2036 "Found reference to delete.\n");
2043 GNUNET_free (data_tmp);
2045 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
2050 &reference_delete_cont,
2056 * Check an attestation reference delete message
2059 * @param sam the message to check
2062 check_reference_delete_message (void *cls,
2063 const struct AttributeDeleteMessage *dam)
2067 size = ntohs (dam->header.size);
2068 if (size <= sizeof(struct AttributeDeleteMessage))
2071 return GNUNET_SYSERR;
2078 * Handle reference deletion
2080 * @param cls our client
2081 * @param dam deletion message
2084 handle_reference_delete_message (void *cls,
2085 const struct AttributeDeleteMessage *dam)
2087 struct AttributeDeleteHandle *adh;
2088 struct IdpClient *idp = cls;
2091 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n");
2092 data_len = ntohs (dam->attr_len);
2093 adh = GNUNET_new (struct AttributeDeleteHandle);
2094 adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &dam[1],
2099 adh->r_id = ntohl (dam->id);
2100 adh->identity = dam->identity;
2102 = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->id,
2103 sizeof(adh->reference->id));
2104 GNUNET_SERVICE_client_continue (idp->client);
2106 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
2107 adh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
2117 /*************************************************
2118 * Attrubute iteration
2119 *************************************************/
2123 * Done iterating over attributes
2125 * @param cls our iterator handle
2128 attr_iter_finished (void *cls)
2130 struct AttributeIterator *ai = cls;
2131 struct GNUNET_MQ_Envelope *env;
2132 struct AttributeResultMessage *arm;
2134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
2135 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2136 arm->id = htonl (ai->request_id);
2137 arm->attr_len = htons (0);
2138 GNUNET_MQ_send (ai->client->mq, env);
2139 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
2140 ai->client->attr_iter_tail,
2147 * Error iterating over attributes. Abort.
2149 * @param cls our attribute iteration handle
2152 attr_iter_error (void *cls)
2154 struct AttributeIterator *ai = cls;
2156 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
2157 attr_iter_finished (ai);
2162 * Got record. Return if it is an attribute or attestation/reference.
2164 * @param cls our attribute iterator
2165 * @param zone zone we are iterating
2166 * @param label label of the records
2167 * @param rd_count record count
2171 attr_iter_cb (void *cls,
2172 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
2174 unsigned int rd_count,
2175 const struct GNUNET_GNSRECORD_Data *rd)
2177 struct AttributeIterator *ai = cls;
2178 struct GNUNET_MQ_Envelope *env;
2183 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2188 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[0].record_type)
2190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2191 "Found Ticket. Ignoring.\n");
2192 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2195 else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
2197 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2198 "Non-Attestation record with multiple entries found: %u\n",
2200 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2205 for (int i = 0; i<rd_count; i++)
2207 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd[i].record_type) &&
2208 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) &&
2209 (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE != rd[i].record_type))
2211 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2215 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
2217 struct AttributeResultMessage *arm;
2218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
2220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2221 "Sending ATTRIBUTE_RESULT message\n");
2222 env = GNUNET_MQ_msg_extra (arm,
2224 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2225 arm->id = htonl (ai->request_id);
2226 arm->attr_len = htons (rd[i].data_size);
2227 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
2228 data_tmp = (char *) &arm[1];
2229 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2230 GNUNET_MQ_send (ai->client->mq, env);
2234 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type)
2236 struct AttributeResultMessage *arm;
2237 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
2239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2240 "Sending ATTESTATION_RESULT message\n");
2241 env = GNUNET_MQ_msg_extra (arm,
2243 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
2244 arm->id = htonl (ai->request_id);
2245 arm->attr_len = htons (rd[i].data_size);
2246 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
2247 data_tmp = (char *) &arm[1];
2248 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2249 GNUNET_MQ_send (ai->client->mq, env);
2253 struct ReferenceResultMessage *rrm;
2254 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reference under: %s\n",
2256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2257 "Sending REFERENCE_RESULT message\n");
2258 env = GNUNET_MQ_msg_extra (rrm,
2259 rd[i].data_size + rd[0].data_size,
2260 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT);
2261 rrm->id = htonl (ai->request_id);
2262 rrm->attest_len = htons (rd[0].data_size);
2263 rrm->ref_len = htons (rd[i].data_size);
2264 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &rrm->identity);
2265 data_tmp = (char *) &rrm[1];
2266 GNUNET_memcpy (data_tmp, rd[0].data, rd[0].data_size);
2267 data_tmp += rd[0].data_size;
2268 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2269 GNUNET_MQ_send (ai->client->mq, env);
2277 * Iterate over zone to get attributes
2279 * @param cls our client
2280 * @param ais_msg the iteration message to start
2283 handle_iteration_start (void *cls,
2284 const struct AttributeIterationStartMessage *ais_msg)
2286 struct IdpClient *idp = cls;
2287 struct AttributeIterator *ai;
2289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2290 "Received ATTRIBUTE_ITERATION_START message\n");
2291 ai = GNUNET_new (struct AttributeIterator);
2292 ai->request_id = ntohl (ais_msg->id);
2294 ai->identity = ais_msg->identity;
2296 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
2297 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
2303 &attr_iter_finished,
2305 GNUNET_SERVICE_client_continue (idp->client);
2310 * Handle iteration stop message from client
2312 * @param cls the client
2313 * @param ais_msg the stop message
2316 handle_iteration_stop (void *cls,
2317 const struct AttributeIterationStopMessage *ais_msg)
2319 struct IdpClient *idp = cls;
2320 struct AttributeIterator *ai;
2323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2324 "Received `%s' message\n",
2325 "ATTRIBUTE_ITERATION_STOP");
2326 rid = ntohl (ais_msg->id);
2327 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2328 if (ai->request_id == rid)
2333 GNUNET_SERVICE_client_drop (idp->client);
2336 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
2338 GNUNET_SERVICE_client_continue (idp->client);
2343 * Client requests next attribute from iterator
2345 * @param cls the client
2346 * @param ais_msg the message
2349 handle_iteration_next (void *cls,
2350 const struct AttributeIterationNextMessage *ais_msg)
2352 struct IdpClient *idp = cls;
2353 struct AttributeIterator *ai;
2356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2357 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2358 rid = ntohl (ais_msg->id);
2359 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2360 if (ai->request_id == rid)
2365 GNUNET_SERVICE_client_drop (idp->client);
2368 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2369 GNUNET_SERVICE_client_continue (idp->client);
2373 /******************************************************
2375 ******************************************************/
2378 * Got a ticket. Return to client
2380 * @param cls our ticket iterator
2381 * @param ticket the ticket
2384 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
2386 struct TicketIteration *ti = cls;
2387 struct GNUNET_MQ_Envelope *env;
2388 struct TicketResultMessage *trm;
2390 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2393 /* send empty response to indicate end of list */
2394 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2395 ti->client->ticket_iter_tail,
2400 trm->ticket = *ticket;
2402 trm->id = htonl (ti->r_id);
2403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
2404 GNUNET_MQ_send (ti->client->mq, env);
2411 * Client requests a ticket iteration
2413 * @param cls the client
2414 * @param tis_msg the iteration request message
2417 handle_ticket_iteration_start (
2419 const struct TicketIterationStartMessage *tis_msg)
2421 struct IdpClient *client = cls;
2422 struct TicketIteration *ti;
2424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2425 "Received TICKET_ITERATION_START message\n");
2426 ti = GNUNET_new (struct TicketIteration);
2427 ti->r_id = ntohl (tis_msg->id);
2428 ti->client = client;
2430 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2431 client->ticket_iter_tail,
2434 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
2435 GNUNET_SERVICE_client_continue (client->client);
2440 * Client has had enough tickets
2442 * @param cls the client
2443 * @param tis_msg the stop message
2446 handle_ticket_iteration_stop (void *cls,
2447 const struct TicketIterationStopMessage *tis_msg)
2449 struct IdpClient *client = cls;
2450 struct TicketIteration *ti;
2453 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2454 "Received `%s' message\n",
2455 "TICKET_ITERATION_STOP");
2456 rid = ntohl (tis_msg->id);
2457 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2458 if (ti->r_id == rid)
2463 GNUNET_SERVICE_client_drop (client->client);
2466 RECLAIM_TICKETS_iteration_stop (ti->iter);
2467 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2468 client->ticket_iter_tail,
2471 GNUNET_SERVICE_client_continue (client->client);
2476 * Client requests next result.
2478 * @param cls the client
2479 * @param tis_msg the message
2482 handle_ticket_iteration_next (void *cls,
2483 const struct TicketIterationNextMessage *tis_msg)
2485 struct IdpClient *client = cls;
2486 struct TicketIteration *ti;
2489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2490 "Received TICKET_ITERATION_NEXT message\n");
2491 rid = ntohl (tis_msg->id);
2492 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2493 if (ti->r_id == rid)
2498 GNUNET_SERVICE_client_drop (client->client);
2501 RECLAIM_TICKETS_iteration_next (ti->iter);
2502 GNUNET_SERVICE_client_continue (client->client);
2507 * Main function that will be run
2509 * @param cls closure
2510 * @param c the configuration used
2511 * @param server the service handle
2515 const struct GNUNET_CONFIGURATION_Handle *c,
2516 struct GNUNET_SERVICE_Handle *server)
2520 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
2522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2523 "Unable to initialize TICKETS subsystem.\n");
2524 GNUNET_SCHEDULER_shutdown ();
2527 // Connect to identity and namestore services
2528 nsh = GNUNET_NAMESTORE_connect (cfg);
2531 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2532 "error connecting to namestore");
2535 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2540 * Called whenever a client is disconnected.
2542 * @param cls closure
2543 * @param client identification of the client
2544 * @param app_ctx @a client
2547 client_disconnect_cb (void *cls,
2548 struct GNUNET_SERVICE_Client *client,
2551 struct IdpClient *idp = app_ctx;
2553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
2554 GNUNET_CONTAINER_DLL_remove (client_list_head,
2557 cleanup_client (idp);
2562 * Add a client to our list of active clients.
2565 * @param client client to add
2566 * @param mq message queue for @a client
2567 * @return internal namestore client structure for this client
2570 client_connect_cb (void *cls,
2571 struct GNUNET_SERVICE_Client *client,
2572 struct GNUNET_MQ_Handle *mq)
2574 struct IdpClient *idp;
2576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
2577 idp = GNUNET_new (struct IdpClient);
2578 idp->client = client;
2580 GNUNET_CONTAINER_DLL_insert (client_list_head,
2588 * Define "main" method using service macro.
2590 GNUNET_SERVICE_MAIN (
2592 GNUNET_SERVICE_OPTION_NONE,
2595 &client_disconnect_cb,
2597 GNUNET_MQ_hd_var_size (attribute_store_message,
2598 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2599 struct AttributeStoreMessage,
2601 GNUNET_MQ_hd_var_size (attestation_store_message,
2602 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
2603 struct AttributeStoreMessage,
2605 GNUNET_MQ_hd_var_size (attribute_delete_message,
2606 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2607 struct AttributeDeleteMessage,
2609 GNUNET_MQ_hd_var_size (attestation_delete_message,
2610 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
2611 struct AttributeDeleteMessage,
2613 GNUNET_MQ_hd_var_size (reference_store_message,
2614 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE,
2615 struct AttributeStoreMessage,
2617 GNUNET_MQ_hd_var_size (reference_delete_message,
2618 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE,
2619 struct AttributeDeleteMessage,
2621 GNUNET_MQ_hd_fixed_size (
2623 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2624 struct AttributeIterationStartMessage,
2626 GNUNET_MQ_hd_fixed_size (iteration_next,
2627 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2628 struct AttributeIterationNextMessage,
2630 GNUNET_MQ_hd_fixed_size (iteration_stop,
2631 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2632 struct AttributeIterationStopMessage,
2634 GNUNET_MQ_hd_var_size (issue_ticket_message,
2635 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2636 struct IssueTicketMessage,
2638 GNUNET_MQ_hd_var_size (consume_ticket_message,
2639 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2640 struct ConsumeTicketMessage,
2642 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2643 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2644 struct TicketIterationStartMessage,
2646 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2647 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2648 struct TicketIterationNextMessage,
2650 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2651 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2652 struct TicketIterationStopMessage,
2654 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2655 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2656 struct RevokeTicketMessage,
2658 GNUNET_MQ_handler_end ());
2659 /* end of gnunet-service-reclaim.c */