2 This file is part of GNUnet.
3 Copyright (C) 2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
17 * @file identity-provider/identity_provider_api.c
18 * @brief api to interact with the identity provider service
19 * @author Martin Schanzenbach
22 #include "gnunet_util_lib.h"
23 #include "gnunet_constants.h"
24 #include "gnunet_protocols.h"
25 #include "gnunet_mq_lib.h"
26 #include "gnunet_identity_provider_service.h"
27 #include "gnunet_identity_attribute_lib.h"
28 #include "identity_provider.h"
30 #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__)
34 * Handle for an operation with the service.
36 struct GNUNET_IDENTITY_PROVIDER_Operation
42 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
45 * We keep operations in a DLL.
47 struct GNUNET_IDENTITY_PROVIDER_Operation *next;
50 * We keep operations in a DLL.
52 struct GNUNET_IDENTITY_PROVIDER_Operation *prev;
55 * Message to send to the service.
56 * Allocated at the end of this struct.
58 const struct GNUNET_MessageHeader *msg;
61 * Continuation to invoke after attribute store call
63 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus as_cb;
66 * Attribute result callback
68 GNUNET_IDENTITY_PROVIDER_AttributeResult ar_cb;
71 * Revocation result callback
73 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus rvk_cb;
76 * Ticket result callback
78 GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
81 * Envelope with the message for this queue entry.
83 struct GNUNET_MQ_Envelope *env;
91 * Closure for @e cont or @e cb.
98 * Handle for a ticket iterator operation
100 struct GNUNET_IDENTITY_PROVIDER_TicketIterator
106 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *next;
111 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *prev;
114 * Main handle to access the idp.
116 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
119 * Function to call on completion.
121 GNUNET_SCHEDULER_TaskCallback finish_cb;
124 * Closure for @e error_cb.
129 * The continuation to call with the results
131 GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
134 * Closure for @e tr_cb.
139 * Function to call on errors.
141 GNUNET_SCHEDULER_TaskCallback error_cb;
144 * Closure for @e error_cb.
149 * Envelope of the message to send to the service, if not yet
152 struct GNUNET_MQ_Envelope *env;
155 * The operation id this zone iteration operation has
163 * Handle for a attribute iterator operation
165 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator
171 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *next;
176 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *prev;
179 * Main handle to access the idp.
181 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
184 * Function to call on completion.
186 GNUNET_SCHEDULER_TaskCallback finish_cb;
189 * Closure for @e error_cb.
194 * The continuation to call with the results
196 GNUNET_IDENTITY_PROVIDER_AttributeResult proc;
199 * Closure for @e proc.
204 * Function to call on errors.
206 GNUNET_SCHEDULER_TaskCallback error_cb;
209 * Closure for @e error_cb.
214 * Envelope of the message to send to the service, if not yet
217 struct GNUNET_MQ_Envelope *env;
220 * Private key of the zone.
222 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
225 * The operation id this zone iteration operation has
233 * Handle for the service.
235 struct GNUNET_IDENTITY_PROVIDER_Handle
238 * Configuration to use.
240 const struct GNUNET_CONFIGURATION_Handle *cfg;
243 * Socket (if available).
245 struct GNUNET_CLIENT_Connection *client;
253 * Head of active operations.
255 struct GNUNET_IDENTITY_PROVIDER_Operation *op_head;
258 * Tail of active operations.
260 struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail;
263 * Head of active iterations
265 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_head;
268 * Tail of active iterations
270 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail;
273 * Head of active iterations
275 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_head;
278 * Tail of active iterations
280 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_tail;
284 * Currently pending transmission request, or NULL for none.
286 struct GNUNET_CLIENT_TransmitHandle *th;
289 * Task doing exponential back-off trying to reconnect.
291 struct GNUNET_SCHEDULER_Task * reconnect_task;
294 * Time for next connect retry.
296 struct GNUNET_TIME_Relative reconnect_backoff;
299 * Connection to service (if available).
301 struct GNUNET_MQ_Handle *mq;
304 * Request Id generator. Incremented by one for each request.
309 * Are we polling for incoming messages right now?
316 * Try again to connect to the service.
318 * @param h handle to the identity provider service.
321 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h);
326 * @param cls the handle
329 reconnect_task (void *cls)
331 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
333 handle->reconnect_task = NULL;
339 * Disconnect from service and then reconnect.
341 * @param handle our service
344 force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle)
346 GNUNET_MQ_destroy (handle->mq);
348 handle->reconnect_backoff
349 = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
350 handle->reconnect_task
351 = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
359 * @param it entry to free
362 free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
364 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
366 GNUNET_CONTAINER_DLL_remove (h->it_head,
370 GNUNET_MQ_discard (it->env);
375 free_op (struct GNUNET_IDENTITY_PROVIDER_Operation* op)
380 GNUNET_MQ_discard (op->env);
386 * Generic error handler, called with the appropriate error code and
387 * the same closure specified at the creation of the message queue.
388 * Not every message queue implementation supports an error handler.
390 * @param cls closure with the `struct GNUNET_GNS_Handle *`
391 * @param error error code
394 mq_error_handler (void *cls,
395 enum GNUNET_MQ_Error error)
397 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
398 force_reconnect (handle);
402 * Handle an incoming message of type
403 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
406 * @param msg the message we received
409 handle_attribute_store_response (void *cls,
410 const struct AttributeStoreResultMessage *msg)
412 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
413 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
414 uint32_t r_id = ntohl (msg->id);
418 for (op = h->op_head; NULL != op; op = op->next)
419 if (op->r_id == r_id)
424 res = ntohl (msg->op_result);
425 LOG (GNUNET_ERROR_TYPE_DEBUG,
426 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
429 /* TODO: add actual error message to response... */
430 if (GNUNET_SYSERR == res)
431 emsg = _("failed to store record\n");
434 if (NULL != op->as_cb)
438 GNUNET_CONTAINER_DLL_remove (h->op_head,
447 * Handle an incoming message of type
448 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
451 * @param msg the message we received
452 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
455 check_consume_ticket_result (void *cls,
456 const struct ConsumeTicketResultMessage *msg)
461 msg_len = ntohs (msg->header.size);
462 attrs_len = ntohs (msg->attrs_len);
463 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len)
466 return GNUNET_SYSERR;
473 * Handle an incoming message of type
474 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
477 * @param msg the message we received
480 handle_consume_ticket_result (void *cls,
481 const struct ConsumeTicketResultMessage *msg)
483 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
484 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
486 uint32_t r_id = ntohl (msg->id);
488 attrs_len = ntohs (msg->attrs_len);
489 LOG (GNUNET_ERROR_TYPE_DEBUG,
490 "Processing attribute result.\n");
493 for (op = h->op_head; NULL != op; op = op->next)
494 if (op->r_id == r_id)
500 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
501 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
502 attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&msg[1],
504 if (NULL != op->ar_cb)
514 for (le = attrs->list_head; NULL != le; le = le->next)
518 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (attrs);
526 GNUNET_CONTAINER_DLL_remove (h->op_head,
538 * Handle an incoming message of type
539 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
542 * @param msg the message we received
543 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
546 check_attribute_result (void *cls,
547 const struct AttributeResultMessage *msg)
552 msg_len = ntohs (msg->header.size);
553 attr_len = ntohs (msg->attr_len);
554 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
557 return GNUNET_SYSERR;
564 * Handle an incoming message of type
565 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
568 * @param msg the message we received
571 handle_attribute_result (void *cls,
572 const struct AttributeResultMessage *msg)
574 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
575 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
576 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
577 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
579 uint32_t r_id = ntohl (msg->id);
581 attr_len = ntohs (msg->attr_len);
582 LOG (GNUNET_ERROR_TYPE_DEBUG,
583 "Processing attribute result.\n");
586 for (it = h->it_head; NULL != it; it = it->next)
587 if (it->r_id == r_id)
589 for (op = h->op_head; NULL != op; op = op->next)
590 if (op->r_id == r_id)
592 if ((NULL == it) && (NULL == op))
595 if ( (0 == (memcmp (&msg->identity,
597 sizeof (identity_dummy)))) )
599 if ((NULL == it) && (NULL == op))
607 if (NULL != it->finish_cb)
608 it->finish_cb (it->finish_cb_cls);
613 if (NULL != op->ar_cb)
617 GNUNET_CONTAINER_DLL_remove (h->op_head,
627 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
628 attr = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&msg[1],
632 if (NULL != it->proc)
633 it->proc (it->proc_cls,
636 } else if (NULL != op)
638 if (NULL != op->ar_cb)
651 * Handle an incoming message of type
652 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
655 * @param msg the message we received
656 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
659 check_ticket_result (void *cls,
660 const struct TicketResultMessage *msg)
664 msg_len = ntohs (msg->header.size);
665 if (msg_len < sizeof (struct TicketResultMessage))
668 return GNUNET_SYSERR;
676 * Handle an incoming message of type
677 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
680 * @param msg the message we received
683 handle_ticket_result (void *cls,
684 const struct TicketResultMessage *msg)
686 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
687 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
688 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
689 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
690 uint32_t r_id = ntohl (msg->id);
693 for (op = handle->op_head; NULL != op; op = op->next)
694 if (op->r_id == r_id)
696 for (it = handle->ticket_it_head; NULL != it; it = it->next)
697 if (it->r_id == r_id)
699 if ((NULL == op) && (NULL == it))
701 msg_len = ntohs (msg->header.size);
704 GNUNET_CONTAINER_DLL_remove (handle->op_head,
707 if (msg_len == sizeof (struct TicketResultMessage))
709 if (NULL != op->tr_cb)
710 op->tr_cb (op->cls, NULL);
712 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
713 if (NULL != op->tr_cb)
714 op->tr_cb (op->cls, ticket);
718 } else if (NULL != it) {
719 if (msg_len == sizeof (struct TicketResultMessage))
721 if (NULL != it->tr_cb)
722 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
723 handle->ticket_it_tail,
725 it->finish_cb (it->finish_cb_cls);
728 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
729 if (NULL != it->tr_cb)
730 it->tr_cb (it->cls, ticket);
739 * Handle an incoming message of type
740 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT
743 * @param msg the message we received
746 handle_revoke_ticket_result (void *cls,
747 const struct RevokeTicketResultMessage *msg)
749 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
750 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
751 uint32_t r_id = ntohl (msg->id);
754 LOG (GNUNET_ERROR_TYPE_DEBUG,
755 "Processing revocation result.\n");
758 for (op = h->op_head; NULL != op; op = op->next)
759 if (op->r_id == r_id)
763 success = ntohl (msg->success);
765 if (NULL != op->rvk_cb)
771 GNUNET_CONTAINER_DLL_remove (h->op_head,
783 * Try again to connect to the service.
785 * @param h handle to the identity provider service.
788 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
790 struct GNUNET_MQ_MessageHandler handlers[] = {
791 GNUNET_MQ_hd_fixed_size (attribute_store_response,
792 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE,
793 struct AttributeStoreResultMessage,
795 GNUNET_MQ_hd_var_size (attribute_result,
796 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
797 struct AttributeResultMessage,
799 GNUNET_MQ_hd_var_size (ticket_result,
800 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT,
801 struct TicketResultMessage,
803 GNUNET_MQ_hd_var_size (consume_ticket_result,
804 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT,
805 struct ConsumeTicketResultMessage,
807 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
808 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT,
809 struct RevokeTicketResultMessage,
811 GNUNET_MQ_handler_end ()
813 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
815 GNUNET_assert (NULL == h->mq);
816 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "Connecting to identity provider service.\n");
819 h->mq = GNUNET_CLIENT_connect (h->cfg,
826 for (op = h->op_head; NULL != op; op = op->next)
827 GNUNET_MQ_send_copy (h->mq,
833 * Connect to the identity provider service.
835 * @param cfg the configuration to use
836 * @return handle to use
838 struct GNUNET_IDENTITY_PROVIDER_Handle *
839 GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
841 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
843 h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle);
856 * Cancel an operation. Note that the operation MAY still
857 * be executed; this merely cancels the continuation; if the request
858 * was already transmitted, the service may still choose to complete
861 * @param op operation to cancel
864 GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
866 struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h;
868 GNUNET_CONTAINER_DLL_remove (h->op_head,
876 * Disconnect from service
878 * @param h handle to destroy
881 GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
883 GNUNET_assert (NULL != h);
886 GNUNET_MQ_destroy (h->mq);
889 if (NULL != h->reconnect_task)
891 GNUNET_SCHEDULER_cancel (h->reconnect_task);
892 h->reconnect_task = NULL;
894 GNUNET_assert (NULL == h->op_head);
899 * Store an attribute. If the attribute is already present,
900 * it is replaced with the new attribute.
902 * @param h handle to the identity provider
903 * @param pkey private key of the identity
904 * @param attr the attribute value
905 * @param exp_interval the relative expiration interval for the attribute
906 * @param cont continuation to call when done
907 * @param cont_cls closure for @a cont
908 * @return handle to abort the request
910 struct GNUNET_IDENTITY_PROVIDER_Operation *
911 GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
912 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
913 const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
914 const struct GNUNET_TIME_Relative *exp_interval,
915 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
918 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
919 struct AttributeStoreMessage *sam;
922 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
926 op->r_id = h->r_id_gen++;
927 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
930 attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (attr);
931 op->env = GNUNET_MQ_msg_extra (sam,
933 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
934 sam->identity = *pkey;
935 sam->id = htonl (op->r_id);
936 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
938 GNUNET_IDENTITY_ATTRIBUTE_serialize (attr,
941 sam->attr_len = htons (attr_len);
943 GNUNET_MQ_send_copy (h->mq,
951 * List all attributes for a local identity.
952 * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
953 * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
954 * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
955 * immediately, and then again after
956 * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
958 * On error (disconnect), @a error_cb will be invoked.
959 * On normal completion, @a finish_cb proc will be
962 * @param h handle to the idp
963 * @param identity identity to access
964 * @param error_cb function to call on error (i.e. disconnect),
965 * the handle is afterwards invalid
966 * @param error_cb_cls closure for @a error_cb
967 * @param proc function to call on each attribute; it
968 * will be called repeatedly with a value (if available)
969 * @param proc_cls closure for @a proc
970 * @param finish_cb function to call on completion
971 * the handle is afterwards invalid
972 * @param finish_cb_cls closure for @a finish_cb
973 * @return an iterator handle to use for iteration
975 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
976 GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
977 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
978 GNUNET_SCHEDULER_TaskCallback error_cb,
980 GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
982 GNUNET_SCHEDULER_TaskCallback finish_cb,
985 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
986 struct GNUNET_MQ_Envelope *env;
987 struct AttributeIterationStartMessage *msg;
991 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator);
993 it->error_cb = error_cb;
994 it->error_cb_cls = error_cb_cls;
995 it->finish_cb = finish_cb;
996 it->finish_cb_cls = finish_cb_cls;
998 it->proc_cls = proc_cls;
1000 it->identity = *identity;
1001 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
1004 env = GNUNET_MQ_msg (msg,
1005 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START);
1006 msg->id = htonl (rid);
1007 msg->identity = *identity;
1011 GNUNET_MQ_send (h->mq,
1018 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
1019 * for the next record.
1021 * @param it the iterator
1024 GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1026 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1027 struct AttributeIterationNextMessage *msg;
1028 struct GNUNET_MQ_Envelope *env;
1030 env = GNUNET_MQ_msg (msg,
1031 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT);
1032 msg->id = htonl (it->r_id);
1033 GNUNET_MQ_send (h->mq,
1039 * Stops iteration and releases the idp handle for further calls. Must
1040 * be called on any iteration that has not yet completed prior to calling
1041 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1043 * @param it the iterator
1046 GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1048 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1049 struct GNUNET_MQ_Envelope *env;
1050 struct AttributeIterationStopMessage *msg;
1054 env = GNUNET_MQ_msg (msg,
1055 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP);
1056 msg->id = htonl (it->r_id);
1057 GNUNET_MQ_send (h->mq,
1065 * Issues a ticket to another identity. The identity may use
1066 * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
1067 * and retrieve the attributes specified in the AttributeList.
1069 * @param h the identity provider to use
1070 * @param iss the issuing identity
1071 * @param rp the subject of the ticket (the relying party)
1072 * @param attrs the attributes that the relying party is given access to
1073 * @param cb the callback
1074 * @param cb_cls the callback closure
1075 * @return handle to abort the operation
1077 struct GNUNET_IDENTITY_PROVIDER_Operation *
1078 GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1079 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1080 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1081 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
1082 GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
1085 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1086 struct IssueTicketMessage *tim;
1089 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1093 op->r_id = h->r_id_gen++;
1094 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1097 attr_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs);
1098 op->env = GNUNET_MQ_msg_extra (tim,
1100 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET);
1101 tim->identity = *iss;
1103 tim->id = htonl (op->r_id);
1105 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs,
1108 tim->attr_len = htons (attr_len);
1110 GNUNET_MQ_send_copy (h->mq,
1116 * Consumes an issued ticket. The ticket is persisted
1117 * and used to retrieve identity information from the issuer
1119 * @param h the identity provider to use
1120 * @param identity the identity that is the subject of the issued ticket (the relying party)
1121 * @param ticket the issued ticket to consume
1122 * @param cb the callback to call
1123 * @param cb_cls the callback closure
1124 * @return handle to abort the operation
1126 struct GNUNET_IDENTITY_PROVIDER_Operation *
1127 GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1128 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1129 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1130 GNUNET_IDENTITY_PROVIDER_AttributeResult cb,
1133 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1134 struct ConsumeTicketMessage *ctm;
1136 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1140 op->r_id = h->r_id_gen++;
1141 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1144 op->env = GNUNET_MQ_msg_extra (ctm,
1145 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket),
1146 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET);
1147 ctm->identity = *identity;
1148 ctm->id = htonl (op->r_id);
1150 GNUNET_memcpy ((char*)&ctm[1],
1152 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket));
1155 GNUNET_MQ_send_copy (h->mq,
1163 * Lists all tickets that have been issued to remote
1164 * identites (relying parties)
1166 * @param h the identity provider to use
1167 * @param identity the issuing identity
1168 * @param error_cb function to call on error (i.e. disconnect),
1169 * the handle is afterwards invalid
1170 * @param error_cb_cls closure for @a error_cb
1171 * @param proc function to call on each ticket; it
1172 * will be called repeatedly with a value (if available)
1173 * @param proc_cls closure for @a proc
1174 * @param finish_cb function to call on completion
1175 * the handle is afterwards invalid
1176 * @param finish_cb_cls closure for @a finish_cb
1177 * @return an iterator handle to use for iteration
1179 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1180 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1181 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1182 GNUNET_SCHEDULER_TaskCallback error_cb,
1184 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1186 GNUNET_SCHEDULER_TaskCallback finish_cb,
1187 void *finish_cb_cls)
1189 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1190 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1191 struct GNUNET_MQ_Envelope *env;
1192 struct TicketIterationStartMessage *msg;
1195 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1197 rid = h->r_id_gen++;
1198 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1200 it->error_cb = error_cb;
1201 it->error_cb_cls = error_cb_cls;
1202 it->finish_cb = finish_cb;
1203 it->finish_cb_cls = finish_cb_cls;
1207 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1210 env = GNUNET_MQ_msg (msg,
1211 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1212 msg->id = htonl (rid);
1213 msg->identity = identity_pub;
1214 msg->is_audience = htonl (GNUNET_NO);
1218 GNUNET_MQ_send (h->mq,
1226 * Lists all tickets that have been issued to remote
1227 * identites (relying parties)
1229 * @param h the identity provider to use
1230 * @param identity the issuing identity
1231 * @param error_cb function to call on error (i.e. disconnect),
1232 * the handle is afterwards invalid
1233 * @param error_cb_cls closure for @a error_cb
1234 * @param proc function to call on each ticket; it
1235 * will be called repeatedly with a value (if available)
1236 * @param proc_cls closure for @a proc
1237 * @param finish_cb function to call on completion
1238 * the handle is afterwards invalid
1239 * @param finish_cb_cls closure for @a finish_cb
1240 * @return an iterator handle to use for iteration
1242 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1243 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1244 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1245 GNUNET_SCHEDULER_TaskCallback error_cb,
1247 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1249 GNUNET_SCHEDULER_TaskCallback finish_cb,
1250 void *finish_cb_cls)
1252 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1253 struct GNUNET_MQ_Envelope *env;
1254 struct TicketIterationStartMessage *msg;
1257 rid = h->r_id_gen++;
1258 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1260 it->error_cb = error_cb;
1261 it->error_cb_cls = error_cb_cls;
1262 it->finish_cb = finish_cb;
1263 it->finish_cb_cls = finish_cb_cls;
1267 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1270 env = GNUNET_MQ_msg (msg,
1271 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1272 msg->id = htonl (rid);
1273 msg->identity = *identity;
1274 msg->is_audience = htonl (GNUNET_YES);
1278 GNUNET_MQ_send (h->mq,
1286 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start
1287 * for the next record.
1289 * @param it the iterator
1292 GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1294 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1295 struct TicketIterationNextMessage *msg;
1296 struct GNUNET_MQ_Envelope *env;
1298 env = GNUNET_MQ_msg (msg,
1299 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT);
1300 msg->id = htonl (it->r_id);
1301 GNUNET_MQ_send (h->mq,
1307 * Stops iteration and releases the idp handle for further calls. Must
1308 * be called on any iteration that has not yet completed prior to calling
1309 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1311 * @param it the iterator
1314 GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1316 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1317 struct GNUNET_MQ_Envelope *env;
1318 struct TicketIterationStopMessage *msg;
1322 env = GNUNET_MQ_msg (msg,
1323 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP);
1324 msg->id = htonl (it->r_id);
1325 GNUNET_MQ_send (h->mq,
1332 * Revoked an issued ticket. The relying party will be unable to retrieve
1333 * updated attributes.
1335 * @param h the identity provider to use
1336 * @param identity the issuing identity
1337 * @param ticket the ticket to revoke
1338 * @param cb the callback
1339 * @param cb_cls the callback closure
1340 * @return handle to abort the operation
1342 struct GNUNET_IDENTITY_PROVIDER_Operation *
1343 GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1344 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1345 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1346 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb,
1349 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1350 struct GNUNET_MQ_Envelope *env;
1351 struct RevokeTicketMessage *msg;
1354 rid = h->r_id_gen++;
1355 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1360 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1363 env = GNUNET_MQ_msg_extra (msg,
1364 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
1365 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
1366 msg->id = htonl (rid);
1367 msg->identity = *identity;
1368 GNUNET_memcpy (&msg[1],
1370 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1374 GNUNET_MQ_send (h->mq,
1381 /* end of identity_provider_api.c */