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);
522 GNUNET_CONTAINER_DLL_remove (h->op_head,
534 * Handle an incoming message of type
535 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
538 * @param msg the message we received
539 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
542 check_attribute_result (void *cls,
543 const struct AttributeResultMessage *msg)
548 msg_len = ntohs (msg->header.size);
549 attr_len = ntohs (msg->attr_len);
550 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
553 return GNUNET_SYSERR;
560 * Handle an incoming message of type
561 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
564 * @param msg the message we received
567 handle_attribute_result (void *cls,
568 const struct AttributeResultMessage *msg)
570 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
571 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
572 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
573 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
575 uint32_t r_id = ntohl (msg->id);
577 attr_len = ntohs (msg->attr_len);
578 LOG (GNUNET_ERROR_TYPE_DEBUG,
579 "Processing attribute result.\n");
582 for (it = h->it_head; NULL != it; it = it->next)
583 if (it->r_id == r_id)
585 for (op = h->op_head; NULL != op; op = op->next)
586 if (op->r_id == r_id)
588 if ((NULL == it) && (NULL == op))
591 if ( (0 == (memcmp (&msg->identity,
593 sizeof (identity_dummy)))) )
595 if ((NULL == it) && (NULL == op))
603 if (NULL != it->finish_cb)
604 it->finish_cb (it->finish_cb_cls);
609 if (NULL != op->ar_cb)
613 GNUNET_CONTAINER_DLL_remove (h->op_head,
623 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
624 attr = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&msg[1],
628 if (NULL != it->proc)
629 it->proc (it->proc_cls,
632 } else if (NULL != op)
634 if (NULL != op->ar_cb)
647 * Handle an incoming message of type
648 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
651 * @param msg the message we received
652 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
655 check_ticket_result (void *cls,
656 const struct TicketResultMessage *msg)
660 msg_len = ntohs (msg->header.size);
661 if (msg_len < sizeof (struct TicketResultMessage))
664 return GNUNET_SYSERR;
672 * Handle an incoming message of type
673 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
676 * @param msg the message we received
679 handle_ticket_result (void *cls,
680 const struct TicketResultMessage *msg)
682 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
683 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
684 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
685 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
686 uint32_t r_id = ntohl (msg->id);
689 for (op = handle->op_head; NULL != op; op = op->next)
690 if (op->r_id == r_id)
692 for (it = handle->ticket_it_head; NULL != it; it = it->next)
693 if (it->r_id == r_id)
695 if ((NULL == op) && (NULL == it))
697 msg_len = ntohs (msg->header.size);
700 GNUNET_CONTAINER_DLL_remove (handle->op_head,
703 if (msg_len == sizeof (struct TicketResultMessage))
705 if (NULL != op->tr_cb)
706 op->tr_cb (op->cls, NULL);
708 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
709 if (NULL != op->tr_cb)
710 op->tr_cb (op->cls, ticket);
714 } else if (NULL != it) {
715 if (msg_len == sizeof (struct TicketResultMessage))
717 if (NULL != it->tr_cb)
718 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
719 handle->ticket_it_tail,
721 it->finish_cb (it->finish_cb_cls);
724 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
725 if (NULL != it->tr_cb)
726 it->tr_cb (it->cls, ticket);
734 * Handle an incoming message of type
735 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT
738 * @param msg the message we received
741 handle_revoke_ticket_result (void *cls,
742 const struct RevokeTicketResultMessage *msg)
744 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
745 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
746 uint32_t r_id = ntohl (msg->id);
749 LOG (GNUNET_ERROR_TYPE_DEBUG,
750 "Processing revocation result.\n");
753 for (op = h->op_head; NULL != op; op = op->next)
754 if (op->r_id == r_id)
758 success = ntohl (msg->success);
760 if (NULL != op->rvk_cb)
766 GNUNET_CONTAINER_DLL_remove (h->op_head,
778 * Try again to connect to the service.
780 * @param h handle to the identity provider service.
783 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
785 struct GNUNET_MQ_MessageHandler handlers[] = {
786 GNUNET_MQ_hd_fixed_size (attribute_store_response,
787 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE,
788 struct AttributeStoreResultMessage,
790 GNUNET_MQ_hd_var_size (attribute_result,
791 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
792 struct AttributeResultMessage,
794 GNUNET_MQ_hd_var_size (ticket_result,
795 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT,
796 struct TicketResultMessage,
798 GNUNET_MQ_hd_var_size (consume_ticket_result,
799 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT,
800 struct ConsumeTicketResultMessage,
802 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
803 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT,
804 struct RevokeTicketResultMessage,
806 GNUNET_MQ_handler_end ()
808 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
810 GNUNET_assert (NULL == h->mq);
811 LOG (GNUNET_ERROR_TYPE_DEBUG,
812 "Connecting to identity provider service.\n");
814 h->mq = GNUNET_CLIENT_connect (h->cfg,
821 for (op = h->op_head; NULL != op; op = op->next)
822 GNUNET_MQ_send_copy (h->mq,
828 * Connect to the identity provider service.
830 * @param cfg the configuration to use
831 * @return handle to use
833 struct GNUNET_IDENTITY_PROVIDER_Handle *
834 GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
836 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
838 h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle);
851 * Cancel an operation. Note that the operation MAY still
852 * be executed; this merely cancels the continuation; if the request
853 * was already transmitted, the service may still choose to complete
856 * @param op operation to cancel
859 GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
861 struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h;
863 GNUNET_CONTAINER_DLL_remove (h->op_head,
866 GNUNET_MQ_discard (op->env);
872 * Disconnect from service
874 * @param h handle to destroy
877 GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
879 GNUNET_assert (NULL != h);
882 GNUNET_MQ_destroy (h->mq);
885 if (NULL != h->reconnect_task)
887 GNUNET_SCHEDULER_cancel (h->reconnect_task);
888 h->reconnect_task = NULL;
890 GNUNET_assert (NULL == h->op_head);
895 * Store an attribute. If the attribute is already present,
896 * it is replaced with the new attribute.
898 * @param h handle to the identity provider
899 * @param pkey private key of the identity
900 * @param attr the attribute value
901 * @param cont continuation to call when done
902 * @param cont_cls closure for @a cont
903 * @return handle to abort the request
905 struct GNUNET_IDENTITY_PROVIDER_Operation *
906 GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
907 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
908 const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
909 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
912 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
913 struct AttributeStoreMessage *sam;
916 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
920 op->r_id = h->r_id_gen++;
921 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
924 attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (attr);
925 op->env = GNUNET_MQ_msg_extra (sam,
927 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
928 sam->identity = *pkey;
929 sam->id = htonl (op->r_id);
931 GNUNET_IDENTITY_ATTRIBUTE_serialize (attr,
934 sam->attr_len = htons (attr_len);
936 GNUNET_MQ_send_copy (h->mq,
944 * List all attributes for a local identity.
945 * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
946 * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
947 * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
948 * immediately, and then again after
949 * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
951 * On error (disconnect), @a error_cb will be invoked.
952 * On normal completion, @a finish_cb proc will be
955 * @param h handle to the idp
956 * @param identity identity to access
957 * @param error_cb function to call on error (i.e. disconnect),
958 * the handle is afterwards invalid
959 * @param error_cb_cls closure for @a error_cb
960 * @param proc function to call on each attribute; it
961 * will be called repeatedly with a value (if available)
962 * @param proc_cls closure for @a proc
963 * @param finish_cb function to call on completion
964 * the handle is afterwards invalid
965 * @param finish_cb_cls closure for @a finish_cb
966 * @return an iterator handle to use for iteration
968 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
969 GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
970 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
971 GNUNET_SCHEDULER_TaskCallback error_cb,
973 GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
975 GNUNET_SCHEDULER_TaskCallback finish_cb,
978 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
979 struct GNUNET_MQ_Envelope *env;
980 struct AttributeIterationStartMessage *msg;
984 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator);
986 it->error_cb = error_cb;
987 it->error_cb_cls = error_cb_cls;
988 it->finish_cb = finish_cb;
989 it->finish_cb_cls = finish_cb_cls;
991 it->proc_cls = proc_cls;
993 it->identity = *identity;
994 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
997 env = GNUNET_MQ_msg (msg,
998 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START);
999 msg->id = htonl (rid);
1000 msg->identity = *identity;
1004 GNUNET_MQ_send (h->mq,
1011 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
1012 * for the next record.
1014 * @param it the iterator
1017 GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1019 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1020 struct AttributeIterationNextMessage *msg;
1021 struct GNUNET_MQ_Envelope *env;
1023 env = GNUNET_MQ_msg (msg,
1024 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT);
1025 msg->id = htonl (it->r_id);
1026 GNUNET_MQ_send (h->mq,
1032 * Stops iteration and releases the idp handle for further calls. Must
1033 * be called on any iteration that has not yet completed prior to calling
1034 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1036 * @param it the iterator
1039 GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1041 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1042 struct GNUNET_MQ_Envelope *env;
1043 struct AttributeIterationStopMessage *msg;
1047 env = GNUNET_MQ_msg (msg,
1048 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP);
1049 msg->id = htonl (it->r_id);
1050 GNUNET_MQ_send (h->mq,
1058 * Issues a ticket to another identity. The identity may use
1059 * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
1060 * and retrieve the attributes specified in the AttributeList.
1062 * @param h the identity provider to use
1063 * @param iss the issuing identity
1064 * @param rp the subject of the ticket (the relying party)
1065 * @param attrs the attributes that the relying party is given access to
1066 * @param cb the callback
1067 * @param cb_cls the callback closure
1068 * @return handle to abort the operation
1070 struct GNUNET_IDENTITY_PROVIDER_Operation *
1071 GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1072 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1073 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1074 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
1075 GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
1078 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1079 struct IssueTicketMessage *tim;
1082 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1086 op->r_id = h->r_id_gen++;
1087 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1090 attr_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs);
1091 op->env = GNUNET_MQ_msg_extra (tim,
1093 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET);
1094 tim->identity = *iss;
1096 tim->id = htonl (op->r_id);
1098 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs,
1101 tim->attr_len = htons (attr_len);
1103 GNUNET_MQ_send_copy (h->mq,
1109 * Consumes an issued ticket. The ticket is persisted
1110 * and used to retrieve identity information from the issuer
1112 * @param h the identity provider to use
1113 * @param identity the identity that is the subject of the issued ticket (the relying party)
1114 * @param ticket the issued ticket to consume
1115 * @param cb the callback to call
1116 * @param cb_cls the callback closure
1117 * @return handle to abort the operation
1119 struct GNUNET_IDENTITY_PROVIDER_Operation *
1120 GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1121 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1122 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1123 GNUNET_IDENTITY_PROVIDER_AttributeResult cb,
1126 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1127 struct ConsumeTicketMessage *ctm;
1129 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1133 op->r_id = h->r_id_gen++;
1134 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1137 op->env = GNUNET_MQ_msg_extra (ctm,
1138 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket),
1139 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET);
1140 ctm->identity = *identity;
1141 ctm->id = htonl (op->r_id);
1143 GNUNET_memcpy ((char*)&ctm[1],
1145 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket));
1148 GNUNET_MQ_send_copy (h->mq,
1156 * Lists all tickets that have been issued to remote
1157 * identites (relying parties)
1159 * @param h the identity provider to use
1160 * @param identity the issuing identity
1161 * @param error_cb function to call on error (i.e. disconnect),
1162 * the handle is afterwards invalid
1163 * @param error_cb_cls closure for @a error_cb
1164 * @param proc function to call on each ticket; it
1165 * will be called repeatedly with a value (if available)
1166 * @param proc_cls closure for @a proc
1167 * @param finish_cb function to call on completion
1168 * the handle is afterwards invalid
1169 * @param finish_cb_cls closure for @a finish_cb
1170 * @return an iterator handle to use for iteration
1172 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1173 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1174 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1175 GNUNET_SCHEDULER_TaskCallback error_cb,
1177 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1179 GNUNET_SCHEDULER_TaskCallback finish_cb,
1180 void *finish_cb_cls)
1182 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1183 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1184 struct GNUNET_MQ_Envelope *env;
1185 struct TicketIterationStartMessage *msg;
1188 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1190 rid = h->r_id_gen++;
1191 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1193 it->error_cb = error_cb;
1194 it->error_cb_cls = error_cb_cls;
1195 it->finish_cb = finish_cb;
1196 it->finish_cb_cls = finish_cb_cls;
1200 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1203 env = GNUNET_MQ_msg (msg,
1204 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1205 msg->id = htonl (rid);
1206 msg->identity = identity_pub;
1207 msg->is_audience = htonl (GNUNET_NO);
1211 GNUNET_MQ_send (h->mq,
1219 * Lists all tickets that have been issued to remote
1220 * identites (relying parties)
1222 * @param h the identity provider to use
1223 * @param identity the issuing identity
1224 * @param error_cb function to call on error (i.e. disconnect),
1225 * the handle is afterwards invalid
1226 * @param error_cb_cls closure for @a error_cb
1227 * @param proc function to call on each ticket; it
1228 * will be called repeatedly with a value (if available)
1229 * @param proc_cls closure for @a proc
1230 * @param finish_cb function to call on completion
1231 * the handle is afterwards invalid
1232 * @param finish_cb_cls closure for @a finish_cb
1233 * @return an iterator handle to use for iteration
1235 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1236 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1237 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1238 GNUNET_SCHEDULER_TaskCallback error_cb,
1240 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1242 GNUNET_SCHEDULER_TaskCallback finish_cb,
1243 void *finish_cb_cls)
1245 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1246 struct GNUNET_MQ_Envelope *env;
1247 struct TicketIterationStartMessage *msg;
1250 rid = h->r_id_gen++;
1251 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1253 it->error_cb = error_cb;
1254 it->error_cb_cls = error_cb_cls;
1255 it->finish_cb = finish_cb;
1256 it->finish_cb_cls = finish_cb_cls;
1260 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1263 env = GNUNET_MQ_msg (msg,
1264 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1265 msg->id = htonl (rid);
1266 msg->identity = *identity;
1267 msg->is_audience = htonl (GNUNET_YES);
1271 GNUNET_MQ_send (h->mq,
1279 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start
1280 * for the next record.
1282 * @param it the iterator
1285 GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1287 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1288 struct TicketIterationNextMessage *msg;
1289 struct GNUNET_MQ_Envelope *env;
1291 env = GNUNET_MQ_msg (msg,
1292 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT);
1293 msg->id = htonl (it->r_id);
1294 GNUNET_MQ_send (h->mq,
1300 * Stops iteration and releases the idp handle for further calls. Must
1301 * be called on any iteration that has not yet completed prior to calling
1302 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1304 * @param it the iterator
1307 GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1309 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1310 struct GNUNET_MQ_Envelope *env;
1311 struct TicketIterationStopMessage *msg;
1315 env = GNUNET_MQ_msg (msg,
1316 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP);
1317 msg->id = htonl (it->r_id);
1318 GNUNET_MQ_send (h->mq,
1325 * Revoked an issued ticket. The relying party will be unable to retrieve
1326 * updated attributes.
1328 * @param h the identity provider to use
1329 * @param identity the issuing identity
1330 * @param ticket the ticket to revoke
1331 * @param cb the callback
1332 * @param cb_cls the callback closure
1333 * @return handle to abort the operation
1335 struct GNUNET_IDENTITY_PROVIDER_Operation *
1336 GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1337 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1338 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1339 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb,
1342 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1343 struct GNUNET_MQ_Envelope *env;
1344 struct RevokeTicketMessage *msg;
1347 rid = h->r_id_gen++;
1348 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1353 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1356 env = GNUNET_MQ_msg_extra (msg,
1357 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
1358 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
1359 msg->id = htonl (rid);
1360 msg->identity = *identity;
1363 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1367 GNUNET_MQ_send (h->mq,
1374 /* end of identity_provider_api.c */