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"
48 * Normal operation state
50 #define STATE_POST_INIT 1
53 * Minimum interval between updates
55 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
58 * Standard token expiration time
60 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
65 static struct GNUNET_IDENTITY_Handle *identity_handle;
70 static struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *TKT_database;
75 static char *db_lib_name;
78 * Token expiration interval
80 static struct GNUNET_TIME_Relative token_expiration_interval;
85 static struct GNUNET_NAMESTORE_Handle *ns_handle;
90 static struct GNUNET_GNS_Handle *gns_handle;
95 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
100 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
105 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
110 static struct GNUNET_SCHEDULER_Task *timeout_task;
115 static struct GNUNET_SCHEDULER_Task *update_task;
119 * Currently processed token
121 static struct IdentityToken *token;
124 * Label for currently processed token
129 * Scopes for processed token
134 * Handle to the statistics service.
136 static struct GNUNET_STATISTICS_Handle *stats;
141 static const struct GNUNET_CONFIGURATION_Handle *cfg;
149 * A ticket iteration operation.
151 struct TicketIteration
156 struct TicketIteration *next;
161 struct TicketIteration *prev;
164 * Client which intiated this zone iteration
166 struct IdpClient *client;
169 * Key of the identity we are iterating over.
171 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
174 * Identity is audience
176 uint32_t is_audience;
179 * The operation id fot the iteration in the response for the client
184 * Offset of the iteration used to address next result of the
185 * iteration in the store
187 * Initialy set to 0 in handle_iteration_start
188 * Incremented with by every call to handle_iteration_next
197 * Callback after an ABE bootstrap
200 * @param abe_key the ABE key that exists or was created
203 (*AbeBootstrapResult) (void *cls,
204 struct GNUNET_CRYPTO_AbeMasterKey *abe_key);
207 struct AbeBootstrapHandle
210 * Function to call when finished
212 AbeBootstrapResult proc;
220 * Key of the zone we are iterating over.
222 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
225 * Namestore Queue Entry
227 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
230 * The issuer egos ABE master key
232 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
236 * An attribute iteration operation.
238 struct AttributeIterator
241 * Next element in the DLL
243 struct AttributeIterator *next;
246 * Previous element in the DLL
248 struct AttributeIterator *prev;
251 * IDP client which intiated this zone iteration
253 struct IdpClient *client;
256 * Key of the zone we are iterating over.
258 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
261 * The issuer egos ABE master key
263 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
268 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
271 * The operation id fot the zone iteration in the response for the client
288 struct GNUNET_SERVICE_Client *client;
291 * Message queue for transmission to @e client
293 struct GNUNET_MQ_Handle *mq;
297 * Attribute iteration operations in
298 * progress initiated by this client
300 struct AttributeIterator *op_head;
304 * Attribute iteration operations
305 * in progress initiated by this client
307 struct AttributeIterator *op_tail;
310 * Head of DLL of ticket iteration ops
312 struct TicketIteration *ticket_iter_head;
315 * Tail of DLL of ticket iteration ops
317 struct TicketIteration *ticket_iter_tail;
322 struct AttributeStoreHandle
328 struct IdpClient *client;
333 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
338 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
341 * The issuer egos ABE master key
343 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
348 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
351 * The attribute to store
353 struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
363 struct ParallelLookup;
365 struct ConsumeTicketHandle
371 struct IdpClient *client;
376 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
381 struct GNUNET_GNS_LookupRequest *lookup_request;
386 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
391 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
396 struct ParallelLookup *parallel_lookups_head;
401 struct ParallelLookup *parallel_lookups_tail;
406 struct GNUNET_SCHEDULER_Task *kill_task;
411 struct GNUNET_CRYPTO_AbeKey *key;
416 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
425 * Handle for a parallel GNS lookup job
427 struct ParallelLookup
430 struct ParallelLookup *next;
433 struct ParallelLookup *prev;
435 /* The GNS request */
436 struct GNUNET_GNS_LookupRequest *lookup_request;
438 /* The handle the return to */
439 struct ConsumeTicketHandle *handle;
441 /* The label to look up */
446 * Ticket issue request handle
448 struct TicketIssueHandle
454 struct IdpClient *client;
457 * Attributes to issue
459 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
464 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
469 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
474 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
484 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
492 struct EgoEntry *next;
497 struct EgoEntry *prev;
502 struct GNUNET_IDENTITY_Ego *ego;
505 * Attribute map. Contains the attributes as json_t
507 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
517 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
521 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
524 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
526 GNUNET_free (db_lib_name);
528 if (NULL != timeout_task)
529 GNUNET_SCHEDULER_cancel (timeout_task);
530 if (NULL != update_task)
531 GNUNET_SCHEDULER_cancel (update_task);
532 if (NULL != identity_handle)
533 GNUNET_IDENTITY_disconnect (identity_handle);
534 if (NULL != gns_handle)
535 GNUNET_GNS_disconnect (gns_handle);
536 if (NULL != credential_handle)
537 GNUNET_CREDENTIAL_disconnect (credential_handle);
539 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
541 GNUNET_NAMESTORE_cancel (ns_qe);
542 if (NULL != ns_handle)
543 GNUNET_NAMESTORE_disconnect (ns_handle);
555 * @param tc task context
558 do_shutdown (void *cls)
560 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
561 "Shutting down...\n");
566 * Finished storing newly bootstrapped ABE key
569 bootstrap_store_cont (void *cls,
573 struct AbeBootstrapHandle *abh = cls;
574 if (GNUNET_SYSERR == success)
576 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
577 "Failed to bootstrap ABE master %s\n",
579 abh->proc (abh->proc_cls, NULL);
580 GNUNET_free (abh->abe_key);
584 abh->proc (abh->proc_cls, abh->abe_key);
589 * Generates and stores a new ABE key
592 bootstrap_store_task (void *cls)
594 struct AbeBootstrapHandle *abh = cls;
595 struct GNUNET_GNSRECORD_Data rd[1];
597 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
598 (void**)&rd[0].data);
599 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
600 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
601 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
602 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
607 &bootstrap_store_cont,
612 * Error checking for ABE master
615 bootstrap_abe_error (void *cls)
617 struct AbeBootstrapHandle *abh = cls;
619 abh->proc (abh->proc_cls, NULL);
625 * Handle ABE lookup in namestore
628 bootstrap_abe_result (void *cls,
629 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
631 unsigned int rd_count,
632 const struct GNUNET_GNSRECORD_Data *rd)
634 struct AbeBootstrapHandle *abh = cls;
635 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
638 for (i=0;i<rd_count;i++) {
639 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
641 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
643 abh->proc (abh->proc_cls, abe_key);
648 //No ABE master found, bootstrapping...
649 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
650 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
654 * Bootstrap ABE master if it does not yet exists.
655 * Will call the AbeBootstrapResult processor when done.
658 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
659 AbeBootstrapResult proc,
662 struct AbeBootstrapHandle *abh;
664 abh = GNUNET_new (struct AbeBootstrapHandle);
667 abh->identity = *identity;
668 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
671 &bootstrap_abe_error,
673 &bootstrap_abe_result,
681 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
682 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
683 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
685 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
687 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
690 static const char ctx_key[] = "gnuid-aes-ctx-key";
691 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
692 new_key_hash, sizeof (struct GNUNET_HashCode),
693 ctx_key, strlen (ctx_key),
695 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
696 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
697 new_key_hash, sizeof (struct GNUNET_HashCode),
698 ctx_iv, strlen (ctx_iv),
704 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
706 if (NULL != handle->attrs)
707 attribute_list_destroy (handle->attrs);
708 if (NULL != handle->ns_qe)
709 GNUNET_NAMESTORE_cancel (handle->ns_qe);
710 GNUNET_free (handle);
715 send_ticket_result (struct IdpClient *client,
717 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
719 struct TicketResultMessage *irm;
720 struct GNUNET_MQ_Envelope *env;
721 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
723 /* store ticket in DB */
724 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
727 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
728 "Unable to store ticket after issue\n");
732 env = GNUNET_MQ_msg_extra (irm,
733 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
734 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
735 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
736 *ticket_buf = *ticket;
737 irm->id = htonl (r_id);
738 GNUNET_MQ_send (client->mq,
743 store_ticket_issue_cont (void *cls,
747 struct TicketIssueHandle *handle = cls;
749 handle->ns_qe = NULL;
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,
761 cleanup_ticket_issue_handle (handle);
767 serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle,
768 const struct GNUNET_CRYPTO_AbeKey *rp_key,
769 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
772 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
773 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
775 char *serialized_key;
781 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
782 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
783 struct GNUNET_HashCode new_key_hash;
786 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
787 (void**)&serialized_key);
789 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
790 attrs_str_len += strlen (le->attribute->name) + 1;
792 buf = GNUNET_malloc (attrs_str_len + size);
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
795 "Writing attributes\n");
796 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
798 "%s\n", le->attribute->name);
801 GNUNET_memcpy (write_ptr,
803 strlen (le->attribute->name));
804 write_ptr[strlen (le->attribute->name)] = ',';
805 write_ptr += strlen (le->attribute->name) + 1;
808 write_ptr[0] = '\0'; //replace last , with a 0-terminator
810 GNUNET_memcpy (write_ptr,
813 // ECDH keypair E = eG
814 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
815 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
817 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
818 // Derived key K = H(eB)
819 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
820 &handle->ticket.audience,
822 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
823 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
824 size + attrs_str_len,
827 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
829 GNUNET_memcpy (*result,
831 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
832 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
835 GNUNET_free (enc_keyinfo);
836 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
842 issue_ticket_after_abe_bootstrap (void *cls,
843 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
845 struct TicketIssueHandle *ih = cls;
846 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
847 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
848 struct GNUNET_GNSRECORD_Data code_record[1];
849 struct GNUNET_CRYPTO_AbeKey *rp_key;
850 char *code_record_data;
855 size_t code_record_len;
857 //Create new ABE key for RP
859 for (le = ih->attrs->list_head; NULL != le; le = le->next)
861 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
863 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
864 attrs[i] = (char*) le->attribute->name;
868 rp_key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
871 //TODO review this wireformat
872 code_record_len = serialize_abe_keyinfo2 (ih,
876 code_record[0].data = code_record_data;
877 code_record[0].data_size = code_record_len;
878 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
879 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
880 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
882 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
885 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
890 &store_ticket_issue_cont,
892 GNUNET_free (ecdhe_privkey);
895 GNUNET_free (code_record_data);
900 * Checks a ticket issue message
902 * @param cls client sending the message
903 * @param im message of type `struct TicketIssueMessage`
904 * @return #GNUNET_OK if @a im is well-formed
907 check_ticket_issue_message(void *cls,
908 const struct TicketIssueMessage *im)
912 size = ntohs (im->header.size);
913 if (size <= sizeof (struct TicketIssueMessage))
916 return GNUNET_SYSERR;
924 * Handler for ticket issue message
927 * @param client who sent the message
928 * @param message the message
931 handle_ticket_issue_message (void *cls,
932 const struct TicketIssueMessage *im)
934 struct TicketIssueHandle *ih;
935 struct IdpClient *idp = cls;
938 ih = GNUNET_new (struct TicketIssueHandle);
939 attrs_len = ntohs (im->attr_len);
940 ih->attrs = attribute_list_deserialize ((char*)&im[1], attrs_len);
941 ih->r_id = ntohl (im->id);
943 ih->identity = im->identity;
944 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
945 &ih->ticket.identity);
946 ih->ticket.audience = im->rp;
948 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
950 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih);
951 GNUNET_SERVICE_client_continue (idp->client);
958 cleanup_as_handle (struct AttributeStoreHandle *handle)
960 if (NULL != handle->attribute)
961 GNUNET_free (handle->attribute);
962 if (NULL != handle->abe_key)
963 GNUNET_free (handle->abe_key);
964 GNUNET_free (handle);
968 * Checks a ticket consume message
970 * @param cls client sending the message
971 * @param im message of type `struct ConsumeTicketMessage`
972 * @return #GNUNET_OK if @a im is well-formed
975 check_consume_ticket_message(void *cls,
976 const struct ConsumeTicketMessage *cm)
980 size = ntohs (cm->header.size);
981 if (size <= sizeof (struct ConsumeTicketMessage))
984 return GNUNET_SYSERR;
990 process_parallel_lookup2 (void *cls, uint32_t rd_count,
991 const struct GNUNET_GNSRECORD_Data *rd)
993 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
994 "Parallel lookup finished (count=%u)\n", rd_count);
995 struct ParallelLookup *parallel_lookup = cls;
996 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
997 struct ConsumeTicketResultMessage *crm;
998 struct GNUNET_MQ_Envelope *env;
999 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *attr_le;
1005 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1006 handle->parallel_lookups_tail,
1008 GNUNET_free (parallel_lookup->label);
1009 GNUNET_free (parallel_lookup);
1011 GNUNET_break(0);//TODO
1012 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1014 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1018 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1019 attr_le->attribute = attribute_deserialize (data,
1021 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1022 handle->attrs->list_tail,
1026 if (NULL != handle->parallel_lookups_head)
1027 return; //Wait for more
1028 /* Else we are done */
1030 /* Store ticket in DB */
1031 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1034 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1035 "Unable to store ticket after consume\n");
1039 GNUNET_SCHEDULER_cancel (handle->kill_task);
1040 attrs_len = attribute_list_serialize_get_size (handle->attrs);
1041 env = GNUNET_MQ_msg_extra (crm,
1043 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1044 crm->id = htonl (handle->r_id);
1045 crm->attrs_len = htons (attrs_len);
1046 crm->identity = handle->ticket.identity;
1047 data_tmp = (char *) &crm[1];
1048 attribute_list_serialize (handle->attrs,
1050 GNUNET_MQ_send (handle->client->mq, env);
1054 abort_parallel_lookups2 (void *cls)
1056 struct ConsumeTicketHandle *handle = cls;
1057 struct ParallelLookup *lu;
1058 struct ParallelLookup *tmp;
1059 struct AttributeResultMessage *arm;
1060 struct GNUNET_MQ_Envelope *env;
1062 for (lu = handle->parallel_lookups_head;
1064 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1065 GNUNET_free (lu->label);
1067 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1068 handle->parallel_lookups_tail,
1073 env = GNUNET_MQ_msg (arm,
1074 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1075 arm->id = htonl (handle->r_id);
1076 arm->attr_len = htons (0);
1077 GNUNET_MQ_send (handle->client->mq, env);
1082 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1084 if (NULL != handle->key)
1085 GNUNET_free (handle->key);
1086 GNUNET_free (handle);
1091 process_consume_abe_key (void *cls, uint32_t rd_count,
1092 const struct GNUNET_GNSRECORD_Data *rd)
1094 struct ConsumeTicketHandle *handle = cls;
1095 struct GNUNET_HashCode new_key_hash;
1096 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1097 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1098 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1099 struct ParallelLookup *parallel_lookup;
1105 handle->lookup_request = NULL;
1108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1109 "Number of keys %d != 1.",
1111 cleanup_consume_ticket_handle (handle);
1112 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1117 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1119 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1121 //Calculate symmetric key from ecdh parameters
1122 GNUNET_assert (GNUNET_OK ==
1123 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1126 create_sym_key_from_ecdh (&new_key_hash,
1129 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1130 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1136 "Decrypted bytes: %zd Expected bytes: %zd\n",
1137 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1139 scopes = GNUNET_strdup (buf);
1140 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1141 "Scopes %s\n", scopes);
1142 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1143 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1144 - strlen (scopes) - 1);
1146 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1148 GNUNET_asprintf (&lookup_query,
1151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1152 "Looking up %s\n", lookup_query);
1153 parallel_lookup = GNUNET_new (struct ParallelLookup);
1154 parallel_lookup->handle = handle;
1155 parallel_lookup->label = GNUNET_strdup (scope);
1156 parallel_lookup->lookup_request
1157 = GNUNET_GNS_lookup (gns_handle,
1159 &handle->ticket.identity,
1160 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1161 GNUNET_GNS_LO_LOCAL_MASTER,
1162 &process_parallel_lookup2,
1164 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1165 handle->parallel_lookups_tail,
1167 GNUNET_free (lookup_query);
1169 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1170 &abort_parallel_lookups2,
1177 * Handler for ticket issue message
1180 * @param client who sent the message
1181 * @param message the message
1184 handle_consume_ticket_message (void *cls,
1185 const struct ConsumeTicketMessage *cm)
1187 struct ConsumeTicketHandle *ch;
1188 struct IdpClient *idp = cls;
1192 ch = GNUNET_new (struct ConsumeTicketHandle);
1193 ch->r_id = ntohl (cm->id);
1195 ch->identity = cm->identity;
1196 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
1197 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1199 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1200 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1202 GNUNET_asprintf (&lookup_query,
1205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1206 "Looking for ABE key under %s\n", lookup_query);
1209 = GNUNET_GNS_lookup (gns_handle,
1211 &ch->ticket.identity,
1212 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1213 GNUNET_GNS_LO_LOCAL_MASTER,
1214 &process_consume_abe_key,
1216 GNUNET_free (rnd_label);
1217 GNUNET_free (lookup_query);
1218 GNUNET_SERVICE_client_continue (idp->client);
1222 attr_store_cont (void *cls,
1226 struct AttributeStoreHandle *as_handle = cls;
1227 struct GNUNET_MQ_Envelope *env;
1228 struct AttributeStoreResponseMessage *acr_msg;
1230 if (GNUNET_SYSERR == success)
1232 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1233 "Failed to store attribute %s\n",
1235 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1240 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1241 env = GNUNET_MQ_msg (acr_msg,
1242 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1243 acr_msg->id = htonl (as_handle->r_id);
1244 acr_msg->op_result = htonl (GNUNET_OK);
1245 GNUNET_MQ_send (as_handle->client->mq,
1247 cleanup_as_handle (as_handle);
1251 attr_store_task (void *cls)
1253 struct AttributeStoreHandle *as_handle = cls;
1254 struct GNUNET_GNSRECORD_Data rd[1];
1258 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1259 "Storing attribute\n");
1260 buf_size = attribute_serialize_get_size (as_handle->attribute);
1261 buf = GNUNET_malloc (buf_size);
1263 attribute_serialize (as_handle->attribute,
1267 * Encrypt the attribute value and store in namestore
1269 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1271 as_handle->attribute->name, //Policy
1273 (void**)&rd[0].data);
1275 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1276 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1277 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1278 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1279 &as_handle->identity,
1280 as_handle->attribute->name,
1285 GNUNET_free ((void*)rd[0].data);
1291 store_after_abe_bootstrap (void *cls,
1292 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1295 "Finished ABE bootstrap\n");
1296 struct AttributeStoreHandle *ash = cls;
1297 ash->abe_key = abe_key;
1298 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1302 * Checks a store message
1304 * @param cls client sending the message
1305 * @param sam message of type `struct AttributeStoreMessage`
1306 * @return #GNUNET_OK if @a im is well-formed
1309 check_attribute_store_message(void *cls,
1310 const struct AttributeStoreMessage *sam)
1314 size = ntohs (sam->header.size);
1315 if (size <= sizeof (struct AttributeStoreMessage))
1318 return GNUNET_SYSERR;
1326 * Handler for store message
1329 * @param client who sent the message
1330 * @param message the message
1333 handle_attribute_store_message (void *cls,
1334 const struct AttributeStoreMessage *sam)
1336 struct AttributeStoreHandle *as_handle;
1337 struct IdpClient *idp = cls;
1339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1340 "Received ATTRIBUTE_STORE message\n");
1342 data_len = ntohs (sam->attr_len);
1344 as_handle = GNUNET_new (struct AttributeStoreHandle);
1345 as_handle->attribute = attribute_deserialize ((char*)&sam[1],
1348 as_handle->r_id = ntohl (sam->id);
1349 as_handle->identity = sam->identity;
1350 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1351 &as_handle->identity_pkey);
1353 GNUNET_SERVICE_client_continue (idp->client);
1354 as_handle->client = idp;
1355 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle);
1359 cleanup_iter_handle (struct AttributeIterator *ai)
1361 if (NULL != ai->abe_key)
1362 GNUNET_free (ai->abe_key);
1363 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1364 ai->client->op_tail,
1370 attr_iter_error (void *cls)
1372 //struct AttributeIterator *ai = cls;
1374 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1375 "Failed to iterate over attributes\n");
1376 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1380 attr_iter_finished (void *cls)
1382 struct AttributeIterator *ai = cls;
1383 struct GNUNET_MQ_Envelope *env;
1384 struct AttributeResultMessage *arm;
1386 env = GNUNET_MQ_msg (arm,
1387 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1388 arm->id = htonl (ai->request_id);
1389 arm->attr_len = htons (0);
1390 GNUNET_MQ_send (ai->client->mq, env);
1391 cleanup_iter_handle (ai);
1395 attr_iter_cb (void *cls,
1396 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1398 unsigned int rd_count,
1399 const struct GNUNET_GNSRECORD_Data *rd)
1401 struct AttributeIterator *ai = cls;
1402 struct AttributeResultMessage *arm;
1403 struct GNUNET_CRYPTO_AbeKey *key;
1404 struct GNUNET_MQ_Envelope *env;
1405 ssize_t msg_extra_len;
1412 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1416 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1417 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1420 attrs[0] = (char*)label;
1422 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
1424 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1428 GNUNET_CRYPTO_cpabe_delete_key (key);
1429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1430 "Found attribute: %s\n", label);
1431 env = GNUNET_MQ_msg_extra (arm,
1433 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1434 arm->id = htonl (ai->request_id);
1435 arm->attr_len = htons (msg_extra_len);
1436 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
1438 data_tmp = (char *) &arm[1];
1439 GNUNET_memcpy (data_tmp,
1442 GNUNET_MQ_send (ai->client->mq, env);
1443 GNUNET_free (attr_ser);
1448 iterate_after_abe_bootstrap (void *cls,
1449 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1451 struct AttributeIterator *ai = cls;
1452 ai->abe_key = abe_key;
1453 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1459 &attr_iter_finished,
1465 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
1467 * @param cls the client sending the message
1468 * @param zis_msg message from the client
1471 handle_iteration_start (void *cls,
1472 const struct AttributeIterationStartMessage *ais_msg)
1474 struct IdpClient *idp = cls;
1475 struct AttributeIterator *ai;
1477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1478 "Received ATTRIBUTE_ITERATION_START message\n");
1479 ai = GNUNET_new (struct AttributeIterator);
1480 ai->request_id = ntohl (ais_msg->id);
1482 ai->identity = ais_msg->identity;
1484 GNUNET_CONTAINER_DLL_insert (idp->op_head,
1487 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai);
1488 GNUNET_SERVICE_client_continue (idp->client);
1493 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
1495 * @param cls the client sending the message
1496 * @param ais_msg message from the client
1499 handle_iteration_stop (void *cls,
1500 const struct AttributeIterationStopMessage *ais_msg)
1502 struct IdpClient *idp = cls;
1503 struct AttributeIterator *ai;
1506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1507 "Received `%s' message\n",
1508 "ATTRIBUTE_ITERATION_STOP");
1509 rid = ntohl (ais_msg->id);
1510 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1511 if (ai->request_id == rid)
1516 GNUNET_SERVICE_client_drop (idp->client);
1519 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1523 GNUNET_SERVICE_client_continue (idp->client);
1528 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
1530 * @param cls the client sending the message
1531 * @param message message from the client
1534 handle_iteration_next (void *cls,
1535 const struct AttributeIterationNextMessage *ais_msg)
1537 struct IdpClient *idp = cls;
1538 struct AttributeIterator *ai;
1541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1542 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1543 rid = ntohl (ais_msg->id);
1544 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1545 if (ai->request_id == rid)
1550 GNUNET_SERVICE_client_drop (idp->client);
1553 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1554 GNUNET_SERVICE_client_continue (idp->client);
1558 * Ticket iteration processor result
1560 enum ZoneIterationResult
1569 * Continue to iterate with next iteration_next call
1571 IT_SUCCESS_MORE_AVAILABLE = 1,
1574 * Iteration complete
1576 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
1581 * Context for ticket iteration
1583 struct TicketIterationProcResult
1586 * The ticket iteration handle
1588 struct TicketIteration *ti;
1591 * Iteration result: iteration done?
1592 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
1593 * we got one for now and have sent it to the client
1594 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
1595 * #IT_START: if we are still trying to find a result.
1597 int res_iteration_finished;
1604 * Process ticket from database
1606 * @param cls struct TicketIterationProcResult
1607 * @param ticket the ticket
1608 * @param attrs the attributes
1611 ticket_iterate_proc (void *cls,
1612 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
1614 struct TicketIterationProcResult *proc = cls;
1618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1619 "Iteration done\n");
1620 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
1623 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
1624 send_ticket_result (proc->ti->client,
1631 * Perform ticket iteration step
1633 * @param ti ticket iterator to process
1636 run_ticket_iteration_round (struct TicketIteration *ti)
1638 struct TicketIterationProcResult proc;
1639 struct GNUNET_MQ_Envelope *env;
1640 struct TicketResultMessage *trm;
1643 memset (&proc, 0, sizeof (proc));
1645 proc.res_iteration_finished = IT_START;
1646 while (IT_START == proc.res_iteration_finished)
1648 if (GNUNET_SYSERR ==
1649 (ret = TKT_database->iterate_tickets (TKT_database->cls,
1653 &ticket_iterate_proc,
1659 if (GNUNET_NO == ret)
1660 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
1663 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
1665 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1666 "More results available\n");
1667 return; /* more later */
1669 /* send empty response to indicate end of list */
1670 env = GNUNET_MQ_msg (trm,
1671 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
1672 trm->id = htonl (ti->r_id);
1673 GNUNET_MQ_send (ti->client->mq,
1675 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
1676 ti->client->ticket_iter_tail,
1682 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START message
1684 * @param cls the client sending the message
1685 * @param tis_msg message from the client
1688 handle_ticket_iteration_start (void *cls,
1689 const struct TicketIterationStartMessage *tis_msg)
1691 struct IdpClient *client = cls;
1692 struct TicketIteration *ti;
1694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1695 "Received TICKET_ITERATION_START message\n");
1696 ti = GNUNET_new (struct TicketIteration);
1697 ti->r_id = ntohl (tis_msg->id);
1699 ti->client = client;
1700 ti->identity = tis_msg->identity;
1701 ti->is_audience = ntohl (tis_msg->is_audience);
1703 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
1704 client->ticket_iter_tail,
1706 run_ticket_iteration_round (ti);
1707 GNUNET_SERVICE_client_continue (client->client);
1712 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP message
1714 * @param cls the client sending the message
1715 * @param tis_msg message from the client
1718 handle_ticket_iteration_stop (void *cls,
1719 const struct TicketIterationStopMessage *tis_msg)
1721 struct IdpClient *client = cls;
1722 struct TicketIteration *ti;
1725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1726 "Received `%s' message\n",
1727 "TICKET_ITERATION_STOP");
1728 rid = ntohl (tis_msg->id);
1729 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1730 if (ti->r_id == rid)
1735 GNUNET_SERVICE_client_drop (client->client);
1738 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
1739 client->ticket_iter_tail,
1742 GNUNET_SERVICE_client_continue (client->client);
1747 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT message
1749 * @param cls the client sending the message
1750 * @param message message from the client
1753 handle_ticket_iteration_next (void *cls,
1754 const struct TicketIterationNextMessage *tis_msg)
1756 struct IdpClient *client = cls;
1757 struct TicketIteration *ti;
1760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1761 "Received TICKET_ITERATION_NEXT message\n");
1762 rid = ntohl (tis_msg->id);
1763 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1764 if (ti->r_id == rid)
1769 GNUNET_SERVICE_client_drop (client->client);
1772 run_ticket_iteration_round (ti);
1773 GNUNET_SERVICE_client_continue (client->client);
1780 * Main function that will be run
1782 * @param cls closure
1783 * @param args remaining command-line arguments
1784 * @param cfgfile name of the configuration file used (for saving, can be NULL)
1785 * @param c configuration
1789 const struct GNUNET_CONFIGURATION_Handle *c,
1790 struct GNUNET_SERVICE_Handle *server)
1795 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
1797 //Connect to identity and namestore services
1798 ns_handle = GNUNET_NAMESTORE_connect (cfg);
1799 if (NULL == ns_handle)
1801 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
1804 gns_handle = GNUNET_GNS_connect (cfg);
1805 if (NULL == gns_handle)
1807 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1809 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
1810 if (NULL == credential_handle)
1812 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
1814 identity_handle = GNUNET_IDENTITY_connect (cfg,
1818 /* Loading DB plugin */
1820 GNUNET_CONFIGURATION_get_value_string (cfg,
1821 "identity-provider",
1824 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1825 "No database backend configured\n");
1826 GNUNET_asprintf (&db_lib_name,
1827 "libgnunet_plugin_identity_provider_%s",
1829 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
1831 GNUNET_free (database);
1832 if (NULL == TKT_database)
1834 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1835 "Could not load database backend `%s'\n",
1837 GNUNET_SCHEDULER_shutdown ();
1842 GNUNET_CONFIGURATION_get_value_time (cfg,
1843 "identity-provider",
1844 "TOKEN_EXPIRATION_INTERVAL",
1845 &token_expiration_interval))
1847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1848 "Time window for zone iteration: %s\n",
1849 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
1852 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
1855 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1859 * Called whenever a client is disconnected.
1861 * @param cls closure
1862 * @param client identification of the client
1863 * @param app_ctx @a client
1866 client_disconnect_cb (void *cls,
1867 struct GNUNET_SERVICE_Client *client,
1870 struct IdpClient *idp = app_ctx;
1871 struct AttributeIterator *ai;
1873 //TODO other operations
1875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1876 "Client %p disconnected\n",
1879 while (NULL != (ai = idp->op_head))
1881 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1891 * Add a client to our list of active clients.
1894 * @param client client to add
1895 * @param mq message queue for @a client
1896 * @return internal namestore client structure for this client
1899 client_connect_cb (void *cls,
1900 struct GNUNET_SERVICE_Client *client,
1901 struct GNUNET_MQ_Handle *mq)
1903 struct IdpClient *idp;
1904 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1905 "Client %p connected\n",
1907 idp = GNUNET_new (struct IdpClient);
1908 idp->client = client;
1916 * Define "main" method using service macro.
1919 ("identity-provider",
1920 GNUNET_SERVICE_OPTION_NONE,
1923 &client_disconnect_cb,
1925 GNUNET_MQ_hd_var_size (attribute_store_message,
1926 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
1927 struct AttributeStoreMessage,
1929 GNUNET_MQ_hd_fixed_size (iteration_start,
1930 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
1931 struct AttributeIterationStartMessage,
1933 GNUNET_MQ_hd_fixed_size (iteration_next,
1934 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
1935 struct AttributeIterationNextMessage,
1937 GNUNET_MQ_hd_fixed_size (iteration_stop,
1938 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
1939 struct AttributeIterationStopMessage,
1941 GNUNET_MQ_hd_var_size (ticket_issue_message,
1942 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE,
1943 struct TicketIssueMessage,
1945 GNUNET_MQ_hd_var_size (consume_ticket_message,
1946 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
1947 struct ConsumeTicketMessage,
1949 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
1950 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
1951 struct TicketIterationStartMessage,
1953 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
1954 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
1955 struct TicketIterationNextMessage,
1957 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
1958 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
1959 struct TicketIterationStopMessage,
1962 GNUNET_MQ_handler_end());
1963 /* end of gnunet-service-identity-provider.c */