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
28 #include "gnunet_util_lib.h"
29 #include "gnunet_namestore_service.h"
30 #include "gnunet_reclaim_service.h"
31 #include "gnunet_identity_service.h"
32 #include "gnunet_signatures.h"
52 static char* attr_name;
57 static char* attr_value;
62 static char* issue_attrs;
67 static char* consume_ticket;
72 static char* type_str;
77 static char* revoke_ticket;
82 static int list_tickets;
87 static char* ego_name;
92 static struct GNUNET_IDENTITY_Handle *identity_handle;
97 static struct GNUNET_RECLAIM_Handle *reclaim_handle;
102 static struct GNUNET_RECLAIM_Operation *reclaim_op;
107 static struct GNUNET_RECLAIM_AttributeIterator *attr_iterator;
112 static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator;
117 static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
122 static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
127 static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key;
132 static struct GNUNET_RECLAIM_Ticket ticket;
137 static struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list;
140 * Attribute expiration interval
142 static struct GNUNET_TIME_Relative exp_interval;
147 static struct GNUNET_SCHEDULER_Task *timeout;
152 static struct GNUNET_SCHEDULER_Task *cleanup_task;
157 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
160 do_cleanup(void *cls)
164 GNUNET_SCHEDULER_cancel (timeout);
165 if (NULL != reclaim_op)
166 GNUNET_RECLAIM_cancel (reclaim_op);
167 if (NULL != attr_iterator)
168 GNUNET_RECLAIM_get_attributes_stop (attr_iterator);
169 if (NULL != ticket_iterator)
170 GNUNET_RECLAIM_ticket_iteration_stop (ticket_iterator);
171 if (NULL != reclaim_handle)
172 GNUNET_RECLAIM_disconnect (reclaim_handle);
173 if (NULL != identity_handle)
174 GNUNET_IDENTITY_disconnect (identity_handle);
176 GNUNET_free (abe_key);
177 if (NULL != attr_list)
178 GNUNET_free (attr_list);
182 ticket_issue_cb (void* cls,
183 const struct GNUNET_RECLAIM_Ticket *ticket)
187 if (NULL != ticket) {
188 ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket,
189 sizeof (struct GNUNET_RECLAIM_Ticket));
192 GNUNET_free (ticket_str);
194 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
198 store_attr_cont (void *cls,
203 if (GNUNET_SYSERR == success) {
207 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
211 process_attrs (void *cls,
212 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
213 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
216 const char* attr_type;
218 if (NULL == identity)
221 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
229 value_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
232 attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
234 "%s: %s [%s,v%u,id=%lu]\n",
235 attr->name, value_str, attr_type, attr->version, attr->id);
239 ticket_iter_err (void *cls)
241 ticket_iterator = NULL;
243 "Failed to iterate over tickets\n");
244 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
248 ticket_iter_fin (void *cls)
250 ticket_iterator = NULL;
251 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
255 ticket_iter (void *cls,
256 const struct GNUNET_RECLAIM_Ticket *ticket)
260 GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator);
264 iter_error (void *cls)
266 attr_iterator = NULL;
268 "Failed to iterate over attributes\n");
269 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
273 timeout_task (void *cls)
279 if (NULL == cleanup_task)
280 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
284 process_rvk (void *cls, int success, const char* msg)
287 if (GNUNET_OK != success)
290 "Revocation failed.\n");
293 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
297 iter_finished (void *cls)
303 attr_iterator = NULL;
306 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
312 reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle,
322 reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle,
327 timeout = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10),
334 reclaim_op = GNUNET_RECLAIM_ticket_revoke (reclaim_handle,
343 if (NULL == type_str)
344 type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING;
346 type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
348 GNUNET_assert (GNUNET_SYSERR != GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
356 claim->data_size = data_size;
360 claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr_name,
365 reclaim_op = GNUNET_RECLAIM_attribute_store (reclaim_handle,
375 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
380 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
381 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
383 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
386 const char *attr_type;
388 if ((NULL != attr_name) && (NULL != claim))
390 if (0 == strcasecmp (attr_name, attr->name))
392 claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
398 else if (issue_attrs)
400 attrs_tmp = GNUNET_strdup (issue_attrs);
401 attr_str = strtok (attrs_tmp, ",");
402 while (NULL != attr_str) {
403 if (0 != strcasecmp (attr_str, attr->name)) {
404 attr_str = strtok (NULL, ",");
407 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
408 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
412 le->claim->version = attr->version;
413 le->claim->id = attr->id;
414 GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
415 attr_list->list_tail,
419 GNUNET_free (attrs_tmp);
423 attr_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
426 attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
428 "%s: %s [%s,v%u,id=%lu]\n",
429 attr->name, attr_str, attr_type, attr->version, attr->id);
431 GNUNET_RECLAIM_get_attributes_next (attr_iterator);
440 "Ego %s not found\n", ego_name);
441 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
447 ticket_iterator = GNUNET_RECLAIM_ticket_iteration_start (reclaim_handle,
459 GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
462 if (NULL != consume_ticket)
463 GNUNET_STRINGS_string_to_data (consume_ticket,
464 strlen (consume_ticket),
466 sizeof (struct GNUNET_RECLAIM_Ticket));
467 if (NULL != revoke_ticket)
468 GNUNET_STRINGS_string_to_data (revoke_ticket,
469 strlen (revoke_ticket),
471 sizeof (struct GNUNET_RECLAIM_Ticket));
473 attr_list = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
475 attr_iterator = GNUNET_RECLAIM_get_attributes_start (reclaim_handle,
487 static int init = GNUNET_YES;
491 struct GNUNET_IDENTITY_Ego *ego,
496 if (GNUNET_YES == init) {
502 if (0 != strcmp (name, ego_name))
504 pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
512 const struct GNUNET_CONFIGURATION_Handle *c)
515 if (NULL == ego_name)
519 _("Ego is required\n"));
523 if ( (NULL == attr_value) && (NULL != attr_name) )
527 _("Attribute value missing!\n"));
531 if ( (NULL == rp) && (NULL != issue_attrs) )
535 _("Requesting party key is required!\n"));
539 reclaim_handle = GNUNET_RECLAIM_connect (c);
541 identity_handle = GNUNET_IDENTITY_connect (c,
550 main(int argc, char *const argv[])
552 exp_interval = GNUNET_TIME_UNIT_HOURS;
553 struct GNUNET_GETOPT_CommandLineOption options[] = {
555 GNUNET_GETOPT_option_string ('a',
558 gettext_noop ("Add an attribute NAME"),
561 GNUNET_GETOPT_option_string ('V',
564 gettext_noop ("The attribute VALUE"),
566 GNUNET_GETOPT_option_string ('e',
569 gettext_noop ("The EGO to use"),
571 GNUNET_GETOPT_option_string ('r',
574 gettext_noop ("Specify the relying party for issue"),
576 GNUNET_GETOPT_option_flag ('D',
578 gettext_noop ("List attributes for EGO"),
580 GNUNET_GETOPT_option_string ('i',
583 gettext_noop ("Issue a ticket for a set of attributes separated by comma"),
585 GNUNET_GETOPT_option_string ('C',
588 gettext_noop ("Consume a ticket"),
590 GNUNET_GETOPT_option_string ('R',
593 gettext_noop ("Revoke a ticket"),
595 GNUNET_GETOPT_option_string ('t',
598 gettext_noop ("Type of attribute"),
600 GNUNET_GETOPT_option_flag ('T',
602 gettext_noop ("List tickets of ego"),
604 GNUNET_GETOPT_option_relative_time ('E',
607 gettext_noop ("Expiration interval of the attribute"),
610 GNUNET_GETOPT_OPTION_END
612 if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "ct",