diff options
Diffstat (limited to 'src/reclaim/gnunet-service-reclaim.c')
-rw-r--r-- | src/reclaim/gnunet-service-reclaim.c | 2786 |
1 files changed, 2786 insertions, 0 deletions
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c new file mode 100644 index 000000000..3321a79d8 --- /dev/null +++ b/src/reclaim/gnunet-service-reclaim.c | |||
@@ -0,0 +1,2786 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2015 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 | * @author Martin Schanzenbach | ||
20 | * @file src/reclaim/gnunet-service-reclaim.c | ||
21 | * @brief reclaim Service | ||
22 | * | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_util_lib.h" | ||
26 | #include "gnunet_constants.h" | ||
27 | #include "gnunet_protocols.h" | ||
28 | #include "gnunet_identity_service.h" | ||
29 | #include "gnunet_gnsrecord_lib.h" | ||
30 | #include "gnunet_namestore_service.h" | ||
31 | #include "gnunet_abe_lib.h" | ||
32 | #include "gnunet_credential_service.h" | ||
33 | #include "gnunet_statistics_service.h" | ||
34 | #include "gnunet_gns_service.h" | ||
35 | #include "gnunet_reclaim_plugin.h" | ||
36 | #include "gnunet_reclaim_attribute_lib.h" | ||
37 | #include "gnunet_signatures.h" | ||
38 | #include "reclaim.h" | ||
39 | |||
40 | /** | ||
41 | * First pass state | ||
42 | */ | ||
43 | #define STATE_INIT 0 | ||
44 | |||
45 | /** | ||
46 | * Normal operation state | ||
47 | */ | ||
48 | #define STATE_POST_INIT 1 | ||
49 | |||
50 | /** | ||
51 | * Minimum interval between updates | ||
52 | */ | ||
53 | #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES | ||
54 | |||
55 | /** | ||
56 | * Standard token expiration time | ||
57 | */ | ||
58 | #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS | ||
59 | |||
60 | /** | ||
61 | * Identity handle | ||
62 | */ | ||
63 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
64 | |||
65 | /** | ||
66 | * Database handle | ||
67 | */ | ||
68 | static struct GNUNET_RECLAIM_PluginFunctions *TKT_database; | ||
69 | |||
70 | /** | ||
71 | * Name of DB plugin | ||
72 | */ | ||
73 | static char *db_lib_name; | ||
74 | |||
75 | /** | ||
76 | * Token expiration interval | ||
77 | */ | ||
78 | static struct GNUNET_TIME_Relative token_expiration_interval; | ||
79 | |||
80 | /** | ||
81 | * Namestore handle | ||
82 | */ | ||
83 | static struct GNUNET_NAMESTORE_Handle *ns_handle; | ||
84 | |||
85 | /** | ||
86 | * GNS handle | ||
87 | */ | ||
88 | static struct GNUNET_GNS_Handle *gns_handle; | ||
89 | |||
90 | /** | ||
91 | * Credential handle | ||
92 | */ | ||
93 | static struct GNUNET_CREDENTIAL_Handle *credential_handle; | ||
94 | |||
95 | /** | ||
96 | * Namestore qe | ||
97 | */ | ||
98 | static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
99 | |||
100 | /** | ||
101 | * Namestore iterator | ||
102 | */ | ||
103 | static struct GNUNET_NAMESTORE_ZoneIterator *ns_it; | ||
104 | |||
105 | /** | ||
106 | * Timeout task | ||
107 | */ | ||
108 | static struct GNUNET_SCHEDULER_Task *timeout_task; | ||
109 | |||
110 | /** | ||
111 | * Update task | ||
112 | */ | ||
113 | static struct GNUNET_SCHEDULER_Task *update_task; | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Currently processed token | ||
118 | */ | ||
119 | static struct IdentityToken *token; | ||
120 | |||
121 | /** | ||
122 | * Label for currently processed token | ||
123 | */ | ||
124 | static char* label; | ||
125 | |||
126 | /** | ||
127 | * Scopes for processed token | ||
128 | */ | ||
129 | static char* scopes; | ||
130 | |||
131 | /** | ||
132 | * Handle to the statistics service. | ||
133 | */ | ||
134 | static struct GNUNET_STATISTICS_Handle *stats; | ||
135 | |||
136 | /** | ||
137 | * Our configuration. | ||
138 | */ | ||
139 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
140 | |||
141 | /** | ||
142 | * An idp client | ||
143 | */ | ||
144 | struct IdpClient; | ||
145 | |||
146 | /** | ||
147 | * A ticket iteration operation. | ||
148 | */ | ||
149 | struct TicketIteration | ||
150 | { | ||
151 | /** | ||
152 | * DLL | ||
153 | */ | ||
154 | struct TicketIteration *next; | ||
155 | |||
156 | /** | ||
157 | * DLL | ||
158 | */ | ||
159 | struct TicketIteration *prev; | ||
160 | |||
161 | /** | ||
162 | * Client which intiated this zone iteration | ||
163 | */ | ||
164 | struct IdpClient *client; | ||
165 | |||
166 | /** | ||
167 | * Key of the identity we are iterating over. | ||
168 | */ | ||
169 | struct GNUNET_CRYPTO_EcdsaPublicKey identity; | ||
170 | |||
171 | /** | ||
172 | * Identity is audience | ||
173 | */ | ||
174 | uint32_t is_audience; | ||
175 | |||
176 | /** | ||
177 | * The operation id fot the iteration in the response for the client | ||
178 | */ | ||
179 | uint32_t r_id; | ||
180 | |||
181 | /** | ||
182 | * Offset of the iteration used to address next result of the | ||
183 | * iteration in the store | ||
184 | * | ||
185 | * Initialy set to 0 in handle_iteration_start | ||
186 | * Incremented with by every call to handle_iteration_next | ||
187 | */ | ||
188 | uint32_t offset; | ||
189 | |||
190 | }; | ||
191 | |||
192 | |||
193 | |||
194 | /** | ||
195 | * Callback after an ABE bootstrap | ||
196 | * | ||
197 | * @param cls closure | ||
198 | * @param abe_key the ABE key that exists or was created | ||
199 | */ | ||
200 | typedef void | ||
201 | (*AbeBootstrapResult) (void *cls, | ||
202 | struct GNUNET_ABE_AbeMasterKey *abe_key); | ||
203 | |||
204 | |||
205 | struct AbeBootstrapHandle | ||
206 | { | ||
207 | /** | ||
208 | * Function to call when finished | ||
209 | */ | ||
210 | AbeBootstrapResult proc; | ||
211 | |||
212 | /** | ||
213 | * Callback closure | ||
214 | */ | ||
215 | char *proc_cls; | ||
216 | |||
217 | /** | ||
218 | * Key of the zone we are iterating over. | ||
219 | */ | ||
220 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
221 | |||
222 | /** | ||
223 | * Namestore Queue Entry | ||
224 | */ | ||
225 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
226 | |||
227 | /** | ||
228 | * The issuer egos ABE master key | ||
229 | */ | ||
230 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
231 | }; | ||
232 | |||
233 | /** | ||
234 | * An attribute iteration operation. | ||
235 | */ | ||
236 | struct AttributeIterator | ||
237 | { | ||
238 | /** | ||
239 | * Next element in the DLL | ||
240 | */ | ||
241 | struct AttributeIterator *next; | ||
242 | |||
243 | /** | ||
244 | * Previous element in the DLL | ||
245 | */ | ||
246 | struct AttributeIterator *prev; | ||
247 | |||
248 | /** | ||
249 | * IDP client which intiated this zone iteration | ||
250 | */ | ||
251 | struct IdpClient *client; | ||
252 | |||
253 | /** | ||
254 | * Key of the zone we are iterating over. | ||
255 | */ | ||
256 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
257 | |||
258 | /** | ||
259 | * The issuer egos ABE master key | ||
260 | */ | ||
261 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
262 | |||
263 | /** | ||
264 | * Namestore iterator | ||
265 | */ | ||
266 | struct GNUNET_NAMESTORE_ZoneIterator *ns_it; | ||
267 | |||
268 | /** | ||
269 | * The operation id fot the zone iteration in the response for the client | ||
270 | */ | ||
271 | uint32_t request_id; | ||
272 | |||
273 | }; | ||
274 | |||
275 | |||
276 | |||
277 | /** | ||
278 | * An idp client | ||
279 | */ | ||
280 | struct IdpClient | ||
281 | { | ||
282 | |||
283 | /** | ||
284 | * The client | ||
285 | */ | ||
286 | struct GNUNET_SERVICE_Client *client; | ||
287 | |||
288 | /** | ||
289 | * Message queue for transmission to @e client | ||
290 | */ | ||
291 | struct GNUNET_MQ_Handle *mq; | ||
292 | |||
293 | /** | ||
294 | * Head of the DLL of | ||
295 | * Attribute iteration operations in | ||
296 | * progress initiated by this client | ||
297 | */ | ||
298 | struct AttributeIterator *attr_iter_head; | ||
299 | |||
300 | /** | ||
301 | * Tail of the DLL of | ||
302 | * Attribute iteration operations | ||
303 | * in progress initiated by this client | ||
304 | */ | ||
305 | struct AttributeIterator *attr_iter_tail; | ||
306 | |||
307 | /** | ||
308 | * Head of DLL of ticket iteration ops | ||
309 | */ | ||
310 | struct TicketIteration *ticket_iter_head; | ||
311 | |||
312 | /** | ||
313 | * Tail of DLL of ticket iteration ops | ||
314 | */ | ||
315 | struct TicketIteration *ticket_iter_tail; | ||
316 | |||
317 | /** | ||
318 | * Head of DLL of ticket revocation ops | ||
319 | */ | ||
320 | struct TicketRevocationHandle *revoke_op_head; | ||
321 | |||
322 | /** | ||
323 | * Tail of DLL of ticket revocation ops | ||
324 | */ | ||
325 | struct TicketRevocationHandle *revoke_op_tail; | ||
326 | |||
327 | /** | ||
328 | * Head of DLL of ticket issue ops | ||
329 | */ | ||
330 | struct TicketIssueHandle *issue_op_head; | ||
331 | |||
332 | /** | ||
333 | * Tail of DLL of ticket issue ops | ||
334 | */ | ||
335 | struct TicketIssueHandle *issue_op_tail; | ||
336 | |||
337 | /** | ||
338 | * Head of DLL of ticket consume ops | ||
339 | */ | ||
340 | struct ConsumeTicketHandle *consume_op_head; | ||
341 | |||
342 | /** | ||
343 | * Tail of DLL of ticket consume ops | ||
344 | */ | ||
345 | struct ConsumeTicketHandle *consume_op_tail; | ||
346 | |||
347 | /** | ||
348 | * Head of DLL of attribute store ops | ||
349 | */ | ||
350 | struct AttributeStoreHandle *store_op_head; | ||
351 | |||
352 | /** | ||
353 | * Tail of DLL of attribute store ops | ||
354 | */ | ||
355 | struct AttributeStoreHandle *store_op_tail; | ||
356 | |||
357 | }; | ||
358 | |||
359 | struct AttributeStoreHandle | ||
360 | { | ||
361 | /** | ||
362 | * DLL | ||
363 | */ | ||
364 | struct AttributeStoreHandle *next; | ||
365 | |||
366 | /** | ||
367 | * DLL | ||
368 | */ | ||
369 | struct AttributeStoreHandle *prev; | ||
370 | |||
371 | /** | ||
372 | * Client connection | ||
373 | */ | ||
374 | struct IdpClient *client; | ||
375 | |||
376 | /** | ||
377 | * Identity | ||
378 | */ | ||
379 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
380 | |||
381 | /** | ||
382 | * Identity pubkey | ||
383 | */ | ||
384 | struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey; | ||
385 | |||
386 | /** | ||
387 | * The issuer egos ABE master key | ||
388 | */ | ||
389 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
390 | |||
391 | /** | ||
392 | * QueueEntry | ||
393 | */ | ||
394 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
395 | |||
396 | /** | ||
397 | * The attribute to store | ||
398 | */ | ||
399 | struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; | ||
400 | |||
401 | /** | ||
402 | * The attribute expiration interval | ||
403 | */ | ||
404 | struct GNUNET_TIME_Relative exp; | ||
405 | |||
406 | /** | ||
407 | * request id | ||
408 | */ | ||
409 | uint32_t r_id; | ||
410 | }; | ||
411 | |||
412 | |||
413 | /* Prototype */ | ||
414 | struct ParallelLookup; | ||
415 | |||
416 | struct ConsumeTicketHandle | ||
417 | { | ||
418 | /** | ||
419 | * DLL | ||
420 | */ | ||
421 | struct ConsumeTicketHandle *next; | ||
422 | |||
423 | /** | ||
424 | * DLL | ||
425 | */ | ||
426 | struct ConsumeTicketHandle *prev; | ||
427 | |||
428 | /** | ||
429 | * Client connection | ||
430 | */ | ||
431 | struct IdpClient *client; | ||
432 | |||
433 | /** | ||
434 | * Ticket | ||
435 | */ | ||
436 | struct GNUNET_RECLAIM_Ticket ticket; | ||
437 | |||
438 | /** | ||
439 | * LookupRequest | ||
440 | */ | ||
441 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
442 | |||
443 | /** | ||
444 | * Audience Key | ||
445 | */ | ||
446 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
447 | |||
448 | /** | ||
449 | * Audience Key | ||
450 | */ | ||
451 | struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; | ||
452 | |||
453 | /** | ||
454 | * Lookup DLL | ||
455 | */ | ||
456 | struct ParallelLookup *parallel_lookups_head; | ||
457 | |||
458 | /** | ||
459 | * Lookup DLL | ||
460 | */ | ||
461 | struct ParallelLookup *parallel_lookups_tail; | ||
462 | |||
463 | /** | ||
464 | * Kill task | ||
465 | */ | ||
466 | struct GNUNET_SCHEDULER_Task *kill_task; | ||
467 | |||
468 | /** | ||
469 | * The ABE key | ||
470 | */ | ||
471 | struct GNUNET_ABE_AbeKey *key; | ||
472 | |||
473 | /** | ||
474 | * Attributes | ||
475 | */ | ||
476 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; | ||
477 | |||
478 | /** | ||
479 | * Lookup time | ||
480 | */ | ||
481 | struct GNUNET_TIME_Absolute lookup_start_time; | ||
482 | |||
483 | /** | ||
484 | * request id | ||
485 | */ | ||
486 | uint32_t r_id; | ||
487 | }; | ||
488 | |||
489 | /** | ||
490 | * Handle for a parallel GNS lookup job | ||
491 | */ | ||
492 | struct ParallelLookup | ||
493 | { | ||
494 | /* DLL */ | ||
495 | struct ParallelLookup *next; | ||
496 | |||
497 | /* DLL */ | ||
498 | struct ParallelLookup *prev; | ||
499 | |||
500 | /* The GNS request */ | ||
501 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
502 | |||
503 | /* The handle the return to */ | ||
504 | struct ConsumeTicketHandle *handle; | ||
505 | |||
506 | /** | ||
507 | * Lookup time | ||
508 | */ | ||
509 | struct GNUNET_TIME_Absolute lookup_start_time; | ||
510 | |||
511 | /* The label to look up */ | ||
512 | char *label; | ||
513 | }; | ||
514 | |||
515 | /** | ||
516 | * Ticket revocation request handle | ||
517 | */ | ||
518 | struct TicketRevocationHandle | ||
519 | { | ||
520 | /** | ||
521 | * DLL | ||
522 | */ | ||
523 | struct TicketRevocationHandle *prev; | ||
524 | |||
525 | /** | ||
526 | * DLL | ||
527 | */ | ||
528 | struct TicketRevocationHandle *next; | ||
529 | |||
530 | /** | ||
531 | * Client connection | ||
532 | */ | ||
533 | struct IdpClient *client; | ||
534 | |||
535 | /** | ||
536 | * Attributes to reissue | ||
537 | */ | ||
538 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; | ||
539 | |||
540 | /** | ||
541 | * Attributes to revoke | ||
542 | */ | ||
543 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *rvk_attrs; | ||
544 | |||
545 | /** | ||
546 | * Issuer Key | ||
547 | */ | ||
548 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
549 | |||
550 | /** | ||
551 | * Ticket to issue | ||
552 | */ | ||
553 | struct GNUNET_RECLAIM_Ticket ticket; | ||
554 | |||
555 | /** | ||
556 | * QueueEntry | ||
557 | */ | ||
558 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
559 | |||
560 | /** | ||
561 | * Namestore iterator | ||
562 | */ | ||
563 | struct GNUNET_NAMESTORE_ZoneIterator *ns_it; | ||
564 | |||
565 | /** | ||
566 | * The ABE master key | ||
567 | */ | ||
568 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
569 | |||
570 | /** | ||
571 | * Offset | ||
572 | */ | ||
573 | uint32_t offset; | ||
574 | |||
575 | /** | ||
576 | * request id | ||
577 | */ | ||
578 | uint32_t r_id; | ||
579 | }; | ||
580 | |||
581 | |||
582 | |||
583 | /** | ||
584 | * Ticket issue request handle | ||
585 | */ | ||
586 | struct TicketIssueHandle | ||
587 | { | ||
588 | /** | ||
589 | * DLL | ||
590 | */ | ||
591 | struct TicketIssueHandle *prev; | ||
592 | |||
593 | /** | ||
594 | * DLL | ||
595 | */ | ||
596 | struct TicketIssueHandle *next; | ||
597 | |||
598 | /** | ||
599 | * Client connection | ||
600 | */ | ||
601 | struct IdpClient *client; | ||
602 | |||
603 | /** | ||
604 | * Attributes to issue | ||
605 | */ | ||
606 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; | ||
607 | |||
608 | /** | ||
609 | * Issuer Key | ||
610 | */ | ||
611 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
612 | |||
613 | /** | ||
614 | * Ticket to issue | ||
615 | */ | ||
616 | struct GNUNET_RECLAIM_Ticket ticket; | ||
617 | |||
618 | /** | ||
619 | * QueueEntry | ||
620 | */ | ||
621 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
622 | |||
623 | /** | ||
624 | * request id | ||
625 | */ | ||
626 | uint32_t r_id; | ||
627 | }; | ||
628 | |||
629 | |||
630 | /** | ||
631 | * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format | ||
632 | * | ||
633 | */ | ||
634 | struct EgoEntry | ||
635 | { | ||
636 | /** | ||
637 | * DLL | ||
638 | */ | ||
639 | struct EgoEntry *next; | ||
640 | |||
641 | /** | ||
642 | * DLL | ||
643 | */ | ||
644 | struct EgoEntry *prev; | ||
645 | |||
646 | /** | ||
647 | * Ego handle | ||
648 | */ | ||
649 | struct GNUNET_IDENTITY_Ego *ego; | ||
650 | |||
651 | /** | ||
652 | * Attribute map. Contains the attributes as json_t | ||
653 | */ | ||
654 | struct GNUNET_CONTAINER_MultiHashMap *attr_map; | ||
655 | |||
656 | }; | ||
657 | |||
658 | /** | ||
659 | * Cleanup task | ||
660 | */ | ||
661 | static void | ||
662 | cleanup() | ||
663 | { | ||
664 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
665 | "Cleaning up\n"); | ||
666 | |||
667 | if (NULL != stats) | ||
668 | { | ||
669 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | ||
670 | stats = NULL; | ||
671 | } | ||
672 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, | ||
673 | TKT_database)); | ||
674 | GNUNET_free (db_lib_name); | ||
675 | db_lib_name = NULL; | ||
676 | if (NULL != timeout_task) | ||
677 | GNUNET_SCHEDULER_cancel (timeout_task); | ||
678 | if (NULL != update_task) | ||
679 | GNUNET_SCHEDULER_cancel (update_task); | ||
680 | if (NULL != identity_handle) | ||
681 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
682 | if (NULL != gns_handle) | ||
683 | GNUNET_GNS_disconnect (gns_handle); | ||
684 | if (NULL != credential_handle) | ||
685 | GNUNET_CREDENTIAL_disconnect (credential_handle); | ||
686 | if (NULL != ns_it) | ||
687 | GNUNET_NAMESTORE_zone_iteration_stop (ns_it); | ||
688 | if (NULL != ns_qe) | ||
689 | GNUNET_NAMESTORE_cancel (ns_qe); | ||
690 | if (NULL != ns_handle) | ||
691 | GNUNET_NAMESTORE_disconnect (ns_handle); | ||
692 | GNUNET_free_non_null (token); | ||
693 | GNUNET_free_non_null (label); | ||
694 | |||
695 | } | ||
696 | |||
697 | /** | ||
698 | * Shutdown task | ||
699 | * | ||
700 | * @param cls NULL | ||
701 | */ | ||
702 | static void | ||
703 | do_shutdown (void *cls) | ||
704 | { | ||
705 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
706 | "Shutting down...\n"); | ||
707 | cleanup(); | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * Finished storing newly bootstrapped ABE key | ||
712 | */ | ||
713 | static void | ||
714 | bootstrap_store_cont (void *cls, | ||
715 | int32_t success, | ||
716 | const char *emsg) | ||
717 | { | ||
718 | struct AbeBootstrapHandle *abh = cls; | ||
719 | if (GNUNET_SYSERR == success) | ||
720 | { | ||
721 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
722 | "Failed to bootstrap ABE master %s\n", | ||
723 | emsg); | ||
724 | abh->proc (abh->proc_cls, NULL); | ||
725 | GNUNET_free (abh->abe_key); | ||
726 | GNUNET_free (abh); | ||
727 | return; | ||
728 | } | ||
729 | abh->proc (abh->proc_cls, abh->abe_key); | ||
730 | GNUNET_free (abh); | ||
731 | } | ||
732 | |||
733 | /** | ||
734 | * Generates and stores a new ABE key | ||
735 | */ | ||
736 | static void | ||
737 | bootstrap_store_task (void *cls) | ||
738 | { | ||
739 | struct AbeBootstrapHandle *abh = cls; | ||
740 | struct GNUNET_GNSRECORD_Data rd[1]; | ||
741 | char *key; | ||
742 | |||
743 | rd[0].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key, | ||
744 | (void**)&key); | ||
745 | rd[0].data = key; | ||
746 | rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER; | ||
747 | rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; | ||
748 | rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? | ||
749 | abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
750 | &abh->identity, | ||
751 | "+", | ||
752 | 1, | ||
753 | rd, | ||
754 | &bootstrap_store_cont, | ||
755 | abh); | ||
756 | GNUNET_free (key); | ||
757 | } | ||
758 | |||
759 | /** | ||
760 | * Error checking for ABE master | ||
761 | */ | ||
762 | static void | ||
763 | bootstrap_abe_error (void *cls) | ||
764 | { | ||
765 | struct AbeBootstrapHandle *abh = cls; | ||
766 | abh->proc (abh->proc_cls, NULL); | ||
767 | GNUNET_free (abh); | ||
768 | } | ||
769 | |||
770 | |||
771 | /** | ||
772 | * Handle ABE lookup in namestore | ||
773 | */ | ||
774 | static void | ||
775 | bootstrap_abe_result (void *cls, | ||
776 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
777 | const char *label, | ||
778 | unsigned int rd_count, | ||
779 | const struct GNUNET_GNSRECORD_Data *rd) | ||
780 | { | ||
781 | struct AbeBootstrapHandle *abh = cls; | ||
782 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
783 | |||
784 | for (uint32_t i=0;i<rd_count;i++) { | ||
785 | if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type) | ||
786 | continue; | ||
787 | abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data, | ||
788 | rd[i].data_size); | ||
789 | abh->proc (abh->proc_cls, abe_key); | ||
790 | GNUNET_free (abh); | ||
791 | return; | ||
792 | } | ||
793 | |||
794 | //No ABE master found, bootstrapping... | ||
795 | abh->abe_key = GNUNET_ABE_cpabe_create_master_key (); | ||
796 | GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh); | ||
797 | } | ||
798 | |||
799 | /** | ||
800 | * Bootstrap ABE master if it does not yet exists. | ||
801 | * Will call the AbeBootstrapResult processor when done. | ||
802 | * will always recreate the ABE key of GNUNET_YES == recreate | ||
803 | */ | ||
804 | static void | ||
805 | bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
806 | AbeBootstrapResult proc, | ||
807 | void* cls, | ||
808 | int recreate) | ||
809 | { | ||
810 | struct AbeBootstrapHandle *abh; | ||
811 | |||
812 | abh = GNUNET_new (struct AbeBootstrapHandle); | ||
813 | abh->proc = proc; | ||
814 | abh->proc_cls = cls; | ||
815 | abh->identity = *identity; | ||
816 | if (GNUNET_YES == recreate) | ||
817 | { | ||
818 | abh->abe_key = GNUNET_ABE_cpabe_create_master_key (); | ||
819 | GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh); | ||
820 | } else { | ||
821 | abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, | ||
822 | identity, | ||
823 | "+", | ||
824 | &bootstrap_abe_error, | ||
825 | abh, | ||
826 | &bootstrap_abe_result, | ||
827 | abh); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | |||
832 | |||
833 | static int | ||
834 | create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, | ||
835 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | ||
836 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) | ||
837 | { | ||
838 | struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; | ||
839 | |||
840 | GNUNET_CRYPTO_hash_to_enc (new_key_hash, | ||
841 | &new_key_hash_str); | ||
842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); | ||
843 | static const char ctx_key[] = "gnuid-aes-ctx-key"; | ||
844 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
845 | new_key_hash, sizeof (struct GNUNET_HashCode), | ||
846 | ctx_key, strlen (ctx_key), | ||
847 | NULL, 0); | ||
848 | static const char ctx_iv[] = "gnuid-aes-ctx-iv"; | ||
849 | GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
850 | new_key_hash, sizeof (struct GNUNET_HashCode), | ||
851 | ctx_iv, strlen (ctx_iv), | ||
852 | NULL, 0); | ||
853 | return GNUNET_OK; | ||
854 | } | ||
855 | |||
856 | /** | ||
857 | * Cleanup ticket consume handle | ||
858 | * @param handle the handle to clean up | ||
859 | */ | ||
860 | static void | ||
861 | cleanup_ticket_issue_handle (struct TicketIssueHandle *handle) | ||
862 | { | ||
863 | if (NULL != handle->attrs) | ||
864 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs); | ||
865 | if (NULL != handle->ns_qe) | ||
866 | GNUNET_NAMESTORE_cancel (handle->ns_qe); | ||
867 | GNUNET_free (handle); | ||
868 | } | ||
869 | |||
870 | |||
871 | static void | ||
872 | send_ticket_result (struct IdpClient *client, | ||
873 | uint32_t r_id, | ||
874 | const struct GNUNET_RECLAIM_Ticket *ticket, | ||
875 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) | ||
876 | { | ||
877 | struct TicketResultMessage *irm; | ||
878 | struct GNUNET_MQ_Envelope *env; | ||
879 | struct GNUNET_RECLAIM_Ticket *ticket_buf; | ||
880 | |||
881 | /* store ticket in DB */ | ||
882 | if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, | ||
883 | ticket, | ||
884 | attrs)) | ||
885 | { | ||
886 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
887 | "Unable to store ticket after issue\n"); | ||
888 | GNUNET_break (0); | ||
889 | } | ||
890 | |||
891 | env = GNUNET_MQ_msg_extra (irm, | ||
892 | sizeof (struct GNUNET_RECLAIM_Ticket), | ||
893 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); | ||
894 | ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1]; | ||
895 | *ticket_buf = *ticket; | ||
896 | irm->id = htonl (r_id); | ||
897 | GNUNET_MQ_send (client->mq, | ||
898 | env); | ||
899 | } | ||
900 | |||
901 | static void | ||
902 | store_ticket_issue_cont (void *cls, | ||
903 | int32_t success, | ||
904 | const char *emsg) | ||
905 | { | ||
906 | struct TicketIssueHandle *handle = cls; | ||
907 | |||
908 | handle->ns_qe = NULL; | ||
909 | GNUNET_CONTAINER_DLL_remove (handle->client->issue_op_head, | ||
910 | handle->client->issue_op_tail, | ||
911 | handle); | ||
912 | if (GNUNET_SYSERR == success) | ||
913 | { | ||
914 | cleanup_ticket_issue_handle (handle); | ||
915 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | ||
916 | "Unknown Error\n"); | ||
917 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
918 | return; | ||
919 | } | ||
920 | send_ticket_result (handle->client, | ||
921 | handle->r_id, | ||
922 | &handle->ticket, | ||
923 | handle->attrs); | ||
924 | cleanup_ticket_issue_handle (handle); | ||
925 | } | ||
926 | |||
927 | |||
928 | |||
929 | int | ||
930 | serialize_abe_keyinfo2 (const struct GNUNET_RECLAIM_Ticket *ticket, | ||
931 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, | ||
932 | const struct GNUNET_ABE_AbeKey *rp_key, | ||
933 | struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, | ||
934 | char **result) | ||
935 | { | ||
936 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; | ||
937 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | ||
938 | char *enc_keyinfo; | ||
939 | char *serialized_key; | ||
940 | char *buf; | ||
941 | char *write_ptr; | ||
942 | char attrs_str_len; | ||
943 | ssize_t size; | ||
944 | |||
945 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
946 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
947 | struct GNUNET_HashCode new_key_hash; | ||
948 | ssize_t enc_size; | ||
949 | |||
950 | size = GNUNET_ABE_cpabe_serialize_key (rp_key, | ||
951 | (void**)&serialized_key); | ||
952 | attrs_str_len = 0; | ||
953 | for (le = attrs->list_head; NULL != le; le = le->next) { | ||
954 | attrs_str_len += strlen (le->claim->name) + 1; | ||
955 | } | ||
956 | buf = GNUNET_malloc (attrs_str_len + size); | ||
957 | write_ptr = buf; | ||
958 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
959 | "Writing attributes\n"); | ||
960 | for (le = attrs->list_head; NULL != le; le = le->next) { | ||
961 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
962 | "%s\n", le->claim->name); | ||
963 | |||
964 | |||
965 | GNUNET_memcpy (write_ptr, | ||
966 | le->claim->name, | ||
967 | strlen (le->claim->name)); | ||
968 | write_ptr[strlen (le->claim->name)] = ','; | ||
969 | write_ptr += strlen (le->claim->name) + 1; | ||
970 | } | ||
971 | write_ptr--; | ||
972 | write_ptr[0] = '\0'; //replace last , with a 0-terminator | ||
973 | write_ptr++; | ||
974 | GNUNET_memcpy (write_ptr, | ||
975 | serialized_key, | ||
976 | size); | ||
977 | GNUNET_free (serialized_key); | ||
978 | // ECDH keypair E = eG | ||
979 | *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create(); | ||
980 | GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, | ||
981 | &ecdh_pubkey); | ||
982 | enc_keyinfo = GNUNET_malloc (size + attrs_str_len); | ||
983 | // Derived key K = H(eB) | ||
984 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, | ||
985 | &ticket->audience, | ||
986 | &new_key_hash)); | ||
987 | create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); | ||
988 | enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf, | ||
989 | size + attrs_str_len, | ||
990 | &skey, &iv, | ||
991 | enc_keyinfo); | ||
992 | *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+ | ||
993 | enc_size); | ||
994 | GNUNET_memcpy (*result, | ||
995 | &ecdh_pubkey, | ||
996 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
997 | GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
998 | enc_keyinfo, | ||
999 | enc_size); | ||
1000 | GNUNET_free (enc_keyinfo); | ||
1001 | GNUNET_free (buf); | ||
1002 | return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size; | ||
1003 | } | ||
1004 | |||
1005 | |||
1006 | |||
1007 | static void | ||
1008 | issue_ticket_after_abe_bootstrap (void *cls, | ||
1009 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
1010 | { | ||
1011 | struct TicketIssueHandle *ih = cls; | ||
1012 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | ||
1013 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; | ||
1014 | struct GNUNET_GNSRECORD_Data code_record[1]; | ||
1015 | struct GNUNET_ABE_AbeKey *rp_key; | ||
1016 | char *code_record_data; | ||
1017 | char **attrs; | ||
1018 | char *label; | ||
1019 | char *policy; | ||
1020 | int attrs_len; | ||
1021 | uint32_t i; | ||
1022 | size_t code_record_len; | ||
1023 | |||
1024 | //Create new ABE key for RP | ||
1025 | attrs_len = 0; | ||
1026 | for (le = ih->attrs->list_head; NULL != le; le = le->next) | ||
1027 | attrs_len++; | ||
1028 | attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); | ||
1029 | i = 0; | ||
1030 | for (le = ih->attrs->list_head; NULL != le; le = le->next) { | ||
1031 | GNUNET_asprintf (&policy, "%s_%lu", | ||
1032 | le->claim->name, | ||
1033 | le->claim->version); | ||
1034 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1035 | "Adding attribute to key: %s\n", | ||
1036 | policy); | ||
1037 | attrs[i] = policy; | ||
1038 | i++; | ||
1039 | } | ||
1040 | attrs[i] = NULL; | ||
1041 | rp_key = GNUNET_ABE_cpabe_create_key (abe_key, | ||
1042 | attrs); | ||
1043 | |||
1044 | //TODO review this wireformat | ||
1045 | code_record_len = serialize_abe_keyinfo2 (&ih->ticket, | ||
1046 | ih->attrs, | ||
1047 | rp_key, | ||
1048 | &ecdhe_privkey, | ||
1049 | &code_record_data); | ||
1050 | code_record[0].data = code_record_data; | ||
1051 | code_record[0].data_size = code_record_len; | ||
1052 | code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; | ||
1053 | code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY; | ||
1054 | code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1055 | |||
1056 | label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, | ||
1057 | sizeof (uint64_t)); | ||
1058 | //Publish record | ||
1059 | ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1060 | &ih->identity, | ||
1061 | label, | ||
1062 | 1, | ||
1063 | code_record, | ||
1064 | &store_ticket_issue_cont, | ||
1065 | ih); | ||
1066 | //for (; i > 0; i--) | ||
1067 | // GNUNET_free (attrs[i-1]); | ||
1068 | GNUNET_free (ecdhe_privkey); | ||
1069 | GNUNET_free (label); | ||
1070 | GNUNET_free (attrs); | ||
1071 | GNUNET_free (code_record_data); | ||
1072 | GNUNET_ABE_cpabe_delete_key (rp_key, | ||
1073 | GNUNET_YES); | ||
1074 | GNUNET_ABE_cpabe_delete_master_key (abe_key); | ||
1075 | } | ||
1076 | |||
1077 | |||
1078 | static int | ||
1079 | check_issue_ticket_message(void *cls, | ||
1080 | const struct IssueTicketMessage *im) | ||
1081 | { | ||
1082 | uint16_t size; | ||
1083 | |||
1084 | size = ntohs (im->header.size); | ||
1085 | if (size <= sizeof (struct IssueTicketMessage)) | ||
1086 | { | ||
1087 | GNUNET_break (0); | ||
1088 | return GNUNET_SYSERR; | ||
1089 | } | ||
1090 | return GNUNET_OK; | ||
1091 | } | ||
1092 | |||
1093 | |||
1094 | static void | ||
1095 | handle_issue_ticket_message (void *cls, | ||
1096 | const struct IssueTicketMessage *im) | ||
1097 | { | ||
1098 | struct TicketIssueHandle *ih; | ||
1099 | struct IdpClient *idp = cls; | ||
1100 | size_t attrs_len; | ||
1101 | |||
1102 | ih = GNUNET_new (struct TicketIssueHandle); | ||
1103 | attrs_len = ntohs (im->attr_len); | ||
1104 | ih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len); | ||
1105 | ih->r_id = ntohl (im->id); | ||
1106 | ih->client = idp; | ||
1107 | ih->identity = im->identity; | ||
1108 | GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity, | ||
1109 | &ih->ticket.identity); | ||
1110 | ih->ticket.audience = im->rp; | ||
1111 | ih->ticket.rnd = | ||
1112 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, | ||
1113 | UINT64_MAX); | ||
1114 | GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, | ||
1115 | idp->issue_op_tail, | ||
1116 | ih); | ||
1117 | bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO); | ||
1118 | GNUNET_SERVICE_client_continue (idp->client); | ||
1119 | |||
1120 | } | ||
1121 | |||
1122 | /********************************************************** | ||
1123 | * Revocation | ||
1124 | **********************************************************/ | ||
1125 | |||
1126 | /** | ||
1127 | * Cleanup revoke handle | ||
1128 | * | ||
1129 | * @param rh the ticket revocation handle | ||
1130 | */ | ||
1131 | static void | ||
1132 | cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh) | ||
1133 | { | ||
1134 | if (NULL != rh->attrs) | ||
1135 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs); | ||
1136 | if (NULL != rh->rvk_attrs) | ||
1137 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs); | ||
1138 | if (NULL != rh->abe_key) | ||
1139 | GNUNET_ABE_cpabe_delete_master_key (rh->abe_key); | ||
1140 | if (NULL != rh->ns_qe) | ||
1141 | GNUNET_NAMESTORE_cancel (rh->ns_qe); | ||
1142 | if (NULL != rh->ns_it) | ||
1143 | GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it); | ||
1144 | GNUNET_free (rh); | ||
1145 | } | ||
1146 | |||
1147 | |||
1148 | /** | ||
1149 | * Send revocation result | ||
1150 | * | ||
1151 | * @param rh ticket revocation handle | ||
1152 | * @param success GNUNET_OK if successful result | ||
1153 | */ | ||
1154 | static void | ||
1155 | send_revocation_finished (struct TicketRevocationHandle *rh, | ||
1156 | uint32_t success) | ||
1157 | { | ||
1158 | struct GNUNET_MQ_Envelope *env; | ||
1159 | struct RevokeTicketResultMessage *trm; | ||
1160 | |||
1161 | GNUNET_break(TKT_database->delete_ticket (TKT_database->cls, | ||
1162 | &rh->ticket)); | ||
1163 | |||
1164 | env = GNUNET_MQ_msg (trm, | ||
1165 | GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT); | ||
1166 | trm->id = htonl (rh->r_id); | ||
1167 | trm->success = htonl (success); | ||
1168 | GNUNET_MQ_send (rh->client->mq, | ||
1169 | env); | ||
1170 | GNUNET_CONTAINER_DLL_remove (rh->client->revoke_op_head, | ||
1171 | rh->client->revoke_op_tail, | ||
1172 | rh); | ||
1173 | } | ||
1174 | |||
1175 | |||
1176 | /** | ||
1177 | * Process ticket from database | ||
1178 | * | ||
1179 | * @param cls struct TicketIterationProcResult | ||
1180 | * @param ticket the ticket | ||
1181 | * @param attrs the attributes | ||
1182 | */ | ||
1183 | static void | ||
1184 | ticket_reissue_proc (void *cls, | ||
1185 | const struct GNUNET_RECLAIM_Ticket *ticket, | ||
1186 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs); | ||
1187 | |||
1188 | static void | ||
1189 | revocation_reissue_tickets (struct TicketRevocationHandle *rh); | ||
1190 | |||
1191 | |||
1192 | static void reissue_next (void *cls) | ||
1193 | { | ||
1194 | struct TicketRevocationHandle *rh = cls; | ||
1195 | revocation_reissue_tickets (rh); | ||
1196 | } | ||
1197 | |||
1198 | |||
1199 | static void | ||
1200 | reissue_ticket_cont (void *cls, | ||
1201 | int32_t success, | ||
1202 | const char *emsg) | ||
1203 | { | ||
1204 | struct TicketRevocationHandle *rh = cls; | ||
1205 | |||
1206 | rh->ns_qe = NULL; | ||
1207 | if (GNUNET_SYSERR == success) | ||
1208 | { | ||
1209 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | ||
1210 | "Unknown Error\n"); | ||
1211 | send_revocation_finished (rh, GNUNET_SYSERR); | ||
1212 | cleanup_revoke_ticket_handle (rh); | ||
1213 | return; | ||
1214 | } | ||
1215 | rh->offset++; | ||
1216 | GNUNET_SCHEDULER_add_now (&reissue_next, rh); | ||
1217 | } | ||
1218 | |||
1219 | |||
1220 | /** | ||
1221 | * Process ticket from database | ||
1222 | * | ||
1223 | * @param cls struct TicketIterationProcResult | ||
1224 | * @param ticket the ticket | ||
1225 | * @param attrs the attributes | ||
1226 | */ | ||
1227 | static void | ||
1228 | ticket_reissue_proc (void *cls, | ||
1229 | const struct GNUNET_RECLAIM_Ticket *ticket, | ||
1230 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) | ||
1231 | { | ||
1232 | struct TicketRevocationHandle *rh = cls; | ||
1233 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | ||
1234 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le_rollover; | ||
1235 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; | ||
1236 | struct GNUNET_GNSRECORD_Data code_record[1]; | ||
1237 | struct GNUNET_ABE_AbeKey *rp_key; | ||
1238 | char *code_record_data; | ||
1239 | char **attr_arr; | ||
1240 | char *label; | ||
1241 | char *policy; | ||
1242 | int attrs_len; | ||
1243 | uint32_t i; | ||
1244 | int reissue_ticket; | ||
1245 | size_t code_record_len; | ||
1246 | |||
1247 | |||
1248 | if (NULL == ticket) | ||
1249 | { | ||
1250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1251 | "Iteration done\n"); | ||
1252 | return; | ||
1253 | } | ||
1254 | |||
1255 | if (0 == memcmp (&ticket->audience, | ||
1256 | &rh->ticket.audience, | ||
1257 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
1258 | { | ||
1259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1260 | "Do not reissue for this identity.!\n"); | ||
1261 | label = GNUNET_STRINGS_data_to_string_alloc (&rh->ticket.rnd, | ||
1262 | sizeof (uint64_t)); | ||
1263 | //Delete record | ||
1264 | rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1265 | &rh->identity, | ||
1266 | label, | ||
1267 | 0, | ||
1268 | NULL, | ||
1269 | &reissue_ticket_cont, | ||
1270 | rh); | ||
1271 | |||
1272 | GNUNET_free (label); | ||
1273 | return; | ||
1274 | } | ||
1275 | |||
1276 | /* | ||
1277 | * Check if any attribute of this ticket intersects with a rollover attribute | ||
1278 | */ | ||
1279 | reissue_ticket = GNUNET_NO; | ||
1280 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
1281 | { | ||
1282 | for (le_rollover = rh->rvk_attrs->list_head; | ||
1283 | NULL != le_rollover; | ||
1284 | le_rollover = le_rollover->next) | ||
1285 | { | ||
1286 | if (0 == strcmp (le_rollover->claim->name, | ||
1287 | le->claim->name)) | ||
1288 | { | ||
1289 | reissue_ticket = GNUNET_YES; | ||
1290 | le->claim->version = le_rollover->claim->version; | ||
1291 | } | ||
1292 | } | ||
1293 | } | ||
1294 | |||
1295 | if (GNUNET_NO == reissue_ticket) | ||
1296 | { | ||
1297 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1298 | "Skipping ticket.\n"); | ||
1299 | |||
1300 | rh->offset++; | ||
1301 | GNUNET_SCHEDULER_add_now (&reissue_next, rh); | ||
1302 | |||
1303 | |||
1304 | return; | ||
1305 | } | ||
1306 | |||
1307 | //Create new ABE key for RP | ||
1308 | attrs_len = 0; | ||
1309 | |||
1310 | /* If this is the RP we want to revoke attributes of, the do so */ | ||
1311 | |||
1312 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
1313 | attrs_len++; | ||
1314 | attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); | ||
1315 | i = 0; | ||
1316 | for (le = attrs->list_head; NULL != le; le = le->next) { | ||
1317 | GNUNET_asprintf (&policy, "%s_%lu", | ||
1318 | le->claim->name, | ||
1319 | le->claim->version); | ||
1320 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1321 | "Recreating key with %s\n", policy); | ||
1322 | attr_arr[i] = policy; | ||
1323 | i++; | ||
1324 | } | ||
1325 | attr_arr[i] = NULL; | ||
1326 | rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key, | ||
1327 | attr_arr); | ||
1328 | |||
1329 | //TODO review this wireformat | ||
1330 | code_record_len = serialize_abe_keyinfo2 (ticket, | ||
1331 | attrs, | ||
1332 | rp_key, | ||
1333 | &ecdhe_privkey, | ||
1334 | &code_record_data); | ||
1335 | code_record[0].data = code_record_data; | ||
1336 | code_record[0].data_size = code_record_len; | ||
1337 | code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; | ||
1338 | code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY; | ||
1339 | code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1340 | |||
1341 | label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, | ||
1342 | sizeof (uint64_t)); | ||
1343 | //Publish record | ||
1344 | rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1345 | &rh->identity, | ||
1346 | label, | ||
1347 | 1, | ||
1348 | code_record, | ||
1349 | &reissue_ticket_cont, | ||
1350 | rh); | ||
1351 | //for (; i > 0; i--) | ||
1352 | // GNUNET_free (attr_arr[i-1]); | ||
1353 | GNUNET_free (ecdhe_privkey); | ||
1354 | GNUNET_free (label); | ||
1355 | GNUNET_free (attr_arr); | ||
1356 | GNUNET_free (code_record_data); | ||
1357 | GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES); | ||
1358 | } | ||
1359 | |||
1360 | |||
1361 | /* Prototype for below function */ | ||
1362 | static void | ||
1363 | attr_reenc_cont (void *cls, | ||
1364 | int32_t success, | ||
1365 | const char *emsg); | ||
1366 | |||
1367 | static void | ||
1368 | revocation_reissue_tickets (struct TicketRevocationHandle *rh) | ||
1369 | { | ||
1370 | int ret; | ||
1371 | /* Done, issue new keys */ | ||
1372 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1373 | "Revocation Phase III: Reissuing Tickets\n"); | ||
1374 | if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls, | ||
1375 | &rh->ticket.identity, | ||
1376 | GNUNET_NO, | ||
1377 | rh->offset, | ||
1378 | &ticket_reissue_proc, | ||
1379 | rh))) | ||
1380 | { | ||
1381 | GNUNET_break (0); | ||
1382 | } | ||
1383 | if (GNUNET_NO == ret) | ||
1384 | { | ||
1385 | send_revocation_finished (rh, GNUNET_OK); | ||
1386 | cleanup_revoke_ticket_handle (rh); | ||
1387 | return; | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | /** | ||
1392 | * Failed to check for attribute | ||
1393 | */ | ||
1394 | static void | ||
1395 | check_attr_error (void *cls) | ||
1396 | { | ||
1397 | struct TicketRevocationHandle *rh = cls; | ||
1398 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1399 | "Unable to check for existing attribute\n"); | ||
1400 | rh->ns_qe = NULL; | ||
1401 | send_revocation_finished (rh, GNUNET_SYSERR); | ||
1402 | cleanup_revoke_ticket_handle (rh); | ||
1403 | } | ||
1404 | |||
1405 | |||
1406 | /** | ||
1407 | * Revoke next attribte by reencryption with | ||
1408 | * new ABE master | ||
1409 | */ | ||
1410 | static void | ||
1411 | reenc_next_attribute (void *cls); | ||
1412 | |||
1413 | /** | ||
1414 | * Check for existing attribute and overwrite | ||
1415 | */ | ||
1416 | static void | ||
1417 | check_attr_cb (void *cls, | ||
1418 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
1419 | const char *label, | ||
1420 | unsigned int rd_count, | ||
1421 | const struct GNUNET_GNSRECORD_Data *rd_old) | ||
1422 | { | ||
1423 | struct TicketRevocationHandle *rh = cls; | ||
1424 | struct GNUNET_GNSRECORD_Data rd[1]; | ||
1425 | char* buf; | ||
1426 | char* enc_buf; | ||
1427 | size_t enc_size; | ||
1428 | char* rd_buf; | ||
1429 | size_t buf_size; | ||
1430 | char* policy; | ||
1431 | uint32_t attr_ver; | ||
1432 | |||
1433 | rh->ns_qe = NULL; | ||
1434 | if (1 != rd_count) { | ||
1435 | GNUNET_SCHEDULER_add_now (&reenc_next_attribute, | ||
1436 | rh); | ||
1437 | return; | ||
1438 | } | ||
1439 | |||
1440 | buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim); | ||
1441 | buf = GNUNET_malloc (buf_size); | ||
1442 | rh->attrs->list_head->claim->version++; | ||
1443 | GNUNET_RECLAIM_ATTRIBUTE_serialize (rh->attrs->list_head->claim, | ||
1444 | buf); | ||
1445 | GNUNET_asprintf (&policy, "%s_%lu", | ||
1446 | rh->attrs->list_head->claim->name, | ||
1447 | rh->attrs->list_head->claim->version); | ||
1448 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1449 | "Encrypting with policy %s\n", policy); | ||
1450 | /** | ||
1451 | * Encrypt the attribute value and store in namestore | ||
1452 | */ | ||
1453 | enc_size = GNUNET_ABE_cpabe_encrypt (buf, | ||
1454 | buf_size, | ||
1455 | policy, //Policy | ||
1456 | rh->abe_key, | ||
1457 | (void**)&enc_buf); | ||
1458 | GNUNET_free (buf); | ||
1459 | if (GNUNET_SYSERR == enc_size) | ||
1460 | { | ||
1461 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1462 | "Unable to re-encrypt with policy %s\n", | ||
1463 | policy); | ||
1464 | GNUNET_free (policy); | ||
1465 | send_revocation_finished (rh, GNUNET_SYSERR); | ||
1466 | cleanup_revoke_ticket_handle (rh); | ||
1467 | return; | ||
1468 | } | ||
1469 | GNUNET_free (policy); | ||
1470 | |||
1471 | rd[0].data_size = enc_size + sizeof (uint32_t); | ||
1472 | rd_buf = GNUNET_malloc (rd[0].data_size); | ||
1473 | attr_ver = htonl (rh->attrs->list_head->claim->version); | ||
1474 | GNUNET_memcpy (rd_buf, | ||
1475 | &attr_ver, | ||
1476 | sizeof (uint32_t)); | ||
1477 | GNUNET_memcpy (rd_buf+sizeof (uint32_t), | ||
1478 | enc_buf, | ||
1479 | enc_size); | ||
1480 | rd[0].data = rd_buf; | ||
1481 | rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; | ||
1482 | rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1483 | rd[0].expiration_time = rd_old[0].expiration_time; | ||
1484 | rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1485 | &rh->identity, | ||
1486 | rh->attrs->list_head->claim->name, | ||
1487 | 1, | ||
1488 | rd, | ||
1489 | &attr_reenc_cont, | ||
1490 | rh); | ||
1491 | GNUNET_free (enc_buf); | ||
1492 | GNUNET_free (rd_buf); | ||
1493 | } | ||
1494 | |||
1495 | |||
1496 | /** | ||
1497 | * Revoke next attribte by reencryption with | ||
1498 | * new ABE master | ||
1499 | */ | ||
1500 | static void | ||
1501 | reenc_next_attribute (void *cls) | ||
1502 | { | ||
1503 | struct TicketRevocationHandle *rh = cls; | ||
1504 | if (NULL == rh->attrs->list_head) | ||
1505 | { | ||
1506 | revocation_reissue_tickets (rh); | ||
1507 | return; | ||
1508 | } | ||
1509 | /* First check if attribute still exists */ | ||
1510 | rh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, | ||
1511 | &rh->identity, | ||
1512 | rh->attrs->list_head->claim->name, | ||
1513 | &check_attr_error, | ||
1514 | rh, | ||
1515 | &check_attr_cb, | ||
1516 | rh); | ||
1517 | } | ||
1518 | |||
1519 | |||
1520 | /** | ||
1521 | * Namestore callback after revoked attribute | ||
1522 | * is stored | ||
1523 | */ | ||
1524 | static void | ||
1525 | attr_reenc_cont (void *cls, | ||
1526 | int32_t success, | ||
1527 | const char *emsg) | ||
1528 | { | ||
1529 | struct TicketRevocationHandle *rh = cls; | ||
1530 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | ||
1531 | |||
1532 | rh->ns_qe = NULL; | ||
1533 | if (GNUNET_SYSERR == success) | ||
1534 | { | ||
1535 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1536 | "Failed to reencrypt attribute %s\n", | ||
1537 | emsg); | ||
1538 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1539 | return; | ||
1540 | } | ||
1541 | if (NULL == rh->attrs->list_head) | ||
1542 | { | ||
1543 | revocation_reissue_tickets (rh); | ||
1544 | return; | ||
1545 | } | ||
1546 | le = rh->attrs->list_head; | ||
1547 | GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, | ||
1548 | rh->attrs->list_tail, | ||
1549 | le); | ||
1550 | GNUNET_assert (NULL != rh->rvk_attrs); | ||
1551 | GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head, | ||
1552 | rh->rvk_attrs->list_tail, | ||
1553 | le); | ||
1554 | |||
1555 | |||
1556 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1557 | "Re-encrypting next attribute\n"); | ||
1558 | reenc_next_attribute (rh); | ||
1559 | } | ||
1560 | |||
1561 | |||
1562 | static void | ||
1563 | process_attributes_to_update (void *cls, | ||
1564 | const struct GNUNET_RECLAIM_Ticket *ticket, | ||
1565 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) | ||
1566 | { | ||
1567 | struct TicketRevocationHandle *rh = cls; | ||
1568 | |||
1569 | rh->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs); | ||
1570 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1571 | "Revocation Phase I: Collecting attributes\n"); | ||
1572 | /* Reencrypt all attributes with new key */ | ||
1573 | if (NULL == rh->attrs->list_head) | ||
1574 | { | ||
1575 | /* No attributes to reencrypt */ | ||
1576 | send_revocation_finished (rh, GNUNET_OK); | ||
1577 | cleanup_revoke_ticket_handle (rh); | ||
1578 | return; | ||
1579 | } else { | ||
1580 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1581 | "Revocation Phase II: Re-encrypting attributes\n"); | ||
1582 | reenc_next_attribute (rh); | ||
1583 | } | ||
1584 | |||
1585 | } | ||
1586 | |||
1587 | |||
1588 | |||
1589 | static void | ||
1590 | get_ticket_after_abe_bootstrap (void *cls, | ||
1591 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
1592 | { | ||
1593 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1594 | "Finished ABE bootstrap\n"); | ||
1595 | struct TicketRevocationHandle *rh = cls; | ||
1596 | rh->abe_key = abe_key; | ||
1597 | TKT_database->get_ticket_attributes (TKT_database->cls, | ||
1598 | &rh->ticket, | ||
1599 | &process_attributes_to_update, | ||
1600 | rh); | ||
1601 | } | ||
1602 | |||
1603 | static int | ||
1604 | check_revoke_ticket_message(void *cls, | ||
1605 | const struct RevokeTicketMessage *im) | ||
1606 | { | ||
1607 | uint16_t size; | ||
1608 | |||
1609 | size = ntohs (im->header.size); | ||
1610 | if (size <= sizeof (struct RevokeTicketMessage)) | ||
1611 | { | ||
1612 | GNUNET_break (0); | ||
1613 | return GNUNET_SYSERR; | ||
1614 | } | ||
1615 | return GNUNET_OK; | ||
1616 | } | ||
1617 | |||
1618 | static void | ||
1619 | handle_revoke_ticket_message (void *cls, | ||
1620 | const struct RevokeTicketMessage *rm) | ||
1621 | { | ||
1622 | struct TicketRevocationHandle *rh; | ||
1623 | struct IdpClient *idp = cls; | ||
1624 | struct GNUNET_RECLAIM_Ticket *ticket; | ||
1625 | |||
1626 | rh = GNUNET_new (struct TicketRevocationHandle); | ||
1627 | ticket = (struct GNUNET_RECLAIM_Ticket*)&rm[1]; | ||
1628 | rh->rvk_attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); | ||
1629 | rh->ticket = *ticket; | ||
1630 | rh->r_id = ntohl (rm->id); | ||
1631 | rh->client = idp; | ||
1632 | rh->identity = rm->identity; | ||
1633 | GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity, | ||
1634 | &rh->ticket.identity); | ||
1635 | GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, | ||
1636 | idp->revoke_op_tail, | ||
1637 | rh); | ||
1638 | bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO); | ||
1639 | GNUNET_SERVICE_client_continue (idp->client); | ||
1640 | |||
1641 | } | ||
1642 | |||
1643 | /** | ||
1644 | * Cleanup ticket consume handle | ||
1645 | * @param handle the handle to clean up | ||
1646 | */ | ||
1647 | static void | ||
1648 | cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle) | ||
1649 | { | ||
1650 | struct ParallelLookup *lu; | ||
1651 | struct ParallelLookup *tmp; | ||
1652 | if (NULL != handle->lookup_request) | ||
1653 | GNUNET_GNS_lookup_cancel (handle->lookup_request); | ||
1654 | for (lu = handle->parallel_lookups_head; | ||
1655 | NULL != lu;) { | ||
1656 | GNUNET_GNS_lookup_cancel (lu->lookup_request); | ||
1657 | GNUNET_free (lu->label); | ||
1658 | tmp = lu->next; | ||
1659 | GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, | ||
1660 | handle->parallel_lookups_tail, | ||
1661 | lu); | ||
1662 | GNUNET_free (lu); | ||
1663 | lu = tmp; | ||
1664 | } | ||
1665 | |||
1666 | if (NULL != handle->key) | ||
1667 | GNUNET_ABE_cpabe_delete_key (handle->key, | ||
1668 | GNUNET_YES); | ||
1669 | if (NULL != handle->attrs) | ||
1670 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs); | ||
1671 | GNUNET_free (handle); | ||
1672 | } | ||
1673 | |||
1674 | |||
1675 | |||
1676 | static int | ||
1677 | check_consume_ticket_message(void *cls, | ||
1678 | const struct ConsumeTicketMessage *cm) | ||
1679 | { | ||
1680 | uint16_t size; | ||
1681 | |||
1682 | size = ntohs (cm->header.size); | ||
1683 | if (size <= sizeof (struct ConsumeTicketMessage)) | ||
1684 | { | ||
1685 | GNUNET_break (0); | ||
1686 | return GNUNET_SYSERR; | ||
1687 | } | ||
1688 | return GNUNET_OK; | ||
1689 | } | ||
1690 | |||
1691 | static void | ||
1692 | process_parallel_lookup2 (void *cls, uint32_t rd_count, | ||
1693 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1694 | { | ||
1695 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1696 | "Parallel lookup finished (count=%u)\n", rd_count); | ||
1697 | struct ParallelLookup *parallel_lookup = cls; | ||
1698 | struct ConsumeTicketHandle *handle = parallel_lookup->handle; | ||
1699 | struct ConsumeTicketResultMessage *crm; | ||
1700 | struct GNUNET_MQ_Envelope *env; | ||
1701 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le; | ||
1702 | struct GNUNET_TIME_Absolute decrypt_duration; | ||
1703 | char *data; | ||
1704 | char *data_tmp; | ||
1705 | ssize_t attr_len; | ||
1706 | size_t attrs_len; | ||
1707 | |||
1708 | GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, | ||
1709 | handle->parallel_lookups_tail, | ||
1710 | parallel_lookup); | ||
1711 | GNUNET_free (parallel_lookup->label); | ||
1712 | |||
1713 | GNUNET_STATISTICS_update (stats, | ||
1714 | "attribute_lookup_time_total", | ||
1715 | GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us, | ||
1716 | GNUNET_YES); | ||
1717 | GNUNET_STATISTICS_update (stats, | ||
1718 | "attribute_lookups_count", | ||
1719 | 1, | ||
1720 | GNUNET_YES); | ||
1721 | |||
1722 | |||
1723 | GNUNET_free (parallel_lookup); | ||
1724 | if (1 != rd_count) | ||
1725 | GNUNET_break(0);//TODO | ||
1726 | if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) | ||
1727 | { | ||
1728 | decrypt_duration = GNUNET_TIME_absolute_get (); | ||
1729 | attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t), | ||
1730 | rd->data_size - sizeof (uint32_t), | ||
1731 | handle->key, | ||
1732 | (void**)&data); | ||
1733 | if (GNUNET_SYSERR != attr_len) | ||
1734 | { | ||
1735 | GNUNET_STATISTICS_update (stats, | ||
1736 | "abe_decrypt_time_total", | ||
1737 | GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us, | ||
1738 | GNUNET_YES); | ||
1739 | GNUNET_STATISTICS_update (stats, | ||
1740 | "abe_decrypt_count", | ||
1741 | 1, | ||
1742 | GNUNET_YES); | ||
1743 | |||
1744 | attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); | ||
1745 | attr_le->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (data, | ||
1746 | attr_len); | ||
1747 | attr_le->claim->version = ntohl(*(uint32_t*)rd->data); | ||
1748 | GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head, | ||
1749 | handle->attrs->list_tail, | ||
1750 | attr_le); | ||
1751 | GNUNET_free (data); | ||
1752 | } | ||
1753 | } | ||
1754 | if (NULL != handle->parallel_lookups_head) | ||
1755 | return; //Wait for more | ||
1756 | /* Else we are done */ | ||
1757 | |||
1758 | /* Store ticket in DB */ | ||
1759 | if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, | ||
1760 | &handle->ticket, | ||
1761 | handle->attrs)) | ||
1762 | { | ||
1763 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1764 | "Unable to store ticket after consume\n"); | ||
1765 | GNUNET_break (0); | ||
1766 | } | ||
1767 | |||
1768 | GNUNET_SCHEDULER_cancel (handle->kill_task); | ||
1769 | attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (handle->attrs); | ||
1770 | env = GNUNET_MQ_msg_extra (crm, | ||
1771 | attrs_len, | ||
1772 | GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT); | ||
1773 | crm->id = htonl (handle->r_id); | ||
1774 | crm->attrs_len = htons (attrs_len); | ||
1775 | crm->identity = handle->ticket.identity; | ||
1776 | data_tmp = (char *) &crm[1]; | ||
1777 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize (handle->attrs, | ||
1778 | data_tmp); | ||
1779 | GNUNET_MQ_send (handle->client->mq, env); | ||
1780 | GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head, | ||
1781 | handle->client->consume_op_tail, | ||
1782 | handle); | ||
1783 | cleanup_consume_ticket_handle (handle); | ||
1784 | } | ||
1785 | |||
1786 | void | ||
1787 | abort_parallel_lookups2 (void *cls) | ||
1788 | { | ||
1789 | struct ConsumeTicketHandle *handle = cls; | ||
1790 | struct ParallelLookup *lu; | ||
1791 | struct ParallelLookup *tmp; | ||
1792 | struct AttributeResultMessage *arm; | ||
1793 | struct GNUNET_MQ_Envelope *env; | ||
1794 | |||
1795 | handle->kill_task = NULL; | ||
1796 | for (lu = handle->parallel_lookups_head; | ||
1797 | NULL != lu;) { | ||
1798 | GNUNET_GNS_lookup_cancel (lu->lookup_request); | ||
1799 | GNUNET_free (lu->label); | ||
1800 | tmp = lu->next; | ||
1801 | GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, | ||
1802 | handle->parallel_lookups_tail, | ||
1803 | lu); | ||
1804 | GNUNET_free (lu); | ||
1805 | lu = tmp; | ||
1806 | } | ||
1807 | env = GNUNET_MQ_msg (arm, | ||
1808 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); | ||
1809 | arm->id = htonl (handle->r_id); | ||
1810 | arm->attr_len = htons (0); | ||
1811 | GNUNET_MQ_send (handle->client->mq, env); | ||
1812 | |||
1813 | } | ||
1814 | |||
1815 | |||
1816 | static void | ||
1817 | process_consume_abe_key (void *cls, uint32_t rd_count, | ||
1818 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1819 | { | ||
1820 | struct ConsumeTicketHandle *handle = cls; | ||
1821 | struct GNUNET_HashCode new_key_hash; | ||
1822 | struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; | ||
1823 | struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; | ||
1824 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key; | ||
1825 | struct ParallelLookup *parallel_lookup; | ||
1826 | size_t size; | ||
1827 | char *buf; | ||
1828 | char *scope; | ||
1829 | |||
1830 | handle->lookup_request = NULL; | ||
1831 | if (1 != rd_count) | ||
1832 | { | ||
1833 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1834 | "Number of keys %d != 1.", | ||
1835 | rd_count); | ||
1836 | cleanup_consume_ticket_handle (handle); | ||
1837 | GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head, | ||
1838 | handle->client->consume_op_tail, | ||
1839 | handle); | ||
1840 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1841 | return; | ||
1842 | } | ||
1843 | |||
1844 | //Decrypt | ||
1845 | ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data; | ||
1846 | |||
1847 | buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
1848 | |||
1849 | //Calculate symmetric key from ecdh parameters | ||
1850 | GNUNET_assert (GNUNET_OK == | ||
1851 | GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity, | ||
1852 | ecdh_key, | ||
1853 | &new_key_hash)); | ||
1854 | create_sym_key_from_ecdh (&new_key_hash, | ||
1855 | &enc_key, | ||
1856 | &enc_iv); | ||
1857 | size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
1858 | rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
1859 | &enc_key, | ||
1860 | &enc_iv, | ||
1861 | buf); | ||
1862 | |||
1863 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1864 | "Decrypted bytes: %zd Expected bytes: %zd\n", | ||
1865 | size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
1866 | GNUNET_STATISTICS_update (stats, | ||
1867 | "abe_key_lookup_time_total", | ||
1868 | GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us, | ||
1869 | GNUNET_YES); | ||
1870 | GNUNET_STATISTICS_update (stats, | ||
1871 | "abe_key_lookups_count", | ||
1872 | 1, | ||
1873 | GNUNET_YES); | ||
1874 | scopes = GNUNET_strdup (buf); | ||
1875 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1876 | "Scopes %s\n", scopes); | ||
1877 | handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1), | ||
1878 | rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) | ||
1879 | - strlen (scopes) - 1); | ||
1880 | |||
1881 | for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ",")) | ||
1882 | { | ||
1883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1884 | "Looking up %s\n", scope); | ||
1885 | parallel_lookup = GNUNET_new (struct ParallelLookup); | ||
1886 | parallel_lookup->handle = handle; | ||
1887 | parallel_lookup->label = GNUNET_strdup (scope); | ||
1888 | parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get(); | ||
1889 | parallel_lookup->lookup_request | ||
1890 | = GNUNET_GNS_lookup (gns_handle, | ||
1891 | scope, | ||
1892 | &handle->ticket.identity, | ||
1893 | GNUNET_GNSRECORD_TYPE_ID_ATTR, | ||
1894 | GNUNET_GNS_LO_DEFAULT, | ||
1895 | &process_parallel_lookup2, | ||
1896 | parallel_lookup); | ||
1897 | GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head, | ||
1898 | handle->parallel_lookups_tail, | ||
1899 | parallel_lookup); | ||
1900 | } | ||
1901 | GNUNET_free (scopes); | ||
1902 | GNUNET_free (buf); | ||
1903 | handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3), | ||
1904 | &abort_parallel_lookups2, | ||
1905 | handle); | ||
1906 | } | ||
1907 | |||
1908 | |||
1909 | static void | ||
1910 | handle_consume_ticket_message (void *cls, | ||
1911 | const struct ConsumeTicketMessage *cm) | ||
1912 | { | ||
1913 | struct ConsumeTicketHandle *ch; | ||
1914 | struct IdpClient *idp = cls; | ||
1915 | char* rnd_label; | ||
1916 | |||
1917 | ch = GNUNET_new (struct ConsumeTicketHandle); | ||
1918 | ch->r_id = ntohl (cm->id); | ||
1919 | ch->client = idp; | ||
1920 | ch->identity = cm->identity; | ||
1921 | ch->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); | ||
1922 | GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity, | ||
1923 | &ch->identity_pub); | ||
1924 | ch->ticket = *((struct GNUNET_RECLAIM_Ticket*)&cm[1]); | ||
1925 | rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd, | ||
1926 | sizeof (uint64_t)); | ||
1927 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1928 | "Looking for ABE key under %s\n", rnd_label); | ||
1929 | ch->lookup_start_time = GNUNET_TIME_absolute_get (); | ||
1930 | ch->lookup_request | ||
1931 | = GNUNET_GNS_lookup (gns_handle, | ||
1932 | rnd_label, | ||
1933 | &ch->ticket.identity, | ||
1934 | GNUNET_GNSRECORD_TYPE_ABE_KEY, | ||
1935 | GNUNET_GNS_LO_DEFAULT, | ||
1936 | &process_consume_abe_key, | ||
1937 | ch); | ||
1938 | GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, | ||
1939 | idp->consume_op_tail, | ||
1940 | ch); | ||
1941 | GNUNET_free (rnd_label); | ||
1942 | GNUNET_SERVICE_client_continue (idp->client); | ||
1943 | } | ||
1944 | |||
1945 | /** | ||
1946 | * Cleanup attribute store handle | ||
1947 | * | ||
1948 | * @param handle handle to clean up | ||
1949 | */ | ||
1950 | static void | ||
1951 | cleanup_as_handle (struct AttributeStoreHandle *handle) | ||
1952 | { | ||
1953 | if (NULL != handle->ns_qe) | ||
1954 | GNUNET_NAMESTORE_cancel (handle->ns_qe); | ||
1955 | if (NULL != handle->claim) | ||
1956 | GNUNET_free (handle->claim); | ||
1957 | if (NULL != handle->abe_key) | ||
1958 | GNUNET_ABE_cpabe_delete_master_key (handle->abe_key); | ||
1959 | GNUNET_free (handle); | ||
1960 | } | ||
1961 | |||
1962 | static void | ||
1963 | attr_store_cont (void *cls, | ||
1964 | int32_t success, | ||
1965 | const char *emsg) | ||
1966 | { | ||
1967 | struct AttributeStoreHandle *as_handle = cls; | ||
1968 | struct GNUNET_MQ_Envelope *env; | ||
1969 | struct AttributeStoreResultMessage *acr_msg; | ||
1970 | |||
1971 | as_handle->ns_qe = NULL; | ||
1972 | GNUNET_CONTAINER_DLL_remove (as_handle->client->store_op_head, | ||
1973 | as_handle->client->store_op_tail, | ||
1974 | as_handle); | ||
1975 | |||
1976 | if (GNUNET_SYSERR == success) | ||
1977 | { | ||
1978 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1979 | "Failed to store attribute %s\n", | ||
1980 | emsg); | ||
1981 | cleanup_as_handle (as_handle); | ||
1982 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1983 | return; | ||
1984 | } | ||
1985 | |||
1986 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1987 | "Sending ATTRIBUTE_STORE_RESPONSE message\n"); | ||
1988 | env = GNUNET_MQ_msg (acr_msg, | ||
1989 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE); | ||
1990 | acr_msg->id = htonl (as_handle->r_id); | ||
1991 | acr_msg->op_result = htonl (GNUNET_OK); | ||
1992 | GNUNET_MQ_send (as_handle->client->mq, | ||
1993 | env); | ||
1994 | cleanup_as_handle (as_handle); | ||
1995 | } | ||
1996 | |||
1997 | static void | ||
1998 | attr_store_task (void *cls) | ||
1999 | { | ||
2000 | struct AttributeStoreHandle *as_handle = cls; | ||
2001 | struct GNUNET_GNSRECORD_Data rd[1]; | ||
2002 | char* buf; | ||
2003 | char* policy; | ||
2004 | char* enc_buf; | ||
2005 | char* rd_buf; | ||
2006 | size_t enc_size; | ||
2007 | size_t buf_size; | ||
2008 | uint32_t attr_ver; | ||
2009 | |||
2010 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2011 | "Storing attribute\n"); | ||
2012 | buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (as_handle->claim); | ||
2013 | buf = GNUNET_malloc (buf_size); | ||
2014 | |||
2015 | GNUNET_RECLAIM_ATTRIBUTE_serialize (as_handle->claim, | ||
2016 | buf); | ||
2017 | |||
2018 | GNUNET_asprintf (&policy, | ||
2019 | "%s_%lu", | ||
2020 | as_handle->claim->name, | ||
2021 | as_handle->claim->version); | ||
2022 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2023 | "Encrypting with policy %s\n", policy); | ||
2024 | /** | ||
2025 | * Encrypt the attribute value and store in namestore | ||
2026 | */ | ||
2027 | enc_size = GNUNET_ABE_cpabe_encrypt (buf, | ||
2028 | buf_size, | ||
2029 | policy, //Policy | ||
2030 | as_handle->abe_key, | ||
2031 | (void**)&enc_buf); | ||
2032 | if (GNUNET_SYSERR == enc_size) | ||
2033 | { | ||
2034 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2035 | "Failed to encrypt with policy %s\n", | ||
2036 | policy); | ||
2037 | GNUNET_CONTAINER_DLL_remove (as_handle->client->store_op_head, | ||
2038 | as_handle->client->store_op_tail, | ||
2039 | as_handle); | ||
2040 | |||
2041 | cleanup_as_handle (as_handle); | ||
2042 | GNUNET_free (buf); | ||
2043 | GNUNET_free (policy); | ||
2044 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
2045 | return; | ||
2046 | } | ||
2047 | GNUNET_free (buf); | ||
2048 | GNUNET_free (policy); | ||
2049 | rd[0].data_size = enc_size + sizeof (uint32_t); | ||
2050 | rd_buf = GNUNET_malloc (rd[0].data_size); | ||
2051 | attr_ver = htonl (as_handle->claim->version); | ||
2052 | GNUNET_memcpy (rd_buf, | ||
2053 | &attr_ver, | ||
2054 | sizeof (uint32_t)); | ||
2055 | GNUNET_memcpy (rd_buf+sizeof (uint32_t), | ||
2056 | enc_buf, | ||
2057 | enc_size); | ||
2058 | rd[0].data = rd_buf; | ||
2059 | rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; | ||
2060 | rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
2061 | rd[0].expiration_time = as_handle->exp.rel_value_us; | ||
2062 | as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
2063 | &as_handle->identity, | ||
2064 | as_handle->claim->name, | ||
2065 | 1, | ||
2066 | rd, | ||
2067 | &attr_store_cont, | ||
2068 | as_handle); | ||
2069 | GNUNET_free (enc_buf); | ||
2070 | GNUNET_free (rd_buf); | ||
2071 | } | ||
2072 | |||
2073 | |||
2074 | static void | ||
2075 | store_after_abe_bootstrap (void *cls, | ||
2076 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
2077 | { | ||
2078 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2079 | "Finished ABE bootstrap\n"); | ||
2080 | struct AttributeStoreHandle *ash = cls; | ||
2081 | ash->abe_key = abe_key; | ||
2082 | GNUNET_SCHEDULER_add_now (&attr_store_task, ash); | ||
2083 | } | ||
2084 | |||
2085 | static int | ||
2086 | check_attribute_store_message(void *cls, | ||
2087 | const struct AttributeStoreMessage *sam) | ||
2088 | { | ||
2089 | uint16_t size; | ||
2090 | |||
2091 | size = ntohs (sam->header.size); | ||
2092 | if (size <= sizeof (struct AttributeStoreMessage)) | ||
2093 | { | ||
2094 | GNUNET_break (0); | ||
2095 | return GNUNET_SYSERR; | ||
2096 | } | ||
2097 | return GNUNET_OK; | ||
2098 | } | ||
2099 | |||
2100 | |||
2101 | static void | ||
2102 | handle_attribute_store_message (void *cls, | ||
2103 | const struct AttributeStoreMessage *sam) | ||
2104 | { | ||
2105 | struct AttributeStoreHandle *as_handle; | ||
2106 | struct IdpClient *idp = cls; | ||
2107 | size_t data_len; | ||
2108 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2109 | "Received ATTRIBUTE_STORE message\n"); | ||
2110 | |||
2111 | data_len = ntohs (sam->attr_len); | ||
2112 | |||
2113 | as_handle = GNUNET_new (struct AttributeStoreHandle); | ||
2114 | as_handle->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&sam[1], | ||
2115 | data_len); | ||
2116 | |||
2117 | as_handle->r_id = ntohl (sam->id); | ||
2118 | as_handle->identity = sam->identity; | ||
2119 | as_handle->exp.rel_value_us = GNUNET_ntohll (sam->exp); | ||
2120 | GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, | ||
2121 | &as_handle->identity_pkey); | ||
2122 | |||
2123 | GNUNET_SERVICE_client_continue (idp->client); | ||
2124 | as_handle->client = idp; | ||
2125 | GNUNET_CONTAINER_DLL_insert (idp->store_op_head, | ||
2126 | idp->store_op_tail, | ||
2127 | as_handle); | ||
2128 | bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO); | ||
2129 | } | ||
2130 | |||
2131 | static void | ||
2132 | cleanup_attribute_iter_handle (struct AttributeIterator *ai) | ||
2133 | { | ||
2134 | if (NULL != ai->abe_key) | ||
2135 | GNUNET_ABE_cpabe_delete_master_key (ai->abe_key); | ||
2136 | GNUNET_free (ai); | ||
2137 | } | ||
2138 | |||
2139 | static void | ||
2140 | attr_iter_error (void *cls) | ||
2141 | { | ||
2142 | struct AttributeIterator *ai = cls; | ||
2143 | //TODO | ||
2144 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2145 | "Failed to iterate over attributes\n"); | ||
2146 | GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head, | ||
2147 | ai->client->attr_iter_tail, | ||
2148 | ai); | ||
2149 | cleanup_attribute_iter_handle (ai); | ||
2150 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
2151 | } | ||
2152 | |||
2153 | static void | ||
2154 | attr_iter_finished (void *cls) | ||
2155 | { | ||
2156 | struct AttributeIterator *ai = cls; | ||
2157 | struct GNUNET_MQ_Envelope *env; | ||
2158 | struct AttributeResultMessage *arm; | ||
2159 | |||
2160 | env = GNUNET_MQ_msg (arm, | ||
2161 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); | ||
2162 | arm->id = htonl (ai->request_id); | ||
2163 | arm->attr_len = htons (0); | ||
2164 | GNUNET_MQ_send (ai->client->mq, env); | ||
2165 | GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head, | ||
2166 | ai->client->attr_iter_tail, | ||
2167 | ai); | ||
2168 | cleanup_attribute_iter_handle (ai); | ||
2169 | } | ||
2170 | |||
2171 | static void | ||
2172 | attr_iter_cb (void *cls, | ||
2173 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
2174 | const char *label, | ||
2175 | unsigned int rd_count, | ||
2176 | const struct GNUNET_GNSRECORD_Data *rd) | ||
2177 | { | ||
2178 | struct AttributeIterator *ai = cls; | ||
2179 | struct AttributeResultMessage *arm; | ||
2180 | struct GNUNET_ABE_AbeKey *key; | ||
2181 | struct GNUNET_MQ_Envelope *env; | ||
2182 | ssize_t msg_extra_len; | ||
2183 | char* attr_ser; | ||
2184 | char* attrs[2]; | ||
2185 | char* data_tmp; | ||
2186 | char* policy; | ||
2187 | uint32_t attr_ver; | ||
2188 | |||
2189 | if (rd_count != 1) | ||
2190 | { | ||
2191 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, | ||
2192 | 1); | ||
2193 | return; | ||
2194 | } | ||
2195 | |||
2196 | if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) | ||
2197 | { | ||
2198 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, | ||
2199 | 1); | ||
2200 | return; | ||
2201 | } | ||
2202 | attr_ver = ntohl(*((uint32_t*)rd->data)); | ||
2203 | GNUNET_asprintf (&policy, "%s_%lu", | ||
2204 | label, attr_ver); | ||
2205 | attrs[0] = policy; | ||
2206 | attrs[1] = 0; | ||
2207 | key = GNUNET_ABE_cpabe_create_key (ai->abe_key, | ||
2208 | attrs); | ||
2209 | msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t), | ||
2210 | rd->data_size-sizeof (uint32_t), | ||
2211 | key, | ||
2212 | (void**)&attr_ser); | ||
2213 | if (GNUNET_SYSERR == msg_extra_len) | ||
2214 | { | ||
2215 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, | ||
2216 | 1); | ||
2217 | return; | ||
2218 | } | ||
2219 | |||
2220 | GNUNET_ABE_cpabe_delete_key (key, | ||
2221 | GNUNET_YES); | ||
2222 | //GNUNET_free (policy); | ||
2223 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2224 | "Found attribute: %s\n", label); | ||
2225 | env = GNUNET_MQ_msg_extra (arm, | ||
2226 | msg_extra_len, | ||
2227 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); | ||
2228 | arm->id = htonl (ai->request_id); | ||
2229 | arm->attr_len = htons (msg_extra_len); | ||
2230 | GNUNET_CRYPTO_ecdsa_key_get_public (zone, | ||
2231 | &arm->identity); | ||
2232 | data_tmp = (char *) &arm[1]; | ||
2233 | GNUNET_memcpy (data_tmp, | ||
2234 | attr_ser, | ||
2235 | msg_extra_len); | ||
2236 | GNUNET_MQ_send (ai->client->mq, env); | ||
2237 | GNUNET_free (attr_ser); | ||
2238 | GNUNET_ABE_cpabe_delete_master_key (ai->abe_key); | ||
2239 | ai->abe_key = NULL; | ||
2240 | } | ||
2241 | |||
2242 | |||
2243 | void | ||
2244 | iterate_after_abe_bootstrap (void *cls, | ||
2245 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
2246 | { | ||
2247 | struct AttributeIterator *ai = cls; | ||
2248 | ai->abe_key = abe_key; | ||
2249 | ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | ||
2250 | &ai->identity, | ||
2251 | &attr_iter_error, | ||
2252 | ai, | ||
2253 | &attr_iter_cb, | ||
2254 | ai, | ||
2255 | &attr_iter_finished, | ||
2256 | ai); | ||
2257 | } | ||
2258 | |||
2259 | |||
2260 | static void | ||
2261 | iterate_next_after_abe_bootstrap (void *cls, | ||
2262 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
2263 | { | ||
2264 | struct AttributeIterator *ai = cls; | ||
2265 | ai->abe_key = abe_key; | ||
2266 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, | ||
2267 | 1); | ||
2268 | } | ||
2269 | |||
2270 | |||
2271 | |||
2272 | static void | ||
2273 | handle_iteration_start (void *cls, | ||
2274 | const struct AttributeIterationStartMessage *ais_msg) | ||
2275 | { | ||
2276 | struct IdpClient *idp = cls; | ||
2277 | struct AttributeIterator *ai; | ||
2278 | |||
2279 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2280 | "Received ATTRIBUTE_ITERATION_START message\n"); | ||
2281 | ai = GNUNET_new (struct AttributeIterator); | ||
2282 | ai->request_id = ntohl (ais_msg->id); | ||
2283 | ai->client = idp; | ||
2284 | ai->identity = ais_msg->identity; | ||
2285 | |||
2286 | GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, | ||
2287 | idp->attr_iter_tail, | ||
2288 | ai); | ||
2289 | bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO); | ||
2290 | GNUNET_SERVICE_client_continue (idp->client); | ||
2291 | } | ||
2292 | |||
2293 | |||
2294 | static void | ||
2295 | handle_iteration_stop (void *cls, | ||
2296 | const struct AttributeIterationStopMessage *ais_msg) | ||
2297 | { | ||
2298 | struct IdpClient *idp = cls; | ||
2299 | struct AttributeIterator *ai; | ||
2300 | uint32_t rid; | ||
2301 | |||
2302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2303 | "Received `%s' message\n", | ||
2304 | "ATTRIBUTE_ITERATION_STOP"); | ||
2305 | rid = ntohl (ais_msg->id); | ||
2306 | for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next) | ||
2307 | if (ai->request_id == rid) | ||
2308 | break; | ||
2309 | if (NULL == ai) | ||
2310 | { | ||
2311 | GNUNET_break (0); | ||
2312 | GNUNET_SERVICE_client_drop (idp->client); | ||
2313 | return; | ||
2314 | } | ||
2315 | GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, | ||
2316 | idp->attr_iter_tail, | ||
2317 | ai); | ||
2318 | GNUNET_free (ai); | ||
2319 | GNUNET_SERVICE_client_continue (idp->client); | ||
2320 | } | ||
2321 | |||
2322 | |||
2323 | static void | ||
2324 | handle_iteration_next (void *cls, | ||
2325 | const struct AttributeIterationNextMessage *ais_msg) | ||
2326 | { | ||
2327 | struct IdpClient *idp = cls; | ||
2328 | struct AttributeIterator *ai; | ||
2329 | uint32_t rid; | ||
2330 | |||
2331 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2332 | "Received ATTRIBUTE_ITERATION_NEXT message\n"); | ||
2333 | rid = ntohl (ais_msg->id); | ||
2334 | for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next) | ||
2335 | if (ai->request_id == rid) | ||
2336 | break; | ||
2337 | if (NULL == ai) | ||
2338 | { | ||
2339 | GNUNET_break (0); | ||
2340 | GNUNET_SERVICE_client_drop (idp->client); | ||
2341 | return; | ||
2342 | } | ||
2343 | bootstrap_abe (&ai->identity, | ||
2344 | &iterate_next_after_abe_bootstrap, | ||
2345 | ai, | ||
2346 | GNUNET_NO); | ||
2347 | GNUNET_SERVICE_client_continue (idp->client); | ||
2348 | } | ||
2349 | |||
2350 | /** | ||
2351 | * Ticket iteration processor result | ||
2352 | */ | ||
2353 | enum ZoneIterationResult | ||
2354 | { | ||
2355 | /** | ||
2356 | * Iteration start. | ||
2357 | */ | ||
2358 | IT_START = 0, | ||
2359 | |||
2360 | /** | ||
2361 | * Found tickets, | ||
2362 | * Continue to iterate with next iteration_next call | ||
2363 | */ | ||
2364 | IT_SUCCESS_MORE_AVAILABLE = 1, | ||
2365 | |||
2366 | /** | ||
2367 | * Iteration complete | ||
2368 | */ | ||
2369 | IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2 | ||
2370 | }; | ||
2371 | |||
2372 | |||
2373 | /** | ||
2374 | * Context for ticket iteration | ||
2375 | */ | ||
2376 | struct TicketIterationProcResult | ||
2377 | { | ||
2378 | /** | ||
2379 | * The ticket iteration handle | ||
2380 | */ | ||
2381 | struct TicketIteration *ti; | ||
2382 | |||
2383 | /** | ||
2384 | * Iteration result: iteration done? | ||
2385 | * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but | ||
2386 | * we got one for now and have sent it to the client | ||
2387 | * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results, | ||
2388 | * #IT_START: if we are still trying to find a result. | ||
2389 | */ | ||
2390 | int res_iteration_finished; | ||
2391 | |||
2392 | }; | ||
2393 | |||
2394 | static void | ||
2395 | cleanup_ticket_iter_handle (struct TicketIteration *ti) | ||
2396 | { | ||
2397 | GNUNET_free (ti); | ||
2398 | } | ||
2399 | |||
2400 | /** | ||
2401 | * Process ticket from database | ||
2402 | * | ||
2403 | * @param cls struct TicketIterationProcResult | ||
2404 | * @param ticket the ticket | ||
2405 | * @param attrs the attributes | ||
2406 | */ | ||
2407 | static void | ||
2408 | ticket_iterate_proc (void *cls, | ||
2409 | const struct GNUNET_RECLAIM_Ticket *ticket, | ||
2410 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) | ||
2411 | { | ||
2412 | struct TicketIterationProcResult *proc = cls; | ||
2413 | |||
2414 | if (NULL == ticket) | ||
2415 | { | ||
2416 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2417 | "Iteration done\n"); | ||
2418 | proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE; | ||
2419 | return; | ||
2420 | } | ||
2421 | proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE; | ||
2422 | send_ticket_result (proc->ti->client, | ||
2423 | proc->ti->r_id, | ||
2424 | ticket, | ||
2425 | attrs); | ||
2426 | |||
2427 | } | ||
2428 | |||
2429 | /** | ||
2430 | * Perform ticket iteration step | ||
2431 | * | ||
2432 | * @param ti ticket iterator to process | ||
2433 | */ | ||
2434 | static void | ||
2435 | run_ticket_iteration_round (struct TicketIteration *ti) | ||
2436 | { | ||
2437 | struct TicketIterationProcResult proc; | ||
2438 | struct GNUNET_MQ_Envelope *env; | ||
2439 | struct TicketResultMessage *trm; | ||
2440 | int ret; | ||
2441 | |||
2442 | memset (&proc, 0, sizeof (proc)); | ||
2443 | proc.ti = ti; | ||
2444 | proc.res_iteration_finished = IT_START; | ||
2445 | while (IT_START == proc.res_iteration_finished) | ||
2446 | { | ||
2447 | if (GNUNET_SYSERR == | ||
2448 | (ret = TKT_database->iterate_tickets (TKT_database->cls, | ||
2449 | &ti->identity, | ||
2450 | ti->is_audience, | ||
2451 | ti->offset, | ||
2452 | &ticket_iterate_proc, | ||
2453 | &proc))) | ||
2454 | { | ||
2455 | GNUNET_break (0); | ||
2456 | break; | ||
2457 | } | ||
2458 | if (GNUNET_NO == ret) | ||
2459 | proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE; | ||
2460 | ti->offset++; | ||
2461 | } | ||
2462 | if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished) | ||
2463 | { | ||
2464 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2465 | "More results available\n"); | ||
2466 | return; /* more later */ | ||
2467 | } | ||
2468 | /* send empty response to indicate end of list */ | ||
2469 | env = GNUNET_MQ_msg (trm, | ||
2470 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); | ||
2471 | trm->id = htonl (ti->r_id); | ||
2472 | GNUNET_MQ_send (ti->client->mq, | ||
2473 | env); | ||
2474 | GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head, | ||
2475 | ti->client->ticket_iter_tail, | ||
2476 | ti); | ||
2477 | cleanup_ticket_iter_handle (ti); | ||
2478 | } | ||
2479 | |||
2480 | static void | ||
2481 | handle_ticket_iteration_start (void *cls, | ||
2482 | const struct TicketIterationStartMessage *tis_msg) | ||
2483 | { | ||
2484 | struct IdpClient *client = cls; | ||
2485 | struct TicketIteration *ti; | ||
2486 | |||
2487 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2488 | "Received TICKET_ITERATION_START message\n"); | ||
2489 | ti = GNUNET_new (struct TicketIteration); | ||
2490 | ti->r_id = ntohl (tis_msg->id); | ||
2491 | ti->offset = 0; | ||
2492 | ti->client = client; | ||
2493 | ti->identity = tis_msg->identity; | ||
2494 | ti->is_audience = ntohl (tis_msg->is_audience); | ||
2495 | |||
2496 | GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head, | ||
2497 | client->ticket_iter_tail, | ||
2498 | ti); | ||
2499 | run_ticket_iteration_round (ti); | ||
2500 | GNUNET_SERVICE_client_continue (client->client); | ||
2501 | } | ||
2502 | |||
2503 | |||
2504 | static void | ||
2505 | handle_ticket_iteration_stop (void *cls, | ||
2506 | const struct TicketIterationStopMessage *tis_msg) | ||
2507 | { | ||
2508 | struct IdpClient *client = cls; | ||
2509 | struct TicketIteration *ti; | ||
2510 | uint32_t rid; | ||
2511 | |||
2512 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2513 | "Received `%s' message\n", | ||
2514 | "TICKET_ITERATION_STOP"); | ||
2515 | rid = ntohl (tis_msg->id); | ||
2516 | for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next) | ||
2517 | if (ti->r_id == rid) | ||
2518 | break; | ||
2519 | if (NULL == ti) | ||
2520 | { | ||
2521 | GNUNET_break (0); | ||
2522 | GNUNET_SERVICE_client_drop (client->client); | ||
2523 | return; | ||
2524 | } | ||
2525 | GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head, | ||
2526 | client->ticket_iter_tail, | ||
2527 | ti); | ||
2528 | cleanup_ticket_iter_handle (ti); | ||
2529 | GNUNET_SERVICE_client_continue (client->client); | ||
2530 | } | ||
2531 | |||
2532 | |||
2533 | static void | ||
2534 | handle_ticket_iteration_next (void *cls, | ||
2535 | const struct TicketIterationNextMessage *tis_msg) | ||
2536 | { | ||
2537 | struct IdpClient *client = cls; | ||
2538 | struct TicketIteration *ti; | ||
2539 | uint32_t rid; | ||
2540 | |||
2541 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2542 | "Received TICKET_ITERATION_NEXT message\n"); | ||
2543 | rid = ntohl (tis_msg->id); | ||
2544 | for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next) | ||
2545 | if (ti->r_id == rid) | ||
2546 | break; | ||
2547 | if (NULL == ti) | ||
2548 | { | ||
2549 | GNUNET_break (0); | ||
2550 | GNUNET_SERVICE_client_drop (client->client); | ||
2551 | return; | ||
2552 | } | ||
2553 | run_ticket_iteration_round (ti); | ||
2554 | GNUNET_SERVICE_client_continue (client->client); | ||
2555 | } | ||
2556 | |||
2557 | |||
2558 | |||
2559 | |||
2560 | /** | ||
2561 | * Main function that will be run | ||
2562 | * | ||
2563 | * @param cls closure | ||
2564 | * @param c the configuration used | ||
2565 | * @param server the service handle | ||
2566 | */ | ||
2567 | static void | ||
2568 | run (void *cls, | ||
2569 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
2570 | struct GNUNET_SERVICE_Handle *server) | ||
2571 | { | ||
2572 | char *database; | ||
2573 | cfg = c; | ||
2574 | |||
2575 | stats = GNUNET_STATISTICS_create ("reclaim", cfg); | ||
2576 | |||
2577 | //Connect to identity and namestore services | ||
2578 | ns_handle = GNUNET_NAMESTORE_connect (cfg); | ||
2579 | if (NULL == ns_handle) | ||
2580 | { | ||
2581 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore"); | ||
2582 | } | ||
2583 | |||
2584 | gns_handle = GNUNET_GNS_connect (cfg); | ||
2585 | if (NULL == gns_handle) | ||
2586 | { | ||
2587 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns"); | ||
2588 | } | ||
2589 | credential_handle = GNUNET_CREDENTIAL_connect (cfg); | ||
2590 | if (NULL == credential_handle) | ||
2591 | { | ||
2592 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential"); | ||
2593 | } | ||
2594 | identity_handle = GNUNET_IDENTITY_connect (cfg, | ||
2595 | NULL, | ||
2596 | NULL); | ||
2597 | /* Loading DB plugin */ | ||
2598 | if (GNUNET_OK != | ||
2599 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
2600 | "reclaim", | ||
2601 | "database", | ||
2602 | &database)) | ||
2603 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2604 | "No database backend configured\n"); | ||
2605 | GNUNET_asprintf (&db_lib_name, | ||
2606 | "libgnunet_plugin_reclaim_%s", | ||
2607 | database); | ||
2608 | TKT_database = GNUNET_PLUGIN_load (db_lib_name, | ||
2609 | (void *) cfg); | ||
2610 | GNUNET_free (database); | ||
2611 | if (NULL == TKT_database) | ||
2612 | { | ||
2613 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2614 | "Could not load database backend `%s'\n", | ||
2615 | db_lib_name); | ||
2616 | GNUNET_SCHEDULER_shutdown (); | ||
2617 | return; | ||
2618 | } | ||
2619 | |||
2620 | if (GNUNET_OK == | ||
2621 | GNUNET_CONFIGURATION_get_value_time (cfg, | ||
2622 | "reclaim", | ||
2623 | "TOKEN_EXPIRATION_INTERVAL", | ||
2624 | &token_expiration_interval)) | ||
2625 | { | ||
2626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2627 | "Time window for zone iteration: %s\n", | ||
2628 | GNUNET_STRINGS_relative_time_to_string (token_expiration_interval, | ||
2629 | GNUNET_YES)); | ||
2630 | } else { | ||
2631 | token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL; | ||
2632 | } | ||
2633 | |||
2634 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | ||
2635 | } | ||
2636 | |||
2637 | /** | ||
2638 | * Called whenever a client is disconnected. | ||
2639 | * | ||
2640 | * @param cls closure | ||
2641 | * @param client identification of the client | ||
2642 | * @param app_ctx @a client | ||
2643 | */ | ||
2644 | static void | ||
2645 | client_disconnect_cb (void *cls, | ||
2646 | struct GNUNET_SERVICE_Client *client, | ||
2647 | void *app_ctx) | ||
2648 | { | ||
2649 | struct IdpClient *idp = app_ctx; | ||
2650 | struct AttributeIterator *ai; | ||
2651 | struct TicketIteration *ti; | ||
2652 | struct TicketRevocationHandle *rh; | ||
2653 | struct TicketIssueHandle *iss; | ||
2654 | struct ConsumeTicketHandle *ct; | ||
2655 | struct AttributeStoreHandle *as; | ||
2656 | |||
2657 | //TODO other operations | ||
2658 | |||
2659 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2660 | "Client %p disconnected\n", | ||
2661 | client); | ||
2662 | |||
2663 | while (NULL != (iss = idp->issue_op_head)) | ||
2664 | { | ||
2665 | GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, | ||
2666 | idp->issue_op_tail, | ||
2667 | iss); | ||
2668 | cleanup_ticket_issue_handle (iss); | ||
2669 | } | ||
2670 | while (NULL != (ct = idp->consume_op_head)) | ||
2671 | { | ||
2672 | GNUNET_CONTAINER_DLL_remove (idp->consume_op_head, | ||
2673 | idp->consume_op_tail, | ||
2674 | ct); | ||
2675 | cleanup_consume_ticket_handle (ct); | ||
2676 | } | ||
2677 | while (NULL != (as = idp->store_op_head)) | ||
2678 | { | ||
2679 | GNUNET_CONTAINER_DLL_remove (idp->store_op_head, | ||
2680 | idp->store_op_tail, | ||
2681 | as); | ||
2682 | cleanup_as_handle (as); | ||
2683 | } | ||
2684 | |||
2685 | while (NULL != (ai = idp->attr_iter_head)) | ||
2686 | { | ||
2687 | GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, | ||
2688 | idp->attr_iter_tail, | ||
2689 | ai); | ||
2690 | cleanup_attribute_iter_handle (ai); | ||
2691 | } | ||
2692 | while (NULL != (rh = idp->revoke_op_head)) | ||
2693 | { | ||
2694 | GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, | ||
2695 | idp->revoke_op_tail, | ||
2696 | rh); | ||
2697 | cleanup_revoke_ticket_handle (rh); | ||
2698 | } | ||
2699 | while (NULL != (ti = idp->ticket_iter_head)) | ||
2700 | { | ||
2701 | GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head, | ||
2702 | idp->ticket_iter_tail, | ||
2703 | ti); | ||
2704 | cleanup_ticket_iter_handle (ti); | ||
2705 | } | ||
2706 | GNUNET_free (idp); | ||
2707 | } | ||
2708 | |||
2709 | |||
2710 | /** | ||
2711 | * Add a client to our list of active clients. | ||
2712 | * | ||
2713 | * @param cls NULL | ||
2714 | * @param client client to add | ||
2715 | * @param mq message queue for @a client | ||
2716 | * @return internal namestore client structure for this client | ||
2717 | */ | ||
2718 | static void * | ||
2719 | client_connect_cb (void *cls, | ||
2720 | struct GNUNET_SERVICE_Client *client, | ||
2721 | struct GNUNET_MQ_Handle *mq) | ||
2722 | { | ||
2723 | struct IdpClient *idp; | ||
2724 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2725 | "Client %p connected\n", | ||
2726 | client); | ||
2727 | idp = GNUNET_new (struct IdpClient); | ||
2728 | idp->client = client; | ||
2729 | idp->mq = mq; | ||
2730 | return idp; | ||
2731 | } | ||
2732 | |||
2733 | |||
2734 | |||
2735 | /** | ||
2736 | * Define "main" method using service macro. | ||
2737 | */ | ||
2738 | GNUNET_SERVICE_MAIN | ||
2739 | ("reclaim", | ||
2740 | GNUNET_SERVICE_OPTION_NONE, | ||
2741 | &run, | ||
2742 | &client_connect_cb, | ||
2743 | &client_disconnect_cb, | ||
2744 | NULL, | ||
2745 | GNUNET_MQ_hd_var_size (attribute_store_message, | ||
2746 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE, | ||
2747 | struct AttributeStoreMessage, | ||
2748 | NULL), | ||
2749 | GNUNET_MQ_hd_fixed_size (iteration_start, | ||
2750 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, | ||
2751 | struct AttributeIterationStartMessage, | ||
2752 | NULL), | ||
2753 | GNUNET_MQ_hd_fixed_size (iteration_next, | ||
2754 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT, | ||
2755 | struct AttributeIterationNextMessage, | ||
2756 | NULL), | ||
2757 | GNUNET_MQ_hd_fixed_size (iteration_stop, | ||
2758 | GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP, | ||
2759 | struct AttributeIterationStopMessage, | ||
2760 | NULL), | ||
2761 | GNUNET_MQ_hd_var_size (issue_ticket_message, | ||
2762 | GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET, | ||
2763 | struct IssueTicketMessage, | ||
2764 | NULL), | ||
2765 | GNUNET_MQ_hd_var_size (consume_ticket_message, | ||
2766 | GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET, | ||
2767 | struct ConsumeTicketMessage, | ||
2768 | NULL), | ||
2769 | GNUNET_MQ_hd_fixed_size (ticket_iteration_start, | ||
2770 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START, | ||
2771 | struct TicketIterationStartMessage, | ||
2772 | NULL), | ||
2773 | GNUNET_MQ_hd_fixed_size (ticket_iteration_next, | ||
2774 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT, | ||
2775 | struct TicketIterationNextMessage, | ||
2776 | NULL), | ||
2777 | GNUNET_MQ_hd_fixed_size (ticket_iteration_stop, | ||
2778 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP, | ||
2779 | struct TicketIterationStopMessage, | ||
2780 | NULL), | ||
2781 | GNUNET_MQ_hd_var_size (revoke_ticket_message, | ||
2782 | GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET, | ||
2783 | struct RevokeTicketMessage, | ||
2784 | NULL), | ||
2785 | GNUNET_MQ_handler_end()); | ||
2786 | /* end of gnunet-service-reclaim.c */ | ||