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/>.
19 * @author Martin Schanzenbach
20 * @file src/reclaim/gnunet-service-reclaim.c
21 * @brief reclaim Service
25 #include "gnunet_util_lib.h"
26 #include "gnunet_constants.h"
27 #include "gnunet_protocols.h"
28 #include "gnunet_identity_service.h"
29 #include "gnunet_gnsrecord_lib.h"
30 #include "gnunet_namestore_service.h"
31 #include "gnunet_abe_lib.h"
32 #include "gnunet_credential_service.h"
33 #include "gnunet_statistics_service.h"
34 #include "gnunet_gns_service.h"
35 #include "gnunet_reclaim_plugin.h"
36 #include "gnunet_reclaim_attribute_lib.h"
37 #include "gnunet_signatures.h"
46 * Normal operation state
48 #define STATE_POST_INIT 1
51 * Minimum interval between updates
53 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
56 * Standard token expiration time
58 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
63 static struct GNUNET_IDENTITY_Handle *identity_handle;
68 static struct GNUNET_RECLAIM_PluginFunctions *TKT_database;
73 static char *db_lib_name;
76 * Token expiration interval
78 static struct GNUNET_TIME_Relative token_expiration_interval;
83 static struct GNUNET_NAMESTORE_Handle *ns_handle;
88 static struct GNUNET_GNS_Handle *gns_handle;
93 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
98 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
103 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
108 static struct GNUNET_SCHEDULER_Task *timeout_task;
113 static struct GNUNET_SCHEDULER_Task *update_task;
117 * Currently processed token
119 static struct IdentityToken *token;
122 * Label for currently processed token
127 * Scopes for processed token
132 * Handle to the statistics service.
134 static struct GNUNET_STATISTICS_Handle *stats;
139 static const struct GNUNET_CONFIGURATION_Handle *cfg;
147 * A ticket iteration operation.
149 struct TicketIteration
154 struct TicketIteration *next;
159 struct TicketIteration *prev;
162 * Client which intiated this zone iteration
164 struct IdpClient *client;
167 * Key of the identity we are iterating over.
169 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
172 * Identity is audience
174 uint32_t is_audience;
177 * The operation id fot the iteration in the response for the client
182 * Offset of the iteration used to address next result of the
183 * iteration in the store
185 * Initialy set to 0 in handle_iteration_start
186 * Incremented with by every call to handle_iteration_next
195 * Callback after an ABE bootstrap
198 * @param abe_key the ABE key that exists or was created
201 (*AbeBootstrapResult) (void *cls,
202 struct GNUNET_ABE_AbeMasterKey *abe_key);
205 struct AbeBootstrapHandle
208 * Function to call when finished
210 AbeBootstrapResult proc;
218 * Key of the zone we are iterating over.
220 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
223 * Namestore Queue Entry
225 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
228 * The issuer egos ABE master key
230 struct GNUNET_ABE_AbeMasterKey *abe_key;
234 * An attribute iteration operation.
236 struct AttributeIterator
239 * Next element in the DLL
241 struct AttributeIterator *next;
244 * Previous element in the DLL
246 struct AttributeIterator *prev;
249 * IDP client which intiated this zone iteration
251 struct IdpClient *client;
254 * Key of the zone we are iterating over.
256 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
259 * The issuer egos ABE master key
261 struct GNUNET_ABE_AbeMasterKey *abe_key;
266 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
269 * The operation id fot the zone iteration in the response for the client
286 struct GNUNET_SERVICE_Client *client;
289 * Message queue for transmission to @e client
291 struct GNUNET_MQ_Handle *mq;
295 * Attribute iteration operations in
296 * progress initiated by this client
298 struct AttributeIterator *attr_iter_head;
302 * Attribute iteration operations
303 * in progress initiated by this client
305 struct AttributeIterator *attr_iter_tail;
308 * Head of DLL of ticket iteration ops
310 struct TicketIteration *ticket_iter_head;
313 * Tail of DLL of ticket iteration ops
315 struct TicketIteration *ticket_iter_tail;
318 * Head of DLL of ticket revocation ops
320 struct TicketRevocationHandle *revoke_op_head;
323 * Tail of DLL of ticket revocation ops
325 struct TicketRevocationHandle *revoke_op_tail;
328 * Head of DLL of ticket issue ops
330 struct TicketIssueHandle *issue_op_head;
333 * Tail of DLL of ticket issue ops
335 struct TicketIssueHandle *issue_op_tail;
338 * Head of DLL of ticket consume ops
340 struct ConsumeTicketHandle *consume_op_head;
343 * Tail of DLL of ticket consume ops
345 struct ConsumeTicketHandle *consume_op_tail;
348 * Head of DLL of attribute store ops
350 struct AttributeStoreHandle *store_op_head;
353 * Tail of DLL of attribute store ops
355 struct AttributeStoreHandle *store_op_tail;
359 struct AttributeStoreHandle
364 struct AttributeStoreHandle *next;
369 struct AttributeStoreHandle *prev;
374 struct IdpClient *client;
379 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
384 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
387 * The issuer egos ABE master key
389 struct GNUNET_ABE_AbeMasterKey *abe_key;
394 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
397 * The attribute to store
399 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
402 * The attribute expiration interval
404 struct GNUNET_TIME_Relative exp;
414 struct ParallelLookup;
416 struct ConsumeTicketHandle
421 struct ConsumeTicketHandle *next;
426 struct ConsumeTicketHandle *prev;
431 struct IdpClient *client;
436 struct GNUNET_RECLAIM_Ticket ticket;
441 struct GNUNET_GNS_LookupRequest *lookup_request;
446 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
451 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
456 struct ParallelLookup *parallel_lookups_head;
461 struct ParallelLookup *parallel_lookups_tail;
466 struct GNUNET_SCHEDULER_Task *kill_task;
471 struct GNUNET_ABE_AbeKey *key;
476 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
481 struct GNUNET_TIME_Absolute lookup_start_time;
490 * Handle for a parallel GNS lookup job
492 struct ParallelLookup
495 struct ParallelLookup *next;
498 struct ParallelLookup *prev;
500 /* The GNS request */
501 struct GNUNET_GNS_LookupRequest *lookup_request;
503 /* The handle the return to */
504 struct ConsumeTicketHandle *handle;
509 struct GNUNET_TIME_Absolute lookup_start_time;
511 /* The label to look up */
516 * Ticket revocation request handle
518 struct TicketRevocationHandle
523 struct TicketRevocationHandle *prev;
528 struct TicketRevocationHandle *next;
533 struct IdpClient *client;
536 * Attributes to reissue
538 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
541 * Attributes to revoke
543 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *rvk_attrs;
548 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
553 struct GNUNET_RECLAIM_Ticket ticket;
558 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
563 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
568 struct GNUNET_ABE_AbeMasterKey *abe_key;
584 * Ticket issue request handle
586 struct TicketIssueHandle
591 struct TicketIssueHandle *prev;
596 struct TicketIssueHandle *next;
601 struct IdpClient *client;
604 * Attributes to issue
606 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
611 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
616 struct GNUNET_RECLAIM_Ticket ticket;
621 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
631 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
639 struct EgoEntry *next;
644 struct EgoEntry *prev;
649 struct GNUNET_IDENTITY_Ego *ego;
652 * Attribute map. Contains the attributes as json_t
654 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
669 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
672 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
674 GNUNET_free (db_lib_name);
676 if (NULL != timeout_task)
677 GNUNET_SCHEDULER_cancel (timeout_task);
678 if (NULL != update_task)
679 GNUNET_SCHEDULER_cancel (update_task);
680 if (NULL != identity_handle)
681 GNUNET_IDENTITY_disconnect (identity_handle);
682 if (NULL != gns_handle)
683 GNUNET_GNS_disconnect (gns_handle);
684 if (NULL != credential_handle)
685 GNUNET_CREDENTIAL_disconnect (credential_handle);
687 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
689 GNUNET_NAMESTORE_cancel (ns_qe);
690 if (NULL != ns_handle)
691 GNUNET_NAMESTORE_disconnect (ns_handle);
692 GNUNET_free_non_null (token);
693 GNUNET_free_non_null (label);
703 do_shutdown (void *cls)
705 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
706 "Shutting down...\n");
711 * Finished storing newly bootstrapped ABE key
714 bootstrap_store_cont (void *cls,
718 struct AbeBootstrapHandle *abh = cls;
719 if (GNUNET_SYSERR == success)
721 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
722 "Failed to bootstrap ABE master %s\n",
724 abh->proc (abh->proc_cls, NULL);
725 GNUNET_free (abh->abe_key);
729 abh->proc (abh->proc_cls, abh->abe_key);
734 * Generates and stores a new ABE key
737 bootstrap_store_task (void *cls)
739 struct AbeBootstrapHandle *abh = cls;
740 struct GNUNET_GNSRECORD_Data rd[1];
743 rd[0].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key,
746 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
747 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
748 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
749 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
754 &bootstrap_store_cont,
760 * Error checking for ABE master
763 bootstrap_abe_error (void *cls)
765 struct AbeBootstrapHandle *abh = cls;
766 abh->proc (abh->proc_cls, NULL);
772 * Handle ABE lookup in namestore
775 bootstrap_abe_result (void *cls,
776 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
778 unsigned int rd_count,
779 const struct GNUNET_GNSRECORD_Data *rd)
781 struct AbeBootstrapHandle *abh = cls;
782 struct GNUNET_ABE_AbeMasterKey *abe_key;
784 for (uint32_t i=0;i<rd_count;i++) {
785 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
787 abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data,
789 abh->proc (abh->proc_cls, abe_key);
794 //No ABE master found, bootstrapping...
795 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
796 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
800 * Bootstrap ABE master if it does not yet exists.
801 * Will call the AbeBootstrapResult processor when done.
802 * will always recreate the ABE key of GNUNET_YES == recreate
805 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
806 AbeBootstrapResult proc,
810 struct AbeBootstrapHandle *abh;
812 abh = GNUNET_new (struct AbeBootstrapHandle);
815 abh->identity = *identity;
816 if (GNUNET_YES == recreate)
818 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
819 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
821 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
824 &bootstrap_abe_error,
826 &bootstrap_abe_result,
834 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
835 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
836 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
838 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
840 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
843 static const char ctx_key[] = "gnuid-aes-ctx-key";
844 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
845 new_key_hash, sizeof (struct GNUNET_HashCode),
846 ctx_key, strlen (ctx_key),
848 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
849 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
850 new_key_hash, sizeof (struct GNUNET_HashCode),
851 ctx_iv, strlen (ctx_iv),
857 * Cleanup ticket consume handle
858 * @param handle the handle to clean up
861 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
863 if (NULL != handle->attrs)
864 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
865 if (NULL != handle->ns_qe)
866 GNUNET_NAMESTORE_cancel (handle->ns_qe);
867 GNUNET_free (handle);
872 send_ticket_result (struct IdpClient *client,
874 const struct GNUNET_RECLAIM_Ticket *ticket,
875 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
877 struct TicketResultMessage *irm;
878 struct GNUNET_MQ_Envelope *env;
879 struct GNUNET_RECLAIM_Ticket *ticket_buf;
881 /* store ticket in DB */
882 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
886 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
887 "Unable to store ticket after issue\n");
891 env = GNUNET_MQ_msg_extra (irm,
892 sizeof (struct GNUNET_RECLAIM_Ticket),
893 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
894 ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
895 *ticket_buf = *ticket;
896 irm->id = htonl (r_id);
897 GNUNET_MQ_send (client->mq,
902 store_ticket_issue_cont (void *cls,
906 struct TicketIssueHandle *handle = cls;
908 handle->ns_qe = NULL;
909 GNUNET_CONTAINER_DLL_remove (handle->client->issue_op_head,
910 handle->client->issue_op_tail,
912 if (GNUNET_SYSERR == success)
914 cleanup_ticket_issue_handle (handle);
915 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
917 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
920 send_ticket_result (handle->client,
924 cleanup_ticket_issue_handle (handle);
930 serialize_abe_keyinfo2 (const struct GNUNET_RECLAIM_Ticket *ticket,
931 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
932 const struct GNUNET_ABE_AbeKey *rp_key,
933 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
936 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
937 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
939 char *serialized_key;
945 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
946 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
947 struct GNUNET_HashCode new_key_hash;
950 size = GNUNET_ABE_cpabe_serialize_key (rp_key,
951 (void**)&serialized_key);
953 for (le = attrs->list_head; NULL != le; le = le->next) {
954 attrs_str_len += strlen (le->claim->name) + 1;
956 buf = GNUNET_malloc (attrs_str_len + size);
958 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
959 "Writing attributes\n");
960 for (le = attrs->list_head; NULL != le; le = le->next) {
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962 "%s\n", le->claim->name);
965 GNUNET_memcpy (write_ptr,
967 strlen (le->claim->name));
968 write_ptr[strlen (le->claim->name)] = ',';
969 write_ptr += strlen (le->claim->name) + 1;
972 write_ptr[0] = '\0'; //replace last , with a 0-terminator
974 GNUNET_memcpy (write_ptr,
977 GNUNET_free (serialized_key);
978 // ECDH keypair E = eG
979 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
980 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
982 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
983 // Derived key K = H(eB)
984 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
987 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
988 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
989 size + attrs_str_len,
992 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
994 GNUNET_memcpy (*result,
996 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
997 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1000 GNUNET_free (enc_keyinfo);
1002 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
1008 issue_ticket_after_abe_bootstrap (void *cls,
1009 struct GNUNET_ABE_AbeMasterKey *abe_key)
1011 struct TicketIssueHandle *ih = cls;
1012 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1013 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1014 struct GNUNET_GNSRECORD_Data code_record[1];
1015 struct GNUNET_ABE_AbeKey *rp_key;
1016 char *code_record_data;
1022 size_t code_record_len;
1024 //Create new ABE key for RP
1026 for (le = ih->attrs->list_head; NULL != le; le = le->next)
1028 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1030 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
1031 GNUNET_asprintf (&policy, "%s_%lu",
1033 le->claim->version);
1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1035 "Adding attribute to key: %s\n",
1041 rp_key = GNUNET_ABE_cpabe_create_key (abe_key,
1044 //TODO review this wireformat
1045 code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
1050 code_record[0].data = code_record_data;
1051 code_record[0].data_size = code_record_len;
1052 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1053 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1054 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1056 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
1059 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1064 &store_ticket_issue_cont,
1066 //for (; i > 0; i--)
1067 // GNUNET_free (attrs[i-1]);
1068 GNUNET_free (ecdhe_privkey);
1069 GNUNET_free (label);
1070 GNUNET_free (attrs);
1071 GNUNET_free (code_record_data);
1072 GNUNET_ABE_cpabe_delete_key (rp_key,
1074 GNUNET_ABE_cpabe_delete_master_key (abe_key);
1079 check_issue_ticket_message(void *cls,
1080 const struct IssueTicketMessage *im)
1084 size = ntohs (im->header.size);
1085 if (size <= sizeof (struct IssueTicketMessage))
1088 return GNUNET_SYSERR;
1095 handle_issue_ticket_message (void *cls,
1096 const struct IssueTicketMessage *im)
1098 struct TicketIssueHandle *ih;
1099 struct IdpClient *idp = cls;
1102 ih = GNUNET_new (struct TicketIssueHandle);
1103 attrs_len = ntohs (im->attr_len);
1104 ih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
1105 ih->r_id = ntohl (im->id);
1107 ih->identity = im->identity;
1108 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1109 &ih->ticket.identity);
1110 ih->ticket.audience = im->rp;
1112 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1114 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head,
1117 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1118 GNUNET_SERVICE_client_continue (idp->client);
1122 /**********************************************************
1124 **********************************************************/
1127 * Cleanup revoke handle
1129 * @param rh the ticket revocation handle
1132 cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
1134 if (NULL != rh->attrs)
1135 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs);
1136 if (NULL != rh->rvk_attrs)
1137 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs);
1138 if (NULL != rh->abe_key)
1139 GNUNET_ABE_cpabe_delete_master_key (rh->abe_key);
1140 if (NULL != rh->ns_qe)
1141 GNUNET_NAMESTORE_cancel (rh->ns_qe);
1142 if (NULL != rh->ns_it)
1143 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
1149 * Send revocation result
1151 * @param rh ticket revocation handle
1152 * @param success GNUNET_OK if successful result
1155 send_revocation_finished (struct TicketRevocationHandle *rh,
1158 struct GNUNET_MQ_Envelope *env;
1159 struct RevokeTicketResultMessage *trm;
1161 GNUNET_break(TKT_database->delete_ticket (TKT_database->cls,
1164 env = GNUNET_MQ_msg (trm,
1165 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
1166 trm->id = htonl (rh->r_id);
1167 trm->success = htonl (success);
1168 GNUNET_MQ_send (rh->client->mq,
1170 GNUNET_CONTAINER_DLL_remove (rh->client->revoke_op_head,
1171 rh->client->revoke_op_tail,
1177 * Process ticket from database
1179 * @param cls struct TicketIterationProcResult
1180 * @param ticket the ticket
1181 * @param attrs the attributes
1184 ticket_reissue_proc (void *cls,
1185 const struct GNUNET_RECLAIM_Ticket *ticket,
1186 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
1189 revocation_reissue_tickets (struct TicketRevocationHandle *rh);
1192 static void reissue_next (void *cls)
1194 struct TicketRevocationHandle *rh = cls;
1195 revocation_reissue_tickets (rh);
1200 reissue_ticket_cont (void *cls,
1204 struct TicketRevocationHandle *rh = cls;
1207 if (GNUNET_SYSERR == success)
1209 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1211 send_revocation_finished (rh, GNUNET_SYSERR);
1212 cleanup_revoke_ticket_handle (rh);
1216 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1221 * Process ticket from database
1223 * @param cls struct TicketIterationProcResult
1224 * @param ticket the ticket
1225 * @param attrs the attributes
1228 ticket_reissue_proc (void *cls,
1229 const struct GNUNET_RECLAIM_Ticket *ticket,
1230 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
1232 struct TicketRevocationHandle *rh = cls;
1233 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1234 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le_rollover;
1235 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1236 struct GNUNET_GNSRECORD_Data code_record[1];
1237 struct GNUNET_ABE_AbeKey *rp_key;
1238 char *code_record_data;
1245 size_t code_record_len;
1250 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1251 "Iteration done\n");
1255 if (0 == memcmp (&ticket->audience,
1256 &rh->ticket.audience,
1257 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1260 "Do not reissue for this identity.!\n");
1261 label = GNUNET_STRINGS_data_to_string_alloc (&rh->ticket.rnd,
1264 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1269 &reissue_ticket_cont,
1272 GNUNET_free (label);
1277 * Check if any attribute of this ticket intersects with a rollover attribute
1279 reissue_ticket = GNUNET_NO;
1280 for (le = attrs->list_head; NULL != le; le = le->next)
1282 for (le_rollover = rh->rvk_attrs->list_head;
1283 NULL != le_rollover;
1284 le_rollover = le_rollover->next)
1286 if (0 == strcmp (le_rollover->claim->name,
1289 reissue_ticket = GNUNET_YES;
1290 le->claim->version = le_rollover->claim->version;
1295 if (GNUNET_NO == reissue_ticket)
1297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1298 "Skipping ticket.\n");
1301 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1307 //Create new ABE key for RP
1310 /* If this is the RP we want to revoke attributes of, the do so */
1312 for (le = attrs->list_head; NULL != le; le = le->next)
1314 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1316 for (le = attrs->list_head; NULL != le; le = le->next) {
1317 GNUNET_asprintf (&policy, "%s_%lu",
1319 le->claim->version);
1320 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1321 "Recreating key with %s\n", policy);
1322 attr_arr[i] = policy;
1326 rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key,
1329 //TODO review this wireformat
1330 code_record_len = serialize_abe_keyinfo2 (ticket,
1335 code_record[0].data = code_record_data;
1336 code_record[0].data_size = code_record_len;
1337 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1338 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1339 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1341 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1344 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1349 &reissue_ticket_cont,
1351 //for (; i > 0; i--)
1352 // GNUNET_free (attr_arr[i-1]);
1353 GNUNET_free (ecdhe_privkey);
1354 GNUNET_free (label);
1355 GNUNET_free (attr_arr);
1356 GNUNET_free (code_record_data);
1357 GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES);
1361 /* Prototype for below function */
1363 attr_reenc_cont (void *cls,
1368 revocation_reissue_tickets (struct TicketRevocationHandle *rh)
1371 /* Done, issue new keys */
1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1373 "Revocation Phase III: Reissuing Tickets\n");
1374 if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
1375 &rh->ticket.identity,
1378 &ticket_reissue_proc,
1383 if (GNUNET_NO == ret)
1385 send_revocation_finished (rh, GNUNET_OK);
1386 cleanup_revoke_ticket_handle (rh);
1392 * Failed to check for attribute
1395 check_attr_error (void *cls)
1397 struct TicketRevocationHandle *rh = cls;
1398 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1399 "Unable to check for existing attribute\n");
1401 send_revocation_finished (rh, GNUNET_SYSERR);
1402 cleanup_revoke_ticket_handle (rh);
1407 * Revoke next attribte by reencryption with
1411 reenc_next_attribute (void *cls);
1414 * Check for existing attribute and overwrite
1417 check_attr_cb (void *cls,
1418 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1420 unsigned int rd_count,
1421 const struct GNUNET_GNSRECORD_Data *rd_old)
1423 struct TicketRevocationHandle *rh = cls;
1424 struct GNUNET_GNSRECORD_Data rd[1];
1434 if (1 != rd_count) {
1435 GNUNET_SCHEDULER_add_now (&reenc_next_attribute,
1440 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
1441 buf = GNUNET_malloc (buf_size);
1442 rh->attrs->list_head->claim->version++;
1443 GNUNET_RECLAIM_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
1445 GNUNET_asprintf (&policy, "%s_%lu",
1446 rh->attrs->list_head->claim->name,
1447 rh->attrs->list_head->claim->version);
1448 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1449 "Encrypting with policy %s\n", policy);
1451 * Encrypt the attribute value and store in namestore
1453 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1459 if (GNUNET_SYSERR == enc_size)
1461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1462 "Unable to re-encrypt with policy %s\n",
1464 GNUNET_free (policy);
1465 send_revocation_finished (rh, GNUNET_SYSERR);
1466 cleanup_revoke_ticket_handle (rh);
1469 GNUNET_free (policy);
1471 rd[0].data_size = enc_size + sizeof (uint32_t);
1472 rd_buf = GNUNET_malloc (rd[0].data_size);
1473 attr_ver = htonl (rh->attrs->list_head->claim->version);
1474 GNUNET_memcpy (rd_buf,
1477 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1480 rd[0].data = rd_buf;
1481 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1482 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1483 rd[0].expiration_time = rd_old[0].expiration_time;
1484 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1486 rh->attrs->list_head->claim->name,
1491 GNUNET_free (enc_buf);
1492 GNUNET_free (rd_buf);
1497 * Revoke next attribte by reencryption with
1501 reenc_next_attribute (void *cls)
1503 struct TicketRevocationHandle *rh = cls;
1504 if (NULL == rh->attrs->list_head)
1506 revocation_reissue_tickets (rh);
1509 /* First check if attribute still exists */
1510 rh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1512 rh->attrs->list_head->claim->name,
1521 * Namestore callback after revoked attribute
1525 attr_reenc_cont (void *cls,
1529 struct TicketRevocationHandle *rh = cls;
1530 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1533 if (GNUNET_SYSERR == success)
1535 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1536 "Failed to reencrypt attribute %s\n",
1538 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1541 if (NULL == rh->attrs->list_head)
1543 revocation_reissue_tickets (rh);
1546 le = rh->attrs->list_head;
1547 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1548 rh->attrs->list_tail,
1550 GNUNET_assert (NULL != rh->rvk_attrs);
1551 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1552 rh->rvk_attrs->list_tail,
1556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1557 "Re-encrypting next attribute\n");
1558 reenc_next_attribute (rh);
1563 process_attributes_to_update (void *cls,
1564 const struct GNUNET_RECLAIM_Ticket *ticket,
1565 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
1567 struct TicketRevocationHandle *rh = cls;
1569 rh->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
1570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1571 "Revocation Phase I: Collecting attributes\n");
1572 /* Reencrypt all attributes with new key */
1573 if (NULL == rh->attrs->list_head)
1575 /* No attributes to reencrypt */
1576 send_revocation_finished (rh, GNUNET_OK);
1577 cleanup_revoke_ticket_handle (rh);
1580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1581 "Revocation Phase II: Re-encrypting attributes\n");
1582 reenc_next_attribute (rh);
1590 get_ticket_after_abe_bootstrap (void *cls,
1591 struct GNUNET_ABE_AbeMasterKey *abe_key)
1593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1594 "Finished ABE bootstrap\n");
1595 struct TicketRevocationHandle *rh = cls;
1596 rh->abe_key = abe_key;
1597 TKT_database->get_ticket_attributes (TKT_database->cls,
1599 &process_attributes_to_update,
1604 check_revoke_ticket_message(void *cls,
1605 const struct RevokeTicketMessage *im)
1609 size = ntohs (im->header.size);
1610 if (size <= sizeof (struct RevokeTicketMessage))
1613 return GNUNET_SYSERR;
1619 handle_revoke_ticket_message (void *cls,
1620 const struct RevokeTicketMessage *rm)
1622 struct TicketRevocationHandle *rh;
1623 struct IdpClient *idp = cls;
1624 struct GNUNET_RECLAIM_Ticket *ticket;
1626 rh = GNUNET_new (struct TicketRevocationHandle);
1627 ticket = (struct GNUNET_RECLAIM_Ticket*)&rm[1];
1628 rh->rvk_attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1629 rh->ticket = *ticket;
1630 rh->r_id = ntohl (rm->id);
1632 rh->identity = rm->identity;
1633 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1634 &rh->ticket.identity);
1635 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head,
1636 idp->revoke_op_tail,
1638 bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO);
1639 GNUNET_SERVICE_client_continue (idp->client);
1644 * Cleanup ticket consume handle
1645 * @param handle the handle to clean up
1648 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1650 struct ParallelLookup *lu;
1651 struct ParallelLookup *tmp;
1652 if (NULL != handle->lookup_request)
1653 GNUNET_GNS_lookup_cancel (handle->lookup_request);
1654 for (lu = handle->parallel_lookups_head;
1656 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1657 GNUNET_free (lu->label);
1659 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1660 handle->parallel_lookups_tail,
1666 if (NULL != handle->key)
1667 GNUNET_ABE_cpabe_delete_key (handle->key,
1669 if (NULL != handle->attrs)
1670 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
1671 GNUNET_free (handle);
1677 check_consume_ticket_message(void *cls,
1678 const struct ConsumeTicketMessage *cm)
1682 size = ntohs (cm->header.size);
1683 if (size <= sizeof (struct ConsumeTicketMessage))
1686 return GNUNET_SYSERR;
1692 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1693 const struct GNUNET_GNSRECORD_Data *rd)
1695 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1696 "Parallel lookup finished (count=%u)\n", rd_count);
1697 struct ParallelLookup *parallel_lookup = cls;
1698 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1699 struct ConsumeTicketResultMessage *crm;
1700 struct GNUNET_MQ_Envelope *env;
1701 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
1702 struct GNUNET_TIME_Absolute decrypt_duration;
1708 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1709 handle->parallel_lookups_tail,
1711 GNUNET_free (parallel_lookup->label);
1713 GNUNET_STATISTICS_update (stats,
1714 "attribute_lookup_time_total",
1715 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
1717 GNUNET_STATISTICS_update (stats,
1718 "attribute_lookups_count",
1723 GNUNET_free (parallel_lookup);
1725 GNUNET_break(0);//TODO
1726 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1728 decrypt_duration = GNUNET_TIME_absolute_get ();
1729 attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t),
1730 rd->data_size - sizeof (uint32_t),
1733 if (GNUNET_SYSERR != attr_len)
1735 GNUNET_STATISTICS_update (stats,
1736 "abe_decrypt_time_total",
1737 GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us,
1739 GNUNET_STATISTICS_update (stats,
1740 "abe_decrypt_count",
1744 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1745 attr_le->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (data,
1747 attr_le->claim->version = ntohl(*(uint32_t*)rd->data);
1748 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1749 handle->attrs->list_tail,
1754 if (NULL != handle->parallel_lookups_head)
1755 return; //Wait for more
1756 /* Else we are done */
1758 /* Store ticket in DB */
1759 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1763 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1764 "Unable to store ticket after consume\n");
1768 GNUNET_SCHEDULER_cancel (handle->kill_task);
1769 attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (handle->attrs);
1770 env = GNUNET_MQ_msg_extra (crm,
1772 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
1773 crm->id = htonl (handle->r_id);
1774 crm->attrs_len = htons (attrs_len);
1775 crm->identity = handle->ticket.identity;
1776 data_tmp = (char *) &crm[1];
1777 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (handle->attrs,
1779 GNUNET_MQ_send (handle->client->mq, env);
1780 GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head,
1781 handle->client->consume_op_tail,
1783 cleanup_consume_ticket_handle (handle);
1787 abort_parallel_lookups2 (void *cls)
1789 struct ConsumeTicketHandle *handle = cls;
1790 struct ParallelLookup *lu;
1791 struct ParallelLookup *tmp;
1792 struct AttributeResultMessage *arm;
1793 struct GNUNET_MQ_Envelope *env;
1795 handle->kill_task = NULL;
1796 for (lu = handle->parallel_lookups_head;
1798 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1799 GNUNET_free (lu->label);
1801 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1802 handle->parallel_lookups_tail,
1807 env = GNUNET_MQ_msg (arm,
1808 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1809 arm->id = htonl (handle->r_id);
1810 arm->attr_len = htons (0);
1811 GNUNET_MQ_send (handle->client->mq, env);
1817 process_consume_abe_key (void *cls, uint32_t rd_count,
1818 const struct GNUNET_GNSRECORD_Data *rd)
1820 struct ConsumeTicketHandle *handle = cls;
1821 struct GNUNET_HashCode new_key_hash;
1822 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1823 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1824 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1825 struct ParallelLookup *parallel_lookup;
1830 handle->lookup_request = NULL;
1833 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1834 "Number of keys %d != 1.",
1836 cleanup_consume_ticket_handle (handle);
1837 GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head,
1838 handle->client->consume_op_tail,
1840 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1845 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1847 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1849 //Calculate symmetric key from ecdh parameters
1850 GNUNET_assert (GNUNET_OK ==
1851 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1854 create_sym_key_from_ecdh (&new_key_hash,
1857 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1858 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1864 "Decrypted bytes: %zd Expected bytes: %zd\n",
1865 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1866 GNUNET_STATISTICS_update (stats,
1867 "abe_key_lookup_time_total",
1868 GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
1870 GNUNET_STATISTICS_update (stats,
1871 "abe_key_lookups_count",
1874 scopes = GNUNET_strdup (buf);
1875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1876 "Scopes %s\n", scopes);
1877 handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1878 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1879 - strlen (scopes) - 1);
1881 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1883 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1884 "Looking up %s\n", scope);
1885 parallel_lookup = GNUNET_new (struct ParallelLookup);
1886 parallel_lookup->handle = handle;
1887 parallel_lookup->label = GNUNET_strdup (scope);
1888 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
1889 parallel_lookup->lookup_request
1890 = GNUNET_GNS_lookup (gns_handle,
1892 &handle->ticket.identity,
1893 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1894 GNUNET_GNS_LO_DEFAULT,
1895 &process_parallel_lookup2,
1897 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1898 handle->parallel_lookups_tail,
1901 GNUNET_free (scopes);
1903 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1904 &abort_parallel_lookups2,
1910 handle_consume_ticket_message (void *cls,
1911 const struct ConsumeTicketMessage *cm)
1913 struct ConsumeTicketHandle *ch;
1914 struct IdpClient *idp = cls;
1917 ch = GNUNET_new (struct ConsumeTicketHandle);
1918 ch->r_id = ntohl (cm->id);
1920 ch->identity = cm->identity;
1921 ch->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1922 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1924 ch->ticket = *((struct GNUNET_RECLAIM_Ticket*)&cm[1]);
1925 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1928 "Looking for ABE key under %s\n", rnd_label);
1929 ch->lookup_start_time = GNUNET_TIME_absolute_get ();
1931 = GNUNET_GNS_lookup (gns_handle,
1933 &ch->ticket.identity,
1934 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1935 GNUNET_GNS_LO_DEFAULT,
1936 &process_consume_abe_key,
1938 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head,
1939 idp->consume_op_tail,
1941 GNUNET_free (rnd_label);
1942 GNUNET_SERVICE_client_continue (idp->client);
1946 * Cleanup attribute store handle
1948 * @param handle handle to clean up
1951 cleanup_as_handle (struct AttributeStoreHandle *handle)
1953 if (NULL != handle->ns_qe)
1954 GNUNET_NAMESTORE_cancel (handle->ns_qe);
1955 if (NULL != handle->claim)
1956 GNUNET_free (handle->claim);
1957 if (NULL != handle->abe_key)
1958 GNUNET_ABE_cpabe_delete_master_key (handle->abe_key);
1959 GNUNET_free (handle);
1963 attr_store_cont (void *cls,
1967 struct AttributeStoreHandle *as_handle = cls;
1968 struct GNUNET_MQ_Envelope *env;
1969 struct AttributeStoreResultMessage *acr_msg;
1971 as_handle->ns_qe = NULL;
1972 GNUNET_CONTAINER_DLL_remove (as_handle->client->store_op_head,
1973 as_handle->client->store_op_tail,
1976 if (GNUNET_SYSERR == success)
1978 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1979 "Failed to store attribute %s\n",
1981 cleanup_as_handle (as_handle);
1982 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1987 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1988 env = GNUNET_MQ_msg (acr_msg,
1989 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE);
1990 acr_msg->id = htonl (as_handle->r_id);
1991 acr_msg->op_result = htonl (GNUNET_OK);
1992 GNUNET_MQ_send (as_handle->client->mq,
1994 cleanup_as_handle (as_handle);
1998 attr_store_task (void *cls)
2000 struct AttributeStoreHandle *as_handle = cls;
2001 struct GNUNET_GNSRECORD_Data rd[1];
2010 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2011 "Storing attribute\n");
2012 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (as_handle->claim);
2013 buf = GNUNET_malloc (buf_size);
2015 GNUNET_RECLAIM_ATTRIBUTE_serialize (as_handle->claim,
2018 GNUNET_asprintf (&policy,
2020 as_handle->claim->name,
2021 as_handle->claim->version);
2022 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2023 "Encrypting with policy %s\n", policy);
2025 * Encrypt the attribute value and store in namestore
2027 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
2032 if (GNUNET_SYSERR == enc_size)
2034 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2035 "Failed to encrypt with policy %s\n",
2037 GNUNET_CONTAINER_DLL_remove (as_handle->client->store_op_head,
2038 as_handle->client->store_op_tail,
2041 cleanup_as_handle (as_handle);
2043 GNUNET_free (policy);
2044 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2048 GNUNET_free (policy);
2049 rd[0].data_size = enc_size + sizeof (uint32_t);
2050 rd_buf = GNUNET_malloc (rd[0].data_size);
2051 attr_ver = htonl (as_handle->claim->version);
2052 GNUNET_memcpy (rd_buf,
2055 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
2058 rd[0].data = rd_buf;
2059 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
2060 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
2061 rd[0].expiration_time = as_handle->exp.rel_value_us;
2062 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
2063 &as_handle->identity,
2064 as_handle->claim->name,
2069 GNUNET_free (enc_buf);
2070 GNUNET_free (rd_buf);
2075 store_after_abe_bootstrap (void *cls,
2076 struct GNUNET_ABE_AbeMasterKey *abe_key)
2078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2079 "Finished ABE bootstrap\n");
2080 struct AttributeStoreHandle *ash = cls;
2081 ash->abe_key = abe_key;
2082 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
2086 check_attribute_store_message(void *cls,
2087 const struct AttributeStoreMessage *sam)
2091 size = ntohs (sam->header.size);
2092 if (size <= sizeof (struct AttributeStoreMessage))
2095 return GNUNET_SYSERR;
2102 handle_attribute_store_message (void *cls,
2103 const struct AttributeStoreMessage *sam)
2105 struct AttributeStoreHandle *as_handle;
2106 struct IdpClient *idp = cls;
2108 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2109 "Received ATTRIBUTE_STORE message\n");
2111 data_len = ntohs (sam->attr_len);
2113 as_handle = GNUNET_new (struct AttributeStoreHandle);
2114 as_handle->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&sam[1],
2117 as_handle->r_id = ntohl (sam->id);
2118 as_handle->identity = sam->identity;
2119 as_handle->exp.rel_value_us = GNUNET_ntohll (sam->exp);
2120 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
2121 &as_handle->identity_pkey);
2123 GNUNET_SERVICE_client_continue (idp->client);
2124 as_handle->client = idp;
2125 GNUNET_CONTAINER_DLL_insert (idp->store_op_head,
2128 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
2132 cleanup_attribute_iter_handle (struct AttributeIterator *ai)
2134 if (NULL != ai->abe_key)
2135 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2140 attr_iter_error (void *cls)
2142 struct AttributeIterator *ai = cls;
2144 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2145 "Failed to iterate over attributes\n");
2146 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
2147 ai->client->attr_iter_tail,
2149 cleanup_attribute_iter_handle (ai);
2150 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2154 attr_iter_finished (void *cls)
2156 struct AttributeIterator *ai = cls;
2157 struct GNUNET_MQ_Envelope *env;
2158 struct AttributeResultMessage *arm;
2160 env = GNUNET_MQ_msg (arm,
2161 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2162 arm->id = htonl (ai->request_id);
2163 arm->attr_len = htons (0);
2164 GNUNET_MQ_send (ai->client->mq, env);
2165 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
2166 ai->client->attr_iter_tail,
2168 cleanup_attribute_iter_handle (ai);
2172 attr_iter_cb (void *cls,
2173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
2175 unsigned int rd_count,
2176 const struct GNUNET_GNSRECORD_Data *rd)
2178 struct AttributeIterator *ai = cls;
2179 struct AttributeResultMessage *arm;
2180 struct GNUNET_ABE_AbeKey *key;
2181 struct GNUNET_MQ_Envelope *env;
2182 ssize_t msg_extra_len;
2191 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2196 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type)
2198 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2202 attr_ver = ntohl(*((uint32_t*)rd->data));
2203 GNUNET_asprintf (&policy, "%s_%lu",
2207 key = GNUNET_ABE_cpabe_create_key (ai->abe_key,
2209 msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t),
2210 rd->data_size-sizeof (uint32_t),
2213 if (GNUNET_SYSERR == msg_extra_len)
2215 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2220 GNUNET_ABE_cpabe_delete_key (key,
2222 //GNUNET_free (policy);
2223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2224 "Found attribute: %s\n", label);
2225 env = GNUNET_MQ_msg_extra (arm,
2227 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2228 arm->id = htonl (ai->request_id);
2229 arm->attr_len = htons (msg_extra_len);
2230 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
2232 data_tmp = (char *) &arm[1];
2233 GNUNET_memcpy (data_tmp,
2236 GNUNET_MQ_send (ai->client->mq, env);
2237 GNUNET_free (attr_ser);
2238 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2244 iterate_after_abe_bootstrap (void *cls,
2245 struct GNUNET_ABE_AbeMasterKey *abe_key)
2247 struct AttributeIterator *ai = cls;
2248 ai->abe_key = abe_key;
2249 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
2255 &attr_iter_finished,
2261 iterate_next_after_abe_bootstrap (void *cls,
2262 struct GNUNET_ABE_AbeMasterKey *abe_key)
2264 struct AttributeIterator *ai = cls;
2265 ai->abe_key = abe_key;
2266 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2273 handle_iteration_start (void *cls,
2274 const struct AttributeIterationStartMessage *ais_msg)
2276 struct IdpClient *idp = cls;
2277 struct AttributeIterator *ai;
2279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2280 "Received ATTRIBUTE_ITERATION_START message\n");
2281 ai = GNUNET_new (struct AttributeIterator);
2282 ai->request_id = ntohl (ais_msg->id);
2284 ai->identity = ais_msg->identity;
2286 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head,
2287 idp->attr_iter_tail,
2289 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
2290 GNUNET_SERVICE_client_continue (idp->client);
2295 handle_iteration_stop (void *cls,
2296 const struct AttributeIterationStopMessage *ais_msg)
2298 struct IdpClient *idp = cls;
2299 struct AttributeIterator *ai;
2302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2303 "Received `%s' message\n",
2304 "ATTRIBUTE_ITERATION_STOP");
2305 rid = ntohl (ais_msg->id);
2306 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2307 if (ai->request_id == rid)
2312 GNUNET_SERVICE_client_drop (idp->client);
2315 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head,
2316 idp->attr_iter_tail,
2319 GNUNET_SERVICE_client_continue (idp->client);
2324 handle_iteration_next (void *cls,
2325 const struct AttributeIterationNextMessage *ais_msg)
2327 struct IdpClient *idp = cls;
2328 struct AttributeIterator *ai;
2331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2332 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2333 rid = ntohl (ais_msg->id);
2334 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2335 if (ai->request_id == rid)
2340 GNUNET_SERVICE_client_drop (idp->client);
2343 bootstrap_abe (&ai->identity,
2344 &iterate_next_after_abe_bootstrap,
2347 GNUNET_SERVICE_client_continue (idp->client);
2351 * Ticket iteration processor result
2353 enum ZoneIterationResult
2362 * Continue to iterate with next iteration_next call
2364 IT_SUCCESS_MORE_AVAILABLE = 1,
2367 * Iteration complete
2369 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2374 * Context for ticket iteration
2376 struct TicketIterationProcResult
2379 * The ticket iteration handle
2381 struct TicketIteration *ti;
2384 * Iteration result: iteration done?
2385 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2386 * we got one for now and have sent it to the client
2387 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2388 * #IT_START: if we are still trying to find a result.
2390 int res_iteration_finished;
2395 cleanup_ticket_iter_handle (struct TicketIteration *ti)
2401 * Process ticket from database
2403 * @param cls struct TicketIterationProcResult
2404 * @param ticket the ticket
2405 * @param attrs the attributes
2408 ticket_iterate_proc (void *cls,
2409 const struct GNUNET_RECLAIM_Ticket *ticket,
2410 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
2412 struct TicketIterationProcResult *proc = cls;
2416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2417 "Iteration done\n");
2418 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2421 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2422 send_ticket_result (proc->ti->client,
2430 * Perform ticket iteration step
2432 * @param ti ticket iterator to process
2435 run_ticket_iteration_round (struct TicketIteration *ti)
2437 struct TicketIterationProcResult proc;
2438 struct GNUNET_MQ_Envelope *env;
2439 struct TicketResultMessage *trm;
2442 memset (&proc, 0, sizeof (proc));
2444 proc.res_iteration_finished = IT_START;
2445 while (IT_START == proc.res_iteration_finished)
2447 if (GNUNET_SYSERR ==
2448 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2452 &ticket_iterate_proc,
2458 if (GNUNET_NO == ret)
2459 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2462 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2465 "More results available\n");
2466 return; /* more later */
2468 /* send empty response to indicate end of list */
2469 env = GNUNET_MQ_msg (trm,
2470 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2471 trm->id = htonl (ti->r_id);
2472 GNUNET_MQ_send (ti->client->mq,
2474 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2475 ti->client->ticket_iter_tail,
2477 cleanup_ticket_iter_handle (ti);
2481 handle_ticket_iteration_start (void *cls,
2482 const struct TicketIterationStartMessage *tis_msg)
2484 struct IdpClient *client = cls;
2485 struct TicketIteration *ti;
2487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2488 "Received TICKET_ITERATION_START message\n");
2489 ti = GNUNET_new (struct TicketIteration);
2490 ti->r_id = ntohl (tis_msg->id);
2492 ti->client = client;
2493 ti->identity = tis_msg->identity;
2494 ti->is_audience = ntohl (tis_msg->is_audience);
2496 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2497 client->ticket_iter_tail,
2499 run_ticket_iteration_round (ti);
2500 GNUNET_SERVICE_client_continue (client->client);
2505 handle_ticket_iteration_stop (void *cls,
2506 const struct TicketIterationStopMessage *tis_msg)
2508 struct IdpClient *client = cls;
2509 struct TicketIteration *ti;
2512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2513 "Received `%s' message\n",
2514 "TICKET_ITERATION_STOP");
2515 rid = ntohl (tis_msg->id);
2516 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2517 if (ti->r_id == rid)
2522 GNUNET_SERVICE_client_drop (client->client);
2525 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2526 client->ticket_iter_tail,
2528 cleanup_ticket_iter_handle (ti);
2529 GNUNET_SERVICE_client_continue (client->client);
2534 handle_ticket_iteration_next (void *cls,
2535 const struct TicketIterationNextMessage *tis_msg)
2537 struct IdpClient *client = cls;
2538 struct TicketIteration *ti;
2541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2542 "Received TICKET_ITERATION_NEXT message\n");
2543 rid = ntohl (tis_msg->id);
2544 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2545 if (ti->r_id == rid)
2550 GNUNET_SERVICE_client_drop (client->client);
2553 run_ticket_iteration_round (ti);
2554 GNUNET_SERVICE_client_continue (client->client);
2561 * Main function that will be run
2563 * @param cls closure
2564 * @param c the configuration used
2565 * @param server the service handle
2569 const struct GNUNET_CONFIGURATION_Handle *c,
2570 struct GNUNET_SERVICE_Handle *server)
2575 stats = GNUNET_STATISTICS_create ("reclaim", cfg);
2577 //Connect to identity and namestore services
2578 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2579 if (NULL == ns_handle)
2581 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2584 gns_handle = GNUNET_GNS_connect (cfg);
2585 if (NULL == gns_handle)
2587 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2589 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2590 if (NULL == credential_handle)
2592 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2594 identity_handle = GNUNET_IDENTITY_connect (cfg,
2597 /* Loading DB plugin */
2599 GNUNET_CONFIGURATION_get_value_string (cfg,
2603 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2604 "No database backend configured\n");
2605 GNUNET_asprintf (&db_lib_name,
2606 "libgnunet_plugin_reclaim_%s",
2608 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2610 GNUNET_free (database);
2611 if (NULL == TKT_database)
2613 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2614 "Could not load database backend `%s'\n",
2616 GNUNET_SCHEDULER_shutdown ();
2621 GNUNET_CONFIGURATION_get_value_time (cfg,
2623 "TOKEN_EXPIRATION_INTERVAL",
2624 &token_expiration_interval))
2626 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2627 "Time window for zone iteration: %s\n",
2628 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2631 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2634 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2638 * Called whenever a client is disconnected.
2640 * @param cls closure
2641 * @param client identification of the client
2642 * @param app_ctx @a client
2645 client_disconnect_cb (void *cls,
2646 struct GNUNET_SERVICE_Client *client,
2649 struct IdpClient *idp = app_ctx;
2650 struct AttributeIterator *ai;
2651 struct TicketIteration *ti;
2652 struct TicketRevocationHandle *rh;
2653 struct TicketIssueHandle *iss;
2654 struct ConsumeTicketHandle *ct;
2655 struct AttributeStoreHandle *as;
2657 //TODO other operations
2659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2660 "Client %p disconnected\n",
2663 while (NULL != (iss = idp->issue_op_head))
2665 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head,
2668 cleanup_ticket_issue_handle (iss);
2670 while (NULL != (ct = idp->consume_op_head))
2672 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
2673 idp->consume_op_tail,
2675 cleanup_consume_ticket_handle (ct);
2677 while (NULL != (as = idp->store_op_head))
2679 GNUNET_CONTAINER_DLL_remove (idp->store_op_head,
2682 cleanup_as_handle (as);
2685 while (NULL != (ai = idp->attr_iter_head))
2687 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head,
2688 idp->attr_iter_tail,
2690 cleanup_attribute_iter_handle (ai);
2692 while (NULL != (rh = idp->revoke_op_head))
2694 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head,
2695 idp->revoke_op_tail,
2697 cleanup_revoke_ticket_handle (rh);
2699 while (NULL != (ti = idp->ticket_iter_head))
2701 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
2702 idp->ticket_iter_tail,
2704 cleanup_ticket_iter_handle (ti);
2711 * Add a client to our list of active clients.
2714 * @param client client to add
2715 * @param mq message queue for @a client
2716 * @return internal namestore client structure for this client
2719 client_connect_cb (void *cls,
2720 struct GNUNET_SERVICE_Client *client,
2721 struct GNUNET_MQ_Handle *mq)
2723 struct IdpClient *idp;
2724 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2725 "Client %p connected\n",
2727 idp = GNUNET_new (struct IdpClient);
2728 idp->client = client;
2736 * Define "main" method using service macro.
2740 GNUNET_SERVICE_OPTION_NONE,
2743 &client_disconnect_cb,
2745 GNUNET_MQ_hd_var_size (attribute_store_message,
2746 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2747 struct AttributeStoreMessage,
2749 GNUNET_MQ_hd_fixed_size (iteration_start,
2750 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2751 struct AttributeIterationStartMessage,
2753 GNUNET_MQ_hd_fixed_size (iteration_next,
2754 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2755 struct AttributeIterationNextMessage,
2757 GNUNET_MQ_hd_fixed_size (iteration_stop,
2758 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2759 struct AttributeIterationStopMessage,
2761 GNUNET_MQ_hd_var_size (issue_ticket_message,
2762 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2763 struct IssueTicketMessage,
2765 GNUNET_MQ_hd_var_size (consume_ticket_message,
2766 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2767 struct ConsumeTicketMessage,
2769 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2770 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2771 struct TicketIterationStartMessage,
2773 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2774 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2775 struct TicketIterationNextMessage,
2777 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2778 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2779 struct TicketIterationStopMessage,
2781 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2782 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2783 struct RevokeTicketMessage,
2785 GNUNET_MQ_handler_end());
2786 /* end of gnunet-service-reclaim.c */