2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @author Martin Schanzenbach
22 * @file src/reclaim/gnunet-reclaim.c
23 * @brief Identity Provider utility
29 #include "gnunet_util_lib.h"
31 #include "gnunet_identity_service.h"
32 #include "gnunet_namestore_service.h"
33 #include "gnunet_reclaim_service.h"
34 #include "gnunet_signatures.h"
53 static char *attr_name;
58 static char *attr_value;
63 static char *issue_attrs;
68 static char *consume_ticket;
73 static char *type_str;
78 static char *revoke_ticket;
83 static int list_tickets;
88 static char *ego_name;
93 static struct GNUNET_IDENTITY_Handle *identity_handle;
98 static struct GNUNET_RECLAIM_Handle *reclaim_handle;
103 static struct GNUNET_RECLAIM_Operation *reclaim_op;
108 static struct GNUNET_RECLAIM_AttributeIterator *attr_iterator;
113 static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator;
118 static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
123 static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
128 static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key;
133 static struct GNUNET_RECLAIM_Ticket ticket;
138 static struct GNUNET_RECLAIM_AttributeList *attr_list;
141 * Attribute expiration interval
143 static struct GNUNET_TIME_Relative exp_interval;
148 static struct GNUNET_SCHEDULER_Task *timeout;
153 static struct GNUNET_SCHEDULER_Task *cleanup_task;
158 struct GNUNET_RECLAIM_Attribute *claim;
163 static char *attr_delete;
166 * Claim object to delete
168 static struct GNUNET_RECLAIM_Attribute *attr_to_delete;
171 do_cleanup (void *cls)
175 GNUNET_SCHEDULER_cancel (timeout);
176 if (NULL != reclaim_op)
177 GNUNET_RECLAIM_cancel (reclaim_op);
178 if (NULL != attr_iterator)
179 GNUNET_RECLAIM_get_attributes_stop (attr_iterator);
180 if (NULL != ticket_iterator)
181 GNUNET_RECLAIM_ticket_iteration_stop (ticket_iterator);
182 if (NULL != reclaim_handle)
183 GNUNET_RECLAIM_disconnect (reclaim_handle);
184 if (NULL != identity_handle)
185 GNUNET_IDENTITY_disconnect (identity_handle);
187 GNUNET_free (abe_key);
188 if (NULL != attr_list)
189 GNUNET_free (attr_list);
190 if (NULL != attr_to_delete)
191 GNUNET_free (attr_to_delete);
196 ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
204 GNUNET_STRINGS_data_to_string_alloc (ticket,
206 struct GNUNET_RECLAIM_Ticket));
207 printf ("%s\n", ticket_str);
208 GNUNET_free (ticket_str);
210 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
215 store_attr_cont (void *cls, int32_t success, const char *emsg)
218 if (GNUNET_SYSERR == success)
220 fprintf (stderr, "%s\n", emsg);
222 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
227 process_attrs (void *cls,
228 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
229 const struct GNUNET_RECLAIM_Attribute *attr,
230 const struct GNUNET_RECLAIM_Attestation *attest)
234 const char *attr_type;
236 if (NULL == identity)
239 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
247 value_str = GNUNET_RECLAIM_attribute_value_to_string (attr->type,
250 attr_type = GNUNET_RECLAIM_attribute_number_to_typename (attr->type);
251 id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(attr->id));
253 "Name: %s; Value: %s (%s); Flag %u; ID: %s %s\n",
259 (NULL == attest) ? "" : "ATTESTED");
265 ticket_iter_err (void *cls)
267 ticket_iterator = NULL;
268 fprintf (stderr, "Failed to iterate over tickets\n");
269 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
274 ticket_iter_fin (void *cls)
276 ticket_iterator = NULL;
277 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
282 ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
289 GNUNET_STRINGS_data_to_string_alloc (&ticket->audience,
291 GNUNET_CRYPTO_EcdsaPublicKey));
292 ref = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(ticket->rnd));
294 GNUNET_STRINGS_data_to_string_alloc (ticket,
295 sizeof(struct GNUNET_RECLAIM_Ticket));
296 fprintf (stdout, "Ticket: %s | ID: %s | Audience: %s\n", tkt, ref, aud);
300 GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator);
305 iter_error (void *cls)
307 attr_iterator = NULL;
308 fprintf (stderr, "Failed to iterate over attributes\n");
309 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
314 timeout_task (void *cls)
318 fprintf (stderr, "Timeout\n");
319 if (NULL == cleanup_task)
320 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
325 process_rvk (void *cls, int success, const char *msg)
328 if (GNUNET_OK != success)
330 fprintf (stderr, "Revocation failed.\n");
333 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
338 process_delete (void *cls, int success, const char *msg)
341 if (GNUNET_OK != success)
343 fprintf (stderr, "Deletion failed.\n");
346 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
351 iter_finished (void *cls)
357 attr_iterator = NULL;
360 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
366 reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle,
376 reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle,
381 timeout = GNUNET_SCHEDULER_add_delayed (
382 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
389 reclaim_op = GNUNET_RECLAIM_ticket_revoke (reclaim_handle,
398 if (NULL == attr_to_delete)
400 fprintf (stdout, "No such attribute ``%s''\n", attr_delete);
403 reclaim_op = GNUNET_RECLAIM_attribute_delete (reclaim_handle,
412 if (NULL == type_str)
413 type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING;
415 type = GNUNET_RECLAIM_attribute_typename_to_number (type_str);
417 GNUNET_assert (GNUNET_SYSERR !=
418 GNUNET_RECLAIM_attribute_string_to_value (type,
426 claim->data_size = data_size;
431 GNUNET_RECLAIM_attribute_new (attr_name, NULL, type, data, data_size);
433 reclaim_op = GNUNET_RECLAIM_attribute_store (reclaim_handle,
443 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
449 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
450 const struct GNUNET_RECLAIM_Attribute *attr)
452 struct GNUNET_RECLAIM_AttributeListEntry *le;
457 const char *attr_type;
459 if ((NULL != attr_name) && (NULL != claim))
461 if (0 == strcasecmp (attr_name, attr->name))
463 claim = GNUNET_RECLAIM_attribute_new (attr->name,
470 else if (issue_attrs)
472 attrs_tmp = GNUNET_strdup (issue_attrs);
473 attr_str = strtok (attrs_tmp, ",");
474 while (NULL != attr_str)
476 if (0 != strcasecmp (attr_str, attr->name))
478 attr_str = strtok (NULL, ",");
481 le = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
482 le->attribute = GNUNET_RECLAIM_attribute_new (attr->name,
487 le->attribute->flag = attr->flag;
488 le->attribute->id = attr->id;
489 GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
490 attr_list->list_tail,
494 GNUNET_free (attrs_tmp);
496 else if (attr_delete && (NULL == attr_to_delete))
498 label = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(attr->id));
499 if (0 == strcasecmp (attr_delete, label))
501 attr_to_delete = GNUNET_RECLAIM_attribute_new (attr->name,
506 attr_to_delete->id = attr->id;
512 attr_str = GNUNET_RECLAIM_attribute_value_to_string (attr->type,
515 attr_type = GNUNET_RECLAIM_attribute_number_to_typename (attr->type);
516 id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(attr->id));
518 "Name: %s; Value: %s (%s); Flag %u; ID: %s\n",
526 GNUNET_RECLAIM_get_attributes_next (attr_iterator);
535 fprintf (stderr, "Ego %s not found\n", ego_name);
536 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
542 ticket_iterator = GNUNET_RECLAIM_ticket_iteration_start (reclaim_handle,
555 GNUNET_CRYPTO_ecdsa_public_key_from_string (rp, strlen (rp), &rp_key)) )
557 fprintf (stderr, "%s is not a public key!\n", rp);
558 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
561 if (NULL != consume_ticket)
562 GNUNET_STRINGS_string_to_data (consume_ticket,
563 strlen (consume_ticket),
565 sizeof(struct GNUNET_RECLAIM_Ticket));
566 if (NULL != revoke_ticket)
567 GNUNET_STRINGS_string_to_data (revoke_ticket,
568 strlen (revoke_ticket),
570 sizeof(struct GNUNET_RECLAIM_Ticket));
572 attr_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
574 attr_iterator = GNUNET_RECLAIM_get_attributes_start (reclaim_handle,
585 static int init = GNUNET_YES;
589 struct GNUNET_IDENTITY_Ego *ego,
595 if (GNUNET_YES == init)
602 if (0 != strcmp (name, ego_name))
604 pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
612 const struct GNUNET_CONFIGURATION_Handle *c)
615 if (NULL == ego_name)
618 fprintf (stderr, _ ("Ego is required\n"));
622 if ((NULL == attr_value) && (NULL != attr_name))
625 fprintf (stderr, _ ("Attribute value missing!\n"));
629 if ((NULL == rp) && (NULL != issue_attrs))
632 fprintf (stderr, _ ("Requesting party key is required!\n"));
636 reclaim_handle = GNUNET_RECLAIM_connect (c);
638 identity_handle = GNUNET_IDENTITY_connect (c, &ego_cb, NULL);
643 main (int argc, char *const argv[])
645 exp_interval = GNUNET_TIME_UNIT_HOURS;
646 struct GNUNET_GETOPT_CommandLineOption options[] = {
647 GNUNET_GETOPT_option_string ('a',
650 gettext_noop ("Add an attribute NAME"),
652 GNUNET_GETOPT_option_string ('d',
655 gettext_noop ("Delete the attribute with ID"),
657 GNUNET_GETOPT_option_string ('V',
660 gettext_noop ("The attribute VALUE"),
662 GNUNET_GETOPT_option_string ('e',
665 gettext_noop ("The EGO to use"),
667 GNUNET_GETOPT_option_string ('r',
671 "Specify the relying party for issue"),
673 GNUNET_GETOPT_option_flag ('D',
675 gettext_noop ("List attributes for EGO"),
677 GNUNET_GETOPT_option_string (
682 "Issue a ticket for a set of attributes separated by comma"),
684 GNUNET_GETOPT_option_string ('C',
687 gettext_noop ("Consume a ticket"),
689 GNUNET_GETOPT_option_string ('R',
692 gettext_noop ("Revoke a ticket"),
694 GNUNET_GETOPT_option_string ('t',
697 gettext_noop ("Type of attribute"),
699 GNUNET_GETOPT_option_flag ('T',
701 gettext_noop ("List tickets of ego"),
703 GNUNET_GETOPT_option_relative_time ('E',
707 "Expiration interval of the attribute"),
710 GNUNET_GETOPT_OPTION_END
712 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
715 _ ("re:claimID command line tool"),