aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/reclaim_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/reclaim/reclaim_api.c')
-rw-r--r--src/reclaim/reclaim_api.c1761
1 files changed, 0 insertions, 1761 deletions
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
deleted file mode 100644
index bc6b835c9..000000000
--- a/src/reclaim/reclaim_api.c
+++ /dev/null
@@ -1,1761 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2016 GNUnet e.V.
4
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.
9
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.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file reclaim/reclaim_api.c
23 * @brief api to interact with the reclaim service
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_mq_lib.h"
30#include "gnunet_protocols.h"
31#include "gnunet_reclaim_lib.h"
32#include "gnunet_reclaim_service.h"
33#include "reclaim.h"
34
35#define LOG(kind, ...) GNUNET_log_from (kind, "reclaim-api", __VA_ARGS__)
36
37
38/**
39 * Handle for an operation with the service.
40 */
41struct GNUNET_RECLAIM_Operation
42{
43 /**
44 * Main handle.
45 */
46 struct GNUNET_RECLAIM_Handle *h;
47
48 /**
49 * We keep operations in a DLL.
50 */
51 struct GNUNET_RECLAIM_Operation *next;
52
53 /**
54 * We keep operations in a DLL.
55 */
56 struct GNUNET_RECLAIM_Operation *prev;
57
58 /**
59 * Message to send to the service.
60 * Allocated at the end of this struct.
61 */
62 const struct GNUNET_MessageHeader *msg;
63
64 /**
65 * Continuation to invoke after attribute store call
66 */
67 GNUNET_RECLAIM_ContinuationWithStatus as_cb;
68
69 /**
70 * Attribute result callback
71 */
72 GNUNET_RECLAIM_AttributeResult ar_cb;
73
74 /**
75 * Attribute result callback
76 */
77 GNUNET_RECLAIM_AttributeTicketResult atr_cb;
78
79 /**
80 * Credential result callback
81 */
82 GNUNET_RECLAIM_CredentialResult at_cb;
83
84 /**
85 * Revocation result callback
86 */
87 GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
88
89 /**
90 * Ticket result callback
91 */
92 GNUNET_RECLAIM_TicketCallback tr_cb;
93
94 /**
95 * Ticket issue result callback
96 */
97 GNUNET_RECLAIM_IssueTicketCallback ti_cb;
98
99 /**
100 * Envelope with the message for this queue entry.
101 */
102 struct GNUNET_MQ_Envelope *env;
103
104 /**
105 * request id
106 */
107 uint32_t r_id;
108
109 /**
110 * Closure for @e cont or @e cb.
111 */
112 void *cls;
113};
114
115
116/**
117 * Handle for a ticket iterator operation
118 */
119struct GNUNET_RECLAIM_TicketIterator
120{
121 /**
122 * Kept in a DLL.
123 */
124 struct GNUNET_RECLAIM_TicketIterator *next;
125
126 /**
127 * Kept in a DLL.
128 */
129 struct GNUNET_RECLAIM_TicketIterator *prev;
130
131 /**
132 * Main handle to access the idp.
133 */
134 struct GNUNET_RECLAIM_Handle *h;
135
136 /**
137 * Function to call on completion.
138 */
139 GNUNET_SCHEDULER_TaskCallback finish_cb;
140
141 /**
142 * Closure for @e finish_cb.
143 */
144 void *finish_cb_cls;
145
146 /**
147 * The continuation to call with the results
148 */
149 GNUNET_RECLAIM_TicketCallback tr_cb;
150
151 /**
152 * Closure for @e tr_cb.
153 */
154 void *cls;
155
156 /**
157 * Function to call on errors.
158 */
159 GNUNET_SCHEDULER_TaskCallback error_cb;
160
161 /**
162 * Closure for @e error_cb.
163 */
164 void *error_cb_cls;
165
166 /**
167 * Envelope of the message to send to the service, if not yet
168 * sent.
169 */
170 struct GNUNET_MQ_Envelope *env;
171
172 /**
173 * The operation id this zone iteration operation has
174 */
175 uint32_t r_id;
176};
177
178
179/**
180 * Handle for a attribute iterator operation
181 */
182struct GNUNET_RECLAIM_AttributeIterator
183{
184 /**
185 * Kept in a DLL.
186 */
187 struct GNUNET_RECLAIM_AttributeIterator *next;
188
189 /**
190 * Kept in a DLL.
191 */
192 struct GNUNET_RECLAIM_AttributeIterator *prev;
193
194 /**
195 * Main handle to access the service.
196 */
197 struct GNUNET_RECLAIM_Handle *h;
198
199 /**
200 * Function to call on completion.
201 */
202 GNUNET_SCHEDULER_TaskCallback finish_cb;
203
204 /**
205 * Closure for @e finish_cb.
206 */
207 void *finish_cb_cls;
208
209 /**
210 * The continuation to call with the results
211 */
212 GNUNET_RECLAIM_AttributeResult proc;
213
214 /**
215 * Closure for @e proc.
216 */
217 void *proc_cls;
218
219 /**
220 * Function to call on errors.
221 */
222 GNUNET_SCHEDULER_TaskCallback error_cb;
223
224 /**
225 * Closure for @e error_cb.
226 */
227 void *error_cb_cls;
228
229 /**
230 * Envelope of the message to send to the service, if not yet
231 * sent.
232 */
233 struct GNUNET_MQ_Envelope *env;
234
235 /**
236 * Private key of the zone.
237 */
238 struct GNUNET_IDENTITY_PrivateKey identity;
239
240 /**
241 * The operation id this zone iteration operation has
242 */
243 uint32_t r_id;
244};
245
246/**
247 * Handle for a credential iterator operation
248 */
249struct GNUNET_RECLAIM_CredentialIterator
250{
251 /**
252 * Kept in a DLL.
253 */
254 struct GNUNET_RECLAIM_CredentialIterator *next;
255
256 /**
257 * Kept in a DLL.
258 */
259 struct GNUNET_RECLAIM_CredentialIterator *prev;
260
261 /**
262 * Main handle to access the service.
263 */
264 struct GNUNET_RECLAIM_Handle *h;
265
266 /**
267 * Function to call on completion.
268 */
269 GNUNET_SCHEDULER_TaskCallback finish_cb;
270
271 /**
272 * Closure for @e finish_cb.
273 */
274 void *finish_cb_cls;
275
276 /**
277 * The continuation to call with the results
278 */
279 GNUNET_RECLAIM_CredentialResult proc;
280
281 /**
282 * Closure for @e proc.
283 */
284 void *proc_cls;
285
286 /**
287 * Function to call on errors.
288 */
289 GNUNET_SCHEDULER_TaskCallback error_cb;
290
291 /**
292 * Closure for @e error_cb.
293 */
294 void *error_cb_cls;
295
296 /**
297 * Envelope of the message to send to the service, if not yet
298 * sent.
299 */
300 struct GNUNET_MQ_Envelope *env;
301
302 /**
303 * Private key of the zone.
304 */
305 struct GNUNET_IDENTITY_PrivateKey identity;
306
307 /**
308 * The operation id this zone iteration operation has
309 */
310 uint32_t r_id;
311};
312
313
314/**
315 * Handle to the service.
316 */
317struct GNUNET_RECLAIM_Handle
318{
319 /**
320 * Configuration to use.
321 */
322 const struct GNUNET_CONFIGURATION_Handle *cfg;
323
324 /**
325 * Socket (if available).
326 */
327 struct GNUNET_CLIENT_Connection *client;
328
329 /**
330 * Closure for 'cb'.
331 */
332 void *cb_cls;
333
334 /**
335 * Head of active operations.
336 */
337 struct GNUNET_RECLAIM_Operation *op_head;
338
339 /**
340 * Tail of active operations.
341 */
342 struct GNUNET_RECLAIM_Operation *op_tail;
343
344 /**
345 * Head of active iterations
346 */
347 struct GNUNET_RECLAIM_AttributeIterator *it_head;
348
349 /**
350 * Tail of active iterations
351 */
352 struct GNUNET_RECLAIM_AttributeIterator *it_tail;
353
354 /**
355 * Head of active iterations
356 */
357 struct GNUNET_RECLAIM_CredentialIterator *ait_head;
358
359 /**
360 * Tail of active iterations
361 */
362 struct GNUNET_RECLAIM_CredentialIterator *ait_tail;
363
364 /**
365 * Head of active iterations
366 */
367 struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
368
369 /**
370 * Tail of active iterations
371 */
372 struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
373
374 /**
375 * Currently pending transmission request, or NULL for none.
376 */
377 struct GNUNET_CLIENT_TransmitHandle *th;
378
379 /**
380 * Task doing exponential back-off trying to reconnect.
381 */
382 struct GNUNET_SCHEDULER_Task *reconnect_task;
383
384 /**
385 * Time for next connect retry.
386 */
387 struct GNUNET_TIME_Relative reconnect_backoff;
388
389 /**
390 * Connection to service (if available).
391 */
392 struct GNUNET_MQ_Handle *mq;
393
394 /**
395 * Request Id generator. Incremented by one for each request.
396 */
397 uint32_t r_id_gen;
398
399 /**
400 * Are we polling for incoming messages right now?
401 */
402 int in_receive;
403};
404
405
406/**
407 * Try again to connect to the service.
408 *
409 * @param h handle to the reclaim service.
410 */
411static void
412reconnect (struct GNUNET_RECLAIM_Handle *h);
413
414
415/**
416 * Reconnect
417 *
418 * @param cls the handle
419 */
420static void
421reconnect_task (void *cls)
422{
423 struct GNUNET_RECLAIM_Handle *handle = cls;
424
425 handle->reconnect_task = NULL;
426 reconnect (handle);
427}
428
429
430/**
431 * Disconnect from service and then reconnect.
432 *
433 * @param handle our service
434 */
435static void
436force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
437{
438 GNUNET_MQ_destroy (handle->mq);
439 handle->mq = NULL;
440 handle->reconnect_backoff =
441 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
442 handle->reconnect_task =
443 GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
444 &reconnect_task,
445 handle);
446}
447
448
449/**
450 * Free @a it.
451 *
452 * @param it entry to free
453 */
454static void
455free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
456{
457 struct GNUNET_RECLAIM_Handle *h = it->h;
458
459 GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it);
460 if (NULL != it->env)
461 GNUNET_MQ_discard (it->env);
462 GNUNET_free (it);
463}
464
465
466/**
467 * Free @a it.
468 *
469 * @param ait entry to free
470 */
471static void
472free_ait (struct GNUNET_RECLAIM_CredentialIterator *ait)
473{
474 struct GNUNET_RECLAIM_Handle *h = ait->h;
475
476 GNUNET_CONTAINER_DLL_remove (h->ait_head, h->ait_tail, ait);
477 if (NULL != ait->env)
478 GNUNET_MQ_discard (ait->env);
479 GNUNET_free (ait);
480}
481
482
483/**
484 * Free @a op
485 *
486 * @param op the operation to free
487 */
488static void
489free_op (struct GNUNET_RECLAIM_Operation *op)
490{
491 if (NULL == op)
492 return;
493 if (NULL != op->env)
494 GNUNET_MQ_discard (op->env);
495 GNUNET_free (op);
496}
497
498
499/**
500 * Generic error handler, called with the appropriate error code and
501 * the same closure specified at the creation of the message queue.
502 * Not every message queue implementation supports an error handler.
503 *
504 * @param cls closure with the `struct GNUNET_GNS_Handle *`
505 * @param error error code
506 */
507static void
508mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
509{
510 struct GNUNET_RECLAIM_Handle *handle = cls;
511
512 force_reconnect (handle);
513}
514
515
516/**
517 * Handle an incoming message of type
518 * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE
519 *
520 * @param cls
521 * @param msg the message we received
522 */
523static void
524handle_success_response (void *cls, const struct SuccessResultMessage *msg)
525{
526 struct GNUNET_RECLAIM_Handle *h = cls;
527 struct GNUNET_RECLAIM_Operation *op;
528 uint32_t r_id = ntohl (msg->id);
529 int res;
530 const char *emsg;
531
532 for (op = h->op_head; NULL != op; op = op->next)
533 if (op->r_id == r_id)
534 break;
535 if (NULL == op)
536 return;
537
538 res = ntohl (msg->op_result);
539 LOG (GNUNET_ERROR_TYPE_DEBUG,
540 "Received SUCCESS_RESPONSE with result %d\n",
541 res);
542
543 /* TODO: add actual error message to response... */
544 if (GNUNET_SYSERR == res)
545 emsg = _ ("failed to store record\n");
546 else
547 emsg = NULL;
548 if (NULL != op->as_cb)
549 op->as_cb (op->cls, res, emsg);
550 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
551 free_op (op);
552}
553
554
555/**
556 * Handle an incoming message of type
557 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
558 *
559 * @param cls
560 * @param msg the message we received
561 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
562 */
563static int
564check_consume_ticket_result (void *cls,
565 const struct ConsumeTicketResultMessage *msg)
566{
567 size_t msg_len;
568 size_t attrs_len;
569 size_t pl_len;
570
571 msg_len = ntohs (msg->header.size);
572 attrs_len = ntohs (msg->attrs_len);
573 pl_len = ntohs (msg->presentations_len);
574 if (msg_len !=
575 sizeof(struct ConsumeTicketResultMessage) + attrs_len + pl_len)
576 {
577 GNUNET_break (0);
578 return GNUNET_SYSERR;
579 }
580 return GNUNET_OK;
581}
582
583
584/**
585 * Handle an incoming message of type
586 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
587 *
588 * @param cls
589 * @param msg the message we received
590 */
591static void
592handle_consume_ticket_result (void *cls,
593 const struct ConsumeTicketResultMessage *msg)
594{
595 struct GNUNET_RECLAIM_Handle *h = cls;
596 struct GNUNET_RECLAIM_Operation *op;
597 size_t attrs_len;
598 size_t pl_len;
599 uint32_t r_id = ntohl (msg->id);
600 char *read_ptr;
601
602 attrs_len = ntohs (msg->attrs_len);
603 pl_len = ntohs (msg->presentations_len);
604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
605
606
607 for (op = h->op_head; NULL != op; op = op->next)
608 if (op->r_id == r_id)
609 break;
610 if (NULL == op)
611 return;
612
613 {
614 struct GNUNET_RECLAIM_AttributeList *attrs;
615 struct GNUNET_RECLAIM_AttributeListEntry *le;
616 struct GNUNET_RECLAIM_PresentationList *pl;
617 struct GNUNET_RECLAIM_PresentationListEntry *ple;
618 attrs =
619 GNUNET_RECLAIM_attribute_list_deserialize ((char *) &msg[1], attrs_len);
620 read_ptr = ((char *) &msg[1]) + attrs_len;
621 pl = GNUNET_RECLAIM_presentation_list_deserialize (read_ptr, pl_len);
622 if (NULL != op->atr_cb)
623 {
624 if (NULL == attrs)
625 {
626 op->atr_cb (op->cls, &msg->identity, NULL, NULL);
627 }
628 else
629 {
630 for (le = attrs->list_head; NULL != le; le = le->next)
631 {
632 if (GNUNET_NO ==
633 GNUNET_RECLAIM_id_is_zero (&le->attribute->credential))
634 {
635 for (ple = pl->list_head; NULL != ple; ple = ple->next)
636 {
637 if (GNUNET_YES ==
638 GNUNET_RECLAIM_id_is_equal (&le->attribute->credential,
639 &ple->presentation->credential_id))
640 {
641 op->atr_cb (op->cls, &msg->identity,
642 le->attribute, ple->presentation);
643 break;
644 }
645
646 }
647 }
648 else // No credentials
649 {
650 op->atr_cb (op->cls, &msg->identity,
651 le->attribute, NULL);
652 }
653 }
654 }
655 op->atr_cb (op->cls, NULL, NULL, NULL);
656 }
657 if (NULL != attrs)
658 GNUNET_RECLAIM_attribute_list_destroy (attrs);
659 if (NULL != pl)
660 GNUNET_RECLAIM_presentation_list_destroy (pl);
661 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
662 free_op (op);
663 return;
664 }
665 GNUNET_assert (0);
666}
667
668
669/**
670 * Handle an incoming message of type
671 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
672 *
673 * @param cls
674 * @param msg the message we received
675 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
676 */
677static int
678check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
679{
680 size_t msg_len;
681 size_t attr_len;
682
683 msg_len = ntohs (msg->header.size);
684 attr_len = ntohs (msg->attr_len);
685 if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
686 {
687 GNUNET_break (0);
688 return GNUNET_SYSERR;
689 }
690 return GNUNET_OK;
691}
692
693
694/**
695 * Handle an incoming message of type
696 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
697 *
698 * @param cls
699 * @param msg the message we received
700 */
701static void
702handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
703{
704 static struct GNUNET_IDENTITY_PrivateKey identity_dummy;
705 struct GNUNET_RECLAIM_Handle *h = cls;
706 struct GNUNET_RECLAIM_AttributeIterator *it;
707 struct GNUNET_RECLAIM_Operation *op;
708 size_t attr_len;
709 uint32_t r_id = ntohl (msg->id);
710
711 attr_len = ntohs (msg->attr_len);
712 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
713
714
715 for (it = h->it_head; NULL != it; it = it->next)
716 if (it->r_id == r_id)
717 break;
718 for (op = h->op_head; NULL != op; op = op->next)
719 if (op->r_id == r_id)
720 break;
721 if ((NULL == it) && (NULL == op))
722 return;
723
724 if ((0 ==
725 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
726 {
727 if ((NULL == it) && (NULL == op))
728 {
729 GNUNET_break (0);
730 force_reconnect (h);
731 return;
732 }
733 if (NULL != it)
734 {
735 if (NULL != it->finish_cb)
736 it->finish_cb (it->finish_cb_cls);
737 free_it (it);
738 }
739 if (NULL != op)
740 {
741 if (NULL != op->ar_cb)
742 op->ar_cb (op->cls, NULL, NULL);
743 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
744 free_op (op);
745 }
746 return;
747 }
748
749 {
750 struct GNUNET_RECLAIM_Attribute *attr;
751 GNUNET_RECLAIM_attribute_deserialize ((char *) &msg[1], attr_len,
752 &attr);
753 if (NULL != it)
754 {
755 if (NULL != it->proc)
756 it->proc (it->proc_cls, &msg->identity, attr);
757 }
758 else if (NULL != op)
759 {
760 if (NULL != op->ar_cb)
761 op->ar_cb (op->cls, &msg->identity, attr);
762 }
763 GNUNET_free (attr);
764 return;
765 }
766 GNUNET_assert (0);
767}
768
769
770/**
771 * Handle an incoming message of type
772 * #GNUNET_MESSAGE_TYPE_RECLAIM_credential_RESULT
773 *
774 * @param cls
775 * @param msg the message we received
776 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
777 */
778static int
779check_credential_result (void *cls, const struct CredentialResultMessage *msg)
780{
781 size_t msg_len;
782 size_t cred_len;
783
784 msg_len = ntohs (msg->header.size);
785 cred_len = ntohs (msg->credential_len);
786 if (msg_len != sizeof(struct CredentialResultMessage) + cred_len)
787 {
788 GNUNET_break (0);
789 return GNUNET_SYSERR;
790 }
791 return GNUNET_OK;
792}
793
794
795/**
796 * Handle an incoming message of type
797 * #GNUNET_MESSAGE_TYPE_RECLAIM_credential_RESULT
798 *
799 * @param cls
800 * @param msg the message we received
801 */
802static void
803handle_credential_result (void *cls, const struct
804 CredentialResultMessage *msg)
805{
806 static struct GNUNET_IDENTITY_PrivateKey identity_dummy;
807 struct GNUNET_RECLAIM_Handle *h = cls;
808 struct GNUNET_RECLAIM_CredentialIterator *it;
809 struct GNUNET_RECLAIM_Operation *op;
810 size_t att_len;
811 uint32_t r_id = ntohl (msg->id);
812
813 att_len = ntohs (msg->credential_len);
814 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing credential result.\n");
815
816
817 for (it = h->ait_head; NULL != it; it = it->next)
818 if (it->r_id == r_id)
819 break;
820 for (op = h->op_head; NULL != op; op = op->next)
821 if (op->r_id == r_id)
822 break;
823 if ((NULL == it) && (NULL == op))
824 return;
825
826 if ((0 ==
827 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
828 {
829 if ((NULL == it) && (NULL == op))
830 {
831 GNUNET_break (0);
832 force_reconnect (h);
833 return;
834 }
835 if (NULL != it)
836 {
837 if (NULL != it->finish_cb)
838 it->finish_cb (it->finish_cb_cls);
839 free_ait (it);
840 }
841 if (NULL != op)
842 {
843 if (NULL != op->at_cb)
844 op->at_cb (op->cls, NULL, NULL);
845 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
846 free_op (op);
847 }
848 return;
849 }
850
851 {
852 struct GNUNET_RECLAIM_Credential *att;
853 att = GNUNET_RECLAIM_credential_deserialize ((char *) &msg[1], att_len);
854
855 if (NULL != it)
856 {
857 if (NULL != it->proc)
858 it->proc (it->proc_cls, &msg->identity, att);
859 }
860 else if (NULL != op)
861 {
862 if (NULL != op->at_cb)
863 op->at_cb (op->cls, &msg->identity, att);
864 }
865 GNUNET_free (att);
866 return;
867 }
868 GNUNET_assert (0);
869}
870
871
872/**
873 * Handle an incoming message of type
874 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
875 *
876 * @param cls
877 * @param msg the message we received
878 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
879 */
880static int
881check_ticket_result (void *cls, const struct TicketResultMessage *msg)
882{
883 size_t msg_len;
884 size_t pres_len;
885
886 msg_len = ntohs (msg->header.size);
887 pres_len = ntohs (msg->presentations_len);
888 if (msg_len != sizeof(struct TicketResultMessage) + pres_len)
889 {
890 GNUNET_break (0);
891 return GNUNET_SYSERR;
892 }
893 return GNUNET_OK;
894}
895
896
897/**
898 * Handle an incoming message of type
899 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
900 *
901 * @param cls
902 * @param msg the message we received
903 */
904static void
905handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
906{
907 struct GNUNET_RECLAIM_Handle *handle = cls;
908 struct GNUNET_RECLAIM_Operation *op;
909 struct GNUNET_RECLAIM_TicketIterator *it;
910 struct GNUNET_RECLAIM_PresentationList *presentation;
911 uint32_t r_id = ntohl (msg->id);
912 static const struct GNUNET_RECLAIM_Ticket ticket;
913 uint32_t pres_len = ntohs (msg->presentations_len);
914
915 for (op = handle->op_head; NULL != op; op = op->next)
916 if (op->r_id == r_id)
917 break;
918 for (it = handle->ticket_it_head; NULL != it; it = it->next)
919 if (it->r_id == r_id)
920 break;
921 if ((NULL == op) && (NULL == it))
922 return;
923 if (NULL != op)
924 {
925 if (0 < pres_len)
926 presentation = GNUNET_RECLAIM_presentation_list_deserialize (
927 (char*) &msg[1],
928 pres_len);
929 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
930 if (0 ==
931 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
932 {
933 if (NULL != op->ti_cb)
934 op->ti_cb (op->cls, NULL, NULL);
935 }
936 else
937 {
938 if (NULL != op->ti_cb)
939 op->ti_cb (op->cls,
940 &msg->ticket,
941 (0 < pres_len) ? presentation : NULL);
942 }
943 if (0 < pres_len)
944 GNUNET_RECLAIM_presentation_list_destroy (presentation);
945 free_op (op);
946 return;
947 }
948 else if (NULL != it)
949 {
950 if (0 ==
951 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
952 {
953 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
954 handle->ticket_it_tail,
955 it);
956 it->finish_cb (it->finish_cb_cls);
957 GNUNET_free (it);
958 }
959 else
960 {
961 if (NULL != it->tr_cb)
962 it->tr_cb (it->cls, &msg->ticket);
963 }
964 return;
965 }
966 GNUNET_break (0);
967}
968
969
970/**
971 * Handle an incoming message of type
972 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
973 *
974 * @param cls
975 * @param msg the message we received
976 */
977static void
978handle_revoke_ticket_result (void *cls,
979 const struct RevokeTicketResultMessage *msg)
980{
981 struct GNUNET_RECLAIM_Handle *h = cls;
982 struct GNUNET_RECLAIM_Operation *op;
983 uint32_t r_id = ntohl (msg->id);
984 int32_t success;
985
986 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
987
988
989 for (op = h->op_head; NULL != op; op = op->next)
990 if (op->r_id == r_id)
991 break;
992 if (NULL == op)
993 return;
994 success = ntohl (msg->success);
995 {
996 if (NULL != op->rvk_cb)
997 {
998 op->rvk_cb (op->cls, success, NULL);
999 }
1000 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
1001 free_op (op);
1002 return;
1003 }
1004 GNUNET_assert (0);
1005}
1006
1007
1008/**
1009 * Try again to connect to the service.
1010 *
1011 * @param h handle to the reclaim service.
1012 */
1013static void
1014reconnect (struct GNUNET_RECLAIM_Handle *h)
1015{
1016 struct GNUNET_MQ_MessageHandler handlers[] =
1017 { GNUNET_MQ_hd_fixed_size (success_response,
1018 GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
1019 struct SuccessResultMessage,
1020 h),
1021 GNUNET_MQ_hd_var_size (attribute_result,
1022 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
1023 struct AttributeResultMessage,
1024 h),
1025 GNUNET_MQ_hd_var_size (credential_result,
1026 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT,
1027 struct CredentialResultMessage,
1028 h),
1029 GNUNET_MQ_hd_var_size (ticket_result,
1030 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
1031 struct TicketResultMessage,
1032 h),
1033 GNUNET_MQ_hd_var_size (consume_ticket_result,
1034 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
1035 struct ConsumeTicketResultMessage,
1036 h),
1037 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
1038 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
1039 struct RevokeTicketResultMessage,
1040 h),
1041 GNUNET_MQ_handler_end () };
1042 struct GNUNET_RECLAIM_Operation *op;
1043
1044 GNUNET_assert (NULL == h->mq);
1045 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
1046
1047 h->mq =
1048 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
1049 if (NULL == h->mq)
1050 return;
1051 for (op = h->op_head; NULL != op; op = op->next)
1052 GNUNET_MQ_send_copy (h->mq, op->env);
1053}
1054
1055
1056/**
1057 * Connect to the reclaim service.
1058 *
1059 * @param cfg the configuration to use
1060 * @return handle to use
1061 */
1062struct GNUNET_RECLAIM_Handle *
1063GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
1064{
1065 struct GNUNET_RECLAIM_Handle *h;
1066
1067 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
1068 h->cfg = cfg;
1069 reconnect (h);
1070 if (NULL == h->mq)
1071 {
1072 GNUNET_free (h);
1073 return NULL;
1074 }
1075 return h;
1076}
1077
1078
1079/**
1080 * Cancel an operation. Note that the operation MAY still
1081 * be executed; this merely cancels the continuation; if the request
1082 * was already transmitted, the service may still choose to complete
1083 * the operation.
1084 *
1085 * @param op operation to cancel
1086 */
1087void
1088GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
1089{
1090 struct GNUNET_RECLAIM_Handle *h = op->h;
1091
1092 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
1093 free_op (op);
1094}
1095
1096
1097/**
1098 * Disconnect from service
1099 *
1100 * @param h handle to destroy
1101 */
1102void
1103GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
1104{
1105 GNUNET_assert (NULL != h);
1106 if (NULL != h->mq)
1107 {
1108 GNUNET_MQ_destroy (h->mq);
1109 h->mq = NULL;
1110 }
1111 if (NULL != h->reconnect_task)
1112 {
1113 GNUNET_SCHEDULER_cancel (h->reconnect_task);
1114 h->reconnect_task = NULL;
1115 }
1116 GNUNET_assert (NULL == h->op_head);
1117 GNUNET_free (h);
1118}
1119
1120
1121/**
1122 * Store an attribute. If the attribute is already present,
1123 * it is replaced with the new attribute.
1124 *
1125 * @param h handle to the re:claimID service
1126 * @param pkey private key of the identity
1127 * @param attr the attribute value
1128 * @param exp_interval the relative expiration interval for the attribute
1129 * @param cont continuation to call when done
1130 * @param cont_cls closure for @a cont
1131 * @return handle to abort the request
1132 */
1133struct GNUNET_RECLAIM_Operation *
1134GNUNET_RECLAIM_attribute_store (
1135 struct GNUNET_RECLAIM_Handle *h,
1136 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1137 const struct GNUNET_RECLAIM_Attribute *attr,
1138 const struct GNUNET_TIME_Relative *exp_interval,
1139 GNUNET_RECLAIM_ContinuationWithStatus cont,
1140 void *cont_cls)
1141{
1142 struct GNUNET_RECLAIM_Operation *op;
1143 struct AttributeStoreMessage *sam;
1144 size_t attr_len;
1145
1146 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1147 op->h = h;
1148 op->as_cb = cont;
1149 op->cls = cont_cls;
1150 op->r_id = h->r_id_gen++;
1151 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1152 attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
1153 op->env = GNUNET_MQ_msg_extra (sam,
1154 attr_len,
1155 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
1156 sam->identity = *pkey;
1157 sam->id = htonl (op->r_id);
1158 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1159
1160 GNUNET_RECLAIM_attribute_serialize (attr, (char *) &sam[1]);
1161
1162 sam->attr_len = htons (attr_len);
1163 if (NULL != h->mq)
1164 GNUNET_MQ_send_copy (h->mq, op->env);
1165 return op;
1166}
1167
1168
1169/**
1170 * Delete an attribute. Tickets used to share this attribute are updated
1171 * accordingly.
1172 *
1173 * @param h handle to the re:claimID service
1174 * @param pkey Private key of the identity to add an attribute to
1175 * @param attr The attribute
1176 * @param cont Continuation to call when done
1177 * @param cont_cls Closure for @a cont
1178 * @return handle Used to to abort the request
1179 */
1180struct GNUNET_RECLAIM_Operation *
1181GNUNET_RECLAIM_attribute_delete (
1182 struct GNUNET_RECLAIM_Handle *h,
1183 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1184 const struct GNUNET_RECLAIM_Attribute *attr,
1185 GNUNET_RECLAIM_ContinuationWithStatus cont,
1186 void *cont_cls)
1187{
1188 struct GNUNET_RECLAIM_Operation *op;
1189 struct AttributeDeleteMessage *dam;
1190 size_t attr_len;
1191
1192 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1193 op->h = h;
1194 op->as_cb = cont;
1195 op->cls = cont_cls;
1196 op->r_id = h->r_id_gen++;
1197 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1198 attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
1199 op->env = GNUNET_MQ_msg_extra (dam,
1200 attr_len,
1201 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE);
1202 dam->identity = *pkey;
1203 dam->id = htonl (op->r_id);
1204 GNUNET_RECLAIM_attribute_serialize (attr, (char *) &dam[1]);
1205
1206 dam->attr_len = htons (attr_len);
1207 if (NULL != h->mq)
1208 GNUNET_MQ_send_copy (h->mq, op->env);
1209 return op;
1210}
1211
1212
1213/**
1214 * Store an credential. If the credential is already present,
1215 * it is replaced with the new credential.
1216 *
1217 * @param h handle to the re:claimID service
1218 * @param pkey private key of the identity
1219 * @param attr the credential value
1220 * @param exp_interval the relative expiration interval for the credential
1221 * @param cont continuation to call when done
1222 * @param cont_cls closure for @a cont
1223 * @return handle to abort the request
1224 */
1225struct GNUNET_RECLAIM_Operation *
1226GNUNET_RECLAIM_credential_store (
1227 struct GNUNET_RECLAIM_Handle *h,
1228 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1229 const struct GNUNET_RECLAIM_Credential *attr,
1230 const struct GNUNET_TIME_Relative *exp_interval,
1231 GNUNET_RECLAIM_ContinuationWithStatus cont,
1232 void *cont_cls)
1233{
1234 struct GNUNET_RECLAIM_Operation *op;
1235 struct AttributeStoreMessage *sam;
1236 size_t attr_len;
1237
1238 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1239 op->h = h;
1240 op->as_cb = cont;
1241 op->cls = cont_cls;
1242 op->r_id = h->r_id_gen++;
1243 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1244 attr_len = GNUNET_RECLAIM_credential_serialize_get_size (attr);
1245 op->env = GNUNET_MQ_msg_extra (sam,
1246 attr_len,
1247 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE);
1248 sam->identity = *pkey;
1249 sam->id = htonl (op->r_id);
1250 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1251
1252 GNUNET_RECLAIM_credential_serialize (attr, (char *) &sam[1]);
1253
1254 sam->attr_len = htons (attr_len);
1255 if (NULL != h->mq)
1256 GNUNET_MQ_send_copy (h->mq, op->env);
1257 return op;
1258}
1259
1260
1261/**
1262 * Delete an credential. Tickets used to share this credential are updated
1263 * accordingly.
1264 *
1265 * @param h handle to the re:claimID service
1266 * @param pkey Private key of the identity to add an attribute to
1267 * @param attr The credential
1268 * @param cont Continuation to call when done
1269 * @param cont_cls Closure for @a cont
1270 * @return handle Used to to abort the request
1271 */
1272struct GNUNET_RECLAIM_Operation *
1273GNUNET_RECLAIM_credential_delete (
1274 struct GNUNET_RECLAIM_Handle *h,
1275 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1276 const struct GNUNET_RECLAIM_Credential *attr,
1277 GNUNET_RECLAIM_ContinuationWithStatus cont,
1278 void *cont_cls)
1279{
1280 struct GNUNET_RECLAIM_Operation *op;
1281 struct AttributeDeleteMessage *dam;
1282 size_t attr_len;
1283
1284 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1285 op->h = h;
1286 op->as_cb = cont;
1287 op->cls = cont_cls;
1288 op->r_id = h->r_id_gen++;
1289 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1290 attr_len = GNUNET_RECLAIM_credential_serialize_get_size (attr);
1291 op->env = GNUNET_MQ_msg_extra (dam,
1292 attr_len,
1293 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE);
1294 dam->identity = *pkey;
1295 dam->id = htonl (op->r_id);
1296 GNUNET_RECLAIM_credential_serialize (attr, (char *) &dam[1]);
1297
1298 dam->attr_len = htons (attr_len);
1299 if (NULL != h->mq)
1300 GNUNET_MQ_send_copy (h->mq, op->env);
1301 return op;
1302}
1303
1304
1305/**
1306 * List all attributes for a local identity.
1307 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1308 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
1309 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
1310 * immediately, and then again after
1311 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
1312 *
1313 * On error (disconnect), @a error_cb will be invoked.
1314 * On normal completion, @a finish_cb proc will be
1315 * invoked.
1316 *
1317 * @param h Handle to the re:claimID service
1318 * @param identity Identity to iterate over
1319 * @param error_cb Function to call on error (i.e. disconnect),
1320 * the handle is afterwards invalid
1321 * @param error_cb_cls Closure for @a error_cb
1322 * @param proc Function to call on each attribute
1323 * @param proc_cls Closure for @a proc
1324 * @param finish_cb Function to call on completion
1325 * the handle is afterwards invalid
1326 * @param finish_cb_cls Closure for @a finish_cb
1327 * @return an iterator Handle to use for iteration
1328 */
1329struct GNUNET_RECLAIM_AttributeIterator *
1330GNUNET_RECLAIM_get_attributes_start (
1331 struct GNUNET_RECLAIM_Handle *h,
1332 const struct GNUNET_IDENTITY_PrivateKey *identity,
1333 GNUNET_SCHEDULER_TaskCallback error_cb,
1334 void *error_cb_cls,
1335 GNUNET_RECLAIM_AttributeResult proc,
1336 void *proc_cls,
1337 GNUNET_SCHEDULER_TaskCallback finish_cb,
1338 void *finish_cb_cls)
1339{
1340 struct GNUNET_RECLAIM_AttributeIterator *it;
1341 struct GNUNET_MQ_Envelope *env;
1342 struct AttributeIterationStartMessage *msg;
1343 uint32_t rid;
1344
1345 rid = h->r_id_gen++;
1346 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
1347 it->h = h;
1348 it->error_cb = error_cb;
1349 it->error_cb_cls = error_cb_cls;
1350 it->finish_cb = finish_cb;
1351 it->finish_cb_cls = finish_cb_cls;
1352 it->proc = proc;
1353 it->proc_cls = proc_cls;
1354 it->r_id = rid;
1355 it->identity = *identity;
1356 GNUNET_CONTAINER_DLL_insert_tail (h->it_head, h->it_tail, it);
1357 env =
1358 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
1359 msg->id = htonl (rid);
1360 msg->identity = *identity;
1361 if (NULL == h->mq)
1362 it->env = env;
1363 else
1364 GNUNET_MQ_send (h->mq, env);
1365 return it;
1366}
1367
1368
1369/**
1370 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
1371 * for the next record.
1372 *
1373 * @param it the iterator
1374 */
1375void
1376GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
1377{
1378 struct GNUNET_RECLAIM_Handle *h = it->h;
1379 struct AttributeIterationNextMessage *msg;
1380 struct GNUNET_MQ_Envelope *env;
1381
1382 env =
1383 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
1384 msg->id = htonl (it->r_id);
1385 GNUNET_MQ_send (h->mq, env);
1386}
1387
1388
1389/**
1390 * Stops iteration and releases the handle for further calls. Must
1391 * be called on any iteration that has not yet completed prior to calling
1392 * #GNUNET_RECLAIM_disconnect.
1393 *
1394 * @param it the iterator
1395 */
1396void
1397GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
1398{
1399 struct GNUNET_RECLAIM_Handle *h = it->h;
1400 struct GNUNET_MQ_Envelope *env;
1401 struct AttributeIterationStopMessage *msg;
1402
1403 if (NULL != h->mq)
1404 {
1405 env =
1406 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
1407 msg->id = htonl (it->r_id);
1408 GNUNET_MQ_send (h->mq, env);
1409 }
1410 free_it (it);
1411}
1412
1413
1414/**
1415 * List all credentials for a local identity.
1416 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1417 * for any other calls than #GNUNET_RECLAIM_get_credentials_next() and
1418 * #GNUNET_RECLAIM_get_credentials_stop. @a proc will be called once
1419 * immediately, and then again after
1420 * #GNUNET_RECLAIM_get_credentials_next() is invoked.
1421 *
1422 * On error (disconnect), @a error_cb will be invoked.
1423 * On normal completion, @a finish_cb proc will be
1424 * invoked.
1425 *
1426 * @param h Handle to the re:claimID service
1427 * @param identity Identity to iterate over
1428 * @param error_cb Function to call on error (i.e. disconnect),
1429 * the handle is afterwards invalid
1430 * @param error_cb_cls Closure for @a error_cb
1431 * @param proc Function to call on each credential
1432 * @param proc_cls Closure for @a proc
1433 * @param finish_cb Function to call on completion
1434 * the handle is afterwards invalid
1435 * @param finish_cb_cls Closure for @a finish_cb
1436 * @return an iterator Handle to use for iteration
1437 */
1438struct GNUNET_RECLAIM_CredentialIterator *
1439GNUNET_RECLAIM_get_credentials_start (
1440 struct GNUNET_RECLAIM_Handle *h,
1441 const struct GNUNET_IDENTITY_PrivateKey *identity,
1442 GNUNET_SCHEDULER_TaskCallback error_cb,
1443 void *error_cb_cls,
1444 GNUNET_RECLAIM_CredentialResult proc,
1445 void *proc_cls,
1446 GNUNET_SCHEDULER_TaskCallback finish_cb,
1447 void *finish_cb_cls)
1448{
1449 struct GNUNET_RECLAIM_CredentialIterator *ait;
1450 struct GNUNET_MQ_Envelope *env;
1451 struct CredentialIterationStartMessage *msg;
1452 uint32_t rid;
1453
1454 rid = h->r_id_gen++;
1455 ait = GNUNET_new (struct GNUNET_RECLAIM_CredentialIterator);
1456 ait->h = h;
1457 ait->error_cb = error_cb;
1458 ait->error_cb_cls = error_cb_cls;
1459 ait->finish_cb = finish_cb;
1460 ait->finish_cb_cls = finish_cb_cls;
1461 ait->proc = proc;
1462 ait->proc_cls = proc_cls;
1463 ait->r_id = rid;
1464 ait->identity = *identity;
1465 GNUNET_CONTAINER_DLL_insert_tail (h->ait_head, h->ait_tail, ait);
1466 env =
1467 GNUNET_MQ_msg (msg,
1468 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START);
1469 msg->id = htonl (rid);
1470 msg->identity = *identity;
1471 if (NULL == h->mq)
1472 ait->env = env;
1473 else
1474 GNUNET_MQ_send (h->mq, env);
1475 return ait;
1476}
1477
1478
1479/**
1480 * Calls the record processor specified in #GNUNET_RECLAIM_get_credential_start
1481 * for the next record.
1482 *
1483 * @param it the iterator
1484 */
1485void
1486GNUNET_RECLAIM_get_credentials_next (struct
1487 GNUNET_RECLAIM_CredentialIterator *ait)
1488{
1489 struct GNUNET_RECLAIM_Handle *h = ait->h;
1490 struct CredentialIterationNextMessage *msg;
1491 struct GNUNET_MQ_Envelope *env;
1492
1493 env =
1494 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT);
1495 msg->id = htonl (ait->r_id);
1496 GNUNET_MQ_send (h->mq, env);
1497}
1498
1499
1500/**
1501 * Stops iteration and releases the handle for further calls. Must
1502 * be called on any iteration that has not yet completed prior to calling
1503 * #GNUNET_RECLAIM_disconnect.
1504 *
1505 * @param it the iterator
1506 */
1507void
1508GNUNET_RECLAIM_get_credentials_stop (struct
1509 GNUNET_RECLAIM_CredentialIterator *ait)
1510{
1511 struct GNUNET_RECLAIM_Handle *h = ait->h;
1512 struct GNUNET_MQ_Envelope *env;
1513 struct CredentialIterationStopMessage *msg;
1514
1515 if (NULL != h->mq)
1516 {
1517 env =
1518 GNUNET_MQ_msg (msg,
1519 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP);
1520 msg->id = htonl (ait->r_id);
1521 GNUNET_MQ_send (h->mq, env);
1522 }
1523 free_ait (ait);
1524}
1525
1526
1527/**
1528 * Issues a ticket to another relying party. The identity may use
1529 * @GNUNET_RECLAIM_ticket_consume to consume the ticket
1530 * and retrieve the attributes specified in the attribute list.
1531 *
1532 * @param h the reclaim to use
1533 * @param iss the issuing identity (= the user)
1534 * @param rp the subject of the ticket (= the relying party)
1535 * @param attrs the attributes that the relying party is given access to
1536 * @param cb the callback
1537 * @param cb_cls the callback closure
1538 * @return handle to abort the operation
1539 */
1540struct GNUNET_RECLAIM_Operation *
1541GNUNET_RECLAIM_ticket_issue (
1542 struct GNUNET_RECLAIM_Handle *h,
1543 const struct GNUNET_IDENTITY_PrivateKey *iss,
1544 const struct GNUNET_IDENTITY_PublicKey *rp,
1545 const struct GNUNET_RECLAIM_AttributeList *attrs,
1546 GNUNET_RECLAIM_IssueTicketCallback cb,
1547 void *cb_cls)
1548{
1549 struct GNUNET_RECLAIM_Operation *op;
1550 struct IssueTicketMessage *tim;
1551 size_t attr_len;
1552
1553 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1554 op->h = h;
1555 op->ti_cb = cb;
1556 op->cls = cb_cls;
1557 op->r_id = h->r_id_gen++;
1558 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1559 attr_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
1560 op->env = GNUNET_MQ_msg_extra (tim,
1561 attr_len,
1562 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1563 tim->identity = *iss;
1564 tim->rp = *rp;
1565 tim->id = htonl (op->r_id);
1566
1567 GNUNET_RECLAIM_attribute_list_serialize (attrs, (char *) &tim[1]);
1568
1569 tim->attr_len = htons (attr_len);
1570 if (NULL != h->mq)
1571 GNUNET_MQ_send_copy (h->mq, op->env);
1572 return op;
1573}
1574
1575
1576/**
1577 * Consumes an issued ticket. The ticket is persisted
1578 * and used to retrieve identity information from the issuer
1579 *
1580 * @param h the reclaim to use
1581 * @param identity the identity that is the subject of the issued ticket (the
1582 * relying party)
1583 * @param ticket the issued ticket to consume
1584 * @param cb the callback to call
1585 * @param cb_cls the callback closure
1586 * @return handle to abort the operation
1587 */
1588struct GNUNET_RECLAIM_Operation *
1589GNUNET_RECLAIM_ticket_consume (
1590 struct GNUNET_RECLAIM_Handle *h,
1591 const struct GNUNET_IDENTITY_PrivateKey *identity,
1592 const struct GNUNET_RECLAIM_Ticket *ticket,
1593 GNUNET_RECLAIM_AttributeTicketResult cb,
1594 void *cb_cls)
1595{
1596 struct GNUNET_RECLAIM_Operation *op;
1597 struct ConsumeTicketMessage *ctm;
1598
1599 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1600 op->h = h;
1601 op->atr_cb = cb;
1602 op->cls = cb_cls;
1603 op->r_id = h->r_id_gen++;
1604 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1605 op->env = GNUNET_MQ_msg (ctm, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1606 ctm->identity = *identity;
1607 ctm->id = htonl (op->r_id);
1608 ctm->ticket = *ticket;
1609 if (NULL != h->mq)
1610 GNUNET_MQ_send_copy (h->mq, op->env);
1611 else
1612 reconnect (h);
1613 return op;
1614}
1615
1616
1617/**
1618 * Lists all tickets that have been issued to remote
1619 * identites (relying parties)
1620 *
1621 * @param h the reclaim to use
1622 * @param identity the issuing identity
1623 * @param error_cb function to call on error (i.e. disconnect),
1624 * the handle is afterwards invalid
1625 * @param error_cb_cls closure for @a error_cb
1626 * @param proc function to call on each ticket; it
1627 * will be called repeatedly with a value (if available)
1628 * @param proc_cls closure for @a proc
1629 * @param finish_cb function to call on completion
1630 * the handle is afterwards invalid
1631 * @param finish_cb_cls closure for @a finish_cb
1632 * @return an iterator handle to use for iteration
1633 */
1634struct GNUNET_RECLAIM_TicketIterator *
1635GNUNET_RECLAIM_ticket_iteration_start (
1636 struct GNUNET_RECLAIM_Handle *h,
1637 const struct GNUNET_IDENTITY_PrivateKey *identity,
1638 GNUNET_SCHEDULER_TaskCallback error_cb,
1639 void *error_cb_cls,
1640 GNUNET_RECLAIM_TicketCallback proc,
1641 void *proc_cls,
1642 GNUNET_SCHEDULER_TaskCallback finish_cb,
1643 void *finish_cb_cls)
1644{
1645 struct GNUNET_RECLAIM_TicketIterator *it;
1646 struct GNUNET_MQ_Envelope *env;
1647 struct TicketIterationStartMessage *msg;
1648 uint32_t rid;
1649
1650 rid = h->r_id_gen++;
1651 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1652 it->h = h;
1653 it->error_cb = error_cb;
1654 it->error_cb_cls = error_cb_cls;
1655 it->finish_cb = finish_cb;
1656 it->finish_cb_cls = finish_cb_cls;
1657 it->tr_cb = proc;
1658 it->cls = proc_cls;
1659 it->r_id = rid;
1660 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it);
1661 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1662 msg->id = htonl (rid);
1663 msg->identity = *identity;
1664 if (NULL == h->mq)
1665 it->env = env;
1666 else
1667 GNUNET_MQ_send (h->mq, env);
1668 return it;
1669}
1670
1671
1672/**
1673 * Calls the ticket processor specified in
1674 * #GNUNET_RECLAIM_ticket_iteration_start for the next record.
1675 *
1676 * @param it the iterator
1677 */
1678void
1679GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1680{
1681 struct GNUNET_RECLAIM_Handle *h = it->h;
1682 struct TicketIterationNextMessage *msg;
1683 struct GNUNET_MQ_Envelope *env;
1684
1685 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1686 msg->id = htonl (it->r_id);
1687 GNUNET_MQ_send (h->mq, env);
1688}
1689
1690
1691/**
1692 * Stops iteration and releases the handle for further calls. Must
1693 * be called on any iteration that has not yet completed prior to calling
1694 * #GNUNET_RECLAIM_disconnect.
1695 *
1696 * @param it the iterator
1697 */
1698void
1699GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1700{
1701 struct GNUNET_RECLAIM_Handle *h = it->h;
1702 struct GNUNET_MQ_Envelope *env;
1703 struct TicketIterationStopMessage *msg;
1704
1705 if (NULL != h->mq)
1706 {
1707 env =
1708 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1709 msg->id = htonl (it->r_id);
1710 GNUNET_MQ_send (h->mq, env);
1711 }
1712 GNUNET_free (it);
1713}
1714
1715
1716/**
1717 * Revoked an issued ticket. The relying party will be unable to retrieve
1718 * attributes. Other issued tickets remain unaffected.
1719 * This includes tickets issued to other relying parties as well as to
1720 * other tickets issued to the audience specified in this ticket.
1721 *
1722 * @param h the identity provider to use
1723 * @param identity the issuing identity
1724 * @param ticket the ticket to revoke
1725 * @param cb the callback
1726 * @param cb_cls the callback closure
1727 * @return handle to abort the operation
1728 */
1729struct GNUNET_RECLAIM_Operation *
1730GNUNET_RECLAIM_ticket_revoke (
1731 struct GNUNET_RECLAIM_Handle *h,
1732 const struct GNUNET_IDENTITY_PrivateKey *identity,
1733 const struct GNUNET_RECLAIM_Ticket *ticket,
1734 GNUNET_RECLAIM_ContinuationWithStatus cb,
1735 void *cb_cls)
1736{
1737 struct GNUNET_RECLAIM_Operation *op;
1738 struct RevokeTicketMessage *msg;
1739 uint32_t rid;
1740
1741 rid = h->r_id_gen++;
1742 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1743 op->h = h;
1744 op->rvk_cb = cb;
1745 op->cls = cb_cls;
1746 op->r_id = rid;
1747 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1748 op->env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1749 msg->id = htonl (rid);
1750 msg->identity = *identity;
1751 msg->ticket = *ticket;
1752 if (NULL != h->mq)
1753 {
1754 GNUNET_MQ_send (h->mq, op->env);
1755 op->env = NULL;
1756 }
1757 return op;
1758}
1759
1760
1761/* end of reclaim_api.c */