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"),