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