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
6 it under the terms of the GNU General Public Liceidentity 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 Liceidentity for more details.
15 You should have received a copy of the GNU General Public Liceidentity
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.
22 * @file identity-provider/identity_provider_api.c
23 * @brief api to interact with the identity provider service
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_mq_lib.h"
31 #include "gnunet_identity_provider_service.h"
32 #include "gnunet_identity_attribute_lib.h"
33 #include "identity_provider.h"
35 #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__)
39 * Handle for an operation with the service.
41 struct GNUNET_IDENTITY_PROVIDER_Operation
47 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
50 * We keep operations in a DLL.
52 struct GNUNET_IDENTITY_PROVIDER_Operation *next;
55 * We keep operations in a DLL.
57 struct GNUNET_IDENTITY_PROVIDER_Operation *prev;
60 * Message to send to the service.
61 * Allocated at the end of this struct.
63 const struct GNUNET_MessageHeader *msg;
66 * Continuation to invoke after attribute store call
68 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus as_cb;
71 * Attribute result callback
73 GNUNET_IDENTITY_PROVIDER_AttributeResult ar_cb;
76 * Revocation result callback
78 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus rvk_cb;
81 * Ticket result callback
83 GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
86 * Envelope with the message for this queue entry.
88 struct GNUNET_MQ_Envelope *env;
96 * Closure for @e cont or @e cb.
103 * Handle for a ticket iterator operation
105 struct GNUNET_IDENTITY_PROVIDER_TicketIterator
111 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *next;
116 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *prev;
119 * Main handle to access the idp.
121 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
124 * Function to call on completion.
126 GNUNET_SCHEDULER_TaskCallback finish_cb;
129 * Closure for @e error_cb.
134 * The continuation to call with the results
136 GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
139 * Closure for @e tr_cb.
144 * Function to call on errors.
146 GNUNET_SCHEDULER_TaskCallback error_cb;
149 * Closure for @e error_cb.
154 * Envelope of the message to send to the service, if not yet
157 struct GNUNET_MQ_Envelope *env;
160 * The operation id this zone iteration operation has
168 * Handle for a attribute iterator operation
170 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator
176 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *next;
181 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *prev;
184 * Main handle to access the idp.
186 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
189 * Function to call on completion.
191 GNUNET_SCHEDULER_TaskCallback finish_cb;
194 * Closure for @e error_cb.
199 * The continuation to call with the results
201 GNUNET_IDENTITY_PROVIDER_AttributeResult proc;
204 * Closure for @e proc.
209 * Function to call on errors.
211 GNUNET_SCHEDULER_TaskCallback error_cb;
214 * Closure for @e error_cb.
219 * Envelope of the message to send to the service, if not yet
222 struct GNUNET_MQ_Envelope *env;
225 * Private key of the zone.
227 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
230 * The operation id this zone iteration operation has
238 * Handle for the service.
240 struct GNUNET_IDENTITY_PROVIDER_Handle
243 * Configuration to use.
245 const struct GNUNET_CONFIGURATION_Handle *cfg;
248 * Socket (if available).
250 struct GNUNET_CLIENT_Connection *client;
258 * Head of active operations.
260 struct GNUNET_IDENTITY_PROVIDER_Operation *op_head;
263 * Tail of active operations.
265 struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail;
268 * Head of active iterations
270 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_head;
273 * Tail of active iterations
275 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail;
278 * Head of active iterations
280 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_head;
283 * Tail of active iterations
285 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_tail;
289 * Currently pending transmission request, or NULL for none.
291 struct GNUNET_CLIENT_TransmitHandle *th;
294 * Task doing exponential back-off trying to reconnect.
296 struct GNUNET_SCHEDULER_Task * reconnect_task;
299 * Time for next connect retry.
301 struct GNUNET_TIME_Relative reconnect_backoff;
304 * Connection to service (if available).
306 struct GNUNET_MQ_Handle *mq;
309 * Request Id generator. Incremented by one for each request.
314 * Are we polling for incoming messages right now?
321 * Try again to connect to the service.
323 * @param h handle to the identity provider service.
326 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h);
331 * @param cls the handle
334 reconnect_task (void *cls)
336 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
338 handle->reconnect_task = NULL;
344 * Disconnect from service and then reconnect.
346 * @param handle our service
349 force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle)
351 GNUNET_MQ_destroy (handle->mq);
353 handle->reconnect_backoff
354 = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
355 handle->reconnect_task
356 = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
364 * @param it entry to free
367 free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
369 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
371 GNUNET_CONTAINER_DLL_remove (h->it_head,
375 GNUNET_MQ_discard (it->env);
382 * Generic error handler, called with the appropriate error code and
383 * the same closure specified at the creation of the message queue.
384 * Not every message queue implementation supports an error handler.
386 * @param cls closure with the `struct GNUNET_GNS_Handle *`
387 * @param error error code
390 mq_error_handler (void *cls,
391 enum GNUNET_MQ_Error error)
393 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
394 force_reconnect (handle);
398 * Handle an incoming message of type
399 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
402 * @param msg the message we received
405 handle_attribute_store_response (void *cls,
406 const struct AttributeStoreResultMessage *msg)
408 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
409 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
410 uint32_t r_id = ntohl (msg->id);
414 for (op = h->op_head; NULL != op; op = op->next)
415 if (op->r_id == r_id)
420 res = ntohl (msg->op_result);
421 LOG (GNUNET_ERROR_TYPE_DEBUG,
422 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
425 /* TODO: add actual error message to response... */
426 if (GNUNET_SYSERR == res)
427 emsg = _("failed to store record\n");
430 if (NULL != op->as_cb)
434 GNUNET_CONTAINER_DLL_remove (h->op_head,
443 * Handle an incoming message of type
444 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
447 * @param msg the message we received
448 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
451 check_consume_ticket_result (void *cls,
452 const struct ConsumeTicketResultMessage *msg)
457 msg_len = ntohs (msg->header.size);
458 attrs_len = ntohs (msg->attrs_len);
459 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len)
462 return GNUNET_SYSERR;
469 * Handle an incoming message of type
470 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
473 * @param msg the message we received
476 handle_consume_ticket_result (void *cls,
477 const struct ConsumeTicketResultMessage *msg)
479 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
480 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
482 uint32_t r_id = ntohl (msg->id);
484 attrs_len = ntohs (msg->attrs_len);
485 LOG (GNUNET_ERROR_TYPE_DEBUG,
486 "Processing attribute result.\n");
489 for (op = h->op_head; NULL != op; op = op->next)
490 if (op->r_id == r_id)
496 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
497 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
498 attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&msg[1],
500 if (NULL != op->ar_cb)
510 for (le = attrs->list_head; NULL != le; le = le->next)
514 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (attrs);
520 GNUNET_CONTAINER_DLL_remove (h->op_head,
531 * Handle an incoming message of type
532 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
535 * @param msg the message we received
536 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
539 check_attribute_result (void *cls,
540 const struct AttributeResultMessage *msg)
545 msg_len = ntohs (msg->header.size);
546 attr_len = ntohs (msg->attr_len);
547 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
550 return GNUNET_SYSERR;
557 * Handle an incoming message of type
558 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
561 * @param msg the message we received
564 handle_attribute_result (void *cls,
565 const struct AttributeResultMessage *msg)
567 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
568 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
569 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
570 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
572 uint32_t r_id = ntohl (msg->id);
574 attr_len = ntohs (msg->attr_len);
575 LOG (GNUNET_ERROR_TYPE_DEBUG,
576 "Processing attribute result.\n");
579 for (it = h->it_head; NULL != it; it = it->next)
580 if (it->r_id == r_id)
582 for (op = h->op_head; NULL != op; op = op->next)
583 if (op->r_id == r_id)
585 if ((NULL == it) && (NULL == op))
588 if ( (0 == (memcmp (&msg->identity,
590 sizeof (identity_dummy)))) )
592 if ((NULL == it) && (NULL == op))
600 if (NULL != it->finish_cb)
601 it->finish_cb (it->finish_cb_cls);
606 if (NULL != op->ar_cb)
610 GNUNET_CONTAINER_DLL_remove (h->op_head,
620 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
621 attr = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&msg[1],
625 if (NULL != it->proc)
626 it->proc (it->proc_cls,
629 } else if (NULL != op)
631 if (NULL != op->ar_cb)
644 * Handle an incoming message of type
645 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
648 * @param msg the message we received
649 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
652 check_ticket_result (void *cls,
653 const struct TicketResultMessage *msg)
657 msg_len = ntohs (msg->header.size);
658 if (msg_len < sizeof (struct TicketResultMessage))
661 return GNUNET_SYSERR;
669 * Handle an incoming message of type
670 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
673 * @param msg the message we received
676 handle_ticket_result (void *cls,
677 const struct TicketResultMessage *msg)
679 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
680 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
681 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
682 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
683 uint32_t r_id = ntohl (msg->id);
686 for (op = handle->op_head; NULL != op; op = op->next)
687 if (op->r_id == r_id)
689 for (it = handle->ticket_it_head; NULL != it; it = it->next)
690 if (it->r_id == r_id)
692 if ((NULL == op) && (NULL == it))
694 msg_len = ntohs (msg->header.size);
697 GNUNET_CONTAINER_DLL_remove (handle->op_head,
700 if (msg_len == sizeof (struct TicketResultMessage))
702 if (NULL != op->tr_cb)
703 op->tr_cb (op->cls, NULL);
705 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
706 if (NULL != op->tr_cb)
707 op->tr_cb (op->cls, ticket);
711 } else if (NULL != it) {
712 if (msg_len == sizeof (struct TicketResultMessage))
714 if (NULL != it->tr_cb)
715 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
716 handle->ticket_it_tail,
718 it->finish_cb (it->finish_cb_cls);
721 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
722 if (NULL != it->tr_cb)
723 it->tr_cb (it->cls, ticket);
731 * Handle an incoming message of type
732 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT
735 * @param msg the message we received
738 handle_revoke_ticket_result (void *cls,
739 const struct RevokeTicketResultMessage *msg)
741 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
742 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
743 uint32_t r_id = ntohl (msg->id);
746 LOG (GNUNET_ERROR_TYPE_DEBUG,
747 "Processing revocation result.\n");
750 for (op = h->op_head; NULL != op; op = op->next)
751 if (op->r_id == r_id)
755 success = ntohl (msg->success);
757 if (NULL != op->rvk_cb)
763 GNUNET_CONTAINER_DLL_remove (h->op_head,
775 * Try again to connect to the service.
777 * @param h handle to the identity provider service.
780 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
782 struct GNUNET_MQ_MessageHandler handlers[] = {
783 GNUNET_MQ_hd_fixed_size (attribute_store_response,
784 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE,
785 struct AttributeStoreResultMessage,
787 GNUNET_MQ_hd_var_size (attribute_result,
788 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
789 struct AttributeResultMessage,
791 GNUNET_MQ_hd_var_size (ticket_result,
792 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT,
793 struct TicketResultMessage,
795 GNUNET_MQ_hd_var_size (consume_ticket_result,
796 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT,
797 struct ConsumeTicketResultMessage,
799 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
800 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT,
801 struct RevokeTicketResultMessage,
803 GNUNET_MQ_handler_end ()
805 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
807 GNUNET_assert (NULL == h->mq);
808 LOG (GNUNET_ERROR_TYPE_DEBUG,
809 "Connecting to identity provider service.\n");
811 h->mq = GNUNET_CLIENT_connect (h->cfg,
818 for (op = h->op_head; NULL != op; op = op->next)
819 GNUNET_MQ_send_copy (h->mq,
825 * Connect to the identity provider service.
827 * @param cfg the configuration to use
828 * @return handle to use
830 struct GNUNET_IDENTITY_PROVIDER_Handle *
831 GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
833 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
835 h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle);
848 * Cancel an operation. Note that the operation MAY still
849 * be executed; this merely cancels the continuation; if the request
850 * was already transmitted, the service may still choose to complete
853 * @param op operation to cancel
856 GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
858 struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h;
860 GNUNET_CONTAINER_DLL_remove (h->op_head,
863 GNUNET_MQ_discard (op->env);
869 * Disconnect from service
871 * @param h handle to destroy
874 GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
876 GNUNET_assert (NULL != h);
879 GNUNET_MQ_destroy (h->mq);
882 if (NULL != h->reconnect_task)
884 GNUNET_SCHEDULER_cancel (h->reconnect_task);
885 h->reconnect_task = NULL;
887 GNUNET_assert (NULL == h->op_head);
892 * Store an attribute. If the attribute is already present,
893 * it is replaced with the new attribute.
895 * @param h handle to the identity provider
896 * @param pkey private key of the identity
897 * @param attr the attribute value
898 * @param cont continuation to call when done
899 * @param cont_cls closure for @a cont
900 * @return handle to abort the request
902 struct GNUNET_IDENTITY_PROVIDER_Operation *
903 GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
904 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
905 const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
906 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
909 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
910 struct AttributeStoreMessage *sam;
913 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
917 op->r_id = h->r_id_gen++;
918 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
921 attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (attr);
922 op->env = GNUNET_MQ_msg_extra (sam,
924 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
925 sam->identity = *pkey;
926 sam->id = htonl (op->r_id);
928 GNUNET_IDENTITY_ATTRIBUTE_serialize (attr,
931 sam->attr_len = htons (attr_len);
933 GNUNET_MQ_send_copy (h->mq,
941 * List all attributes for a local identity.
942 * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
943 * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
944 * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
945 * immediately, and then again after
946 * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
948 * On error (disconnect), @a error_cb will be invoked.
949 * On normal completion, @a finish_cb proc will be
952 * @param h handle to the idp
953 * @param identity identity to access
954 * @param error_cb function to call on error (i.e. disconnect),
955 * the handle is afterwards invalid
956 * @param error_cb_cls closure for @a error_cb
957 * @param proc function to call on each attribute; it
958 * will be called repeatedly with a value (if available)
959 * @param proc_cls closure for @a proc
960 * @param finish_cb function to call on completion
961 * the handle is afterwards invalid
962 * @param finish_cb_cls closure for @a finish_cb
963 * @return an iterator handle to use for iteration
965 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
966 GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
967 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
968 GNUNET_SCHEDULER_TaskCallback error_cb,
970 GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
972 GNUNET_SCHEDULER_TaskCallback finish_cb,
975 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
976 struct GNUNET_MQ_Envelope *env;
977 struct AttributeIterationStartMessage *msg;
981 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator);
983 it->error_cb = error_cb;
984 it->error_cb_cls = error_cb_cls;
985 it->finish_cb = finish_cb;
986 it->finish_cb_cls = finish_cb_cls;
988 it->proc_cls = proc_cls;
990 it->identity = *identity;
991 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
994 env = GNUNET_MQ_msg (msg,
995 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START);
996 msg->id = htonl (rid);
997 msg->identity = *identity;
1001 GNUNET_MQ_send (h->mq,
1008 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
1009 * for the next record.
1011 * @param it the iterator
1014 GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1016 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1017 struct AttributeIterationNextMessage *msg;
1018 struct GNUNET_MQ_Envelope *env;
1020 env = GNUNET_MQ_msg (msg,
1021 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT);
1022 msg->id = htonl (it->r_id);
1023 GNUNET_MQ_send (h->mq,
1029 * Stops iteration and releases the idp handle for further calls. Must
1030 * be called on any iteration that has not yet completed prior to calling
1031 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1033 * @param it the iterator
1036 GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1038 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1039 struct GNUNET_MQ_Envelope *env;
1040 struct AttributeIterationStopMessage *msg;
1044 env = GNUNET_MQ_msg (msg,
1045 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP);
1046 msg->id = htonl (it->r_id);
1047 GNUNET_MQ_send (h->mq,
1055 * Issues a ticket to another identity. The identity may use
1056 * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
1057 * and retrieve the attributes specified in the AttributeList.
1059 * @param h the identity provider to use
1060 * @param iss the issuing identity
1061 * @param rp the subject of the ticket (the relying party)
1062 * @param attrs the attributes that the relying party is given access to
1063 * @param cb the callback
1064 * @param cb_cls the callback closure
1065 * @return handle to abort the operation
1067 struct GNUNET_IDENTITY_PROVIDER_Operation *
1068 GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1069 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1070 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1071 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
1072 GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
1075 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1076 struct IssueTicketMessage *tim;
1079 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1083 op->r_id = h->r_id_gen++;
1084 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1087 attr_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs);
1088 op->env = GNUNET_MQ_msg_extra (tim,
1090 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET);
1091 tim->identity = *iss;
1093 tim->id = htonl (op->r_id);
1095 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs,
1098 tim->attr_len = htons (attr_len);
1100 GNUNET_MQ_send_copy (h->mq,
1106 * Consumes an issued ticket. The ticket is persisted
1107 * and used to retrieve identity information from the issuer
1109 * @param h the identity provider to use
1110 * @param identity the identity that is the subject of the issued ticket (the relying party)
1111 * @param ticket the issued ticket to consume
1112 * @param cb the callback to call
1113 * @param cb_cls the callback closure
1114 * @return handle to abort the operation
1116 struct GNUNET_IDENTITY_PROVIDER_Operation *
1117 GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1118 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1119 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1120 GNUNET_IDENTITY_PROVIDER_AttributeResult cb,
1123 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1124 struct ConsumeTicketMessage *ctm;
1126 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1130 op->r_id = h->r_id_gen++;
1131 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1134 op->env = GNUNET_MQ_msg_extra (ctm,
1135 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket),
1136 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET);
1137 ctm->identity = *identity;
1138 ctm->id = htonl (op->r_id);
1140 GNUNET_memcpy ((char*)&ctm[1],
1142 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket));
1145 GNUNET_MQ_send_copy (h->mq,
1153 * Lists all tickets that have been issued to remote
1154 * identites (relying parties)
1156 * @param h the identity provider to use
1157 * @param identity the issuing identity
1158 * @param error_cb function to call on error (i.e. disconnect),
1159 * the handle is afterwards invalid
1160 * @param error_cb_cls closure for @a error_cb
1161 * @param proc function to call on each ticket; it
1162 * will be called repeatedly with a value (if available)
1163 * @param proc_cls closure for @a proc
1164 * @param finish_cb function to call on completion
1165 * the handle is afterwards invalid
1166 * @param finish_cb_cls closure for @a finish_cb
1167 * @return an iterator handle to use for iteration
1169 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1170 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1171 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1172 GNUNET_SCHEDULER_TaskCallback error_cb,
1174 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1176 GNUNET_SCHEDULER_TaskCallback finish_cb,
1177 void *finish_cb_cls)
1179 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1180 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1181 struct GNUNET_MQ_Envelope *env;
1182 struct TicketIterationStartMessage *msg;
1185 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1187 rid = h->r_id_gen++;
1188 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1190 it->error_cb = error_cb;
1191 it->error_cb_cls = error_cb_cls;
1192 it->finish_cb = finish_cb;
1193 it->finish_cb_cls = finish_cb_cls;
1197 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1200 env = GNUNET_MQ_msg (msg,
1201 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1202 msg->id = htonl (rid);
1203 msg->identity = identity_pub;
1204 msg->is_audience = htonl (GNUNET_NO);
1208 GNUNET_MQ_send (h->mq,
1216 * Lists all tickets that have been issued to remote
1217 * identites (relying parties)
1219 * @param h the identity provider to use
1220 * @param identity the issuing identity
1221 * @param error_cb function to call on error (i.e. disconnect),
1222 * the handle is afterwards invalid
1223 * @param error_cb_cls closure for @a error_cb
1224 * @param proc function to call on each ticket; it
1225 * will be called repeatedly with a value (if available)
1226 * @param proc_cls closure for @a proc
1227 * @param finish_cb function to call on completion
1228 * the handle is afterwards invalid
1229 * @param finish_cb_cls closure for @a finish_cb
1230 * @return an iterator handle to use for iteration
1232 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1233 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1234 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1235 GNUNET_SCHEDULER_TaskCallback error_cb,
1237 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1239 GNUNET_SCHEDULER_TaskCallback finish_cb,
1240 void *finish_cb_cls)
1242 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1243 struct GNUNET_MQ_Envelope *env;
1244 struct TicketIterationStartMessage *msg;
1247 rid = h->r_id_gen++;
1248 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1250 it->error_cb = error_cb;
1251 it->error_cb_cls = error_cb_cls;
1252 it->finish_cb = finish_cb;
1253 it->finish_cb_cls = finish_cb_cls;
1257 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1260 env = GNUNET_MQ_msg (msg,
1261 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1262 msg->id = htonl (rid);
1263 msg->identity = *identity;
1264 msg->is_audience = htonl (GNUNET_YES);
1268 GNUNET_MQ_send (h->mq,
1276 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start
1277 * for the next record.
1279 * @param it the iterator
1282 GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1284 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1285 struct TicketIterationNextMessage *msg;
1286 struct GNUNET_MQ_Envelope *env;
1288 env = GNUNET_MQ_msg (msg,
1289 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT);
1290 msg->id = htonl (it->r_id);
1291 GNUNET_MQ_send (h->mq,
1297 * Stops iteration and releases the idp handle for further calls. Must
1298 * be called on any iteration that has not yet completed prior to calling
1299 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1301 * @param it the iterator
1304 GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1306 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1307 struct GNUNET_MQ_Envelope *env;
1308 struct TicketIterationStopMessage *msg;
1312 env = GNUNET_MQ_msg (msg,
1313 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP);
1314 msg->id = htonl (it->r_id);
1315 GNUNET_MQ_send (h->mq,
1322 * Revoked an issued ticket. The relying party will be unable to retrieve
1323 * updated attributes.
1325 * @param h the identity provider to use
1326 * @param identity the issuing identity
1327 * @param ticket the ticket to revoke
1328 * @param cb the callback
1329 * @param cb_cls the callback closure
1330 * @return handle to abort the operation
1332 struct GNUNET_IDENTITY_PROVIDER_Operation *
1333 GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1334 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1335 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1336 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb,
1339 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1340 struct GNUNET_MQ_Envelope *env;
1341 struct RevokeTicketMessage *msg;
1344 rid = h->r_id_gen++;
1345 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1350 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1353 env = GNUNET_MQ_msg_extra (msg,
1354 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
1355 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
1356 msg->id = htonl (rid);
1357 msg->identity = *identity;
1360 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1364 GNUNET_MQ_send (h->mq,
1371 /* end of identity_provider_api.c */