aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/reclaim_api.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-19 23:28:53 +0200
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-19 23:28:53 +0200
commit4fd677cec39e5621d16bc2c63926b803b31582e3 (patch)
treeb1ed7c7544c1a8a721308d67c908e0f3cd758486 /src/reclaim/reclaim_api.c
parent0f75e5c54c6e6c9087cf565539266514abd67e98 (diff)
downloadgnunet-4fd677cec39e5621d16bc2c63926b803b31582e3.tar.gz
gnunet-4fd677cec39e5621d16bc2c63926b803b31582e3.zip
renamed identity-provider subsystem to reclaim
Diffstat (limited to 'src/reclaim/reclaim_api.c')
-rw-r--r--src/reclaim/reclaim_api.c1383
1 files changed, 1383 insertions, 0 deletions
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
new file mode 100644
index 000000000..3f1584ccd
--- /dev/null
+++ b/src/reclaim/reclaim_api.c
@@ -0,0 +1,1383 @@
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
19/**
20 * @file reclaim/reclaim_api.c
21 * @brief api to interact with the reclaim service
22 * @author Martin Schanzenbach
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_constants.h"
27#include "gnunet_protocols.h"
28#include "gnunet_mq_lib.h"
29#include "gnunet_reclaim_service.h"
30#include "gnunet_reclaim_attribute_lib.h"
31#include "reclaim.h"
32
33#define LOG(kind,...) GNUNET_log_from (kind, "reclaim-api",__VA_ARGS__)
34
35
36/**
37 * Handle for an operation with the service.
38 */
39struct GNUNET_RECLAIM_Operation
40{
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 * Revocation result callback
75 */
76 GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
77
78 /**
79 * Ticket result callback
80 */
81 GNUNET_RECLAIM_TicketCallback tr_cb;
82
83 /**
84 * Envelope with the message for this queue entry.
85 */
86 struct GNUNET_MQ_Envelope *env;
87
88 /**
89 * request id
90 */
91 uint32_t r_id;
92
93 /**
94 * Closure for @e cont or @e cb.
95 */
96 void *cls;
97
98};
99
100/**
101 * Handle for a ticket iterator operation
102 */
103struct GNUNET_RECLAIM_TicketIterator
104{
105
106 /**
107 * Kept in a DLL.
108 */
109 struct GNUNET_RECLAIM_TicketIterator *next;
110
111 /**
112 * Kept in a DLL.
113 */
114 struct GNUNET_RECLAIM_TicketIterator *prev;
115
116 /**
117 * Main handle to access the idp.
118 */
119 struct GNUNET_RECLAIM_Handle *h;
120
121 /**
122 * Function to call on completion.
123 */
124 GNUNET_SCHEDULER_TaskCallback finish_cb;
125
126 /**
127 * Closure for @e error_cb.
128 */
129 void *finish_cb_cls;
130
131 /**
132 * The continuation to call with the results
133 */
134 GNUNET_RECLAIM_TicketCallback tr_cb;
135
136 /**
137 * Closure for @e tr_cb.
138 */
139 void *cls;
140
141 /**
142 * Function to call on errors.
143 */
144 GNUNET_SCHEDULER_TaskCallback error_cb;
145
146 /**
147 * Closure for @e error_cb.
148 */
149 void *error_cb_cls;
150
151 /**
152 * Envelope of the message to send to the service, if not yet
153 * sent.
154 */
155 struct GNUNET_MQ_Envelope *env;
156
157 /**
158 * The operation id this zone iteration operation has
159 */
160 uint32_t r_id;
161
162};
163
164
165/**
166 * Handle for a attribute iterator operation
167 */
168struct GNUNET_RECLAIM_AttributeIterator
169{
170
171 /**
172 * Kept in a DLL.
173 */
174 struct GNUNET_RECLAIM_AttributeIterator *next;
175
176 /**
177 * Kept in a DLL.
178 */
179 struct GNUNET_RECLAIM_AttributeIterator *prev;
180
181 /**
182 * Main handle to access the idp.
183 */
184 struct GNUNET_RECLAIM_Handle *h;
185
186 /**
187 * Function to call on completion.
188 */
189 GNUNET_SCHEDULER_TaskCallback finish_cb;
190
191 /**
192 * Closure for @e error_cb.
193 */
194 void *finish_cb_cls;
195
196 /**
197 * The continuation to call with the results
198 */
199 GNUNET_RECLAIM_AttributeResult proc;
200
201 /**
202 * Closure for @e proc.
203 */
204 void *proc_cls;
205
206 /**
207 * Function to call on errors.
208 */
209 GNUNET_SCHEDULER_TaskCallback error_cb;
210
211 /**
212 * Closure for @e error_cb.
213 */
214 void *error_cb_cls;
215
216 /**
217 * Envelope of the message to send to the service, if not yet
218 * sent.
219 */
220 struct GNUNET_MQ_Envelope *env;
221
222 /**
223 * Private key of the zone.
224 */
225 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
226
227 /**
228 * The operation id this zone iteration operation has
229 */
230 uint32_t r_id;
231
232};
233
234
235/**
236 * Handle for the service.
237 */
238struct GNUNET_RECLAIM_Handle
239{
240 /**
241 * Configuration to use.
242 */
243 const struct GNUNET_CONFIGURATION_Handle *cfg;
244
245 /**
246 * Socket (if available).
247 */
248 struct GNUNET_CLIENT_Connection *client;
249
250 /**
251 * Closure for 'cb'.
252 */
253 void *cb_cls;
254
255 /**
256 * Head of active operations.
257 */
258 struct GNUNET_RECLAIM_Operation *op_head;
259
260 /**
261 * Tail of active operations.
262 */
263 struct GNUNET_RECLAIM_Operation *op_tail;
264
265 /**
266 * Head of active iterations
267 */
268 struct GNUNET_RECLAIM_AttributeIterator *it_head;
269
270 /**
271 * Tail of active iterations
272 */
273 struct GNUNET_RECLAIM_AttributeIterator *it_tail;
274
275 /**
276 * Head of active iterations
277 */
278 struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
279
280 /**
281 * Tail of active iterations
282 */
283 struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
284
285
286 /**
287 * Currently pending transmission request, or NULL for none.
288 */
289 struct GNUNET_CLIENT_TransmitHandle *th;
290
291 /**
292 * Task doing exponential back-off trying to reconnect.
293 */
294 struct GNUNET_SCHEDULER_Task * reconnect_task;
295
296 /**
297 * Time for next connect retry.
298 */
299 struct GNUNET_TIME_Relative reconnect_backoff;
300
301 /**
302 * Connection to service (if available).
303 */
304 struct GNUNET_MQ_Handle *mq;
305
306 /**
307 * Request Id generator. Incremented by one for each request.
308 */
309 uint32_t r_id_gen;
310
311 /**
312 * Are we polling for incoming messages right now?
313 */
314 int in_receive;
315
316};
317
318/**
319 * Try again to connect to the service.
320 *
321 * @param h handle to the reclaim service.
322 */
323static void
324reconnect (struct GNUNET_RECLAIM_Handle *h);
325
326/**
327 * Reconnect
328 *
329 * @param cls the handle
330 */
331static void
332reconnect_task (void *cls)
333{
334 struct GNUNET_RECLAIM_Handle *handle = cls;
335
336 handle->reconnect_task = NULL;
337 reconnect (handle);
338}
339
340
341/**
342 * Disconnect from service and then reconnect.
343 *
344 * @param handle our service
345 */
346static void
347force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
348{
349 GNUNET_MQ_destroy (handle->mq);
350 handle->mq = NULL;
351 handle->reconnect_backoff
352 = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
353 handle->reconnect_task
354 = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
355 &reconnect_task,
356 handle);
357}
358
359/**
360 * Free @a it.
361 *
362 * @param it entry to free
363 */
364static void
365free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
366{
367 struct GNUNET_RECLAIM_Handle *h = it->h;
368
369 GNUNET_CONTAINER_DLL_remove (h->it_head,
370 h->it_tail,
371 it);
372 if (NULL != it->env)
373 GNUNET_MQ_discard (it->env);
374 GNUNET_free (it);
375}
376
377static void
378free_op (struct GNUNET_RECLAIM_Operation* op)
379{
380 if (NULL == op)
381 return;
382 if (NULL != op->env)
383 GNUNET_MQ_discard (op->env);
384 GNUNET_free(op);
385}
386
387
388/**
389 * Generic error handler, called with the appropriate error code and
390 * the same closure specified at the creation of the message queue.
391 * Not every message queue implementation supports an error handler.
392 *
393 * @param cls closure with the `struct GNUNET_GNS_Handle *`
394 * @param error error code
395 */
396static void
397mq_error_handler (void *cls,
398 enum GNUNET_MQ_Error error)
399{
400 struct GNUNET_RECLAIM_Handle *handle = cls;
401 force_reconnect (handle);
402}
403
404/**
405 * Handle an incoming message of type
406 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
407 *
408 * @param cls
409 * @param msg the message we received
410 */
411static void
412handle_attribute_store_response (void *cls,
413 const struct AttributeStoreResultMessage *msg)
414{
415 struct GNUNET_RECLAIM_Handle *h = cls;
416 struct GNUNET_RECLAIM_Operation *op;
417 uint32_t r_id = ntohl (msg->id);
418 int res;
419 const char *emsg;
420
421 for (op = h->op_head; NULL != op; op = op->next)
422 if (op->r_id == r_id)
423 break;
424 if (NULL == op)
425 return;
426
427 res = ntohl (msg->op_result);
428 LOG (GNUNET_ERROR_TYPE_DEBUG,
429 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
430 res);
431
432 /* TODO: add actual error message to response... */
433 if (GNUNET_SYSERR == res)
434 emsg = _("failed to store record\n");
435 else
436 emsg = NULL;
437 if (NULL != op->as_cb)
438 op->as_cb (op->cls,
439 res,
440 emsg);
441 GNUNET_CONTAINER_DLL_remove (h->op_head,
442 h->op_tail,
443 op);
444 free_op (op);
445
446}
447
448
449/**
450 * Handle an incoming message of type
451 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
452 *
453 * @param cls
454 * @param msg the message we received
455 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
456 */
457static int
458check_consume_ticket_result (void *cls,
459 const struct ConsumeTicketResultMessage *msg)
460{
461 size_t msg_len;
462 size_t attrs_len;
463
464 msg_len = ntohs (msg->header.size);
465 attrs_len = ntohs (msg->attrs_len);
466 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len)
467 {
468 GNUNET_break (0);
469 return GNUNET_SYSERR;
470 }
471 return GNUNET_OK;
472}
473
474
475/**
476 * Handle an incoming message of type
477 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
478 *
479 * @param cls
480 * @param msg the message we received
481 */
482static void
483handle_consume_ticket_result (void *cls,
484 const struct ConsumeTicketResultMessage *msg)
485{
486 struct GNUNET_RECLAIM_Handle *h = cls;
487 struct GNUNET_RECLAIM_Operation *op;
488 size_t attrs_len;
489 uint32_t r_id = ntohl (msg->id);
490
491 attrs_len = ntohs (msg->attrs_len);
492 LOG (GNUNET_ERROR_TYPE_DEBUG,
493 "Processing attribute result.\n");
494
495
496 for (op = h->op_head; NULL != op; op = op->next)
497 if (op->r_id == r_id)
498 break;
499 if (NULL == op)
500 return;
501
502 {
503 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
504 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
505 attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&msg[1],
506 attrs_len);
507 if (NULL != op->ar_cb)
508 {
509 if (NULL == attrs)
510 {
511 op->ar_cb (op->cls,
512 &msg->identity,
513 NULL);
514 }
515 else
516 {
517 for (le = attrs->list_head; NULL != le; le = le->next)
518 op->ar_cb (op->cls,
519 &msg->identity,
520 le->claim);
521 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
522 }
523 }
524 if (NULL != op)
525 {
526 op->ar_cb (op->cls,
527 NULL,
528 NULL);
529 GNUNET_CONTAINER_DLL_remove (h->op_head,
530 h->op_tail,
531 op);
532 free_op (op);
533 }
534 return;
535 }
536 GNUNET_assert (0);
537}
538
539
540/**
541 * Handle an incoming message of type
542 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
543 *
544 * @param cls
545 * @param msg the message we received
546 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
547 */
548static int
549check_attribute_result (void *cls,
550 const struct AttributeResultMessage *msg)
551{
552 size_t msg_len;
553 size_t attr_len;
554
555 msg_len = ntohs (msg->header.size);
556 attr_len = ntohs (msg->attr_len);
557 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
558 {
559 GNUNET_break (0);
560 return GNUNET_SYSERR;
561 }
562 return GNUNET_OK;
563}
564
565
566/**
567 * Handle an incoming message of type
568 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
569 *
570 * @param cls
571 * @param msg the message we received
572 */
573static void
574handle_attribute_result (void *cls,
575 const struct AttributeResultMessage *msg)
576{
577 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
578 struct GNUNET_RECLAIM_Handle *h = cls;
579 struct GNUNET_RECLAIM_AttributeIterator *it;
580 struct GNUNET_RECLAIM_Operation *op;
581 size_t attr_len;
582 uint32_t r_id = ntohl (msg->id);
583
584 attr_len = ntohs (msg->attr_len);
585 LOG (GNUNET_ERROR_TYPE_DEBUG,
586 "Processing attribute result.\n");
587
588
589 for (it = h->it_head; NULL != it; it = it->next)
590 if (it->r_id == r_id)
591 break;
592 for (op = h->op_head; NULL != op; op = op->next)
593 if (op->r_id == r_id)
594 break;
595 if ((NULL == it) && (NULL == op))
596 return;
597
598 if ( (0 == (memcmp (&msg->identity,
599 &identity_dummy,
600 sizeof (identity_dummy)))) )
601 {
602 if ((NULL == it) && (NULL == op))
603 {
604 GNUNET_break (0);
605 force_reconnect (h);
606 return;
607 }
608 if (NULL != it)
609 {
610 if (NULL != it->finish_cb)
611 it->finish_cb (it->finish_cb_cls);
612 free_it (it);
613 }
614 if (NULL != op)
615 {
616 if (NULL != op->ar_cb)
617 op->ar_cb (op->cls,
618 NULL,
619 NULL);
620 GNUNET_CONTAINER_DLL_remove (h->op_head,
621 h->op_tail,
622 op);
623 free_op (op);
624
625 }
626 return;
627 }
628
629 {
630 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
631 attr = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&msg[1],
632 attr_len);
633 if (NULL != it)
634 {
635 if (NULL != it->proc)
636 it->proc (it->proc_cls,
637 &msg->identity,
638 attr);
639 } else if (NULL != op)
640 {
641 if (NULL != op->ar_cb)
642 op->ar_cb (op->cls,
643 &msg->identity,
644 attr);
645
646 }
647 GNUNET_free (attr);
648 return;
649 }
650 GNUNET_assert (0);
651}
652
653/**
654 * Handle an incoming message of type
655 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
656 *
657 * @param cls
658 * @param msg the message we received
659 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
660 */
661static int
662check_ticket_result (void *cls,
663 const struct TicketResultMessage *msg)
664{
665 size_t msg_len;
666
667 msg_len = ntohs (msg->header.size);
668 if (msg_len < sizeof (struct TicketResultMessage))
669 {
670 GNUNET_break (0);
671 return GNUNET_SYSERR;
672 }
673 return GNUNET_OK;
674}
675
676
677
678/**
679 * Handle an incoming message of type
680 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
681 *
682 * @param cls
683 * @param msg the message we received
684 */
685static void
686handle_ticket_result (void *cls,
687 const struct TicketResultMessage *msg)
688{
689 struct GNUNET_RECLAIM_Handle *handle = cls;
690 struct GNUNET_RECLAIM_Operation *op;
691 struct GNUNET_RECLAIM_TicketIterator *it;
692 const struct GNUNET_RECLAIM_Ticket *ticket;
693 uint32_t r_id = ntohl (msg->id);
694 size_t msg_len;
695
696 for (op = handle->op_head; NULL != op; op = op->next)
697 if (op->r_id == r_id)
698 break;
699 for (it = handle->ticket_it_head; NULL != it; it = it->next)
700 if (it->r_id == r_id)
701 break;
702 if ((NULL == op) && (NULL == it))
703 return;
704 msg_len = ntohs (msg->header.size);
705 if (NULL != op)
706 {
707 GNUNET_CONTAINER_DLL_remove (handle->op_head,
708 handle->op_tail,
709 op);
710 if (msg_len == sizeof (struct TicketResultMessage))
711 {
712 if (NULL != op->tr_cb)
713 op->tr_cb (op->cls, NULL);
714 } else {
715 ticket = (struct GNUNET_RECLAIM_Ticket *)&msg[1];
716 if (NULL != op->tr_cb)
717 op->tr_cb (op->cls, ticket);
718 }
719 free_op (op);
720 return;
721 } else if (NULL != it) {
722 if (msg_len == sizeof (struct TicketResultMessage))
723 {
724 if (NULL != it->tr_cb)
725 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
726 handle->ticket_it_tail,
727 it);
728 it->finish_cb (it->finish_cb_cls);
729 GNUNET_free (it);
730 } else {
731 ticket = (struct GNUNET_RECLAIM_Ticket *)&msg[1];
732 if (NULL != it->tr_cb)
733 it->tr_cb (it->cls, ticket);
734 }
735 return;
736 }
737 GNUNET_break (0);
738}
739
740
741/**
742 * Handle an incoming message of type
743 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
744 *
745 * @param cls
746 * @param msg the message we received
747 */
748static void
749handle_revoke_ticket_result (void *cls,
750 const struct RevokeTicketResultMessage *msg)
751{
752 struct GNUNET_RECLAIM_Handle *h = cls;
753 struct GNUNET_RECLAIM_Operation *op;
754 uint32_t r_id = ntohl (msg->id);
755 int32_t success;
756
757 LOG (GNUNET_ERROR_TYPE_DEBUG,
758 "Processing revocation result.\n");
759
760
761 for (op = h->op_head; NULL != op; op = op->next)
762 if (op->r_id == r_id)
763 break;
764 if (NULL == op)
765 return;
766 success = ntohl (msg->success);
767 {
768 if (NULL != op->rvk_cb)
769 {
770 op->rvk_cb (op->cls,
771 success,
772 NULL);
773 }
774 GNUNET_CONTAINER_DLL_remove (h->op_head,
775 h->op_tail,
776 op);
777 free_op (op);
778 return;
779 }
780 GNUNET_assert (0);
781}
782
783
784
785/**
786 * Try again to connect to the service.
787 *
788 * @param h handle to the reclaim service.
789 */
790static void
791reconnect (struct GNUNET_RECLAIM_Handle *h)
792{
793 struct GNUNET_MQ_MessageHandler handlers[] = {
794 GNUNET_MQ_hd_fixed_size (attribute_store_response,
795 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE,
796 struct AttributeStoreResultMessage,
797 h),
798 GNUNET_MQ_hd_var_size (attribute_result,
799 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
800 struct AttributeResultMessage,
801 h),
802 GNUNET_MQ_hd_var_size (ticket_result,
803 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
804 struct TicketResultMessage,
805 h),
806 GNUNET_MQ_hd_var_size (consume_ticket_result,
807 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
808 struct ConsumeTicketResultMessage,
809 h),
810 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
811 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
812 struct RevokeTicketResultMessage,
813 h),
814 GNUNET_MQ_handler_end ()
815 };
816 struct GNUNET_RECLAIM_Operation *op;
817
818 GNUNET_assert (NULL == h->mq);
819 LOG (GNUNET_ERROR_TYPE_DEBUG,
820 "Connecting to reclaim service.\n");
821
822 h->mq = GNUNET_CLIENT_connect (h->cfg,
823 "reclaim",
824 handlers,
825 &mq_error_handler,
826 h);
827 if (NULL == h->mq)
828 return;
829 for (op = h->op_head; NULL != op; op = op->next)
830 GNUNET_MQ_send_copy (h->mq,
831 op->env);
832}
833
834
835/**
836 * Connect to the reclaim service.
837 *
838 * @param cfg the configuration to use
839 * @return handle to use
840 */
841struct GNUNET_RECLAIM_Handle *
842GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
843{
844 struct GNUNET_RECLAIM_Handle *h;
845
846 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
847 h->cfg = cfg;
848 reconnect (h);
849 if (NULL == h->mq)
850 {
851 GNUNET_free (h);
852 return NULL;
853 }
854 return h;
855}
856
857
858/**
859 * Cancel an operation. Note that the operation MAY still
860 * be executed; this merely cancels the continuation; if the request
861 * was already transmitted, the service may still choose to complete
862 * the operation.
863 *
864 * @param op operation to cancel
865 */
866void
867GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
868{
869 struct GNUNET_RECLAIM_Handle *h = op->h;
870
871 GNUNET_CONTAINER_DLL_remove (h->op_head,
872 h->op_tail,
873 op);
874 free_op (op);
875}
876
877
878/**
879 * Disconnect from service
880 *
881 * @param h handle to destroy
882 */
883void
884GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
885{
886 GNUNET_assert (NULL != h);
887 if (NULL != h->mq)
888 {
889 GNUNET_MQ_destroy (h->mq);
890 h->mq = NULL;
891 }
892 if (NULL != h->reconnect_task)
893 {
894 GNUNET_SCHEDULER_cancel (h->reconnect_task);
895 h->reconnect_task = NULL;
896 }
897 GNUNET_assert (NULL == h->op_head);
898 GNUNET_free (h);
899}
900
901/**
902 * Store an attribute. If the attribute is already present,
903 * it is replaced with the new attribute.
904 *
905 * @param h handle to the reclaim
906 * @param pkey private key of the identity
907 * @param attr the attribute value
908 * @param exp_interval the relative expiration interval for the attribute
909 * @param cont continuation to call when done
910 * @param cont_cls closure for @a cont
911 * @return handle to abort the request
912 */
913struct GNUNET_RECLAIM_Operation *
914GNUNET_RECLAIM_attribute_store (struct GNUNET_RECLAIM_Handle *h,
915 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
916 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
917 const struct GNUNET_TIME_Relative *exp_interval,
918 GNUNET_RECLAIM_ContinuationWithStatus cont,
919 void *cont_cls)
920{
921 struct GNUNET_RECLAIM_Operation *op;
922 struct AttributeStoreMessage *sam;
923 size_t attr_len;
924
925 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
926 op->h = h;
927 op->as_cb = cont;
928 op->cls = cont_cls;
929 op->r_id = h->r_id_gen++;
930 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
931 h->op_tail,
932 op);
933 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (attr);
934 op->env = GNUNET_MQ_msg_extra (sam,
935 attr_len,
936 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
937 sam->identity = *pkey;
938 sam->id = htonl (op->r_id);
939 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
940
941 GNUNET_RECLAIM_ATTRIBUTE_serialize (attr,
942 (char*)&sam[1]);
943
944 sam->attr_len = htons (attr_len);
945 if (NULL != h->mq)
946 GNUNET_MQ_send_copy (h->mq,
947 op->env);
948 return op;
949
950}
951
952
953/**
954 * List all attributes for a local identity.
955 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
956 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
957 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
958 * immediately, and then again after
959 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
960 *
961 * On error (disconnect), @a error_cb will be invoked.
962 * On normal completion, @a finish_cb proc will be
963 * invoked.
964 *
965 * @param h handle to the idp
966 * @param identity identity to access
967 * @param error_cb function to call on error (i.e. disconnect),
968 * the handle is afterwards invalid
969 * @param error_cb_cls closure for @a error_cb
970 * @param proc function to call on each attribute; it
971 * will be called repeatedly with a value (if available)
972 * @param proc_cls closure for @a proc
973 * @param finish_cb function to call on completion
974 * the handle is afterwards invalid
975 * @param finish_cb_cls closure for @a finish_cb
976 * @return an iterator handle to use for iteration
977 */
978struct GNUNET_RECLAIM_AttributeIterator *
979GNUNET_RECLAIM_get_attributes_start (struct GNUNET_RECLAIM_Handle *h,
980 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
981 GNUNET_SCHEDULER_TaskCallback error_cb,
982 void *error_cb_cls,
983 GNUNET_RECLAIM_AttributeResult proc,
984 void *proc_cls,
985 GNUNET_SCHEDULER_TaskCallback finish_cb,
986 void *finish_cb_cls)
987{
988 struct GNUNET_RECLAIM_AttributeIterator *it;
989 struct GNUNET_MQ_Envelope *env;
990 struct AttributeIterationStartMessage *msg;
991 uint32_t rid;
992
993 rid = h->r_id_gen++;
994 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
995 it->h = h;
996 it->error_cb = error_cb;
997 it->error_cb_cls = error_cb_cls;
998 it->finish_cb = finish_cb;
999 it->finish_cb_cls = finish_cb_cls;
1000 it->proc = proc;
1001 it->proc_cls = proc_cls;
1002 it->r_id = rid;
1003 it->identity = *identity;
1004 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
1005 h->it_tail,
1006 it);
1007 env = GNUNET_MQ_msg (msg,
1008 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
1009 msg->id = htonl (rid);
1010 msg->identity = *identity;
1011 if (NULL == h->mq)
1012 it->env = env;
1013 else
1014 GNUNET_MQ_send (h->mq,
1015 env);
1016 return it;
1017}
1018
1019
1020/**
1021 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
1022 * for the next record.
1023 *
1024 * @param it the iterator
1025 */
1026void
1027GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
1028{
1029 struct GNUNET_RECLAIM_Handle *h = it->h;
1030 struct AttributeIterationNextMessage *msg;
1031 struct GNUNET_MQ_Envelope *env;
1032
1033 env = GNUNET_MQ_msg (msg,
1034 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
1035 msg->id = htonl (it->r_id);
1036 GNUNET_MQ_send (h->mq,
1037 env);
1038}
1039
1040
1041/**
1042 * Stops iteration and releases the idp handle for further calls. Must
1043 * be called on any iteration that has not yet completed prior to calling
1044 * #GNUNET_RECLAIM_disconnect.
1045 *
1046 * @param it the iterator
1047 */
1048void
1049GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
1050{
1051 struct GNUNET_RECLAIM_Handle *h = it->h;
1052 struct GNUNET_MQ_Envelope *env;
1053 struct AttributeIterationStopMessage *msg;
1054
1055 if (NULL != h->mq)
1056 {
1057 env = GNUNET_MQ_msg (msg,
1058 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
1059 msg->id = htonl (it->r_id);
1060 GNUNET_MQ_send (h->mq,
1061 env);
1062 }
1063 free_it (it);
1064}
1065
1066
1067/** TODO
1068 * Issues a ticket to another identity. The identity may use
1069 * @GNUNET_RECLAIM_authorization_ticket_consume to consume the ticket
1070 * and retrieve the attributes specified in the AttributeList.
1071 *
1072 * @param h the reclaim to use
1073 * @param iss the issuing identity
1074 * @param rp the subject of the ticket (the relying party)
1075 * @param attrs the attributes that the relying party is given access to
1076 * @param cb the callback
1077 * @param cb_cls the callback closure
1078 * @return handle to abort the operation
1079 */
1080struct GNUNET_RECLAIM_Operation *
1081GNUNET_RECLAIM_ticket_issue (struct GNUNET_RECLAIM_Handle *h,
1082 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1083 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1084 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
1085 GNUNET_RECLAIM_TicketCallback cb,
1086 void *cb_cls)
1087{
1088 struct GNUNET_RECLAIM_Operation *op;
1089 struct IssueTicketMessage *tim;
1090 size_t attr_len;
1091
1092 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1093 op->h = h;
1094 op->tr_cb = cb;
1095 op->cls = cb_cls;
1096 op->r_id = h->r_id_gen++;
1097 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1098 h->op_tail,
1099 op);
1100 attr_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
1101 op->env = GNUNET_MQ_msg_extra (tim,
1102 attr_len,
1103 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1104 tim->identity = *iss;
1105 tim->rp = *rp;
1106 tim->id = htonl (op->r_id);
1107
1108 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs,
1109 (char*)&tim[1]);
1110
1111 tim->attr_len = htons (attr_len);
1112 if (NULL != h->mq)
1113 GNUNET_MQ_send_copy (h->mq,
1114 op->env);
1115 return op;
1116}
1117
1118/**
1119 * Consumes an issued ticket. The ticket is persisted
1120 * and used to retrieve identity information from the issuer
1121 *
1122 * @param h the reclaim to use
1123 * @param identity the identity that is the subject of the issued ticket (the relying party)
1124 * @param ticket the issued ticket to consume
1125 * @param cb the callback to call
1126 * @param cb_cls the callback closure
1127 * @return handle to abort the operation
1128 */
1129struct GNUNET_RECLAIM_Operation *
1130GNUNET_RECLAIM_ticket_consume (struct GNUNET_RECLAIM_Handle *h,
1131 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1132 const struct GNUNET_RECLAIM_Ticket *ticket,
1133 GNUNET_RECLAIM_AttributeResult cb,
1134 void *cb_cls)
1135{
1136 struct GNUNET_RECLAIM_Operation *op;
1137 struct ConsumeTicketMessage *ctm;
1138
1139 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1140 op->h = h;
1141 op->ar_cb = cb;
1142 op->cls = cb_cls;
1143 op->r_id = h->r_id_gen++;
1144 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1145 h->op_tail,
1146 op);
1147 op->env = GNUNET_MQ_msg_extra (ctm,
1148 sizeof (const struct GNUNET_RECLAIM_Ticket),
1149 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1150 ctm->identity = *identity;
1151 ctm->id = htonl (op->r_id);
1152
1153 GNUNET_memcpy ((char*)&ctm[1],
1154 ticket,
1155 sizeof (const struct GNUNET_RECLAIM_Ticket));
1156
1157 if (NULL != h->mq)
1158 GNUNET_MQ_send_copy (h->mq,
1159 op->env);
1160 return op;
1161
1162}
1163
1164
1165/**
1166 * Lists all tickets that have been issued to remote
1167 * identites (relying parties)
1168 *
1169 * @param h the reclaim to use
1170 * @param identity the issuing identity
1171 * @param error_cb function to call on error (i.e. disconnect),
1172 * the handle is afterwards invalid
1173 * @param error_cb_cls closure for @a error_cb
1174 * @param proc function to call on each ticket; it
1175 * will be called repeatedly with a value (if available)
1176 * @param proc_cls closure for @a proc
1177 * @param finish_cb function to call on completion
1178 * the handle is afterwards invalid
1179 * @param finish_cb_cls closure for @a finish_cb
1180 * @return an iterator handle to use for iteration
1181 */
1182struct GNUNET_RECLAIM_TicketIterator *
1183GNUNET_RECLAIM_ticket_iteration_start (struct GNUNET_RECLAIM_Handle *h,
1184 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1185 GNUNET_SCHEDULER_TaskCallback error_cb,
1186 void *error_cb_cls,
1187 GNUNET_RECLAIM_TicketCallback proc,
1188 void *proc_cls,
1189 GNUNET_SCHEDULER_TaskCallback finish_cb,
1190 void *finish_cb_cls)
1191{
1192 struct GNUNET_RECLAIM_TicketIterator *it;
1193 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1194 struct GNUNET_MQ_Envelope *env;
1195 struct TicketIterationStartMessage *msg;
1196 uint32_t rid;
1197
1198 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1199 &identity_pub);
1200 rid = h->r_id_gen++;
1201 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1202 it->h = h;
1203 it->error_cb = error_cb;
1204 it->error_cb_cls = error_cb_cls;
1205 it->finish_cb = finish_cb;
1206 it->finish_cb_cls = finish_cb_cls;
1207 it->tr_cb = proc;
1208 it->cls = proc_cls;
1209 it->r_id = rid;
1210 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1211 h->ticket_it_tail,
1212 it);
1213 env = GNUNET_MQ_msg (msg,
1214 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1215 msg->id = htonl (rid);
1216 msg->identity = identity_pub;
1217 msg->is_audience = htonl (GNUNET_NO);
1218 if (NULL == h->mq)
1219 it->env = env;
1220 else
1221 GNUNET_MQ_send (h->mq,
1222 env);
1223 return it;
1224
1225}
1226
1227
1228/**
1229 * Lists all tickets that have been issued to remote
1230 * identites (relying parties)
1231 *
1232 * @param h the reclaim to use
1233 * @param identity the issuing identity
1234 * @param error_cb function to call on error (i.e. disconnect),
1235 * the handle is afterwards invalid
1236 * @param error_cb_cls closure for @a error_cb
1237 * @param proc function to call on each ticket; it
1238 * will be called repeatedly with a value (if available)
1239 * @param proc_cls closure for @a proc
1240 * @param finish_cb function to call on completion
1241 * the handle is afterwards invalid
1242 * @param finish_cb_cls closure for @a finish_cb
1243 * @return an iterator handle to use for iteration
1244 */
1245struct GNUNET_RECLAIM_TicketIterator *
1246GNUNET_RECLAIM_ticket_iteration_start_rp (struct GNUNET_RECLAIM_Handle *h,
1247 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1248 GNUNET_SCHEDULER_TaskCallback error_cb,
1249 void *error_cb_cls,
1250 GNUNET_RECLAIM_TicketCallback proc,
1251 void *proc_cls,
1252 GNUNET_SCHEDULER_TaskCallback finish_cb,
1253 void *finish_cb_cls)
1254{
1255 struct GNUNET_RECLAIM_TicketIterator *it;
1256 struct GNUNET_MQ_Envelope *env;
1257 struct TicketIterationStartMessage *msg;
1258 uint32_t rid;
1259
1260 rid = h->r_id_gen++;
1261 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1262 it->h = h;
1263 it->error_cb = error_cb;
1264 it->error_cb_cls = error_cb_cls;
1265 it->finish_cb = finish_cb;
1266 it->finish_cb_cls = finish_cb_cls;
1267 it->tr_cb = proc;
1268 it->cls = proc_cls;
1269 it->r_id = rid;
1270 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1271 h->ticket_it_tail,
1272 it);
1273 env = GNUNET_MQ_msg (msg,
1274 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1275 msg->id = htonl (rid);
1276 msg->identity = *identity;
1277 msg->is_audience = htonl (GNUNET_YES);
1278 if (NULL == h->mq)
1279 it->env = env;
1280 else
1281 GNUNET_MQ_send (h->mq,
1282 env);
1283 return it;
1284
1285
1286}
1287
1288/**
1289 * Calls the record processor specified in #GNUNET_RECLAIM_ticket_iteration_start
1290 * for the next record.
1291 *
1292 * @param it the iterator
1293 */
1294void
1295GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1296{
1297 struct GNUNET_RECLAIM_Handle *h = it->h;
1298 struct TicketIterationNextMessage *msg;
1299 struct GNUNET_MQ_Envelope *env;
1300
1301 env = GNUNET_MQ_msg (msg,
1302 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1303 msg->id = htonl (it->r_id);
1304 GNUNET_MQ_send (h->mq,
1305 env);
1306}
1307
1308
1309/**
1310 * Stops iteration and releases the idp handle for further calls. Must
1311 * be called on any iteration that has not yet completed prior to calling
1312 * #GNUNET_RECLAIM_disconnect.
1313 *
1314 * @param it the iterator
1315 */
1316void
1317GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1318{
1319 struct GNUNET_RECLAIM_Handle *h = it->h;
1320 struct GNUNET_MQ_Envelope *env;
1321 struct TicketIterationStopMessage *msg;
1322
1323 if (NULL != h->mq)
1324 {
1325 env = GNUNET_MQ_msg (msg,
1326 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1327 msg->id = htonl (it->r_id);
1328 GNUNET_MQ_send (h->mq,
1329 env);
1330 }
1331 GNUNET_free (it);
1332}
1333
1334/**
1335 * Revoked an issued ticket. The relying party will be unable to retrieve
1336 * updated attributes.
1337 *
1338 * @param h the reclaim to use
1339 * @param identity the issuing identity
1340 * @param ticket the ticket to revoke
1341 * @param cb the callback
1342 * @param cb_cls the callback closure
1343 * @return handle to abort the operation
1344 */
1345struct GNUNET_RECLAIM_Operation *
1346GNUNET_RECLAIM_ticket_revoke (struct GNUNET_RECLAIM_Handle *h,
1347 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1348 const struct GNUNET_RECLAIM_Ticket *ticket,
1349 GNUNET_RECLAIM_ContinuationWithStatus cb,
1350 void *cb_cls)
1351{
1352 struct GNUNET_RECLAIM_Operation *op;
1353 struct RevokeTicketMessage *msg;
1354 uint32_t rid;
1355
1356 rid = h->r_id_gen++;
1357 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1358 op->h = h;
1359 op->rvk_cb = cb;
1360 op->cls = cb_cls;
1361 op->r_id = rid;
1362 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1363 h->op_tail,
1364 op);
1365 op->env = GNUNET_MQ_msg_extra (msg,
1366 sizeof (struct GNUNET_RECLAIM_Ticket),
1367 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1368 msg->id = htonl (rid);
1369 msg->identity = *identity;
1370 GNUNET_memcpy (&msg[1],
1371 ticket,
1372 sizeof (struct GNUNET_RECLAIM_Ticket));
1373 if (NULL != h->mq) {
1374 GNUNET_MQ_send (h->mq,
1375 op->env);
1376 op->env = NULL;
1377 }
1378 return op;
1379}
1380
1381
1382
1383/* end of reclaim_api.c */