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_constants.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_identity_service.h"
31 #include "gnunet_gnsrecord_lib.h"
32 #include "gnunet_namestore_service.h"
33 #include "gnunet_credential_service.h"
34 #include "gnunet_statistics_service.h"
35 #include "gnunet_gns_service.h"
36 #include "gnunet_reclaim_plugin.h"
37 #include "gnunet_reclaim_attribute_lib.h"
38 #include "gnunet_signatures.h"
47 * Normal operation state
49 #define STATE_POST_INIT 1
52 * Minimum interval between updates
54 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
57 * Standard token expiration time
59 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
64 static struct GNUNET_IDENTITY_Handle *identity_handle;
69 static struct GNUNET_RECLAIM_PluginFunctions *TKT_database;
74 static char *db_lib_name;
77 * Token expiration interval
79 static struct GNUNET_TIME_Relative token_expiration_interval;
84 static struct GNUNET_NAMESTORE_Handle *nsh;
89 static struct GNUNET_GNS_Handle *gns_handle;
94 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
99 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
104 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
109 static struct GNUNET_SCHEDULER_Task *timeout_task;
114 static struct GNUNET_SCHEDULER_Task *update_task;
118 * Handle to the statistics service.
120 static struct GNUNET_STATISTICS_Handle *stats;
125 static const struct GNUNET_CONFIGURATION_Handle *cfg;
133 * A ticket iteration operation.
135 struct TicketIteration
140 struct TicketIteration *next;
145 struct TicketIteration *prev;
148 * Client which intiated this zone iteration
150 struct IdpClient *client;
153 * Key of the identity we are iterating over.
155 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
158 * Identity is audience
160 uint32_t is_audience;
163 * The operation id fot the iteration in the response for the client
168 * Offset of the iteration used to address next result of the
169 * iteration in the store
171 * Initialy set to 0 in handle_iteration_start
172 * Incremented with by every call to handle_iteration_next
180 * An attribute iteration operation.
182 struct AttributeIterator
185 * Next element in the DLL
187 struct AttributeIterator *next;
190 * Previous element in the DLL
192 struct AttributeIterator *prev;
195 * IDP client which intiated this zone iteration
197 struct IdpClient *client;
200 * Key of the zone we are iterating over.
202 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
207 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
210 * The operation id fot the zone iteration in the response for the client
227 struct GNUNET_SERVICE_Client *client;
230 * Message queue for transmission to @e client
232 struct GNUNET_MQ_Handle *mq;
236 * Attribute iteration operations in
237 * progress initiated by this client
239 struct AttributeIterator *attr_iter_head;
243 * Attribute iteration operations
244 * in progress initiated by this client
246 struct AttributeIterator *attr_iter_tail;
249 * Head of DLL of ticket iteration ops
251 struct TicketIteration *ticket_iter_head;
254 * Tail of DLL of ticket iteration ops
256 struct TicketIteration *ticket_iter_tail;
259 * Head of DLL of ticket revocation ops
261 struct TicketRevocationHandle *revoke_op_head;
264 * Tail of DLL of ticket revocation ops
266 struct TicketRevocationHandle *revoke_op_tail;
269 * Head of DLL of ticket issue ops
271 struct TicketIssueHandle *issue_op_head;
274 * Tail of DLL of ticket issue ops
276 struct TicketIssueHandle *issue_op_tail;
279 * Head of DLL of ticket consume ops
281 struct ConsumeTicketHandle *consume_op_head;
284 * Tail of DLL of ticket consume ops
286 struct ConsumeTicketHandle *consume_op_tail;
289 * Head of DLL of attribute store ops
291 struct AttributeStoreHandle *store_op_head;
294 * Tail of DLL of attribute store ops
296 struct AttributeStoreHandle *store_op_tail;
300 struct AttributeStoreHandle
305 struct AttributeStoreHandle *next;
310 struct AttributeStoreHandle *prev;
315 struct IdpClient *client;
320 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
325 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
330 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
333 * The attribute to store
335 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
338 * The attribute expiration interval
340 struct GNUNET_TIME_Relative exp;
350 struct ParallelLookup;
352 struct ConsumeTicketHandle
357 struct ConsumeTicketHandle *next;
362 struct ConsumeTicketHandle *prev;
367 struct IdpClient *client;
372 struct GNUNET_RECLAIM_Ticket ticket;
377 struct GNUNET_GNS_LookupRequest *lookup_request;
382 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
387 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
392 struct ParallelLookup *parallel_lookups_head;
397 struct ParallelLookup *parallel_lookups_tail;
402 struct GNUNET_SCHEDULER_Task *kill_task;
407 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
412 struct GNUNET_TIME_Absolute lookup_start_time;
421 * Handle for a parallel GNS lookup job
423 struct ParallelLookup
426 struct ParallelLookup *next;
429 struct ParallelLookup *prev;
431 /* The GNS request */
432 struct GNUNET_GNS_LookupRequest *lookup_request;
434 /* The handle the return to */
435 struct ConsumeTicketHandle *handle;
440 struct GNUNET_TIME_Absolute lookup_start_time;
442 /* The label to look up */
447 * Updated attribute IDs
449 struct TicketAttributeUpdateEntry
454 struct TicketAttributeUpdateEntry *next;
459 struct TicketAttributeUpdateEntry *prev;
473 * Ticket revocation request handle
475 struct TicketRevocationHandle
480 struct TicketRevocationHandle *prev;
485 struct TicketRevocationHandle *next;
490 struct TicketAttributeUpdateEntry *attr_updates_head;
495 struct TicketAttributeUpdateEntry *attr_updates_tail;
500 struct IdpClient *client;
503 * Attributes to reissue
505 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
508 * Attributes to revoke
510 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *rvk_attrs;
515 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
520 struct GNUNET_RECLAIM_Ticket ticket;
525 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
530 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
546 * Ticket issue request handle
548 struct TicketIssueHandle
553 struct TicketIssueHandle *prev;
558 struct TicketIssueHandle *next;
563 struct IdpClient *client;
566 * Attributes to issue
568 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
573 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
578 struct GNUNET_RECLAIM_Ticket ticket;
583 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
593 * DLL for ego handles to egos containing the RECLAIM_ATTRS in a
594 * map in json_t format
602 struct EgoEntry *next;
607 struct EgoEntry *prev;
612 struct GNUNET_IDENTITY_Ego *ego;
615 * Attribute map. Contains the attributes as json_t
617 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
632 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
635 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
637 GNUNET_free (db_lib_name);
639 if (NULL != timeout_task)
640 GNUNET_SCHEDULER_cancel (timeout_task);
641 if (NULL != update_task)
642 GNUNET_SCHEDULER_cancel (update_task);
643 if (NULL != identity_handle)
644 GNUNET_IDENTITY_disconnect (identity_handle);
645 if (NULL != gns_handle)
646 GNUNET_GNS_disconnect (gns_handle);
647 if (NULL != credential_handle)
648 GNUNET_CREDENTIAL_disconnect (credential_handle);
650 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
652 GNUNET_NAMESTORE_cancel (ns_qe);
654 GNUNET_NAMESTORE_disconnect (nsh);
663 do_shutdown (void *cls)
665 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
666 "Shutting down...\n");
672 create_sym_key_from_ecdh (const struct GNUNET_HashCode *new_key_hash,
673 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
674 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
676 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
678 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
681 static const char ctx_key[] = "gnuid-aes-ctx-key";
682 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
683 new_key_hash, sizeof (struct GNUNET_HashCode),
684 ctx_key, strlen (ctx_key),
686 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
687 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
688 new_key_hash, sizeof (struct GNUNET_HashCode),
689 ctx_iv, strlen (ctx_iv),
695 * Cleanup ticket consume handle
696 * @param handle the handle to clean up
699 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
701 if (NULL != handle->attrs)
702 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
703 if (NULL != handle->ns_qe)
704 GNUNET_NAMESTORE_cancel (handle->ns_qe);
705 GNUNET_free (handle);
710 send_ticket_result (struct IdpClient *client,
712 const struct GNUNET_RECLAIM_Ticket *ticket,
713 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
715 struct TicketResultMessage *irm;
716 struct GNUNET_MQ_Envelope *env;
717 struct GNUNET_RECLAIM_Ticket *ticket_buf;
719 /* store ticket in DB */
720 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
724 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
725 "Unable to store ticket after issue\n");
729 env = GNUNET_MQ_msg_extra (irm,
730 sizeof (struct GNUNET_RECLAIM_Ticket),
731 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
732 ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
733 *ticket_buf = *ticket;
734 irm->id = htonl (r_id);
735 GNUNET_MQ_send (client->mq,
740 store_ticket_issue_cont (void *cls,
744 struct TicketIssueHandle *handle = cls;
746 handle->ns_qe = NULL;
747 GNUNET_CONTAINER_DLL_remove (handle->client->issue_op_head,
748 handle->client->issue_op_tail,
750 if (GNUNET_SYSERR == success)
752 cleanup_ticket_issue_handle (handle);
753 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
755 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
758 send_ticket_result (handle->client,
762 cleanup_ticket_issue_handle (handle);
767 serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket,
768 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
769 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
772 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
773 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
774 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
775 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
776 struct GNUNET_HashCode new_key_hash;
784 GNUNET_assert (NULL != attrs->list_head);
786 for (le = attrs->list_head; NULL != le; le = le->next) {
787 attrs_str_len += 15 + 1; //TODO propery calculate
789 buf = GNUNET_malloc (attrs_str_len);
791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
792 "Writing attributes\n");
793 for (le = attrs->list_head; NULL != le; le = le->next) {
794 label = GNUNET_STRINGS_data_to_string_alloc (&le->claim->id,
796 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
797 "Adding attribute to record: %s\n", label);
799 GNUNET_memcpy (write_ptr,
802 write_ptr[strlen (label)] = ',';
803 write_ptr += strlen (label) + 1;
807 write_ptr[0] = '\0'; //replace last , with a 0-terminator
808 // ECDH keypair E = eG
809 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
810 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
812 enc_keyinfo = GNUNET_malloc (attrs_str_len);
813 // Derived key K = H(eB)
814 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
817 create_sym_key_from_ecdh (&new_key_hash, &skey, &iv);
818 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
822 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
824 GNUNET_memcpy (*result,
826 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
827 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
830 GNUNET_free (enc_keyinfo);
832 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
838 issue_ticket (struct TicketIssueHandle *ih)
840 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
841 struct GNUNET_GNSRECORD_Data code_record[1];
842 char *authz_record_data;
843 size_t authz_record_len;
846 //TODO rename function
847 authz_record_len = serialize_authz_record (&ih->ticket,
851 code_record[0].data = authz_record_data;
852 code_record[0].data_size = authz_record_len;
853 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
854 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ;
855 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
857 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
860 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
865 &store_ticket_issue_cont,
867 GNUNET_free (ecdhe_privkey);
869 GNUNET_free (authz_record_data);
874 check_issue_ticket_message(void *cls,
875 const struct IssueTicketMessage *im)
879 size = ntohs (im->header.size);
880 if (size <= sizeof (struct IssueTicketMessage))
883 return GNUNET_SYSERR;
890 handle_issue_ticket_message (void *cls,
891 const struct IssueTicketMessage *im)
893 struct TicketIssueHandle *ih;
894 struct IdpClient *idp = cls;
897 ih = GNUNET_new (struct TicketIssueHandle);
898 attrs_len = ntohs (im->attr_len);
899 ih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
900 ih->r_id = ntohl (im->id);
902 ih->identity = im->identity;
903 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
904 &ih->ticket.identity);
905 ih->ticket.audience = im->rp;
907 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
909 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head,
913 GNUNET_SERVICE_client_continue (idp->client);
917 /**********************************************************
919 **********************************************************/
922 * Cleanup revoke handle
924 * @param rh the ticket revocation handle
927 cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
929 if (NULL != rh->attrs)
930 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs);
931 if (NULL != rh->rvk_attrs)
932 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs);
933 if (NULL != rh->ns_qe)
934 GNUNET_NAMESTORE_cancel (rh->ns_qe);
935 if (NULL != rh->ns_it)
936 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
942 * Send revocation result
944 * @param rh ticket revocation handle
945 * @param success GNUNET_OK if successful result
948 send_revocation_finished (struct TicketRevocationHandle *rh,
951 struct GNUNET_MQ_Envelope *env;
952 struct RevokeTicketResultMessage *trm;
954 GNUNET_break(TKT_database->delete_ticket (TKT_database->cls,
957 env = GNUNET_MQ_msg (trm,
958 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
959 trm->id = htonl (rh->r_id);
960 trm->success = htonl (success);
961 GNUNET_MQ_send (rh->client->mq,
963 GNUNET_CONTAINER_DLL_remove (rh->client->revoke_op_head,
964 rh->client->revoke_op_tail,
970 * Process ticket from database
972 * @param cls struct TicketIterationProcResult
973 * @param ticket the ticket
974 * @param attrs the attributes
977 ticket_reissue_proc (void *cls,
978 const struct GNUNET_RECLAIM_Ticket *ticket,
979 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
982 revocation_reissue_tickets (struct TicketRevocationHandle *rh);
985 static void reissue_next (void *cls)
987 struct TicketRevocationHandle *rh = cls;
988 revocation_reissue_tickets (rh);
993 reissue_ticket_cont (void *cls,
997 struct TicketRevocationHandle *rh = cls;
1000 if (GNUNET_SYSERR == success)
1002 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1004 send_revocation_finished (rh, GNUNET_SYSERR);
1005 cleanup_revoke_ticket_handle (rh);
1009 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1014 * Process ticket from database
1016 * @param cls struct TicketIterationProcResult
1017 * @param ticket the ticket
1018 * @param attrs the attributes
1021 ticket_reissue_proc (void *cls,
1022 const struct GNUNET_RECLAIM_Ticket *ticket,
1023 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
1025 struct TicketRevocationHandle *rh = cls;
1026 struct TicketAttributeUpdateEntry *tue;
1027 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1028 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1029 struct GNUNET_GNSRECORD_Data code_record[1];
1031 size_t authz_record_len;
1032 char *authz_record_data;
1038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1039 "Iteration done\n");
1043 if (0 == memcmp (&ticket->audience,
1044 &rh->ticket.audience,
1045 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1048 "Do not reissue for this identity.!\n");
1049 label = GNUNET_STRINGS_data_to_string_alloc (&rh->ticket.rnd,
1052 rh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1057 &reissue_ticket_cont,
1060 GNUNET_free (label);
1065 * Check if any attribute of this ticket intersects with a rollover attribute
1067 reissue_ticket = GNUNET_NO;
1068 for (le = attrs->list_head; NULL != le; le = le->next)
1070 for (tue = rh->attr_updates_head;
1074 if (tue->old_id == le->claim->id)
1076 reissue_ticket = GNUNET_YES;
1077 le->claim->id = tue->new_id;
1082 if (GNUNET_NO == reissue_ticket)
1084 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1085 "Skipping ticket.\n");
1088 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1094 //Create new ABE key for RP
1096 /* If this is the RP we want to revoke attributes of, the do so */
1098 //TODO rename function
1099 authz_record_len = serialize_authz_record (ticket,
1102 &authz_record_data);
1103 code_record[0].data = authz_record_data;
1104 code_record[0].data_size = authz_record_len;
1105 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1106 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ;
1107 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1109 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1112 rh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1117 &reissue_ticket_cont,
1119 GNUNET_free (ecdhe_privkey);
1120 GNUNET_free (label);
1121 GNUNET_free (authz_record_data);
1125 /* Prototype for below function */
1127 attr_reenc_cont (void *cls,
1132 revocation_reissue_tickets (struct TicketRevocationHandle *rh)
1135 /* Done, issue new keys */
1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1137 "Revocation Phase III: Reissuing Tickets\n");
1138 if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
1139 &rh->ticket.identity,
1142 &ticket_reissue_proc,
1147 if (GNUNET_NO == ret)
1149 send_revocation_finished (rh, GNUNET_OK);
1150 cleanup_revoke_ticket_handle (rh);
1156 * Failed to check for attribute
1159 check_attr_error (void *cls)
1161 struct TicketRevocationHandle *rh = cls;
1162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1163 "Unable to check for existing attribute\n");
1165 send_revocation_finished (rh, GNUNET_SYSERR);
1166 cleanup_revoke_ticket_handle (rh);
1171 * Revoke next attribte by reencryption with
1175 reenc_next_attribute (void *cls);
1178 * Check for existing attribute and overwrite
1181 check_attr_cb (void *cls,
1182 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1184 unsigned int rd_count,
1185 const struct GNUNET_GNSRECORD_Data *rd_old)
1187 struct TicketRevocationHandle *rh = cls;
1188 struct TicketAttributeUpdateEntry *tue;
1189 struct GNUNET_GNSRECORD_Data rd[1];
1195 if (1 != rd_count) {
1196 GNUNET_SCHEDULER_add_now (&reenc_next_attribute,
1201 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
1202 buf = GNUNET_malloc (buf_size);
1203 rh->attrs->list_head->claim->version++;
1204 GNUNET_RECLAIM_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
1206 tue = GNUNET_new (struct TicketAttributeUpdateEntry);
1207 tue->old_id = rh->attrs->list_head->claim->id;
1208 tue->new_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1210 GNUNET_CONTAINER_DLL_insert (rh->attr_updates_head,
1211 rh->attr_updates_tail,
1213 rh->attrs->list_head->claim->id = tue->new_id;
1214 new_label = GNUNET_STRINGS_data_to_string_alloc (&tue->new_id,
1216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1217 "New attr id %s\n", new_label);
1218 rd[0].data_size = buf_size;
1220 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR;
1221 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1222 rd[0].expiration_time = rd_old[0].expiration_time;
1223 rh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1234 * Revoke next attribte by reencryption with
1238 reenc_next_attribute (void *cls)
1240 struct TicketRevocationHandle *rh = cls;
1242 if (NULL == rh->attrs->list_head)
1244 revocation_reissue_tickets (rh);
1247 /* First check if attribute still exists */
1248 label = GNUNET_STRINGS_data_to_string_alloc (&rh->attrs->list_head->claim->id,
1250 rh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1257 GNUNET_free (label);
1262 * Namestore callback after revoked attribute
1266 attr_reenc_cont (void *cls,
1270 struct TicketRevocationHandle *rh = cls;
1271 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1274 if (GNUNET_SYSERR == success)
1276 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1277 "Failed to reencrypt attribute %s\n",
1279 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1282 if (NULL == rh->attrs->list_head)
1284 revocation_reissue_tickets (rh);
1287 le = rh->attrs->list_head;
1288 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1289 rh->attrs->list_tail,
1291 GNUNET_assert (NULL != rh->rvk_attrs);
1292 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1293 rh->rvk_attrs->list_tail,
1297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1298 "Re-encrypting next attribute\n");
1299 reenc_next_attribute (rh);
1304 process_attributes_to_update (void *cls,
1305 const struct GNUNET_RECLAIM_Ticket *ticket,
1306 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
1308 struct TicketRevocationHandle *rh = cls;
1310 rh->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
1311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1312 "Revocation Phase I: Collecting attributes\n");
1313 /* Reencrypt all attributes with new key */
1314 if (NULL == rh->attrs->list_head)
1316 /* No attributes to reencrypt */
1317 send_revocation_finished (rh, GNUNET_OK);
1318 cleanup_revoke_ticket_handle (rh);
1321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1322 "Revocation Phase II: Re-encrypting attributes\n");
1323 reenc_next_attribute (rh);
1330 check_revoke_ticket_message(void *cls,
1331 const struct RevokeTicketMessage *im)
1335 size = ntohs (im->header.size);
1336 if (size <= sizeof (struct RevokeTicketMessage))
1339 return GNUNET_SYSERR;
1345 handle_revoke_ticket_message (void *cls,
1346 const struct RevokeTicketMessage *rm)
1348 struct TicketRevocationHandle *rh;
1349 struct IdpClient *idp = cls;
1350 struct GNUNET_RECLAIM_Ticket *ticket;
1352 rh = GNUNET_new (struct TicketRevocationHandle);
1353 ticket = (struct GNUNET_RECLAIM_Ticket*)&rm[1];
1354 rh->rvk_attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1355 rh->ticket = *ticket;
1356 rh->r_id = ntohl (rm->id);
1358 rh->identity = rm->identity;
1359 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1360 &rh->ticket.identity);
1361 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head,
1362 idp->revoke_op_tail,
1365 * TODO replace with GNS storage
1367 TKT_database->get_ticket_attributes (TKT_database->cls,
1369 &process_attributes_to_update,
1371 GNUNET_SERVICE_client_continue (idp->client);
1376 * Cleanup ticket consume handle
1377 * @param handle the handle to clean up
1380 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1382 struct ParallelLookup *lu;
1383 struct ParallelLookup *tmp;
1384 if (NULL != handle->lookup_request)
1385 GNUNET_GNS_lookup_cancel (handle->lookup_request);
1386 for (lu = handle->parallel_lookups_head;
1388 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1389 GNUNET_free (lu->label);
1391 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1392 handle->parallel_lookups_tail,
1398 if (NULL != handle->attrs)
1399 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
1400 GNUNET_free (handle);
1406 check_consume_ticket_message(void *cls,
1407 const struct ConsumeTicketMessage *cm)
1411 size = ntohs (cm->header.size);
1412 if (size <= sizeof (struct ConsumeTicketMessage))
1415 return GNUNET_SYSERR;
1421 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1422 const struct GNUNET_GNSRECORD_Data *rd)
1424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1425 "Parallel lookup finished (count=%u)\n", rd_count);
1426 struct ParallelLookup *parallel_lookup = cls;
1427 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1428 struct ConsumeTicketResultMessage *crm;
1429 struct GNUNET_MQ_Envelope *env;
1430 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
1434 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1435 handle->parallel_lookups_tail,
1437 GNUNET_free (parallel_lookup->label);
1439 GNUNET_STATISTICS_update (stats,
1440 "attribute_lookup_time_total",
1441 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
1443 GNUNET_STATISTICS_update (stats,
1444 "attribute_lookups_count",
1449 GNUNET_free (parallel_lookup);
1451 GNUNET_break(0);//TODO
1452 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
1454 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1455 attr_le->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data,
1457 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1458 handle->attrs->list_tail,
1461 if (NULL != handle->parallel_lookups_head)
1462 return; //Wait for more
1463 /* Else we are done */
1465 /** Store ticket in DB
1466 * TODO: Store in GNS
1468 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1473 "Unable to store ticket after consume\n");
1477 GNUNET_SCHEDULER_cancel (handle->kill_task);
1478 attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (handle->attrs);
1479 env = GNUNET_MQ_msg_extra (crm,
1481 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
1482 crm->id = htonl (handle->r_id);
1483 crm->attrs_len = htons (attrs_len);
1484 crm->identity = handle->ticket.identity;
1485 data_tmp = (char *) &crm[1];
1486 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (handle->attrs,
1488 GNUNET_MQ_send (handle->client->mq, env);
1489 GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head,
1490 handle->client->consume_op_tail,
1492 cleanup_consume_ticket_handle (handle);
1496 abort_parallel_lookups2 (void *cls)
1498 struct ConsumeTicketHandle *handle = cls;
1499 struct ParallelLookup *lu;
1500 struct ParallelLookup *tmp;
1501 struct AttributeResultMessage *arm;
1502 struct GNUNET_MQ_Envelope *env;
1504 handle->kill_task = NULL;
1505 for (lu = handle->parallel_lookups_head;
1507 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1508 GNUNET_free (lu->label);
1510 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1511 handle->parallel_lookups_tail,
1516 env = GNUNET_MQ_msg (arm,
1517 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1518 arm->id = htonl (handle->r_id);
1519 arm->attr_len = htons (0);
1520 GNUNET_MQ_send (handle->client->mq, env);
1526 process_attr_labels (void *cls, uint32_t rd_count,
1527 const struct GNUNET_GNSRECORD_Data *rd)
1529 struct ConsumeTicketHandle *handle = cls;
1530 struct GNUNET_HashCode new_key_hash;
1531 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1532 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1533 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1534 struct ParallelLookup *parallel_lookup;
1540 handle->lookup_request = NULL;
1543 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1544 "Number of keys %d != 1.",
1546 cleanup_consume_ticket_handle (handle);
1547 GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head,
1548 handle->client->consume_op_tail,
1550 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1555 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1557 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1559 //Calculate symmetric key from ecdh parameters
1560 GNUNET_assert (GNUNET_OK ==
1561 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1564 create_sym_key_from_ecdh (&new_key_hash,
1567 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1568 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1573 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1574 "Decrypted bytes: %zd Expected bytes: %zd\n",
1575 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1576 GNUNET_STATISTICS_update (stats,
1577 "reclaim_authz_lookup_time_total",
1578 GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
1580 GNUNET_STATISTICS_update (stats,
1581 "reclaim_authz_lookups_count",
1584 lbls = GNUNET_strdup (buf);
1585 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1586 "Attributes found %s\n", lbls);
1588 for (attr_lbl = strtok (lbls, ",");
1590 attr_lbl = strtok (NULL, ","))
1592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1593 "Looking up %s\n", attr_lbl);
1594 parallel_lookup = GNUNET_new (struct ParallelLookup);
1595 parallel_lookup->handle = handle;
1596 parallel_lookup->label = GNUNET_strdup (attr_lbl);
1597 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
1598 parallel_lookup->lookup_request
1599 = GNUNET_GNS_lookup (gns_handle,
1601 &handle->ticket.identity,
1602 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
1603 GNUNET_GNS_LO_DEFAULT,
1604 &process_parallel_lookup2,
1606 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1607 handle->parallel_lookups_tail,
1612 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1613 &abort_parallel_lookups2,
1619 handle_consume_ticket_message (void *cls,
1620 const struct ConsumeTicketMessage *cm)
1622 struct ConsumeTicketHandle *ch;
1623 struct IdpClient *idp = cls;
1626 ch = GNUNET_new (struct ConsumeTicketHandle);
1627 ch->r_id = ntohl (cm->id);
1629 ch->identity = cm->identity;
1630 ch->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1631 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1633 ch->ticket = *((struct GNUNET_RECLAIM_Ticket*)&cm[1]);
1634 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1637 "Looking for ABE key under %s\n", rnd_label);
1638 ch->lookup_start_time = GNUNET_TIME_absolute_get ();
1640 = GNUNET_GNS_lookup (gns_handle,
1642 &ch->ticket.identity,
1643 GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ,
1644 GNUNET_GNS_LO_DEFAULT,
1645 &process_attr_labels,
1647 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head,
1648 idp->consume_op_tail,
1650 GNUNET_free (rnd_label);
1651 GNUNET_SERVICE_client_continue (idp->client);
1655 * Cleanup attribute store handle
1657 * @param handle handle to clean up
1660 cleanup_as_handle (struct AttributeStoreHandle *ash)
1662 if (NULL != ash->ns_qe)
1663 GNUNET_NAMESTORE_cancel (ash->ns_qe);
1664 if (NULL != ash->claim)
1665 GNUNET_free (ash->claim);
1670 attr_store_cont (void *cls,
1674 struct AttributeStoreHandle *ash = cls;
1675 struct GNUNET_MQ_Envelope *env;
1676 struct AttributeStoreResultMessage *acr_msg;
1679 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1680 ash->client->store_op_tail,
1683 if (GNUNET_SYSERR == success)
1685 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1686 "Failed to store attribute %s\n",
1688 cleanup_as_handle (ash);
1689 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1694 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1695 env = GNUNET_MQ_msg (acr_msg,
1696 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE);
1697 acr_msg->id = htonl (ash->r_id);
1698 acr_msg->op_result = htonl (GNUNET_OK);
1699 GNUNET_MQ_send (ash->client->mq,
1701 cleanup_as_handle (ash);
1705 * Adds a new attribute
1707 * @param cls the AttributeStoreHandle
1710 attr_store_task (void *cls)
1712 struct AttributeStoreHandle *ash = cls;
1713 struct GNUNET_GNSRECORD_Data rd[1];
1718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1719 "Storing attribute\n");
1720 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (ash->claim);
1721 buf = GNUNET_malloc (buf_size);
1722 //Give the ash a new id
1723 ash->claim->id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1725 GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim,
1727 label = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id,
1729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1730 "Encrypting with label %s\n", label);
1732 rd[0].data_size = buf_size;
1734 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR;
1735 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1736 rd[0].expiration_time = ash->exp.rel_value_us;
1737 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1749 check_attribute_store_message(void *cls,
1750 const struct AttributeStoreMessage *sam)
1754 size = ntohs (sam->header.size);
1755 if (size <= sizeof (struct AttributeStoreMessage))
1758 return GNUNET_SYSERR;
1765 handle_attribute_store_message (void *cls,
1766 const struct AttributeStoreMessage *sam)
1768 struct AttributeStoreHandle *ash;
1769 struct IdpClient *idp = cls;
1771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1772 "Received ATTRIBUTE_STORE message\n");
1774 data_len = ntohs (sam->attr_len);
1776 ash = GNUNET_new (struct AttributeStoreHandle);
1777 ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&sam[1],
1780 ash->r_id = ntohl (sam->id);
1781 ash->identity = sam->identity;
1782 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1783 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1784 &ash->identity_pkey);
1786 GNUNET_SERVICE_client_continue (idp->client);
1788 GNUNET_CONTAINER_DLL_insert (idp->store_op_head,
1791 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1795 cleanup_attribute_iter_handle (struct AttributeIterator *ai)
1801 attr_iter_error (void *cls)
1803 struct AttributeIterator *ai = cls;
1804 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1805 "Failed to iterate over attributes\n");
1806 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1807 ai->client->attr_iter_tail,
1809 cleanup_attribute_iter_handle (ai);
1810 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1814 attr_iter_finished (void *cls)
1816 struct AttributeIterator *ai = cls;
1817 struct GNUNET_MQ_Envelope *env;
1818 struct AttributeResultMessage *arm;
1820 env = GNUNET_MQ_msg (arm,
1821 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1822 arm->id = htonl (ai->request_id);
1823 arm->attr_len = htons (0);
1824 GNUNET_MQ_send (ai->client->mq, env);
1825 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1826 ai->client->attr_iter_tail,
1828 cleanup_attribute_iter_handle (ai);
1832 attr_iter_cb (void *cls,
1833 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1835 unsigned int rd_count,
1836 const struct GNUNET_GNSRECORD_Data *rd)
1838 struct AttributeIterator *ai = cls;
1839 struct AttributeResultMessage *arm;
1840 struct GNUNET_MQ_Envelope *env;
1845 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
1850 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type)
1852 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
1856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1857 "Found attribute under: %s\n", label);
1858 env = GNUNET_MQ_msg_extra (arm,
1860 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1861 arm->id = htonl (ai->request_id);
1862 arm->attr_len = htons (rd->data_size);
1863 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
1865 data_tmp = (char *) &arm[1];
1866 GNUNET_memcpy (data_tmp,
1869 GNUNET_MQ_send (ai->client->mq, env);
1874 handle_iteration_start (void *cls,
1875 const struct AttributeIterationStartMessage *ais_msg)
1877 struct IdpClient *idp = cls;
1878 struct AttributeIterator *ai;
1880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1881 "Received ATTRIBUTE_ITERATION_START message\n");
1882 ai = GNUNET_new (struct AttributeIterator);
1883 ai->request_id = ntohl (ais_msg->id);
1885 ai->identity = ais_msg->identity;
1887 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head,
1888 idp->attr_iter_tail,
1890 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1896 &attr_iter_finished,
1898 GNUNET_SERVICE_client_continue (idp->client);
1903 handle_iteration_stop (void *cls,
1904 const struct AttributeIterationStopMessage *ais_msg)
1906 struct IdpClient *idp = cls;
1907 struct AttributeIterator *ai;
1910 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1911 "Received `%s' message\n",
1912 "ATTRIBUTE_ITERATION_STOP");
1913 rid = ntohl (ais_msg->id);
1914 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1915 if (ai->request_id == rid)
1920 GNUNET_SERVICE_client_drop (idp->client);
1923 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head,
1924 idp->attr_iter_tail,
1927 GNUNET_SERVICE_client_continue (idp->client);
1932 handle_iteration_next (void *cls,
1933 const struct AttributeIterationNextMessage *ais_msg)
1935 struct IdpClient *idp = cls;
1936 struct AttributeIterator *ai;
1939 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1940 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1941 rid = ntohl (ais_msg->id);
1942 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1943 if (ai->request_id == rid)
1948 GNUNET_SERVICE_client_drop (idp->client);
1951 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
1953 GNUNET_SERVICE_client_continue (idp->client);
1957 * Ticket iteration processor result
1959 enum ZoneIterationResult
1968 * Continue to iterate with next iteration_next call
1970 IT_SUCCESS_MORE_AVAILABLE = 1,
1973 * Iteration complete
1975 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
1980 * Context for ticket iteration
1982 struct TicketIterationProcResult
1985 * The ticket iteration handle
1987 struct TicketIteration *ti;
1990 * Iteration result: iteration done?
1991 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
1992 * we got one for now and have sent it to the client
1993 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
1994 * #IT_START: if we are still trying to find a result.
1996 int res_iteration_finished;
2001 cleanup_ticket_iter_handle (struct TicketIteration *ti)
2007 * Process ticket from database
2009 * @param cls struct TicketIterationProcResult
2010 * @param ticket the ticket
2011 * @param attrs the attributes
2014 ticket_iterate_proc (void *cls,
2015 const struct GNUNET_RECLAIM_Ticket *ticket,
2016 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
2018 struct TicketIterationProcResult *proc = cls;
2022 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2023 "Iteration done\n");
2024 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2027 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2028 send_ticket_result (proc->ti->client,
2036 * Perform ticket iteration step
2038 * @param ti ticket iterator to process
2041 run_ticket_iteration_round (struct TicketIteration *ti)
2043 struct TicketIterationProcResult proc;
2044 struct GNUNET_MQ_Envelope *env;
2045 struct TicketResultMessage *trm;
2048 memset (&proc, 0, sizeof (proc));
2050 proc.res_iteration_finished = IT_START;
2051 while (IT_START == proc.res_iteration_finished)
2053 if (GNUNET_SYSERR ==
2054 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2058 &ticket_iterate_proc,
2064 if (GNUNET_NO == ret)
2065 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2068 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2071 "More results available\n");
2072 return; /* more later */
2074 /* send empty response to indicate end of list */
2075 env = GNUNET_MQ_msg (trm,
2076 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2077 trm->id = htonl (ti->r_id);
2078 GNUNET_MQ_send (ti->client->mq,
2080 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2081 ti->client->ticket_iter_tail,
2083 cleanup_ticket_iter_handle (ti);
2087 handle_ticket_iteration_start (void *cls,
2088 const struct TicketIterationStartMessage *tis_msg)
2090 struct IdpClient *client = cls;
2091 struct TicketIteration *ti;
2093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2094 "Received TICKET_ITERATION_START message\n");
2095 ti = GNUNET_new (struct TicketIteration);
2096 ti->r_id = ntohl (tis_msg->id);
2098 ti->client = client;
2099 ti->identity = tis_msg->identity;
2100 ti->is_audience = ntohl (tis_msg->is_audience);
2102 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2103 client->ticket_iter_tail,
2105 run_ticket_iteration_round (ti);
2106 GNUNET_SERVICE_client_continue (client->client);
2111 handle_ticket_iteration_stop (void *cls,
2112 const struct TicketIterationStopMessage *tis_msg)
2114 struct IdpClient *client = cls;
2115 struct TicketIteration *ti;
2118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2119 "Received `%s' message\n",
2120 "TICKET_ITERATION_STOP");
2121 rid = ntohl (tis_msg->id);
2122 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2123 if (ti->r_id == rid)
2128 GNUNET_SERVICE_client_drop (client->client);
2131 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2132 client->ticket_iter_tail,
2134 cleanup_ticket_iter_handle (ti);
2135 GNUNET_SERVICE_client_continue (client->client);
2140 handle_ticket_iteration_next (void *cls,
2141 const struct TicketIterationNextMessage *tis_msg)
2143 struct IdpClient *client = cls;
2144 struct TicketIteration *ti;
2147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2148 "Received TICKET_ITERATION_NEXT message\n");
2149 rid = ntohl (tis_msg->id);
2150 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2151 if (ti->r_id == rid)
2156 GNUNET_SERVICE_client_drop (client->client);
2159 run_ticket_iteration_round (ti);
2160 GNUNET_SERVICE_client_continue (client->client);
2167 * Main function that will be run
2169 * @param cls closure
2170 * @param c the configuration used
2171 * @param server the service handle
2175 const struct GNUNET_CONFIGURATION_Handle *c,
2176 struct GNUNET_SERVICE_Handle *server)
2181 stats = GNUNET_STATISTICS_create ("reclaim", cfg);
2183 //Connect to identity and namestore services
2184 nsh = GNUNET_NAMESTORE_connect (cfg);
2187 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2190 gns_handle = GNUNET_GNS_connect (cfg);
2191 if (NULL == gns_handle)
2193 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2195 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2196 if (NULL == credential_handle)
2198 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2200 identity_handle = GNUNET_IDENTITY_connect (cfg,
2203 /* Loading DB plugin */
2205 GNUNET_CONFIGURATION_get_value_string (cfg,
2209 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2210 "No database backend configured\n");
2211 GNUNET_asprintf (&db_lib_name,
2212 "libgnunet_plugin_reclaim_%s",
2214 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2216 GNUNET_free (database);
2217 if (NULL == TKT_database)
2219 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2220 "Could not load database backend `%s'\n",
2222 GNUNET_SCHEDULER_shutdown ();
2227 GNUNET_CONFIGURATION_get_value_time (cfg,
2229 "TOKEN_EXPIRATION_INTERVAL",
2230 &token_expiration_interval))
2232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2233 "Time window for zone iteration: %s\n",
2234 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2237 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2240 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2244 * Called whenever a client is disconnected.
2246 * @param cls closure
2247 * @param client identification of the client
2248 * @param app_ctx @a client
2251 client_disconnect_cb (void *cls,
2252 struct GNUNET_SERVICE_Client *client,
2255 struct IdpClient *idp = app_ctx;
2256 struct AttributeIterator *ai;
2257 struct TicketIteration *ti;
2258 struct TicketRevocationHandle *rh;
2259 struct TicketIssueHandle *iss;
2260 struct ConsumeTicketHandle *ct;
2261 struct AttributeStoreHandle *as;
2263 //TODO other operations
2265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2266 "Client %p disconnected\n",
2269 while (NULL != (iss = idp->issue_op_head))
2271 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head,
2274 cleanup_ticket_issue_handle (iss);
2276 while (NULL != (ct = idp->consume_op_head))
2278 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
2279 idp->consume_op_tail,
2281 cleanup_consume_ticket_handle (ct);
2283 while (NULL != (as = idp->store_op_head))
2285 GNUNET_CONTAINER_DLL_remove (idp->store_op_head,
2288 cleanup_as_handle (as);
2291 while (NULL != (ai = idp->attr_iter_head))
2293 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head,
2294 idp->attr_iter_tail,
2296 cleanup_attribute_iter_handle (ai);
2298 while (NULL != (rh = idp->revoke_op_head))
2300 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head,
2301 idp->revoke_op_tail,
2303 cleanup_revoke_ticket_handle (rh);
2305 while (NULL != (ti = idp->ticket_iter_head))
2307 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
2308 idp->ticket_iter_tail,
2310 cleanup_ticket_iter_handle (ti);
2317 * Add a client to our list of active clients.
2320 * @param client client to add
2321 * @param mq message queue for @a client
2322 * @return internal namestore client structure for this client
2325 client_connect_cb (void *cls,
2326 struct GNUNET_SERVICE_Client *client,
2327 struct GNUNET_MQ_Handle *mq)
2329 struct IdpClient *idp;
2330 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2331 "Client %p connected\n",
2333 idp = GNUNET_new (struct IdpClient);
2334 idp->client = client;
2342 * Define "main" method using service macro.
2346 GNUNET_SERVICE_OPTION_NONE,
2349 &client_disconnect_cb,
2351 GNUNET_MQ_hd_var_size (attribute_store_message,
2352 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2353 struct AttributeStoreMessage,
2355 GNUNET_MQ_hd_fixed_size (iteration_start,
2356 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2357 struct AttributeIterationStartMessage,
2359 GNUNET_MQ_hd_fixed_size (iteration_next,
2360 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2361 struct AttributeIterationNextMessage,
2363 GNUNET_MQ_hd_fixed_size (iteration_stop,
2364 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2365 struct AttributeIterationStopMessage,
2367 GNUNET_MQ_hd_var_size (issue_ticket_message,
2368 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2369 struct IssueTicketMessage,
2371 GNUNET_MQ_hd_var_size (consume_ticket_message,
2372 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2373 struct ConsumeTicketMessage,
2375 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2376 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2377 struct TicketIterationStartMessage,
2379 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2380 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2381 struct TicketIterationNextMessage,
2383 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2384 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2385 struct TicketIterationStopMessage,
2387 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2388 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2389 struct RevokeTicketMessage,
2391 GNUNET_MQ_handler_end());
2392 /* end of gnunet-service-reclaim.c */