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?
322 * Try again to connect to the service.
324 * @param cls handle to the service.
327 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle);
332 * @param cls the handle
335 reconnect_task (void *cls)
337 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
339 handle->reconnect_task = NULL;
345 * Disconnect from service and then reconnect.
347 * @param handle our handle
350 force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle)
352 GNUNET_MQ_destroy (handle->mq);
354 handle->reconnect_backoff
355 = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
356 handle->reconnect_task
357 = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
365 * @param it entry to free
368 free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
370 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
372 GNUNET_CONTAINER_DLL_remove (h->it_head,
376 GNUNET_MQ_discard (it->env);
383 * Generic error handler, called with the appropriate error code and
384 * the same closure specified at the creation of the message queue.
385 * Not every message queue implementation supports an error handler.
387 * @param cls closure with the `struct GNUNET_GNS_Handle *`
388 * @param error error code
391 mq_error_handler (void *cls,
392 enum GNUNET_MQ_Error error)
394 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
395 force_reconnect (handle);
399 * Handle an incoming message of type
400 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
403 * @param msg the message we received
406 handle_attribute_store_response (void *cls,
407 const struct AttributeStoreResultMessage *msg)
409 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
410 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
411 uint32_t r_id = ntohl (msg->id);
415 for (op = h->op_head; NULL != op; op = op->next)
416 if (op->r_id == r_id)
421 res = ntohl (msg->op_result);
422 LOG (GNUNET_ERROR_TYPE_DEBUG,
423 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
426 /* TODO: add actual error message to response... */
427 if (GNUNET_SYSERR == res)
428 emsg = _("failed to store record\n");
431 if (NULL != op->as_cb)
435 GNUNET_CONTAINER_DLL_remove (h->op_head,
444 * Handle an incoming message of type
445 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
448 * @param msg the message we received
449 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
452 check_consume_ticket_result (void *cls,
453 const struct ConsumeTicketResultMessage *msg)
458 msg_len = ntohs (msg->header.size);
459 attrs_len = ntohs (msg->attrs_len);
460 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len)
463 return GNUNET_SYSERR;
470 * Handle an incoming message of type
471 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
474 * @param msg the message we received
477 handle_consume_ticket_result (void *cls,
478 const struct ConsumeTicketResultMessage *msg)
480 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
481 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
483 uint32_t r_id = ntohl (msg->id);
485 attrs_len = ntohs (msg->attrs_len);
486 LOG (GNUNET_ERROR_TYPE_DEBUG,
487 "Processing attribute result.\n");
490 for (op = h->op_head; NULL != op; op = op->next)
491 if (op->r_id == r_id)
497 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
498 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
499 attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&msg[1],
501 if (NULL != op->ar_cb)
511 for (le = attrs->list_head; NULL != le; le = le->next)
515 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (attrs);
521 GNUNET_CONTAINER_DLL_remove (h->op_head,
532 * Handle an incoming message of type
533 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
536 * @param msg the message we received
537 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
540 check_attribute_result (void *cls,
541 const struct AttributeResultMessage *msg)
546 msg_len = ntohs (msg->header.size);
547 attr_len = ntohs (msg->attr_len);
548 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
551 return GNUNET_SYSERR;
558 * Handle an incoming message of type
559 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
562 * @param msg the message we received
565 handle_attribute_result (void *cls,
566 const struct AttributeResultMessage *msg)
568 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
569 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
570 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
571 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
573 uint32_t r_id = ntohl (msg->id);
575 attr_len = ntohs (msg->attr_len);
576 LOG (GNUNET_ERROR_TYPE_DEBUG,
577 "Processing attribute result.\n");
580 for (it = h->it_head; NULL != it; it = it->next)
581 if (it->r_id == r_id)
583 for (op = h->op_head; NULL != op; op = op->next)
584 if (op->r_id == r_id)
586 if ((NULL == it) && (NULL == op))
589 if ( (0 == (memcmp (&msg->identity,
591 sizeof (identity_dummy)))) )
593 if ((NULL == it) && (NULL == op))
601 if (NULL != it->finish_cb)
602 it->finish_cb (it->finish_cb_cls);
607 if (NULL != op->ar_cb)
611 GNUNET_CONTAINER_DLL_remove (h->op_head,
621 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
622 attr = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&msg[1],
626 if (NULL != it->proc)
627 it->proc (it->proc_cls,
630 } else if (NULL != op)
632 if (NULL != op->ar_cb)
645 * Handle an incoming message of type
646 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
649 * @param msg the message we received
650 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
653 check_ticket_result (void *cls,
654 const struct TicketResultMessage *msg)
658 msg_len = ntohs (msg->header.size);
659 if (msg_len < sizeof (struct TicketResultMessage))
662 return GNUNET_SYSERR;
670 * Handle an incoming message of type
671 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
674 * @param msg the message we received
677 handle_ticket_result (void *cls,
678 const struct TicketResultMessage *msg)
680 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
681 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
682 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
683 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
684 uint32_t r_id = ntohl (msg->id);
687 for (op = handle->op_head; NULL != op; op = op->next)
688 if (op->r_id == r_id)
690 for (it = handle->ticket_it_head; NULL != it; it = it->next)
691 if (it->r_id == r_id)
693 if ((NULL == op) && (NULL == it))
695 msg_len = ntohs (msg->header.size);
698 GNUNET_CONTAINER_DLL_remove (handle->op_head,
701 if (msg_len == sizeof (struct TicketResultMessage))
703 if (NULL != op->tr_cb)
704 op->tr_cb (op->cls, NULL);
706 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
707 if (NULL != op->tr_cb)
708 op->tr_cb (op->cls, ticket);
712 } else if (NULL != it) {
713 if (msg_len == sizeof (struct TicketResultMessage))
715 if (NULL != it->tr_cb)
716 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
717 handle->ticket_it_tail,
719 it->finish_cb (it->finish_cb_cls);
722 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
723 if (NULL != it->tr_cb)
724 it->tr_cb (it->cls, ticket);
732 * Handle an incoming message of type
733 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT
736 * @param msg the message we received
739 handle_revoke_ticket_result (void *cls,
740 const struct RevokeTicketResultMessage *msg)
742 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
743 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
744 uint32_t r_id = ntohl (msg->id);
747 LOG (GNUNET_ERROR_TYPE_DEBUG,
748 "Processing revocation result.\n");
751 for (op = h->op_head; NULL != op; op = op->next)
752 if (op->r_id == r_id)
756 success = ntohl (msg->success);
758 if (NULL != op->rvk_cb)
764 GNUNET_CONTAINER_DLL_remove (h->op_head,
776 * Try again to connect to the service.
778 * @param cls handle to the identity provider service.
781 reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
783 struct GNUNET_MQ_MessageHandler handlers[] = {
784 GNUNET_MQ_hd_fixed_size (attribute_store_response,
785 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE,
786 struct AttributeStoreResultMessage,
788 GNUNET_MQ_hd_var_size (attribute_result,
789 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
790 struct AttributeResultMessage,
792 GNUNET_MQ_hd_var_size (ticket_result,
793 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT,
794 struct TicketResultMessage,
796 GNUNET_MQ_hd_var_size (consume_ticket_result,
797 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT,
798 struct ConsumeTicketResultMessage,
800 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
801 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT,
802 struct RevokeTicketResultMessage,
804 GNUNET_MQ_handler_end ()
806 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
808 GNUNET_assert (NULL == h->mq);
809 LOG (GNUNET_ERROR_TYPE_DEBUG,
810 "Connecting to identity provider service.\n");
812 h->mq = GNUNET_CLIENT_connect (h->cfg,
819 for (op = h->op_head; NULL != op; op = op->next)
820 GNUNET_MQ_send_copy (h->mq,
826 * Connect to the identity provider service.
828 * @param cfg the configuration to use
829 * @return handle to use
831 struct GNUNET_IDENTITY_PROVIDER_Handle *
832 GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
834 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
836 h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle);
849 * Cancel an operation. Note that the operation MAY still
850 * be executed; this merely cancels the continuation; if the request
851 * was already transmitted, the service may still choose to complete
854 * @param op operation to cancel
857 GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
859 struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h;
861 GNUNET_CONTAINER_DLL_remove (h->op_head,
864 GNUNET_MQ_discard (op->env);
870 * Disconnect from service
872 * @param h handle to destroy
875 GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
877 GNUNET_assert (NULL != h);
880 GNUNET_MQ_destroy (h->mq);
883 if (NULL != h->reconnect_task)
885 GNUNET_SCHEDULER_cancel (h->reconnect_task);
886 h->reconnect_task = NULL;
888 GNUNET_assert (NULL == h->op_head);
893 * Store an attribute. If the attribute is already present,
894 * it is replaced with the new attribute.
896 * @param h handle to the identity provider
897 * @param pkey private key of the identity
898 * @param name the attribute name
899 * @param value the attribute value
900 * @param cont continuation to call when done
901 * @param cont_cls closure for @a cont
902 * @return handle to abort the request
904 struct GNUNET_IDENTITY_PROVIDER_Operation *
905 GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
906 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
907 const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
908 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
911 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
912 struct AttributeStoreMessage *sam;
915 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
919 op->r_id = h->r_id_gen++;
920 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
923 attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (attr);
924 op->env = GNUNET_MQ_msg_extra (sam,
926 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
927 sam->identity = *pkey;
928 sam->id = htonl (op->r_id);
930 GNUNET_IDENTITY_ATTRIBUTE_serialize (attr,
933 sam->attr_len = htons (attr_len);
935 GNUNET_MQ_send_copy (h->mq,
943 * List all attributes for a local identity.
944 * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
945 * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
946 * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
947 * immediately, and then again after
948 * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
950 * On error (disconnect), @a error_cb will be invoked.
951 * On normal completion, @a finish_cb proc will be
954 * @param h handle to the idp
955 * @param identity identity to access
956 * @param error_cb function to call on error (i.e. disconnect),
957 * the handle is afterwards invalid
958 * @param error_cb_cls closure for @a error_cb
959 * @param proc function to call on each attribute; it
960 * will be called repeatedly with a value (if available)
961 * @param proc_cls closure for @a proc
962 * @param finish_cb function to call on completion
963 * the handle is afterwards invalid
964 * @param finish_cb_cls closure for @a finish_cb
965 * @return an iterator handle to use for iteration
967 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
968 GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
969 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
970 GNUNET_SCHEDULER_TaskCallback error_cb,
972 GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
974 GNUNET_SCHEDULER_TaskCallback finish_cb,
977 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
978 struct GNUNET_MQ_Envelope *env;
979 struct AttributeIterationStartMessage *msg;
983 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator);
985 it->error_cb = error_cb;
986 it->error_cb_cls = error_cb_cls;
987 it->finish_cb = finish_cb;
988 it->finish_cb_cls = finish_cb_cls;
990 it->proc_cls = proc_cls;
992 it->identity = *identity;
993 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
996 env = GNUNET_MQ_msg (msg,
997 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START);
998 msg->id = htonl (rid);
999 msg->identity = *identity;
1003 GNUNET_MQ_send (h->mq,
1010 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
1011 * for the next record.
1013 * @param it the iterator
1016 GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1018 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1019 struct AttributeIterationNextMessage *msg;
1020 struct GNUNET_MQ_Envelope *env;
1022 env = GNUNET_MQ_msg (msg,
1023 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT);
1024 msg->id = htonl (it->r_id);
1025 GNUNET_MQ_send (h->mq,
1031 * Stops iteration and releases the idp handle for further calls. Must
1032 * be called on any iteration that has not yet completed prior to calling
1033 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1035 * @param it the iterator
1038 GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1040 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1041 struct GNUNET_MQ_Envelope *env;
1042 struct AttributeIterationStopMessage *msg;
1046 env = GNUNET_MQ_msg (msg,
1047 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP);
1048 msg->id = htonl (it->r_id);
1049 GNUNET_MQ_send (h->mq,
1057 * Issues a ticket to another identity. The identity may use
1058 * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
1059 * and retrieve the attributes specified in the AttributeList.
1061 * @param h the identity provider to use
1062 * @param iss the issuing identity
1063 * @param rp the subject of the ticket (the relying party)
1064 * @param attr the attributes that the relying party is given access to
1065 * @param cb the callback
1066 * @param cb_cls the callback closure
1067 * @return handle to abort the operation
1069 struct GNUNET_IDENTITY_PROVIDER_Operation *
1070 GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1071 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1072 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1073 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
1074 GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
1077 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1078 struct IssueTicketMessage *tim;
1081 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1085 op->r_id = h->r_id_gen++;
1086 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1089 attr_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs);
1090 op->env = GNUNET_MQ_msg_extra (tim,
1092 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET);
1093 tim->identity = *iss;
1095 tim->id = htonl (op->r_id);
1097 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs,
1100 tim->attr_len = htons (attr_len);
1102 GNUNET_MQ_send_copy (h->mq,
1108 * Consumes an issued ticket. The ticket is persisted
1109 * and used to retrieve identity information from the issuer
1111 * @param id the identity provider to use
1112 * @param identity the identity that is the subject of the issued ticket (the relying party)
1113 * @param ticket the issued ticket to consume
1114 * @param cb the callback to call
1115 * @param cb_cls the callback closure
1116 * @return handle to abort the operation
1118 struct GNUNET_IDENTITY_PROVIDER_Operation *
1119 GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1120 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1121 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1122 GNUNET_IDENTITY_PROVIDER_AttributeResult cb,
1125 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1126 struct ConsumeTicketMessage *ctm;
1128 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1132 op->r_id = h->r_id_gen++;
1133 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1136 op->env = GNUNET_MQ_msg_extra (ctm,
1137 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket),
1138 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET);
1139 ctm->identity = *identity;
1140 ctm->id = htonl (op->r_id);
1142 GNUNET_memcpy ((char*)&ctm[1],
1144 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket));
1147 GNUNET_MQ_send_copy (h->mq,
1155 * Lists all tickets that have been issued to remote
1156 * identites (relying parties)
1158 * @param h the identity provider to use
1159 * @param identity the issuing identity
1160 * @param error_cb function to call on error (i.e. disconnect),
1161 * the handle is afterwards invalid
1162 * @param error_cb_cls closure for @a error_cb
1163 * @param proc function to call on each ticket; it
1164 * will be called repeatedly with a value (if available)
1165 * @param proc_cls closure for @a proc
1166 * @param finish_cb function to call on completion
1167 * the handle is afterwards invalid
1168 * @param finish_cb_cls closure for @a finish_cb
1169 * @return an iterator handle to use for iteration
1171 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1172 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1174 GNUNET_SCHEDULER_TaskCallback error_cb,
1176 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1178 GNUNET_SCHEDULER_TaskCallback finish_cb,
1179 void *finish_cb_cls)
1181 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1182 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1183 struct GNUNET_MQ_Envelope *env;
1184 struct TicketIterationStartMessage *msg;
1187 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1189 rid = h->r_id_gen++;
1190 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1192 it->error_cb = error_cb;
1193 it->error_cb_cls = error_cb_cls;
1194 it->finish_cb = finish_cb;
1195 it->finish_cb_cls = finish_cb_cls;
1199 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1202 env = GNUNET_MQ_msg (msg,
1203 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1204 msg->id = htonl (rid);
1205 msg->identity = identity_pub;
1206 msg->is_audience = htonl (GNUNET_NO);
1210 GNUNET_MQ_send (h->mq,
1218 * Lists all tickets that have been issued to remote
1219 * identites (relying parties)
1221 * @param id the identity provider to use
1222 * @param identity the issuing identity
1223 * @param error_cb function to call on error (i.e. disconnect),
1224 * the handle is afterwards invalid
1225 * @param error_cb_cls closure for @a error_cb
1226 * @param proc function to call on each ticket; it
1227 * will be called repeatedly with a value (if available)
1228 * @param proc_cls closure for @a proc
1229 * @param finish_cb function to call on completion
1230 * the handle is afterwards invalid
1231 * @param finish_cb_cls closure for @a finish_cb
1232 * @return an iterator handle to use for iteration
1234 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
1235 GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1236 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1237 GNUNET_SCHEDULER_TaskCallback error_cb,
1239 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1241 GNUNET_SCHEDULER_TaskCallback finish_cb,
1242 void *finish_cb_cls)
1244 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1245 struct GNUNET_MQ_Envelope *env;
1246 struct TicketIterationStartMessage *msg;
1249 rid = h->r_id_gen++;
1250 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1252 it->error_cb = error_cb;
1253 it->error_cb_cls = error_cb_cls;
1254 it->finish_cb = finish_cb;
1255 it->finish_cb_cls = finish_cb_cls;
1259 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1262 env = GNUNET_MQ_msg (msg,
1263 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1264 msg->id = htonl (rid);
1265 msg->identity = *identity;
1266 msg->is_audience = htonl (GNUNET_YES);
1270 GNUNET_MQ_send (h->mq,
1278 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start
1279 * for the next record.
1281 * @param it the iterator
1284 GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1286 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1287 struct TicketIterationNextMessage *msg;
1288 struct GNUNET_MQ_Envelope *env;
1290 env = GNUNET_MQ_msg (msg,
1291 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT);
1292 msg->id = htonl (it->r_id);
1293 GNUNET_MQ_send (h->mq,
1299 * Stops iteration and releases the idp handle for further calls. Must
1300 * be called on any iteration that has not yet completed prior to calling
1301 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1303 * @param it the iterator
1306 GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
1308 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1309 struct GNUNET_MQ_Envelope *env;
1310 struct TicketIterationStopMessage *msg;
1314 env = GNUNET_MQ_msg (msg,
1315 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP);
1316 msg->id = htonl (it->r_id);
1317 GNUNET_MQ_send (h->mq,
1324 * Revoked an issued ticket. The relying party will be unable to retrieve
1325 * updated attributes.
1327 * @param id the identity provider to use
1328 * @param identity the issuing identity
1329 * @param ticket the ticket to revoke
1330 * @param cb the callback
1331 * @param cb_cls the callback closure
1332 * @return handle to abort the operation
1334 struct GNUNET_IDENTITY_PROVIDER_Operation *
1335 GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1336 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1337 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1338 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb,
1341 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1342 struct GNUNET_MQ_Envelope *env;
1343 struct RevokeTicketMessage *msg;
1346 rid = h->r_id_gen++;
1347 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1352 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1355 env = GNUNET_MQ_msg_extra (msg,
1356 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
1357 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
1358 msg->id = htonl (rid);
1359 msg->identity = *identity;
1362 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1366 GNUNET_MQ_send (h->mq,
1373 /* end of identity_provider_api.c */