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_ATTRIBUTE_ClaimList *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 *claim;
163 static char *attr_delete;
166 * Claim object to delete
168 static struct GNUNET_RECLAIM_ATTRIBUTE_Claim *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);
195 ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
203 GNUNET_STRINGS_data_to_string_alloc (ticket,
205 struct GNUNET_RECLAIM_Ticket));
206 printf ("%s\n", ticket_str);
207 GNUNET_free (ticket_str);
209 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
213 store_attr_cont (void *cls, int32_t success, const char *emsg)
216 if (GNUNET_SYSERR == success)
218 fprintf (stderr, "%s\n", emsg);
220 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
224 process_attrs (void *cls,
225 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
226 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
230 const char *attr_type;
232 if (NULL == identity)
235 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
243 value_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
246 attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
247 id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
249 "Name: %s; Value: %s (%s); Version %u; ID: %s\n",
259 ticket_iter_err (void *cls)
261 ticket_iterator = NULL;
262 fprintf (stderr, "Failed to iterate over tickets\n");
263 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
267 ticket_iter_fin (void *cls)
269 ticket_iterator = NULL;
270 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
274 ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
281 GNUNET_STRINGS_data_to_string_alloc (&ticket->audience,
283 GNUNET_CRYPTO_EcdsaPublicKey));
284 ref = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(uint64_t));
286 GNUNET_STRINGS_data_to_string_alloc (ticket,
287 sizeof(struct GNUNET_RECLAIM_Ticket));
288 fprintf (stdout, "Ticket: %s | ID: %s | Audience: %s\n", tkt, ref, aud);
292 GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator);
296 iter_error (void *cls)
298 attr_iterator = NULL;
299 fprintf (stderr, "Failed to iterate over attributes\n");
300 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
304 timeout_task (void *cls)
308 fprintf (stderr, "Timeout\n");
309 if (NULL == cleanup_task)
310 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
314 process_rvk (void *cls, int success, const char *msg)
317 if (GNUNET_OK != success)
319 fprintf (stderr, "Revocation failed.\n");
322 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
327 process_delete (void *cls, int success, const char *msg)
330 if (GNUNET_OK != success)
332 fprintf (stderr, "Deletion failed.\n");
335 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
340 iter_finished (void *cls)
346 attr_iterator = NULL;
349 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
355 reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle,
365 reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle,
370 timeout = GNUNET_SCHEDULER_add_delayed (
371 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
378 reclaim_op = GNUNET_RECLAIM_ticket_revoke (reclaim_handle,
387 if (NULL == attr_to_delete)
389 fprintf (stdout, "No such attribute ``%s''\n", attr_delete);
392 reclaim_op = GNUNET_RECLAIM_attribute_delete (reclaim_handle,
401 if (NULL == type_str)
402 type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING;
404 type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
406 GNUNET_assert (GNUNET_SYSERR !=
407 GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
415 claim->data_size = data_size;
420 GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr_name, type, data, data_size);
422 reclaim_op = GNUNET_RECLAIM_attribute_store (reclaim_handle,
432 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
437 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
438 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
440 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
445 const char *attr_type;
447 if ((NULL != attr_name) && (NULL != claim))
449 if (0 == strcasecmp (attr_name, attr->name))
451 claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
457 else if (issue_attrs)
459 attrs_tmp = GNUNET_strdup (issue_attrs);
460 attr_str = strtok (attrs_tmp, ",");
461 while (NULL != attr_str)
463 if (0 != strcasecmp (attr_str, attr->name))
465 attr_str = strtok (NULL, ",");
468 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
469 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
473 le->claim->version = attr->version;
474 le->claim->id = attr->id;
475 GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
476 attr_list->list_tail,
480 GNUNET_free (attrs_tmp);
482 else if (attr_delete && (NULL == attr_to_delete))
484 label = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
485 if (0 == strcasecmp (attr_delete, label))
487 attr_to_delete = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
491 attr_to_delete->id = attr->id;
497 attr_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
500 attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
501 id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
503 "Name: %s; Value: %s (%s); Version %u; ID: %s\n",
511 GNUNET_RECLAIM_get_attributes_next (attr_iterator);
519 fprintf (stderr, "Ego %s not found\n", ego_name);
520 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
526 ticket_iterator = GNUNET_RECLAIM_ticket_iteration_start (reclaim_handle,
539 GNUNET_CRYPTO_ecdsa_public_key_from_string (rp, strlen (rp), &rp_key)) )
541 fprintf (stderr, "%s is not a public key!\n", rp);
542 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
545 if (NULL != consume_ticket)
546 GNUNET_STRINGS_string_to_data (consume_ticket,
547 strlen (consume_ticket),
549 sizeof(struct GNUNET_RECLAIM_Ticket));
550 if (NULL != revoke_ticket)
551 GNUNET_STRINGS_string_to_data (revoke_ticket,
552 strlen (revoke_ticket),
554 sizeof(struct GNUNET_RECLAIM_Ticket));
556 attr_list = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
558 attr_iterator = GNUNET_RECLAIM_get_attributes_start (reclaim_handle,
568 static int init = GNUNET_YES;
572 struct GNUNET_IDENTITY_Ego *ego,
578 if (GNUNET_YES == init)
585 if (0 != strcmp (name, ego_name))
587 pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
595 const struct GNUNET_CONFIGURATION_Handle *c)
598 if (NULL == ego_name)
601 fprintf (stderr, _ ("Ego is required\n"));
605 if ((NULL == attr_value) && (NULL != attr_name))
608 fprintf (stderr, _ ("Attribute value missing!\n"));
612 if ((NULL == rp) && (NULL != issue_attrs))
615 fprintf (stderr, _ ("Requesting party key is required!\n"));
619 reclaim_handle = GNUNET_RECLAIM_connect (c);
621 identity_handle = GNUNET_IDENTITY_connect (c, &ego_cb, NULL);
626 main (int argc, char *const argv[])
628 exp_interval = GNUNET_TIME_UNIT_HOURS;
629 struct GNUNET_GETOPT_CommandLineOption options[] = {
630 GNUNET_GETOPT_option_string ('a',
633 gettext_noop ("Add an attribute NAME"),
635 GNUNET_GETOPT_option_string ('d',
638 gettext_noop ("Delete the attribute with ID"),
640 GNUNET_GETOPT_option_string ('V',
643 gettext_noop ("The attribute VALUE"),
645 GNUNET_GETOPT_option_string ('e',
648 gettext_noop ("The EGO to use"),
650 GNUNET_GETOPT_option_string ('r',
654 "Specify the relying party for issue"),
656 GNUNET_GETOPT_option_flag ('D',
658 gettext_noop ("List attributes for EGO"),
660 GNUNET_GETOPT_option_string (
665 "Issue a ticket for a set of attributes separated by comma"),
667 GNUNET_GETOPT_option_string ('C',
670 gettext_noop ("Consume a ticket"),
672 GNUNET_GETOPT_option_string ('R',
675 gettext_noop ("Revoke a ticket"),
677 GNUNET_GETOPT_option_string ('t',
680 gettext_noop ("Type of attribute"),
682 GNUNET_GETOPT_option_flag ('T',
684 gettext_noop ("List tickets of ego"),
686 GNUNET_GETOPT_option_relative_time ('E',
690 "Expiration interval of the attribute"),
693 GNUNET_GETOPT_OPTION_END
695 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
698 _ ("re:claimID command line tool"),