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 issue request handle
447 struct TicketIssueHandle
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;
483 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
491 struct EgoEntry *next;
496 struct EgoEntry *prev;
501 struct GNUNET_IDENTITY_Ego *ego;
504 * Attribute map. Contains the attributes as json_t
506 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
520 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
523 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
525 GNUNET_free (db_lib_name);
527 if (NULL != timeout_task)
528 GNUNET_SCHEDULER_cancel (timeout_task);
529 if (NULL != update_task)
530 GNUNET_SCHEDULER_cancel (update_task);
531 if (NULL != identity_handle)
532 GNUNET_IDENTITY_disconnect (identity_handle);
533 if (NULL != gns_handle)
534 GNUNET_GNS_disconnect (gns_handle);
535 if (NULL != credential_handle)
536 GNUNET_CREDENTIAL_disconnect (credential_handle);
538 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
540 GNUNET_NAMESTORE_cancel (ns_qe);
541 if (NULL != ns_handle)
542 GNUNET_NAMESTORE_disconnect (ns_handle);
554 * @param tc task context
557 do_shutdown (void *cls)
559 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
560 "Shutting down...\n");
565 * Finished storing newly bootstrapped ABE key
568 bootstrap_store_cont (void *cls,
572 struct AbeBootstrapHandle *abh = cls;
573 if (GNUNET_SYSERR == success)
575 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
576 "Failed to bootstrap ABE master %s\n",
578 abh->proc (abh->proc_cls, NULL);
579 GNUNET_free (abh->abe_key);
583 abh->proc (abh->proc_cls, abh->abe_key);
588 * Generates and stores a new ABE key
591 bootstrap_store_task (void *cls)
593 struct AbeBootstrapHandle *abh = cls;
594 struct GNUNET_GNSRECORD_Data rd[1];
596 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
597 (void**)&rd[0].data);
598 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
599 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
600 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
601 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
606 &bootstrap_store_cont,
611 * Error checking for ABE master
614 bootstrap_abe_error (void *cls)
616 struct AbeBootstrapHandle *abh = cls;
618 abh->proc (abh->proc_cls, NULL);
624 * Handle ABE lookup in namestore
627 bootstrap_abe_result (void *cls,
628 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
630 unsigned int rd_count,
631 const struct GNUNET_GNSRECORD_Data *rd)
633 struct AbeBootstrapHandle *abh = cls;
634 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
637 for (i=0;i<rd_count;i++) {
638 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
640 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
642 abh->proc (abh->proc_cls, abe_key);
647 //No ABE master found, bootstrapping...
648 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
649 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
653 * Bootstrap ABE master if it does not yet exists.
654 * Will call the AbeBootstrapResult processor when done.
657 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
658 AbeBootstrapResult proc,
661 struct AbeBootstrapHandle *abh;
663 abh = GNUNET_new (struct AbeBootstrapHandle);
666 abh->identity = *identity;
667 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
670 &bootstrap_abe_error,
672 &bootstrap_abe_result,
680 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
681 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
682 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
684 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
686 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
689 static const char ctx_key[] = "gnuid-aes-ctx-key";
690 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
691 new_key_hash, sizeof (struct GNUNET_HashCode),
692 ctx_key, strlen (ctx_key),
694 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
695 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
696 new_key_hash, sizeof (struct GNUNET_HashCode),
697 ctx_iv, strlen (ctx_iv),
703 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
705 if (NULL != handle->attrs)
706 attribute_list_destroy (handle->attrs);
707 if (NULL != handle->ns_qe)
708 GNUNET_NAMESTORE_cancel (handle->ns_qe);
709 GNUNET_free (handle);
714 send_ticket_result (struct IdpClient *client,
716 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
718 struct TicketResultMessage *irm;
719 struct GNUNET_MQ_Envelope *env;
720 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
722 /* store ticket in DB */
723 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
726 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
727 "Unable to store ticket after issue\n");
731 env = GNUNET_MQ_msg_extra (irm,
732 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
733 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
734 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
735 *ticket_buf = *ticket;
736 irm->id = htonl (r_id);
737 GNUNET_MQ_send (client->mq,
742 store_ticket_issue_cont (void *cls,
746 struct TicketIssueHandle *handle = cls;
748 handle->ns_qe = NULL;
749 if (GNUNET_SYSERR == success)
751 cleanup_ticket_issue_handle (handle);
752 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
754 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
757 send_ticket_result (handle->client,
760 cleanup_ticket_issue_handle (handle);
766 serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle,
767 const struct GNUNET_CRYPTO_AbeKey *rp_key,
768 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
771 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
772 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
774 char *serialized_key;
780 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
781 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
782 struct GNUNET_HashCode new_key_hash;
785 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
786 (void**)&serialized_key);
788 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
789 attrs_str_len += strlen (le->attribute->name) + 1;
791 buf = GNUNET_malloc (attrs_str_len + size);
793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
794 "Writing attributes\n");
795 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
797 "%s\n", le->attribute->name);
800 GNUNET_memcpy (write_ptr,
802 strlen (le->attribute->name));
803 write_ptr[strlen (le->attribute->name)] = ',';
804 write_ptr += strlen (le->attribute->name) + 1;
807 write_ptr[0] = '\0'; //replace last , with a 0-terminator
809 GNUNET_memcpy (write_ptr,
812 // ECDH keypair E = eG
813 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
814 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
816 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
817 // Derived key K = H(eB)
818 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
819 &handle->ticket.audience,
821 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
822 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
823 size + attrs_str_len,
826 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
828 GNUNET_memcpy (*result,
830 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
831 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
834 GNUNET_free (enc_keyinfo);
835 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
841 issue_ticket_after_abe_bootstrap (void *cls,
842 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
844 struct TicketIssueHandle *ih = cls;
845 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
846 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
847 struct GNUNET_GNSRECORD_Data code_record[1];
848 struct GNUNET_CRYPTO_AbeKey *rp_key;
849 char *code_record_data;
854 size_t code_record_len;
856 //Create new ABE key for RP
858 for (le = ih->attrs->list_head; NULL != le; le = le->next)
860 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
862 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
863 attrs[i] = (char*) le->attribute->name;
867 rp_key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
870 //TODO review this wireformat
871 code_record_len = serialize_abe_keyinfo2 (ih,
875 code_record[0].data = code_record_data;
876 code_record[0].data_size = code_record_len;
877 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
878 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
879 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
881 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
884 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
889 &store_ticket_issue_cont,
891 GNUNET_free (ecdhe_privkey);
894 GNUNET_free (code_record_data);
899 * Checks a ticket issue message
901 * @param cls client sending the message
902 * @param im message of type `struct TicketIssueMessage`
903 * @return #GNUNET_OK if @a im is well-formed
906 check_ticket_issue_message(void *cls,
907 const struct TicketIssueMessage *im)
911 size = ntohs (im->header.size);
912 if (size <= sizeof (struct TicketIssueMessage))
915 return GNUNET_SYSERR;
923 * Handler for ticket issue message
926 * @param client who sent the message
927 * @param message the message
930 handle_ticket_issue_message (void *cls,
931 const struct TicketIssueMessage *im)
933 struct TicketIssueHandle *ih;
934 struct IdpClient *idp = cls;
937 ih = GNUNET_new (struct TicketIssueHandle);
938 attrs_len = ntohs (im->attr_len);
939 ih->attrs = attribute_list_deserialize ((char*)&im[1], attrs_len);
940 ih->r_id = ntohl (im->id);
942 ih->identity = im->identity;
943 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
944 &ih->ticket.identity);
945 ih->ticket.audience = im->rp;
947 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
949 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih);
950 GNUNET_SERVICE_client_continue (idp->client);
957 cleanup_as_handle (struct AttributeStoreHandle *handle)
959 if (NULL != handle->attribute)
960 GNUNET_free (handle->attribute);
961 if (NULL != handle->abe_key)
962 GNUNET_free (handle->abe_key);
963 GNUNET_free (handle);
967 * Checks a ticket consume message
969 * @param cls client sending the message
970 * @param im message of type `struct ConsumeTicketMessage`
971 * @return #GNUNET_OK if @a im is well-formed
974 check_consume_ticket_message(void *cls,
975 const struct ConsumeTicketMessage *cm)
979 size = ntohs (cm->header.size);
980 if (size <= sizeof (struct ConsumeTicketMessage))
983 return GNUNET_SYSERR;
989 process_parallel_lookup2 (void *cls, uint32_t rd_count,
990 const struct GNUNET_GNSRECORD_Data *rd)
992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
993 "Parallel lookup finished (count=%u)\n", rd_count);
994 struct ParallelLookup *parallel_lookup = cls;
995 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
996 struct ConsumeTicketResultMessage *crm;
997 struct GNUNET_MQ_Envelope *env;
998 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *attr_le;
1004 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1005 handle->parallel_lookups_tail,
1007 GNUNET_free (parallel_lookup->label);
1008 GNUNET_free (parallel_lookup);
1010 GNUNET_break(0);//TODO
1011 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1013 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1017 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1018 attr_le->attribute = attribute_deserialize (data,
1020 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1021 handle->attrs->list_tail,
1025 if (NULL != handle->parallel_lookups_head)
1026 return; //Wait for more
1027 /* Else we are done */
1029 /* Store ticket in DB */
1030 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1033 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1034 "Unable to store ticket after consume\n");
1038 GNUNET_SCHEDULER_cancel (handle->kill_task);
1039 attrs_len = attribute_list_serialize_get_size (handle->attrs);
1040 env = GNUNET_MQ_msg_extra (crm,
1042 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1043 crm->id = htonl (handle->r_id);
1044 crm->attrs_len = htons (attrs_len);
1045 crm->identity = handle->ticket.identity;
1046 data_tmp = (char *) &crm[1];
1047 attribute_list_serialize (handle->attrs,
1049 GNUNET_MQ_send (handle->client->mq, env);
1053 abort_parallel_lookups2 (void *cls)
1055 struct ConsumeTicketHandle *handle = cls;
1056 struct ParallelLookup *lu;
1057 struct ParallelLookup *tmp;
1058 struct AttributeResultMessage *arm;
1059 struct GNUNET_MQ_Envelope *env;
1061 for (lu = handle->parallel_lookups_head;
1063 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1064 GNUNET_free (lu->label);
1066 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1067 handle->parallel_lookups_tail,
1072 env = GNUNET_MQ_msg (arm,
1073 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1074 arm->id = htonl (handle->r_id);
1075 arm->attr_len = htons (0);
1076 GNUNET_MQ_send (handle->client->mq, env);
1081 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1083 if (NULL != handle->key)
1084 GNUNET_free (handle->key);
1085 GNUNET_free (handle);
1090 process_consume_abe_key (void *cls, uint32_t rd_count,
1091 const struct GNUNET_GNSRECORD_Data *rd)
1093 struct ConsumeTicketHandle *handle = cls;
1094 struct GNUNET_HashCode new_key_hash;
1095 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1096 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1097 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1098 struct ParallelLookup *parallel_lookup;
1104 handle->lookup_request = NULL;
1107 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1108 "Number of keys %d != 1.",
1110 cleanup_consume_ticket_handle (handle);
1111 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1116 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1118 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1120 //Calculate symmetric key from ecdh parameters
1121 GNUNET_assert (GNUNET_OK ==
1122 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1125 create_sym_key_from_ecdh (&new_key_hash,
1128 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1129 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1135 "Decrypted bytes: %zd Expected bytes: %zd\n",
1136 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1138 scopes = GNUNET_strdup (buf);
1139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1140 "Scopes %s\n", scopes);
1141 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1142 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1143 - strlen (scopes) - 1);
1145 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1147 GNUNET_asprintf (&lookup_query,
1150 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1151 "Looking up %s\n", lookup_query);
1152 parallel_lookup = GNUNET_new (struct ParallelLookup);
1153 parallel_lookup->handle = handle;
1154 parallel_lookup->label = GNUNET_strdup (scope);
1155 parallel_lookup->lookup_request
1156 = GNUNET_GNS_lookup (gns_handle,
1158 &handle->ticket.identity,
1159 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1160 GNUNET_GNS_LO_LOCAL_MASTER,
1161 &process_parallel_lookup2,
1163 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1164 handle->parallel_lookups_tail,
1166 GNUNET_free (lookup_query);
1168 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1169 &abort_parallel_lookups2,
1176 * Handler for ticket issue message
1179 * @param client who sent the message
1180 * @param message the message
1183 handle_consume_ticket_message (void *cls,
1184 const struct ConsumeTicketMessage *cm)
1186 struct ConsumeTicketHandle *ch;
1187 struct IdpClient *idp = cls;
1191 ch = GNUNET_new (struct ConsumeTicketHandle);
1192 ch->r_id = ntohl (cm->id);
1194 ch->identity = cm->identity;
1195 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
1196 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1198 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1199 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1201 GNUNET_asprintf (&lookup_query,
1204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1205 "Looking for ABE key under %s\n", lookup_query);
1208 = GNUNET_GNS_lookup (gns_handle,
1210 &ch->ticket.identity,
1211 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1212 GNUNET_GNS_LO_LOCAL_MASTER,
1213 &process_consume_abe_key,
1215 GNUNET_free (rnd_label);
1216 GNUNET_free (lookup_query);
1217 GNUNET_SERVICE_client_continue (idp->client);
1221 attr_store_cont (void *cls,
1225 struct AttributeStoreHandle *as_handle = cls;
1226 struct GNUNET_MQ_Envelope *env;
1227 struct AttributeStoreResponseMessage *acr_msg;
1229 if (GNUNET_SYSERR == success)
1231 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1232 "Failed to store attribute %s\n",
1234 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1238 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1239 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1240 env = GNUNET_MQ_msg (acr_msg,
1241 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1242 acr_msg->id = htonl (as_handle->r_id);
1243 acr_msg->op_result = htonl (GNUNET_OK);
1244 GNUNET_MQ_send (as_handle->client->mq,
1246 cleanup_as_handle (as_handle);
1250 attr_store_task (void *cls)
1252 struct AttributeStoreHandle *as_handle = cls;
1253 struct GNUNET_GNSRECORD_Data rd[1];
1257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1258 "Storing attribute\n");
1259 buf_size = attribute_serialize_get_size (as_handle->attribute);
1260 buf = GNUNET_malloc (buf_size);
1262 attribute_serialize (as_handle->attribute,
1266 * Encrypt the attribute value and store in namestore
1268 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1270 as_handle->attribute->name, //Policy
1272 (void**)&rd[0].data);
1274 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1275 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1276 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1277 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1278 &as_handle->identity,
1279 as_handle->attribute->name,
1284 GNUNET_free ((void*)rd[0].data);
1290 store_after_abe_bootstrap (void *cls,
1291 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1293 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1294 "Finished ABE bootstrap\n");
1295 struct AttributeStoreHandle *ash = cls;
1296 ash->abe_key = abe_key;
1297 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1301 * Checks a store message
1303 * @param cls client sending the message
1304 * @param sam message of type `struct AttributeStoreMessage`
1305 * @return #GNUNET_OK if @a im is well-formed
1308 check_attribute_store_message(void *cls,
1309 const struct AttributeStoreMessage *sam)
1313 size = ntohs (sam->header.size);
1314 if (size <= sizeof (struct AttributeStoreMessage))
1317 return GNUNET_SYSERR;
1325 * Handler for store message
1328 * @param client who sent the message
1329 * @param message the message
1332 handle_attribute_store_message (void *cls,
1333 const struct AttributeStoreMessage *sam)
1335 struct AttributeStoreHandle *as_handle;
1336 struct IdpClient *idp = cls;
1338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1339 "Received ATTRIBUTE_STORE message\n");
1341 data_len = ntohs (sam->attr_len);
1343 as_handle = GNUNET_new (struct AttributeStoreHandle);
1344 as_handle->attribute = attribute_deserialize ((char*)&sam[1],
1347 as_handle->r_id = ntohl (sam->id);
1348 as_handle->identity = sam->identity;
1349 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1350 &as_handle->identity_pkey);
1352 GNUNET_SERVICE_client_continue (idp->client);
1353 as_handle->client = idp;
1354 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle);
1358 cleanup_iter_handle (struct AttributeIterator *ai)
1360 if (NULL != ai->abe_key)
1361 GNUNET_free (ai->abe_key);
1362 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1363 ai->client->op_tail,
1369 attr_iter_error (void *cls)
1371 //struct AttributeIterator *ai = cls;
1373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1374 "Failed to iterate over attributes\n");
1375 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1379 attr_iter_finished (void *cls)
1381 struct AttributeIterator *ai = cls;
1382 struct GNUNET_MQ_Envelope *env;
1383 struct AttributeResultMessage *arm;
1385 env = GNUNET_MQ_msg (arm,
1386 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1387 arm->id = htonl (ai->request_id);
1388 arm->attr_len = htons (0);
1389 GNUNET_MQ_send (ai->client->mq, env);
1390 cleanup_iter_handle (ai);
1394 attr_iter_cb (void *cls,
1395 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1397 unsigned int rd_count,
1398 const struct GNUNET_GNSRECORD_Data *rd)
1400 struct AttributeIterator *ai = cls;
1401 struct AttributeResultMessage *arm;
1402 struct GNUNET_CRYPTO_AbeKey *key;
1403 struct GNUNET_MQ_Envelope *env;
1404 ssize_t msg_extra_len;
1411 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1415 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1416 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1419 attrs[0] = (char*)label;
1421 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
1423 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1427 GNUNET_CRYPTO_cpabe_delete_key (key);
1428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1429 "Found attribute: %s\n", label);
1430 env = GNUNET_MQ_msg_extra (arm,
1432 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1433 arm->id = htonl (ai->request_id);
1434 arm->attr_len = htons (msg_extra_len);
1435 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
1437 data_tmp = (char *) &arm[1];
1438 GNUNET_memcpy (data_tmp,
1441 GNUNET_MQ_send (ai->client->mq, env);
1442 GNUNET_free (attr_ser);
1447 iterate_after_abe_bootstrap (void *cls,
1448 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1450 struct AttributeIterator *ai = cls;
1451 ai->abe_key = abe_key;
1452 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1458 &attr_iter_finished,
1464 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
1466 * @param cls the client sending the message
1467 * @param zis_msg message from the client
1470 handle_iteration_start (void *cls,
1471 const struct AttributeIterationStartMessage *ais_msg)
1473 struct IdpClient *idp = cls;
1474 struct AttributeIterator *ai;
1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1477 "Received ATTRIBUTE_ITERATION_START message\n");
1478 ai = GNUNET_new (struct AttributeIterator);
1479 ai->request_id = ntohl (ais_msg->id);
1481 ai->identity = ais_msg->identity;
1483 GNUNET_CONTAINER_DLL_insert (idp->op_head,
1486 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai);
1487 GNUNET_SERVICE_client_continue (idp->client);
1492 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
1494 * @param cls the client sending the message
1495 * @param ais_msg message from the client
1498 handle_iteration_stop (void *cls,
1499 const struct AttributeIterationStopMessage *ais_msg)
1501 struct IdpClient *idp = cls;
1502 struct AttributeIterator *ai;
1505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1506 "Received `%s' message\n",
1507 "ATTRIBUTE_ITERATION_STOP");
1508 rid = ntohl (ais_msg->id);
1509 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1510 if (ai->request_id == rid)
1515 GNUNET_SERVICE_client_drop (idp->client);
1518 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1522 GNUNET_SERVICE_client_continue (idp->client);
1527 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
1529 * @param cls the client sending the message
1530 * @param message message from the client
1533 handle_iteration_next (void *cls,
1534 const struct AttributeIterationNextMessage *ais_msg)
1536 struct IdpClient *idp = cls;
1537 struct AttributeIterator *ai;
1540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1541 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1542 rid = ntohl (ais_msg->id);
1543 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1544 if (ai->request_id == rid)
1549 GNUNET_SERVICE_client_drop (idp->client);
1552 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1553 GNUNET_SERVICE_client_continue (idp->client);
1557 * Ticket iteration processor result
1559 enum ZoneIterationResult
1568 * Continue to iterate with next iteration_next call
1570 IT_SUCCESS_MORE_AVAILABLE = 1,
1573 * Iteration complete
1575 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
1580 * Context for ticket iteration
1582 struct TicketIterationProcResult
1585 * The ticket iteration handle
1587 struct TicketIteration *ti;
1590 * Iteration result: iteration done?
1591 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
1592 * we got one for now and have sent it to the client
1593 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
1594 * #IT_START: if we are still trying to find a result.
1596 int res_iteration_finished;
1603 * Process ticket from database
1605 * @param cls struct TicketIterationProcResult
1606 * @param ticket the ticket
1607 * @param attrs the attributes
1610 ticket_iterate_proc (void *cls,
1611 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
1613 struct TicketIterationProcResult *proc = cls;
1617 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1618 "Iteration done\n");
1619 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
1622 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
1623 send_ticket_result (proc->ti->client,
1630 * Perform ticket iteration step
1632 * @param ti ticket iterator to process
1635 run_ticket_iteration_round (struct TicketIteration *ti)
1637 struct TicketIterationProcResult proc;
1638 struct GNUNET_MQ_Envelope *env;
1639 struct TicketResultMessage *trm;
1642 memset (&proc, 0, sizeof (proc));
1644 proc.res_iteration_finished = IT_START;
1645 while (IT_START == proc.res_iteration_finished)
1647 if (GNUNET_SYSERR ==
1648 (ret = TKT_database->iterate_tickets (TKT_database->cls,
1652 &ticket_iterate_proc,
1658 if (GNUNET_NO == ret)
1659 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
1662 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
1664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1665 "More results available\n");
1666 return; /* more later */
1668 /* send empty response to indicate end of list */
1669 env = GNUNET_MQ_msg (trm,
1670 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
1671 trm->id = htonl (ti->r_id);
1672 GNUNET_MQ_send (ti->client->mq,
1674 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
1675 ti->client->ticket_iter_tail,
1681 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START message
1683 * @param cls the client sending the message
1684 * @param tis_msg message from the client
1687 handle_ticket_iteration_start (void *cls,
1688 const struct TicketIterationStartMessage *tis_msg)
1690 struct IdpClient *client = cls;
1691 struct TicketIteration *ti;
1693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1694 "Received TICKET_ITERATION_START message\n");
1695 ti = GNUNET_new (struct TicketIteration);
1696 ti->r_id = ntohl (tis_msg->id);
1698 ti->client = client;
1699 ti->identity = tis_msg->identity;
1700 ti->is_audience = ntohl (tis_msg->is_audience);
1702 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
1703 client->ticket_iter_tail,
1705 run_ticket_iteration_round (ti);
1706 GNUNET_SERVICE_client_continue (client->client);
1711 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP message
1713 * @param cls the client sending the message
1714 * @param tis_msg message from the client
1717 handle_ticket_iteration_stop (void *cls,
1718 const struct TicketIterationStopMessage *tis_msg)
1720 struct IdpClient *client = cls;
1721 struct TicketIteration *ti;
1724 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1725 "Received `%s' message\n",
1726 "TICKET_ITERATION_STOP");
1727 rid = ntohl (tis_msg->id);
1728 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1729 if (ti->r_id == rid)
1734 GNUNET_SERVICE_client_drop (client->client);
1737 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
1738 client->ticket_iter_tail,
1741 GNUNET_SERVICE_client_continue (client->client);
1746 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT message
1748 * @param cls the client sending the message
1749 * @param message message from the client
1752 handle_ticket_iteration_next (void *cls,
1753 const struct TicketIterationNextMessage *tis_msg)
1755 struct IdpClient *client = cls;
1756 struct TicketIteration *ti;
1759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1760 "Received TICKET_ITERATION_NEXT message\n");
1761 rid = ntohl (tis_msg->id);
1762 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1763 if (ti->r_id == rid)
1768 GNUNET_SERVICE_client_drop (client->client);
1771 run_ticket_iteration_round (ti);
1772 GNUNET_SERVICE_client_continue (client->client);
1779 * Main function that will be run
1781 * @param cls closure
1782 * @param args remaining command-line arguments
1783 * @param cfgfile name of the configuration file used (for saving, can be NULL)
1784 * @param c configuration
1788 const struct GNUNET_CONFIGURATION_Handle *c,
1789 struct GNUNET_SERVICE_Handle *server)
1794 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
1796 //Connect to identity and namestore services
1797 ns_handle = GNUNET_NAMESTORE_connect (cfg);
1798 if (NULL == ns_handle)
1800 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
1803 gns_handle = GNUNET_GNS_connect (cfg);
1804 if (NULL == gns_handle)
1806 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1808 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
1809 if (NULL == credential_handle)
1811 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
1813 identity_handle = GNUNET_IDENTITY_connect (cfg,
1817 /* Loading DB plugin */
1819 GNUNET_CONFIGURATION_get_value_string (cfg,
1820 "identity-provider",
1823 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1824 "No database backend configured\n");
1825 GNUNET_asprintf (&db_lib_name,
1826 "libgnunet_plugin_identity_provider_%s",
1828 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
1830 GNUNET_free (database);
1831 if (NULL == TKT_database)
1833 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1834 "Could not load database backend `%s'\n",
1836 GNUNET_SCHEDULER_shutdown ();
1841 GNUNET_CONFIGURATION_get_value_time (cfg,
1842 "identity-provider",
1843 "TOKEN_EXPIRATION_INTERVAL",
1844 &token_expiration_interval))
1846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1847 "Time window for zone iteration: %s\n",
1848 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
1851 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
1854 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1858 * Called whenever a client is disconnected.
1860 * @param cls closure
1861 * @param client identification of the client
1862 * @param app_ctx @a client
1865 client_disconnect_cb (void *cls,
1866 struct GNUNET_SERVICE_Client *client,
1869 struct IdpClient *idp = app_ctx;
1870 struct AttributeIterator *ai;
1872 //TODO other operations
1874 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1875 "Client %p disconnected\n",
1878 while (NULL != (ai = idp->op_head))
1880 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1890 * Add a client to our list of active clients.
1893 * @param client client to add
1894 * @param mq message queue for @a client
1895 * @return internal namestore client structure for this client
1898 client_connect_cb (void *cls,
1899 struct GNUNET_SERVICE_Client *client,
1900 struct GNUNET_MQ_Handle *mq)
1902 struct IdpClient *idp;
1903 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1904 "Client %p connected\n",
1906 idp = GNUNET_new (struct IdpClient);
1907 idp->client = client;
1915 * Define "main" method using service macro.
1918 ("identity-provider",
1919 GNUNET_SERVICE_OPTION_NONE,
1922 &client_disconnect_cb,
1924 GNUNET_MQ_hd_var_size (attribute_store_message,
1925 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
1926 struct AttributeStoreMessage,
1928 GNUNET_MQ_hd_fixed_size (iteration_start,
1929 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
1930 struct AttributeIterationStartMessage,
1932 GNUNET_MQ_hd_fixed_size (iteration_next,
1933 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
1934 struct AttributeIterationNextMessage,
1936 GNUNET_MQ_hd_fixed_size (iteration_stop,
1937 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
1938 struct AttributeIterationStopMessage,
1940 GNUNET_MQ_hd_var_size (ticket_issue_message,
1941 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE,
1942 struct TicketIssueMessage,
1944 GNUNET_MQ_hd_var_size (consume_ticket_message,
1945 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
1946 struct ConsumeTicketMessage,
1948 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
1949 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
1950 struct TicketIterationStartMessage,
1952 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
1953 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
1954 struct TicketIterationNextMessage,
1956 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
1957 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
1958 struct TicketIterationStopMessage,
1961 GNUNET_MQ_handler_end());
1962 /* end of gnunet-service-identity-provider.c */