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
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @author Martin Schanzenbach
22 * @file src/identity-provider/gnunet-service-identity-provider.c
23 * @brief Identity Token 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_identity_provider_plugin.h"
37 #include "gnunet_signatures.h"
38 #include "identity_provider.h"
39 #include "identity_attribute.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_IDENTITY_PROVIDER_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 *ns_handle;
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 * Currently processed token
120 static struct IdentityToken *token;
123 * Label for currently processed token
128 * Scopes for processed token
133 * Handle to the statistics service.
135 static struct GNUNET_STATISTICS_Handle *stats;
140 static const struct GNUNET_CONFIGURATION_Handle *cfg;
148 * A ticket iteration operation.
150 struct TicketIteration
155 struct TicketIteration *next;
160 struct TicketIteration *prev;
163 * Client which intiated this zone iteration
165 struct IdpClient *client;
168 * Key of the identity we are iterating over.
170 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
173 * Identity is audience
175 uint32_t is_audience;
178 * The operation id fot the iteration in the response for the client
183 * Offset of the iteration used to address next result of the
184 * iteration in the store
186 * Initialy set to 0 in handle_iteration_start
187 * Incremented with by every call to handle_iteration_next
196 * Callback after an ABE bootstrap
199 * @param abe_key the ABE key that exists or was created
202 (*AbeBootstrapResult) (void *cls,
203 struct GNUNET_CRYPTO_AbeMasterKey *abe_key);
206 struct AbeBootstrapHandle
209 * Function to call when finished
211 AbeBootstrapResult proc;
219 * Key of the zone we are iterating over.
221 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
224 * Namestore Queue Entry
226 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
229 * The issuer egos ABE master key
231 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
235 * An attribute iteration operation.
237 struct AttributeIterator
240 * Next element in the DLL
242 struct AttributeIterator *next;
245 * Previous element in the DLL
247 struct AttributeIterator *prev;
250 * IDP client which intiated this zone iteration
252 struct IdpClient *client;
255 * Key of the zone we are iterating over.
257 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
260 * The issuer egos ABE master key
262 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
267 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
270 * The operation id fot the zone iteration in the response for the client
287 struct GNUNET_SERVICE_Client *client;
290 * Message queue for transmission to @e client
292 struct GNUNET_MQ_Handle *mq;
296 * Attribute iteration operations in
297 * progress initiated by this client
299 struct AttributeIterator *op_head;
303 * Attribute iteration operations
304 * in progress initiated by this client
306 struct AttributeIterator *op_tail;
309 * Head of DLL of ticket iteration ops
311 struct TicketIteration *ticket_iter_head;
314 * Tail of DLL of ticket iteration ops
316 struct TicketIteration *ticket_iter_tail;
321 struct AttributeStoreHandle
327 struct IdpClient *client;
332 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
337 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
340 * The issuer egos ABE master key
342 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
347 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
350 * The attribute to store
352 struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
362 struct ParallelLookup;
364 struct ConsumeTicketHandle
370 struct IdpClient *client;
375 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
380 struct GNUNET_GNS_LookupRequest *lookup_request;
385 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
390 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
395 struct ParallelLookup *parallel_lookups_head;
400 struct ParallelLookup *parallel_lookups_tail;
405 struct GNUNET_SCHEDULER_Task *kill_task;
410 struct GNUNET_CRYPTO_AbeKey *key;
415 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
424 * Handle for a parallel GNS lookup job
426 struct ParallelLookup
429 struct ParallelLookup *next;
432 struct ParallelLookup *prev;
434 /* The GNS request */
435 struct GNUNET_GNS_LookupRequest *lookup_request;
437 /* The handle the return to */
438 struct ConsumeTicketHandle *handle;
440 /* The label to look up */
445 * Ticket revocation request handle
447 struct TicketRevocationHandle
453 struct IdpClient *client;
456 * Attributes to issue
458 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
463 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
468 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
473 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
478 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
483 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
495 * Ticket issue request handle
497 struct TicketIssueHandle
503 struct IdpClient *client;
506 * Attributes to issue
508 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
513 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
518 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
523 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
533 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
541 struct EgoEntry *next;
546 struct EgoEntry *prev;
551 struct GNUNET_IDENTITY_Ego *ego;
554 * Attribute map. Contains the attributes as json_t
556 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
570 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
573 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
575 GNUNET_free (db_lib_name);
577 if (NULL != timeout_task)
578 GNUNET_SCHEDULER_cancel (timeout_task);
579 if (NULL != update_task)
580 GNUNET_SCHEDULER_cancel (update_task);
581 if (NULL != identity_handle)
582 GNUNET_IDENTITY_disconnect (identity_handle);
583 if (NULL != gns_handle)
584 GNUNET_GNS_disconnect (gns_handle);
585 if (NULL != credential_handle)
586 GNUNET_CREDENTIAL_disconnect (credential_handle);
588 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
590 GNUNET_NAMESTORE_cancel (ns_qe);
591 if (NULL != ns_handle)
592 GNUNET_NAMESTORE_disconnect (ns_handle);
604 * @param tc task context
607 do_shutdown (void *cls)
609 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
610 "Shutting down...\n");
615 * Finished storing newly bootstrapped ABE key
618 bootstrap_store_cont (void *cls,
622 struct AbeBootstrapHandle *abh = cls;
623 if (GNUNET_SYSERR == success)
625 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
626 "Failed to bootstrap ABE master %s\n",
628 abh->proc (abh->proc_cls, NULL);
629 GNUNET_free (abh->abe_key);
633 abh->proc (abh->proc_cls, abh->abe_key);
638 * Generates and stores a new ABE key
641 bootstrap_store_task (void *cls)
643 struct AbeBootstrapHandle *abh = cls;
644 struct GNUNET_GNSRECORD_Data rd[1];
646 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
647 (void**)&rd[0].data);
648 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
649 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
650 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
651 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
656 &bootstrap_store_cont,
661 * Error checking for ABE master
664 bootstrap_abe_error (void *cls)
666 struct AbeBootstrapHandle *abh = cls;
668 abh->proc (abh->proc_cls, NULL);
674 * Handle ABE lookup in namestore
677 bootstrap_abe_result (void *cls,
678 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
680 unsigned int rd_count,
681 const struct GNUNET_GNSRECORD_Data *rd)
683 struct AbeBootstrapHandle *abh = cls;
684 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
687 for (i=0;i<rd_count;i++) {
688 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
690 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
692 abh->proc (abh->proc_cls, abe_key);
697 //No ABE master found, bootstrapping...
698 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
699 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
703 * Bootstrap ABE master if it does not yet exists.
704 * Will call the AbeBootstrapResult processor when done.
705 * will always recreate the ABE key of GNUNET_YES == recreate
708 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
709 AbeBootstrapResult proc,
713 struct AbeBootstrapHandle *abh;
715 abh = GNUNET_new (struct AbeBootstrapHandle);
718 abh->identity = *identity;
719 if (GNUNET_YES == recreate)
721 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
722 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
724 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
727 &bootstrap_abe_error,
729 &bootstrap_abe_result,
737 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
738 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
739 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
741 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
743 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
745 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
746 static const char ctx_key[] = "gnuid-aes-ctx-key";
747 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
748 new_key_hash, sizeof (struct GNUNET_HashCode),
749 ctx_key, strlen (ctx_key),
751 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
752 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
753 new_key_hash, sizeof (struct GNUNET_HashCode),
754 ctx_iv, strlen (ctx_iv),
760 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
762 if (NULL != handle->attrs)
763 attribute_list_destroy (handle->attrs);
764 if (NULL != handle->ns_qe)
765 GNUNET_NAMESTORE_cancel (handle->ns_qe);
766 GNUNET_free (handle);
771 send_ticket_result (struct IdpClient *client,
773 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
775 struct TicketResultMessage *irm;
776 struct GNUNET_MQ_Envelope *env;
777 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
779 /* store ticket in DB */
780 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
783 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
784 "Unable to store ticket after issue\n");
788 env = GNUNET_MQ_msg_extra (irm,
789 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
790 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
791 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
792 *ticket_buf = *ticket;
793 irm->id = htonl (r_id);
794 GNUNET_MQ_send (client->mq,
799 store_ticket_issue_cont (void *cls,
803 struct TicketIssueHandle *handle = cls;
805 handle->ns_qe = NULL;
806 if (GNUNET_SYSERR == success)
808 cleanup_ticket_issue_handle (handle);
809 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
811 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
814 send_ticket_result (handle->client,
817 cleanup_ticket_issue_handle (handle);
823 serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle,
824 const struct GNUNET_CRYPTO_AbeKey *rp_key,
825 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
828 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
829 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
831 char *serialized_key;
837 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
838 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
839 struct GNUNET_HashCode new_key_hash;
842 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
843 (void**)&serialized_key);
845 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
846 attrs_str_len += strlen (le->attribute->name) + 1;
848 buf = GNUNET_malloc (attrs_str_len + size);
850 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
851 "Writing attributes\n");
852 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
854 "%s\n", le->attribute->name);
857 GNUNET_memcpy (write_ptr,
859 strlen (le->attribute->name));
860 write_ptr[strlen (le->attribute->name)] = ',';
861 write_ptr += strlen (le->attribute->name) + 1;
864 write_ptr[0] = '\0'; //replace last , with a 0-terminator
866 GNUNET_memcpy (write_ptr,
869 // ECDH keypair E = eG
870 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
871 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
873 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
874 // Derived key K = H(eB)
875 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
876 &handle->ticket.audience,
878 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
879 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
880 size + attrs_str_len,
883 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
885 GNUNET_memcpy (*result,
887 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
888 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
891 GNUNET_free (enc_keyinfo);
892 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
898 issue_ticket_after_abe_bootstrap (void *cls,
899 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
901 struct TicketIssueHandle *ih = cls;
902 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
903 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
904 struct GNUNET_GNSRECORD_Data code_record[1];
905 struct GNUNET_CRYPTO_AbeKey *rp_key;
906 char *code_record_data;
911 size_t code_record_len;
913 //Create new ABE key for RP
915 for (le = ih->attrs->list_head; NULL != le; le = le->next)
917 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
919 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
920 attrs[i] = (char*) le->attribute->name;
924 rp_key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
927 //TODO review this wireformat
928 code_record_len = serialize_abe_keyinfo2 (ih,
932 code_record[0].data = code_record_data;
933 code_record[0].data_size = code_record_len;
934 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
935 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
936 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
938 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
941 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
946 &store_ticket_issue_cont,
948 GNUNET_free (ecdhe_privkey);
951 GNUNET_free (code_record_data);
956 * Checks a ticket issue message
958 * @param cls client sending the message
959 * @param im message of type `struct TicketIssueMessage`
960 * @return #GNUNET_OK if @a im is well-formed
963 check_issue_ticket_message(void *cls,
964 const struct IssueTicketMessage *im)
968 size = ntohs (im->header.size);
969 if (size <= sizeof (struct IssueTicketMessage))
972 return GNUNET_SYSERR;
980 * Handler for ticket issue message
983 * @param client who sent the message
984 * @param message the message
987 handle_issue_ticket_message (void *cls,
988 const struct IssueTicketMessage *im)
990 struct TicketIssueHandle *ih;
991 struct IdpClient *idp = cls;
994 ih = GNUNET_new (struct TicketIssueHandle);
995 attrs_len = ntohs (im->attr_len);
996 ih->attrs = attribute_list_deserialize ((char*)&im[1], attrs_len);
997 ih->r_id = ntohl (im->id);
999 ih->identity = im->identity;
1000 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1001 &ih->ticket.identity);
1002 ih->ticket.audience = im->rp;
1004 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1006 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1007 GNUNET_SERVICE_client_continue (idp->client);
1012 attr_reenc_cont (void *cls,
1016 struct TicketRevocationHandle *rh = cls;
1017 struct GNUNET_GNSRECORD_Data rd[1];
1021 if (GNUNET_SYSERR == success)
1023 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1024 "Failed to reencrypt attribute %s\n",
1026 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1029 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1030 rh->attrs->list_tail,
1031 rh->attrs->list_head);
1032 if (NULL == rh->attrs->list_head)
1034 /* Done, issue new keys */
1035 GNUNET_break (0); //TODO
1038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1039 "Re-encrypting attribute\n");
1040 buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
1041 buf = GNUNET_malloc (buf_size);
1043 attribute_serialize (rh->attrs->list_head->attribute,
1047 * Encrypt the attribute value and store in namestore
1049 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1051 rh->attrs->list_head->attribute->name, //Policy
1053 (void**)&rd[0].data);
1055 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1056 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1057 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1058 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1060 rh->attrs->list_head->attribute->name,
1065 GNUNET_free ((void*)rd[0].data);
1071 reenc_after_abe_bootstrap (void *cls,
1072 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1074 struct TicketRevocationHandle *rh = cls;
1075 struct GNUNET_GNSRECORD_Data rd[1];
1080 rh->abe_key = abe_key;
1081 GNUNET_assert (NULL != abe_key);
1083 if (NULL == rh->attrs->list_head)
1085 /* No attributes to reencrypt, this is odd... */
1087 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1088 "Re-encrypting attribute\n");
1089 buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
1090 buf = GNUNET_malloc (buf_size);
1092 attribute_serialize (rh->attrs->list_head->attribute,
1096 * Encrypt the attribute value and store in namestore
1098 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1100 rh->attrs->list_head->attribute->name, //Policy
1102 (void**)&rd[0].data);
1104 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1105 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1106 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1107 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1109 rh->attrs->list_head->attribute->name,
1114 GNUNET_free ((void*)rd[0].data);
1121 revoke_collect_iter_error (void *cls)
1123 //struct AttributeIterator *ai = cls;
1125 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1126 "Failed to iterate over attributes\n");
1127 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1131 revoke_collect_iter_finished (void *cls)
1133 struct TicketRevocationHandle *rh = cls;
1135 /* Bootstrap new abe key */
1136 bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES);
1140 revoke_collect_iter_cb (void *cls,
1141 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1143 unsigned int rd_count,
1144 const struct GNUNET_GNSRECORD_Data *rd)
1146 struct TicketRevocationHandle *rh = cls;
1147 struct GNUNET_CRYPTO_AbeKey *key;
1148 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1155 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1159 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1160 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1163 attrs[0] = (char*)label;
1165 key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key,
1167 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1171 GNUNET_CRYPTO_cpabe_delete_key (key);
1172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1173 "Attribute to reencrypt: %s\n", label);
1174 le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1175 le->attribute = attribute_deserialize (attr_ser, attr_len);
1176 GNUNET_CONTAINER_DLL_insert_tail (rh->attrs->list_head,
1177 rh->attrs->list_tail,
1179 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1184 collect_after_abe_bootstrap (void *cls,
1185 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1187 struct TicketRevocationHandle *rh = cls;
1190 GNUNET_assert (NULL != abe_key);
1192 /* Reencrypt all attributes with new key */
1193 rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1195 &revoke_collect_iter_error,
1197 &revoke_collect_iter_cb,
1199 &revoke_collect_iter_finished,
1206 * Checks a ticket revocation message
1208 * @param cls client sending the message
1209 * @param im message of type `struct RevokeTicketMessage`
1210 * @return #GNUNET_OK if @a im is well-formed
1213 check_revoke_ticket_message(void *cls,
1214 const struct RevokeTicketMessage *im)
1218 size = ntohs (im->header.size);
1219 if (size <= sizeof (struct RevokeTicketMessage))
1222 return GNUNET_SYSERR;
1230 * Handler for ticket revocation message
1233 * @param client who sent the message
1234 * @param message the message
1237 handle_revoke_ticket_message (void *cls,
1238 const struct RevokeTicketMessage *rm)
1240 struct TicketRevocationHandle *rh;
1241 struct IdpClient *idp = cls;
1242 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
1245 rh = GNUNET_new (struct TicketRevocationHandle);
1246 attrs_len = ntohs (rm->attrs_len);
1247 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
1249 rh->attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len);
1250 rh->ticket = *ticket;
1251 rh->r_id = ntohl (rm->id);
1253 rh->identity = rm->identity;
1254 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1255 &rh->ticket.identity);
1256 bootstrap_abe (&rh->identity, &collect_after_abe_bootstrap, rh, GNUNET_NO);
1257 GNUNET_SERVICE_client_continue (idp->client);
1263 cleanup_as_handle (struct AttributeStoreHandle *handle)
1265 if (NULL != handle->attribute)
1266 GNUNET_free (handle->attribute);
1267 if (NULL != handle->abe_key)
1268 GNUNET_free (handle->abe_key);
1269 GNUNET_free (handle);
1273 * Checks a ticket consume message
1275 * @param cls client sending the message
1276 * @param im message of type `struct ConsumeTicketMessage`
1277 * @return #GNUNET_OK if @a im is well-formed
1280 check_consume_ticket_message(void *cls,
1281 const struct ConsumeTicketMessage *cm)
1285 size = ntohs (cm->header.size);
1286 if (size <= sizeof (struct ConsumeTicketMessage))
1289 return GNUNET_SYSERR;
1295 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1296 const struct GNUNET_GNSRECORD_Data *rd)
1298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1299 "Parallel lookup finished (count=%u)\n", rd_count);
1300 struct ParallelLookup *parallel_lookup = cls;
1301 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1302 struct ConsumeTicketResultMessage *crm;
1303 struct GNUNET_MQ_Envelope *env;
1304 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *attr_le;
1310 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1311 handle->parallel_lookups_tail,
1313 GNUNET_free (parallel_lookup->label);
1314 GNUNET_free (parallel_lookup);
1316 GNUNET_break(0);//TODO
1317 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1319 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1323 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1324 attr_le->attribute = attribute_deserialize (data,
1326 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1327 handle->attrs->list_tail,
1331 if (NULL != handle->parallel_lookups_head)
1332 return; //Wait for more
1333 /* Else we are done */
1335 /* Store ticket in DB */
1336 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1339 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1340 "Unable to store ticket after consume\n");
1344 GNUNET_SCHEDULER_cancel (handle->kill_task);
1345 attrs_len = attribute_list_serialize_get_size (handle->attrs);
1346 env = GNUNET_MQ_msg_extra (crm,
1348 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1349 crm->id = htonl (handle->r_id);
1350 crm->attrs_len = htons (attrs_len);
1351 crm->identity = handle->ticket.identity;
1352 data_tmp = (char *) &crm[1];
1353 attribute_list_serialize (handle->attrs,
1355 GNUNET_MQ_send (handle->client->mq, env);
1359 abort_parallel_lookups2 (void *cls)
1361 struct ConsumeTicketHandle *handle = cls;
1362 struct ParallelLookup *lu;
1363 struct ParallelLookup *tmp;
1364 struct AttributeResultMessage *arm;
1365 struct GNUNET_MQ_Envelope *env;
1367 for (lu = handle->parallel_lookups_head;
1369 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1370 GNUNET_free (lu->label);
1372 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1373 handle->parallel_lookups_tail,
1378 env = GNUNET_MQ_msg (arm,
1379 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1380 arm->id = htonl (handle->r_id);
1381 arm->attr_len = htons (0);
1382 GNUNET_MQ_send (handle->client->mq, env);
1387 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1389 if (NULL != handle->key)
1390 GNUNET_free (handle->key);
1391 GNUNET_free (handle);
1396 process_consume_abe_key (void *cls, uint32_t rd_count,
1397 const struct GNUNET_GNSRECORD_Data *rd)
1399 struct ConsumeTicketHandle *handle = cls;
1400 struct GNUNET_HashCode new_key_hash;
1401 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1402 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1403 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1404 struct ParallelLookup *parallel_lookup;
1410 handle->lookup_request = NULL;
1413 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1414 "Number of keys %d != 1.",
1416 cleanup_consume_ticket_handle (handle);
1417 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1422 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1424 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1426 //Calculate symmetric key from ecdh parameters
1427 GNUNET_assert (GNUNET_OK ==
1428 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1431 create_sym_key_from_ecdh (&new_key_hash,
1434 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1435 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1441 "Decrypted bytes: %zd Expected bytes: %zd\n",
1442 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1444 scopes = GNUNET_strdup (buf);
1445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1446 "Scopes %s\n", scopes);
1447 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1448 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1449 - strlen (scopes) - 1);
1451 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1453 GNUNET_asprintf (&lookup_query,
1456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1457 "Looking up %s\n", lookup_query);
1458 parallel_lookup = GNUNET_new (struct ParallelLookup);
1459 parallel_lookup->handle = handle;
1460 parallel_lookup->label = GNUNET_strdup (scope);
1461 parallel_lookup->lookup_request
1462 = GNUNET_GNS_lookup (gns_handle,
1464 &handle->ticket.identity,
1465 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1466 GNUNET_GNS_LO_LOCAL_MASTER,
1467 &process_parallel_lookup2,
1469 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1470 handle->parallel_lookups_tail,
1472 GNUNET_free (lookup_query);
1474 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1475 &abort_parallel_lookups2,
1482 * Handler for ticket issue message
1485 * @param client who sent the message
1486 * @param message the message
1489 handle_consume_ticket_message (void *cls,
1490 const struct ConsumeTicketMessage *cm)
1492 struct ConsumeTicketHandle *ch;
1493 struct IdpClient *idp = cls;
1497 ch = GNUNET_new (struct ConsumeTicketHandle);
1498 ch->r_id = ntohl (cm->id);
1500 ch->identity = cm->identity;
1501 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
1502 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1504 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1505 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1507 GNUNET_asprintf (&lookup_query,
1510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1511 "Looking for ABE key under %s\n", lookup_query);
1514 = GNUNET_GNS_lookup (gns_handle,
1516 &ch->ticket.identity,
1517 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1518 GNUNET_GNS_LO_LOCAL_MASTER,
1519 &process_consume_abe_key,
1521 GNUNET_free (rnd_label);
1522 GNUNET_free (lookup_query);
1523 GNUNET_SERVICE_client_continue (idp->client);
1527 attr_store_cont (void *cls,
1531 struct AttributeStoreHandle *as_handle = cls;
1532 struct GNUNET_MQ_Envelope *env;
1533 struct AttributeStoreResponseMessage *acr_msg;
1535 if (GNUNET_SYSERR == success)
1537 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1538 "Failed to store attribute %s\n",
1540 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1545 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1546 env = GNUNET_MQ_msg (acr_msg,
1547 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1548 acr_msg->id = htonl (as_handle->r_id);
1549 acr_msg->op_result = htonl (GNUNET_OK);
1550 GNUNET_MQ_send (as_handle->client->mq,
1552 cleanup_as_handle (as_handle);
1556 attr_store_task (void *cls)
1558 struct AttributeStoreHandle *as_handle = cls;
1559 struct GNUNET_GNSRECORD_Data rd[1];
1563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1564 "Storing attribute\n");
1565 buf_size = attribute_serialize_get_size (as_handle->attribute);
1566 buf = GNUNET_malloc (buf_size);
1568 attribute_serialize (as_handle->attribute,
1572 * Encrypt the attribute value and store in namestore
1574 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1576 as_handle->attribute->name, //Policy
1578 (void**)&rd[0].data);
1580 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1581 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1582 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1583 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1584 &as_handle->identity,
1585 as_handle->attribute->name,
1590 GNUNET_free ((void*)rd[0].data);
1596 store_after_abe_bootstrap (void *cls,
1597 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1600 "Finished ABE bootstrap\n");
1601 struct AttributeStoreHandle *ash = cls;
1602 ash->abe_key = abe_key;
1603 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1607 * Checks a store message
1609 * @param cls client sending the message
1610 * @param sam message of type `struct AttributeStoreMessage`
1611 * @return #GNUNET_OK if @a im is well-formed
1614 check_attribute_store_message(void *cls,
1615 const struct AttributeStoreMessage *sam)
1619 size = ntohs (sam->header.size);
1620 if (size <= sizeof (struct AttributeStoreMessage))
1623 return GNUNET_SYSERR;
1631 * Handler for store message
1634 * @param client who sent the message
1635 * @param message the message
1638 handle_attribute_store_message (void *cls,
1639 const struct AttributeStoreMessage *sam)
1641 struct AttributeStoreHandle *as_handle;
1642 struct IdpClient *idp = cls;
1644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1645 "Received ATTRIBUTE_STORE message\n");
1647 data_len = ntohs (sam->attr_len);
1649 as_handle = GNUNET_new (struct AttributeStoreHandle);
1650 as_handle->attribute = attribute_deserialize ((char*)&sam[1],
1653 as_handle->r_id = ntohl (sam->id);
1654 as_handle->identity = sam->identity;
1655 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1656 &as_handle->identity_pkey);
1658 GNUNET_SERVICE_client_continue (idp->client);
1659 as_handle->client = idp;
1660 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
1664 cleanup_iter_handle (struct AttributeIterator *ai)
1666 if (NULL != ai->abe_key)
1667 GNUNET_free (ai->abe_key);
1668 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1669 ai->client->op_tail,
1675 attr_iter_error (void *cls)
1677 //struct AttributeIterator *ai = cls;
1679 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1680 "Failed to iterate over attributes\n");
1681 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1685 attr_iter_finished (void *cls)
1687 struct AttributeIterator *ai = cls;
1688 struct GNUNET_MQ_Envelope *env;
1689 struct AttributeResultMessage *arm;
1691 env = GNUNET_MQ_msg (arm,
1692 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1693 arm->id = htonl (ai->request_id);
1694 arm->attr_len = htons (0);
1695 GNUNET_MQ_send (ai->client->mq, env);
1696 cleanup_iter_handle (ai);
1700 attr_iter_cb (void *cls,
1701 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1703 unsigned int rd_count,
1704 const struct GNUNET_GNSRECORD_Data *rd)
1706 struct AttributeIterator *ai = cls;
1707 struct AttributeResultMessage *arm;
1708 struct GNUNET_CRYPTO_AbeKey *key;
1709 struct GNUNET_MQ_Envelope *env;
1710 ssize_t msg_extra_len;
1717 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1721 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1722 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1725 attrs[0] = (char*)label;
1727 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
1729 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1733 GNUNET_CRYPTO_cpabe_delete_key (key);
1734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1735 "Found attribute: %s\n", label);
1736 env = GNUNET_MQ_msg_extra (arm,
1738 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1739 arm->id = htonl (ai->request_id);
1740 arm->attr_len = htons (msg_extra_len);
1741 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
1743 data_tmp = (char *) &arm[1];
1744 GNUNET_memcpy (data_tmp,
1747 GNUNET_MQ_send (ai->client->mq, env);
1748 GNUNET_free (attr_ser);
1753 iterate_after_abe_bootstrap (void *cls,
1754 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1756 struct AttributeIterator *ai = cls;
1757 ai->abe_key = abe_key;
1758 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1764 &attr_iter_finished,
1770 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
1772 * @param cls the client sending the message
1773 * @param zis_msg message from the client
1776 handle_iteration_start (void *cls,
1777 const struct AttributeIterationStartMessage *ais_msg)
1779 struct IdpClient *idp = cls;
1780 struct AttributeIterator *ai;
1782 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1783 "Received ATTRIBUTE_ITERATION_START message\n");
1784 ai = GNUNET_new (struct AttributeIterator);
1785 ai->request_id = ntohl (ais_msg->id);
1787 ai->identity = ais_msg->identity;
1789 GNUNET_CONTAINER_DLL_insert (idp->op_head,
1792 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
1793 GNUNET_SERVICE_client_continue (idp->client);
1798 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
1800 * @param cls the client sending the message
1801 * @param ais_msg message from the client
1804 handle_iteration_stop (void *cls,
1805 const struct AttributeIterationStopMessage *ais_msg)
1807 struct IdpClient *idp = cls;
1808 struct AttributeIterator *ai;
1811 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1812 "Received `%s' message\n",
1813 "ATTRIBUTE_ITERATION_STOP");
1814 rid = ntohl (ais_msg->id);
1815 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1816 if (ai->request_id == rid)
1821 GNUNET_SERVICE_client_drop (idp->client);
1824 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1828 GNUNET_SERVICE_client_continue (idp->client);
1833 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
1835 * @param cls the client sending the message
1836 * @param message message from the client
1839 handle_iteration_next (void *cls,
1840 const struct AttributeIterationNextMessage *ais_msg)
1842 struct IdpClient *idp = cls;
1843 struct AttributeIterator *ai;
1846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1847 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1848 rid = ntohl (ais_msg->id);
1849 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1850 if (ai->request_id == rid)
1855 GNUNET_SERVICE_client_drop (idp->client);
1858 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1859 GNUNET_SERVICE_client_continue (idp->client);
1863 * Ticket iteration processor result
1865 enum ZoneIterationResult
1874 * Continue to iterate with next iteration_next call
1876 IT_SUCCESS_MORE_AVAILABLE = 1,
1879 * Iteration complete
1881 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
1886 * Context for ticket iteration
1888 struct TicketIterationProcResult
1891 * The ticket iteration handle
1893 struct TicketIteration *ti;
1896 * Iteration result: iteration done?
1897 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
1898 * we got one for now and have sent it to the client
1899 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
1900 * #IT_START: if we are still trying to find a result.
1902 int res_iteration_finished;
1909 * Process ticket from database
1911 * @param cls struct TicketIterationProcResult
1912 * @param ticket the ticket
1913 * @param attrs the attributes
1916 ticket_iterate_proc (void *cls,
1917 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
1919 struct TicketIterationProcResult *proc = cls;
1923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1924 "Iteration done\n");
1925 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
1928 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
1929 send_ticket_result (proc->ti->client,
1936 * Perform ticket iteration step
1938 * @param ti ticket iterator to process
1941 run_ticket_iteration_round (struct TicketIteration *ti)
1943 struct TicketIterationProcResult proc;
1944 struct GNUNET_MQ_Envelope *env;
1945 struct TicketResultMessage *trm;
1948 memset (&proc, 0, sizeof (proc));
1950 proc.res_iteration_finished = IT_START;
1951 while (IT_START == proc.res_iteration_finished)
1953 if (GNUNET_SYSERR ==
1954 (ret = TKT_database->iterate_tickets (TKT_database->cls,
1958 &ticket_iterate_proc,
1964 if (GNUNET_NO == ret)
1965 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
1968 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
1970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1971 "More results available\n");
1972 return; /* more later */
1974 /* send empty response to indicate end of list */
1975 env = GNUNET_MQ_msg (trm,
1976 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
1977 trm->id = htonl (ti->r_id);
1978 GNUNET_MQ_send (ti->client->mq,
1980 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
1981 ti->client->ticket_iter_tail,
1987 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START message
1989 * @param cls the client sending the message
1990 * @param tis_msg message from the client
1993 handle_ticket_iteration_start (void *cls,
1994 const struct TicketIterationStartMessage *tis_msg)
1996 struct IdpClient *client = cls;
1997 struct TicketIteration *ti;
1999 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2000 "Received TICKET_ITERATION_START message\n");
2001 ti = GNUNET_new (struct TicketIteration);
2002 ti->r_id = ntohl (tis_msg->id);
2004 ti->client = client;
2005 ti->identity = tis_msg->identity;
2006 ti->is_audience = ntohl (tis_msg->is_audience);
2008 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2009 client->ticket_iter_tail,
2011 run_ticket_iteration_round (ti);
2012 GNUNET_SERVICE_client_continue (client->client);
2017 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP message
2019 * @param cls the client sending the message
2020 * @param tis_msg message from the client
2023 handle_ticket_iteration_stop (void *cls,
2024 const struct TicketIterationStopMessage *tis_msg)
2026 struct IdpClient *client = cls;
2027 struct TicketIteration *ti;
2030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2031 "Received `%s' message\n",
2032 "TICKET_ITERATION_STOP");
2033 rid = ntohl (tis_msg->id);
2034 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2035 if (ti->r_id == rid)
2040 GNUNET_SERVICE_client_drop (client->client);
2043 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2044 client->ticket_iter_tail,
2047 GNUNET_SERVICE_client_continue (client->client);
2052 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT message
2054 * @param cls the client sending the message
2055 * @param message message from the client
2058 handle_ticket_iteration_next (void *cls,
2059 const struct TicketIterationNextMessage *tis_msg)
2061 struct IdpClient *client = cls;
2062 struct TicketIteration *ti;
2065 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2066 "Received TICKET_ITERATION_NEXT message\n");
2067 rid = ntohl (tis_msg->id);
2068 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2069 if (ti->r_id == rid)
2074 GNUNET_SERVICE_client_drop (client->client);
2077 run_ticket_iteration_round (ti);
2078 GNUNET_SERVICE_client_continue (client->client);
2085 * Main function that will be run
2087 * @param cls closure
2088 * @param args remaining command-line arguments
2089 * @param cfgfile name of the configuration file used (for saving, can be NULL)
2090 * @param c configuration
2094 const struct GNUNET_CONFIGURATION_Handle *c,
2095 struct GNUNET_SERVICE_Handle *server)
2100 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
2102 //Connect to identity and namestore services
2103 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2104 if (NULL == ns_handle)
2106 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2109 gns_handle = GNUNET_GNS_connect (cfg);
2110 if (NULL == gns_handle)
2112 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2114 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2115 if (NULL == credential_handle)
2117 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2119 identity_handle = GNUNET_IDENTITY_connect (cfg,
2123 /* Loading DB plugin */
2125 GNUNET_CONFIGURATION_get_value_string (cfg,
2126 "identity-provider",
2129 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2130 "No database backend configured\n");
2131 GNUNET_asprintf (&db_lib_name,
2132 "libgnunet_plugin_identity_provider_%s",
2134 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2136 GNUNET_free (database);
2137 if (NULL == TKT_database)
2139 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2140 "Could not load database backend `%s'\n",
2142 GNUNET_SCHEDULER_shutdown ();
2147 GNUNET_CONFIGURATION_get_value_time (cfg,
2148 "identity-provider",
2149 "TOKEN_EXPIRATION_INTERVAL",
2150 &token_expiration_interval))
2152 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2153 "Time window for zone iteration: %s\n",
2154 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2157 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2160 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2164 * Called whenever a client is disconnected.
2166 * @param cls closure
2167 * @param client identification of the client
2168 * @param app_ctx @a client
2171 client_disconnect_cb (void *cls,
2172 struct GNUNET_SERVICE_Client *client,
2175 struct IdpClient *idp = app_ctx;
2176 struct AttributeIterator *ai;
2178 //TODO other operations
2180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2181 "Client %p disconnected\n",
2184 while (NULL != (ai = idp->op_head))
2186 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2196 * Add a client to our list of active clients.
2199 * @param client client to add
2200 * @param mq message queue for @a client
2201 * @return internal namestore client structure for this client
2204 client_connect_cb (void *cls,
2205 struct GNUNET_SERVICE_Client *client,
2206 struct GNUNET_MQ_Handle *mq)
2208 struct IdpClient *idp;
2209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2210 "Client %p connected\n",
2212 idp = GNUNET_new (struct IdpClient);
2213 idp->client = client;
2221 * Define "main" method using service macro.
2224 ("identity-provider",
2225 GNUNET_SERVICE_OPTION_NONE,
2228 &client_disconnect_cb,
2230 GNUNET_MQ_hd_var_size (attribute_store_message,
2231 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
2232 struct AttributeStoreMessage,
2234 GNUNET_MQ_hd_fixed_size (iteration_start,
2235 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
2236 struct AttributeIterationStartMessage,
2238 GNUNET_MQ_hd_fixed_size (iteration_next,
2239 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
2240 struct AttributeIterationNextMessage,
2242 GNUNET_MQ_hd_fixed_size (iteration_stop,
2243 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
2244 struct AttributeIterationStopMessage,
2246 GNUNET_MQ_hd_var_size (issue_ticket_message,
2247 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET,
2248 struct IssueTicketMessage,
2250 GNUNET_MQ_hd_var_size (consume_ticket_message,
2251 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
2252 struct ConsumeTicketMessage,
2254 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2255 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
2256 struct TicketIterationStartMessage,
2258 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2259 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
2260 struct TicketIterationNextMessage,
2262 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2263 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
2264 struct TicketIterationStopMessage,
2266 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2267 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET,
2268 struct RevokeTicketMessage,
2270 GNUNET_MQ_handler_end());
2271 /* end of gnunet-service-identity-provider.c */