aboutsummaryrefslogtreecommitdiff
path: root/src/cli/reclaim
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/reclaim')
-rw-r--r--src/cli/reclaim/.gitignore2
-rw-r--r--src/cli/reclaim/Makefile.am57
-rw-r--r--src/cli/reclaim/gnunet-did.c661
-rw-r--r--src/cli/reclaim/gnunet-reclaim.c943
-rw-r--r--src/cli/reclaim/meson.build22
-rw-r--r--src/cli/reclaim/test_reclaim.conf44
-rwxr-xr-xsrc/cli/reclaim/test_reclaim.sh31
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_attribute.sh40
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_consume.sh51
-rw-r--r--src/cli/reclaim/test_reclaim_defaults.conf24
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_issue.sh42
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_oidc.sh57
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_revoke.sh65
13 files changed, 2039 insertions, 0 deletions
diff --git a/src/cli/reclaim/.gitignore b/src/cli/reclaim/.gitignore
new file mode 100644
index 000000000..49e84eb66
--- /dev/null
+++ b/src/cli/reclaim/.gitignore
@@ -0,0 +1,2 @@
1gnunet-reclaim
2gnunet-did
diff --git a/src/cli/reclaim/Makefile.am b/src/cli/reclaim/Makefile.am
new file mode 100644
index 000000000..9803ac7ac
--- /dev/null
+++ b/src/cli/reclaim/Makefile.am
@@ -0,0 +1,57 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4 plugindir = $(libdir)/gnunet
5
6if USE_COVERAGE
7 AM_CFLAGS = --coverage -O0
8 XLIB = -lgcov
9endif
10
11
12EXTRA_DIST = \
13 test_reclaim_defaults.conf \
14 test_reclaim.conf \
15 $(check_SCRIPTS)
16
17pkgcfgdir= $(pkgdatadir)/config.d/
18
19libexecdir= $(pkglibdir)/libexec/
20
21bin_PROGRAMS = \
22 gnunet-reclaim \
23 gnunet-did
24
25gnunet_reclaim_SOURCES = \
26 gnunet-reclaim.c
27gnunet_reclaim_LDADD = \
28 $(top_builddir)/src/lib/util/libgnunetutil.la \
29 $(top_builddir)/src/service/namestore/libgnunetnamestore.la \
30 $(top_builddir)/src/service/reclaim/libgnunetreclaim.la \
31 $(top_builddir)/src/service/identity/libgnunetidentity.la \
32 $(GN_LIBINTL)
33
34gnunet_did_SOURCES = \
35 gnunet-did.c
36gnunet_did_LDADD = \
37 $(top_builddir)/src/lib/util/libgnunetutil.la \
38 $(top_builddir)/src/service/gns/libgnunetgns.la \
39 $(top_builddir)/src/lib/gnsrecord/libgnunetgnsrecord.la \
40 $(top_builddir)/src/service/identity/libgnunetidentity.la \
41 $(top_builddir)/src/service/namestore/libgnunetnamestore.la \
42 $(top_builddir)/src/service/reclaim/libgnunetdid.la \
43 -ljansson
44gnunet_did_CFLAGS = \
45 -I$(top_builddir)/src/service/reclaim
46
47check_SCRIPTS = \
48 test_reclaim_attribute.sh \
49 test_reclaim_issue.sh \
50 test_reclaim_consume.sh
51
52if ENABLE_TEST_RUN
53 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
54 TESTS = \
55 $(check_SCRIPTS) \
56 $(check_PROGRAMS)
57endif
diff --git a/src/cli/reclaim/gnunet-did.c b/src/cli/reclaim/gnunet-did.c
new file mode 100644
index 000000000..a8ac7652e
--- /dev/null
+++ b/src/cli/reclaim/gnunet-did.c
@@ -0,0 +1,661 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2022 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 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * FIXME: Do we only want to handle EdDSA identities?
23 * TODO: Own GNS record type
24 * TODO: Fix overwrite of records in @ if present look for other with same sub
25 * TODO. Tests
26 * TODO: Move constants to did.h
27 * FIXME: Remove and lookup require differnt representations (did vs egoname)
28 */
29
30/**
31 * @author Tristan Schwieren
32 * @file src/did/gnunet-did.c
33 * @brief DID Method Wrapper
34 */
35#include "platform.h"
36#include "gnunet_util_lib.h"
37#include "gnunet_namestore_service.h"
38#include "gnunet_identity_service.h"
39#include "gnunet_gns_service.h"
40#include "gnunet_gnsrecord_lib.h"
41#include "did_core.h"
42
43#define GNUNET_DID_DEFAULT_DID_DOCUMENT_EXPIRATION_TIME "1d"
44
45/**
46 * return value
47 */
48static int ret;
49
50/**
51 * Replace DID Document Flag
52 */
53static int replace;
54
55/**
56 * Remove DID Document Flag
57 */
58static int remove_did;
59
60/**
61 * Get DID Documement for DID Flag
62 */
63static int get;
64
65/**
66 * Create DID Document Flag
67 */
68static int create;
69
70/**
71 * Show DID for Ego Flag
72 */
73static int show;
74
75/**
76 * Show DID for Ego Flag
77 */
78static int show_all;
79
80/**
81 * DID Attribut String
82 */
83static char *did;
84
85/**
86 * DID Document Attribut String
87 */
88static char *didd;
89
90/**
91 * Ego Attribut String
92 */
93static char *egoname;
94
95/**
96 * DID Document expiration Date Attribut String
97 */
98static char *expire;
99
100/*
101 * Handle to the GNS service
102 */
103static struct GNUNET_GNS_Handle *gns_handle;
104
105/*
106 * Handle to the NAMESTORE service
107 */
108static struct GNUNET_NAMESTORE_Handle *namestore_handle;
109
110/*
111 * Handle to the IDENTITY service
112 */
113static struct GNUNET_IDENTITY_Handle *identity_handle;
114
115
116/*
117 * The configuration
118 */
119const static struct GNUNET_CONFIGURATION_Handle *my_cfg;
120
121/**
122 * Give ego exists
123 */
124static int ego_exists = 0;
125
126/**
127 * @brief Disconnect and shutdown
128 * @param cls closure
129 */
130static void
131cleanup (void *cls)
132{
133 if (NULL != gns_handle)
134 GNUNET_GNS_disconnect (gns_handle);
135 if (NULL != namestore_handle)
136 GNUNET_NAMESTORE_disconnect (namestore_handle);
137 if (NULL != identity_handle)
138 GNUNET_IDENTITY_disconnect (identity_handle);
139
140 GNUNET_free (did);
141 GNUNET_free (didd);
142 GNUNET_free (egoname);
143 GNUNET_free (expire);
144
145 GNUNET_SCHEDULER_shutdown ();
146}
147
148
149/**
150 * @brief GNS lookup callback. Prints the DID Document to standard out.
151 * Fails if there is more than one DID record.
152 *
153 * @param cls closure
154 * @param rd_count number of records in @a rd
155 * @param rd the records in the reply
156 */
157static void
158print_did_document (
159 enum GNUNET_GenericReturnValue status,
160 char *did_document,
161 void *cls
162 )
163{
164 if (GNUNET_OK == status)
165 printf ("%s\n", did_document);
166 else
167 printf ("An error occured: %s\n", did_document);
168
169 GNUNET_SCHEDULER_add_now (cleanup, NULL);
170 ret = 0;
171 return;
172}
173
174
175/**
176 * @brief Resolve a DID given by the user.
177 */
178static void
179resolve_did ()
180{
181
182 if (did == NULL)
183 {
184 printf ("Set DID option to resolve DID\n");
185 GNUNET_SCHEDULER_add_now (cleanup, NULL);
186 ret = 1;
187 return;
188 }
189
190 if (GNUNET_OK != DID_resolve (did, gns_handle, print_did_document, NULL))
191 {
192 printf ("An error occured while resoling the DID\n");
193 GNUNET_SCHEDULER_add_now (cleanup, NULL);
194 ret = 0;
195 return;
196 }
197}
198
199
200/**
201 * @brief Signature of a callback function that is called after a did has been removed
202 */
203typedef void
204(*remove_did_document_callback) (void *cls);
205
206/**
207 * @brief A Structure containing a cont and cls. Can be passed as a cls to a callback function
208 *
209 */
210struct Event
211{
212 remove_did_document_callback cont;
213 void *cls;
214};
215
216/**
217 * @brief Implements the GNUNET_NAMESTORE_ContinuationWithStatus
218 * Calls the callback function and cls in the event struct
219 *
220 * @param cls closure containing the event struct
221 * @param success
222 * @param emgs
223 */
224static void
225remove_did_document_namestore_cb (void *cls, enum GNUNET_ErrorCode ec)
226{
227 struct Event *event;
228
229 if (GNUNET_EC_NONE == ec)
230 {
231 event = (struct Event *) cls;
232
233 if (event->cont != NULL)
234 {
235 event->cont (event->cls);
236 free (event);
237 }
238 else
239 {
240 free (event);
241 GNUNET_SCHEDULER_add_now (cleanup, NULL);
242 ret = 0;
243 return;
244 }
245 }
246 else
247 {
248 printf ("Something went wrong when deleting the DID Document\n");
249
250 printf ("%s\n", GNUNET_ErrorCode_get_hint (ec));
251
252 GNUNET_SCHEDULER_add_now (cleanup, NULL);
253 ret = 0;
254 return;
255 }
256}
257
258
259/**
260 * @brief Callback called after the ego has been locked up
261 *
262 * @param cls closure
263 * @param ego the ego returned by the identity service
264 */
265static void
266remove_did_document_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
267{
268 const struct GNUNET_CRYPTO_PrivateKey *skey =
269 GNUNET_IDENTITY_ego_get_private_key (ego);
270
271 GNUNET_NAMESTORE_record_set_store (namestore_handle,
272 skey,
273 GNUNET_GNS_EMPTY_LABEL_AT,
274 0,
275 NULL,
276 &remove_did_document_namestore_cb,
277 cls);
278}
279
280
281/**
282 * @brief Remove a DID Document
283 */
284static void
285remove_did_document (remove_did_document_callback cont, void *cls)
286{
287 struct Event *event;
288
289 if (egoname == NULL)
290 {
291 printf ("Remove requieres an ego option\n");
292 GNUNET_SCHEDULER_add_now (cleanup, NULL);
293 ret = 1;
294 return;
295 }
296 else
297 {
298 event = malloc (sizeof(*event));
299 event->cont = cont;
300 event->cls = cls;
301
302 GNUNET_IDENTITY_ego_lookup (my_cfg,
303 egoname,
304 &remove_did_document_ego_lookup_cb,
305 (void *) event);
306 }
307}
308
309
310// Needed because create_did_ego_lookup_cb() and
311// create_did_ego_create_cb() can call each other
312static void create_did_ego_lockup_cb ();
313
314/**
315 * @brief Create a DID(-Document). Called after DID has been created
316 * Prints status and the DID.
317 *
318 */
319static void
320create_did_cb (enum GNUNET_GenericReturnValue status, void *cls)
321{
322 if (GNUNET_OK == status)
323 {
324 printf ("DID has been created.\n%s\n", (char *) cls);
325 free (cls);
326 ret = 0;
327 }
328 else
329 {
330 printf ("An error occured while creating the DID.\n");
331 ret = 1;
332 }
333
334 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
335 return;
336}
337
338
339/**
340 * @brief Create a DID(-Document) - Called after a new Identity has been created.
341 */
342static void
343create_did_ego_create_cb (void *cls,
344 const struct GNUNET_CRYPTO_PrivateKey *pk,
345 enum GNUNET_ErrorCode ec)
346{
347 if (GNUNET_EC_NONE != ec)
348 {
349 printf ("%s\n", GNUNET_ErrorCode_get_hint (ec));
350 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
351 ret = 1;
352 return;
353 }
354
355 GNUNET_IDENTITY_ego_lookup (my_cfg,
356 egoname,
357 &create_did_ego_lockup_cb,
358 NULL);
359}
360
361
362/**
363 * @brief Create a DID(-Document). Called after ego lookup
364 *
365 */
366static void
367create_did_ego_lockup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
368{
369 if (ego == NULL)
370 {
371 // If Ego was not found. Create new one first
372 printf ("Ego was not found. Creating new one.\n");
373 GNUNET_IDENTITY_create (identity_handle,
374 egoname,
375 NULL,
376 GNUNET_PUBLIC_KEY_TYPE_EDDSA,
377 &create_did_ego_create_cb,
378 egoname);
379 }
380 else
381 {
382 char *did = DID_identity_to_did (ego);
383 void *cls = malloc (strlen (did) + 1);
384 struct GNUNET_TIME_Relative expire_relative;
385
386 if (expire == NULL)
387 {
388 GNUNET_STRINGS_fancy_time_to_relative (
389 DID_DOCUMENT_DEFAULT_EXPIRATION_TIME, &expire_relative);
390 }
391 else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (expire,
392 &
393 expire_relative))
394 {
395 printf ("Failed to read given expiration time\n");
396 GNUNET_SCHEDULER_add_now (cleanup, NULL);
397 ret = 1;
398 return;
399 }
400
401 strcpy (cls, did);
402 // TODO: Add DID_document argument
403 if (GNUNET_OK != DID_create (ego,
404 NULL,
405 &expire_relative,
406 namestore_handle,
407 create_did_cb,
408 cls))
409 {
410 printf ("An error occured while creating the DID.\n");
411 ret = 1;
412 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
413 return;
414 }
415 }
416}
417
418
419/**
420 * @brief Create a DID(-Document).
421 *
422 */
423static void
424create_did ()
425{
426 // Ego name to be set
427 if (egoname == NULL)
428 {
429 printf ("Set the Ego argument to create a new DID(-Document)\n");
430 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
431 ret = 1;
432 return;
433 }
434
435 GNUNET_IDENTITY_ego_lookup (my_cfg,
436 egoname,
437 &create_did_ego_lockup_cb,
438 NULL);
439}
440
441
442/**
443 * @brief Replace a DID Docuemnt. Callback function after ego lockup
444 *
445 * @param cls
446 * @param ego
447 */
448static void
449replace_did_document_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
450{
451 // create_did_store (didd, ego);
452}
453
454
455/**
456 * @brief Replace a DID Document. Callback functiona after remove
457 *
458 * @param cls
459 */
460static void
461replace_did_document_remove_cb (void *cls)
462{
463 GNUNET_IDENTITY_ego_lookup (my_cfg,
464 egoname,
465 &replace_did_document_ego_lookup_cb,
466 NULL);
467}
468
469
470/**
471 * @brief Replace a DID Docuemnt
472 *
473 */
474static void
475replace_did_document ()
476{
477 if ((didd != NULL) && (expire != NULL))
478 {
479 remove_did_document (&replace_did_document_remove_cb, NULL);
480 }
481 else
482 {
483 printf (
484 "Set the DID Document and expiration time argument to replace the DID Document\n");
485 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
486 ret = 1;
487 return;
488 }
489}
490
491
492static void
493post_ego_iteration (void *cls)
494{
495 // TODO: Check that only one argument is set
496
497 if (1 == replace)
498 {
499 replace_did_document ();
500 }
501 else if (1 == get)
502 {
503 resolve_did ();
504 }
505 else if (1 == remove_did)
506 {
507 remove_did_document (NULL, NULL);
508 }
509 else if (1 == create)
510 {
511 create_did ();
512 }
513 else
514 {
515 // No Argument found
516 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
517 return;
518 }
519}
520
521
522static void
523process_dids (void *cls, struct GNUNET_IDENTITY_Ego *ego,
524 void **ctx, const char*name)
525{
526 char *did_str;
527
528 if (ego == NULL)
529 {
530 if (1 == ego_exists)
531 {
532 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
533 return;
534 }
535 GNUNET_SCHEDULER_add_now (&post_ego_iteration, NULL);
536 return;
537 }
538
539 if (1 == show_all)
540 {
541 did_str = DID_identity_to_did (ego);
542 printf ("%s:\n\t%s\n", name, did_str);
543 GNUNET_free (did_str);
544 return;
545 }
546 if (1 == show)
547 {
548 if (0 == strncmp (name, egoname, strlen (egoname)))
549 {
550 did_str = DID_identity_to_did (ego);
551 printf ("%s:\n\t%s\n", name, did_str);
552 GNUNET_free (did_str);
553 return;
554 }
555 }
556}
557
558
559static void
560run (void *cls,
561 char *const *args,
562 const char *cfgfile,
563 const struct GNUNET_CONFIGURATION_Handle *c)
564{
565 gns_handle = GNUNET_GNS_connect (c);
566 namestore_handle = GNUNET_NAMESTORE_connect (c);
567 my_cfg = c;
568
569 // check if GNS_handle could connect
570 if (gns_handle == NULL)
571 {
572 ret = 1;
573 return;
574 }
575
576 // check if NAMESTORE_handle could connect
577 if (namestore_handle == NULL)
578 {
579 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
580 ret = 1;
581 return;
582 }
583
584 identity_handle = GNUNET_IDENTITY_connect (c, &process_dids, NULL);
585 if (identity_handle == NULL)
586 {
587 GNUNET_SCHEDULER_add_now (&cleanup, NULL);
588 ret = 1;
589 return;
590 }
591}
592
593
594int
595main (int argc, char *const argv[])
596{
597 struct GNUNET_GETOPT_CommandLineOption options[] = {
598 GNUNET_GETOPT_option_flag ('C',
599 "create",
600 gettext_noop (
601 "Create a DID Document and display its DID"),
602 &create),
603 GNUNET_GETOPT_option_flag ('g',
604 "get",
605 gettext_noop (
606 "Get the DID Document associated with the given DID"),
607 &get),
608 GNUNET_GETOPT_option_flag ('r',
609 "remove",
610 gettext_noop (
611 "Remove the DID"),
612 &remove_did),
613 GNUNET_GETOPT_option_flag ('R',
614 "replace",
615 gettext_noop ("Replace the DID Document."),
616 &replace),
617 GNUNET_GETOPT_option_flag ('s',
618 "show",
619 gettext_noop ("Show the DID for a given ego"),
620 &show),
621 GNUNET_GETOPT_option_flag ('A',
622 "show-all",
623 gettext_noop ("Show egos with DIDs"),
624 &show_all),
625 GNUNET_GETOPT_option_string ('d',
626 "did",
627 "DID",
628 gettext_noop (
629 "The Decentralized Identity (DID)"),
630 &did),
631 GNUNET_GETOPT_option_string ('D',
632 "did-document",
633 "JSON",
634 gettext_noop (
635 "The DID Document to store in GNUNET"),
636 &didd),
637 GNUNET_GETOPT_option_string ('e',
638 "ego",
639 "EGO",
640 gettext_noop ("The name of the EGO"),
641 &egoname),
642 GNUNET_GETOPT_option_string ('t',
643 "expiration-time",
644 "TIME",
645 gettext_noop (
646 "The time until the DID Document is going to expire (e.g. 5d)"),
647 &expire),
648 GNUNET_GETOPT_OPTION_END
649 };
650
651 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
652 argv,
653 "gnunet-did",
654 "Manage Decentralized Identities (DIDs)",
655 options,
656 &run,
657 NULL))
658 return 1;
659 else
660 return ret;
661}
diff --git a/src/cli/reclaim/gnunet-reclaim.c b/src/cli/reclaim/gnunet-reclaim.c
new file mode 100644
index 000000000..94bceb8da
--- /dev/null
+++ b/src/cli/reclaim/gnunet-reclaim.c
@@ -0,0 +1,943 @@
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 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @author Martin Schanzenbach
22 * @file src/reclaim/gnunet-reclaim.c
23 * @brief Identity Provider utility
24 *
25 */
26#include "platform.h"
27#include <inttypes.h>
28
29#include "gnunet_util_lib.h"
30
31#include "gnunet_identity_service.h"
32#include "gnunet_namestore_service.h"
33#include "gnunet_reclaim_service.h"
34#include "gnunet_signatures.h"
35/**
36 * return value
37 */
38static int ret;
39
40/**
41 * List attribute flag
42 */
43static int list;
44
45/**
46 * List credentials flag
47 */
48static int list_credentials;
49
50/**
51 * Credential ID string
52 */
53static char *credential_id;
54
55/**
56 * The expected RP URI
57 */
58static char *ex_rp_uri;
59
60/**
61 * Credential ID
62 */
63static struct GNUNET_RECLAIM_Identifier credential;
64
65/**
66 * Credential name
67 */
68static char *credential_name;
69
70/**
71 * Credential type
72 */
73static char *credential_type;
74
75/**
76 * Credential exists
77 */
78static int credential_exists;
79
80/**
81 * Relying party
82 */
83static char *rp;
84
85/**
86 * The attribute
87 */
88static char *attr_name;
89
90/**
91 * Attribute value
92 */
93static char *attr_value;
94
95/**
96 * Attributes to issue
97 */
98static char *issue_attrs;
99
100/**
101 * Ticket to consume
102 */
103static char *consume_ticket;
104
105/**
106 * Attribute type
107 */
108static char *type_str;
109
110/**
111 * Ticket to revoke
112 */
113static char *revoke_ticket;
114
115/**
116 * Ticket listing
117 */
118static int list_tickets;
119
120/**
121 * Ego name
122 */
123static char *ego_name;
124
125/**
126 * Identity handle
127 */
128static struct GNUNET_IDENTITY_Handle *identity_handle;
129
130/**
131 * reclaim handle
132 */
133static struct GNUNET_RECLAIM_Handle *reclaim_handle;
134
135/**
136 * reclaim operation
137 */
138static struct GNUNET_RECLAIM_Operation *reclaim_op;
139
140/**
141 * Attribute iterator
142 */
143static struct GNUNET_RECLAIM_AttributeIterator *attr_iterator;
144
145/**
146 * Credential iterator
147 */
148static struct GNUNET_RECLAIM_CredentialIterator *cred_iterator;
149
150
151/**
152 * Ticket iterator
153 */
154static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator;
155
156
157/**
158 * ego private key
159 */
160static const struct GNUNET_CRYPTO_PrivateKey *pkey;
161
162/**
163 * Ticket to consume
164 */
165static struct GNUNET_RECLAIM_Ticket ticket;
166
167/**
168 * Attribute list
169 */
170static struct GNUNET_RECLAIM_AttributeList *attr_list;
171
172/**
173 * Attribute expiration interval
174 */
175static struct GNUNET_TIME_Relative exp_interval;
176
177/**
178 * Timeout task
179 */
180static struct GNUNET_SCHEDULER_Task *timeout;
181
182/**
183 * Cleanup task
184 */
185static struct GNUNET_SCHEDULER_Task *cleanup_task;
186
187/**
188 * Claim to store
189 */
190struct GNUNET_RECLAIM_Attribute *claim;
191
192/**
193 * Claim to delete
194 */
195static char *attr_delete;
196
197/**
198 * Claim object to delete
199 */
200static struct GNUNET_RECLAIM_Attribute *attr_to_delete;
201
202static void
203do_cleanup (void *cls)
204{
205 cleanup_task = NULL;
206 if (NULL != timeout)
207 GNUNET_SCHEDULER_cancel (timeout);
208 if (NULL != reclaim_op)
209 GNUNET_RECLAIM_cancel (reclaim_op);
210 if (NULL != attr_iterator)
211 GNUNET_RECLAIM_get_attributes_stop (attr_iterator);
212 if (NULL != cred_iterator)
213 GNUNET_RECLAIM_get_credentials_stop (cred_iterator);
214 if (NULL != ticket_iterator)
215 GNUNET_RECLAIM_ticket_iteration_stop (ticket_iterator);
216 if (NULL != reclaim_handle)
217 GNUNET_RECLAIM_disconnect (reclaim_handle);
218 if (NULL != identity_handle)
219 GNUNET_IDENTITY_disconnect (identity_handle);
220 if (NULL != attr_list)
221 {
222 GNUNET_RECLAIM_attribute_list_destroy (attr_list);
223 attr_list = NULL;
224 }
225 if (NULL != attr_to_delete)
226 GNUNET_free (attr_to_delete);
227 if (NULL == credential_type)
228 GNUNET_free (credential_type);
229}
230
231
232static void
233ticket_issue_cb (void *cls,
234 const struct GNUNET_RECLAIM_Ticket *ticket,
235 const struct GNUNET_RECLAIM_PresentationList *presentations)
236{
237 reclaim_op = NULL;
238 if (NULL != ticket)
239 {
240 printf ("%s\n", ticket->gns_name);
241 }
242 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
243}
244
245
246static void
247store_cont (void *cls, int32_t success, const char *emsg)
248{
249 reclaim_op = NULL;
250 if (GNUNET_SYSERR == success)
251 {
252 fprintf (stderr, "%s\n", emsg);
253 }
254 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
255}
256
257
258static void
259process_attrs (void *cls,
260 const struct GNUNET_CRYPTO_PublicKey *identity,
261 const struct GNUNET_RECLAIM_Attribute *attr,
262 const struct GNUNET_RECLAIM_Presentation *presentation)
263{
264 char *value_str;
265 char *id;
266 const char *attr_type;
267
268 if (NULL == identity)
269 {
270 reclaim_op = NULL;
271 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
272 return;
273 }
274 if (NULL == attr)
275 {
276 ret = 1;
277 return;
278 }
279 attr_type = GNUNET_RECLAIM_attribute_number_to_typename (attr->type);
280 id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(attr->id));
281 value_str = NULL;
282 if (NULL == presentation)
283 {
284 value_str = GNUNET_RECLAIM_attribute_value_to_string (attr->type,
285 attr->data,
286 attr->data_size);
287 }
288 else
289 {
290 struct GNUNET_RECLAIM_AttributeListEntry *ale;
291 struct GNUNET_RECLAIM_AttributeList *al
292 = GNUNET_RECLAIM_presentation_get_attributes (presentation);
293
294 for (ale = al->list_head; NULL != ale; ale = ale->next)
295 {
296 if (0 != strncmp (attr->data, ale->attribute->name, attr->data_size))
297 continue;
298 value_str
299 = GNUNET_RECLAIM_attribute_value_to_string (ale->attribute->type,
300 ale->attribute->data,
301 ale->attribute->data_size);
302 break;
303 }
304 }
305 fprintf (stdout,
306 "Name: %s; Value: %s (%s); Flag %u; ID: %s %s\n",
307 attr->name,
308 (NULL != value_str) ? value_str : "???",
309 attr_type,
310 attr->flag,
311 id,
312 (NULL == presentation) ? "" : "(ATTESTED)");
313 GNUNET_free (value_str);
314 GNUNET_free (id);
315}
316
317
318static void
319ticket_iter_err (void *cls)
320{
321 ticket_iterator = NULL;
322 fprintf (stderr, "Failed to iterate over tickets\n");
323 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
324}
325
326
327static void
328ticket_iter_fin (void *cls)
329{
330 ticket_iterator = NULL;
331 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
332}
333
334
335static void
336ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket, const char* rp_uri)
337{
338 fprintf (stdout, "Ticket: %s | RP URI: %s\n", ticket->gns_name, rp_uri);
339 GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator);
340}
341
342
343static void
344iter_error (void *cls)
345{
346 attr_iterator = NULL;
347 cred_iterator = NULL;
348 fprintf (stderr, "Failed\n");
349
350 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
351}
352
353
354static void
355timeout_task (void *cls)
356{
357 timeout = NULL;
358 ret = 1;
359 fprintf (stderr, "Timeout\n");
360 if (NULL == cleanup_task)
361 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
362}
363
364
365static void
366process_rvk (void *cls, int success, const char *msg)
367{
368 reclaim_op = NULL;
369 if (GNUNET_OK != success)
370 {
371 fprintf (stderr, "Revocation failed.\n");
372 ret = 1;
373 }
374 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
375}
376
377
378static void
379process_delete (void *cls, int success, const char *msg)
380{
381 reclaim_op = NULL;
382 if (GNUNET_OK != success)
383 {
384 fprintf (stderr, "Deletion failed.\n");
385 ret = 1;
386 }
387 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
388}
389
390
391static void
392iter_finished (void *cls)
393{
394 struct GNUNET_RECLAIM_AttributeListEntry *le;
395 char *attrs_tmp;
396 char *attr_str;
397 char *data;
398 size_t data_size;
399 int type;
400
401 attr_iterator = NULL;
402 if (list)
403 {
404 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
405 return;
406 }
407
408 if (issue_attrs)
409 {
410 attrs_tmp = GNUNET_strdup (issue_attrs);
411 attr_str = strtok (attrs_tmp, ",");
412 while (NULL != attr_str)
413 {
414 le = attr_list->list_head;
415 while (le)
416 {
417 if (0 == strcasecmp (attr_str, le->attribute->name))
418 break;
419
420 le = le->next;
421 }
422
423 if (! le)
424 {
425 fprintf (stdout, "No such attribute ``%s''\n", attr_str);
426 break;
427 }
428 attr_str = strtok (NULL, ",");
429 }
430 GNUNET_free (attrs_tmp);
431 if (NULL != attr_str)
432 {
433 GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
434 return;
435 }
436 if (NULL == ex_rp_uri)
437 {
438 fprintf (stdout, "No RP URI provided\n");
439 GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
440 return;
441 }
442 reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle,
443 pkey,
444 ex_rp_uri,
445 attr_list,
446 &ticket_issue_cb,
447 NULL);
448 return;
449 }
450 if (consume_ticket)
451 {
452 if (NULL == ex_rp_uri)
453 {
454 fprintf (stderr, "Expected an RP URI to consume ticket\n");
455 GNUNET_SCHEDULER_add_now(&do_cleanup, NULL);
456 return;
457 }
458 reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle,
459 &ticket,
460 ex_rp_uri,
461 &process_attrs,
462 NULL);
463 timeout = GNUNET_SCHEDULER_add_delayed (
464 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
465 &timeout_task,
466 NULL);
467 return;
468 }
469 if (revoke_ticket)
470 {
471 reclaim_op = GNUNET_RECLAIM_ticket_revoke (reclaim_handle,
472 pkey,
473 &ticket,
474 &process_rvk,
475 NULL);
476 return;
477 }
478 if (attr_delete)
479 {
480 if (NULL == attr_to_delete)
481 {
482 fprintf (stdout, "No such attribute ``%s''\n", attr_delete);
483 GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
484 return;
485 }
486 reclaim_op = GNUNET_RECLAIM_attribute_delete (reclaim_handle,
487 pkey,
488 attr_to_delete,
489 &process_delete,
490 NULL);
491 return;
492 }
493 if (attr_name)
494 {
495 if (NULL == type_str)
496 type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING;
497 else
498 type = GNUNET_RECLAIM_attribute_typename_to_number (type_str);
499
500 GNUNET_assert (GNUNET_SYSERR !=
501 GNUNET_RECLAIM_attribute_string_to_value (type,
502 attr_value,
503 (void **) &data,
504 &data_size));
505 if (NULL != claim)
506 {
507 claim->type = type;
508 claim->data = data;
509 claim->data_size = data_size;
510 }
511 else
512 {
513 claim =
514 GNUNET_RECLAIM_attribute_new (attr_name, NULL, type, data, data_size);
515 }
516 if (NULL != credential_id)
517 {
518 claim->credential = credential;
519 }
520 reclaim_op = GNUNET_RECLAIM_attribute_store (reclaim_handle,
521 pkey,
522 claim,
523 &exp_interval,
524 &store_cont,
525 NULL);
526 GNUNET_free (data);
527 GNUNET_free (claim);
528 return;
529 }
530 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
531}
532
533
534static void
535iter_cb (void *cls,
536 const struct GNUNET_CRYPTO_PublicKey *identity,
537 const struct GNUNET_RECLAIM_Attribute *attr)
538{
539 struct GNUNET_RECLAIM_AttributeListEntry *le;
540 char *attrs_tmp;
541 char *attr_str;
542 char *label;
543 char *id;
544 const char *attr_type;
545
546 if ((NULL != attr_name) && (NULL == claim))
547 {
548 if (0 == strcasecmp (attr_name, attr->name))
549 {
550 claim = GNUNET_RECLAIM_attribute_new (attr->name,
551 &attr->credential,
552 attr->type,
553 attr->data,
554 attr->data_size);
555 claim->id = attr->id;
556 }
557 }
558 else if (issue_attrs)
559 {
560 attrs_tmp = GNUNET_strdup (issue_attrs);
561 attr_str = strtok (attrs_tmp, ",");
562 while (NULL != attr_str)
563 {
564 if (0 != strcasecmp (attr_str, attr->name))
565 {
566 attr_str = strtok (NULL, ",");
567 continue;
568 }
569 le = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
570 le->attribute = GNUNET_RECLAIM_attribute_new (attr->name,
571 &attr->credential,
572 attr->type,
573 attr->data,
574 attr->data_size);
575 le->attribute->flag = attr->flag;
576 le->attribute->id = attr->id;
577 GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
578 attr_list->list_tail,
579 le);
580 break;
581 }
582 GNUNET_free (attrs_tmp);
583 }
584 else if (attr_delete && (NULL == attr_to_delete))
585 {
586 label = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(attr->id));
587 if (0 == strcasecmp (attr_delete, label))
588 {
589 attr_to_delete = GNUNET_RECLAIM_attribute_new (attr->name,
590 &attr->credential,
591 attr->type,
592 attr->data,
593 attr->data_size);
594 attr_to_delete->id = attr->id;
595 }
596 GNUNET_free (label);
597 }
598 else if (list)
599 {
600 attr_str = GNUNET_RECLAIM_attribute_value_to_string (attr->type,
601 attr->data,
602 attr->data_size);
603 attr_type = GNUNET_RECLAIM_attribute_number_to_typename (attr->type);
604 id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(attr->id));
605 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attr->credential))
606 {
607 fprintf (stdout,
608 "%s: ``%s'' (%s); ID: %s\n",
609 attr->name,
610 attr_str,
611 attr_type,
612 id);
613 }
614 else
615 {
616 char *cred_id =
617 GNUNET_STRINGS_data_to_string_alloc (&attr->credential,
618 sizeof(attr->credential));
619 fprintf (stdout,
620 "%s: ``%s'' in credential presentation `%s' (%s); ID: %s\n",
621 attr->name,
622 attr_str,
623 cred_id,
624 attr_type,
625 id);
626 GNUNET_free (cred_id);
627
628 }
629 GNUNET_free (id);
630 }
631 GNUNET_RECLAIM_get_attributes_next (attr_iterator);
632}
633
634
635static void
636cred_iter_finished (void *cls)
637{
638 cred_iterator = NULL;
639
640 // Add new credential
641 if ((NULL != credential_name) &&
642 (NULL != attr_value))
643 {
644 enum GNUNET_RECLAIM_CredentialType ctype =
645 GNUNET_RECLAIM_credential_typename_to_number (credential_type);
646 struct GNUNET_RECLAIM_Credential *credential =
647 GNUNET_RECLAIM_credential_new (credential_name,
648 ctype,
649 attr_value,
650 strlen (attr_value));
651 reclaim_op = GNUNET_RECLAIM_credential_store (reclaim_handle,
652 pkey,
653 credential,
654 &exp_interval,
655 store_cont,
656 NULL);
657 return;
658
659 }
660 if (list_credentials)
661 {
662 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
663 return;
664 }
665 attr_iterator = GNUNET_RECLAIM_get_attributes_start (reclaim_handle,
666 pkey,
667 &iter_error,
668 NULL,
669 &iter_cb,
670 NULL,
671 &iter_finished,
672 NULL);
673
674}
675
676
677static void
678cred_iter_cb (void *cls,
679 const struct GNUNET_CRYPTO_PublicKey *identity,
680 const struct GNUNET_RECLAIM_Credential *cred)
681{
682 char *cred_str;
683 char *attr_str;
684 char *id;
685 const char *cred_type;
686 struct GNUNET_RECLAIM_AttributeListEntry *ale;
687
688 if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (&credential,
689 &cred->id))
690 credential_exists = GNUNET_YES;
691 if (list_credentials)
692 {
693 cred_str = GNUNET_RECLAIM_credential_value_to_string (cred->type,
694 cred->data,
695 cred->data_size);
696 cred_type = GNUNET_RECLAIM_credential_number_to_typename (cred->type);
697 id = GNUNET_STRINGS_data_to_string_alloc (&cred->id, sizeof(cred->id));
698 fprintf (stdout,
699 "%s: ``%s'' (%s); ID: %s\n",
700 cred->name,
701 cred_str,
702 cred_type,
703 id);
704 struct GNUNET_RECLAIM_AttributeList *attrs =
705 GNUNET_RECLAIM_credential_get_attributes (cred);
706 if (NULL != attrs)
707 {
708 fprintf (stdout,
709 "\t Attributes:\n");
710 for (ale = attrs->list_head; NULL != ale; ale = ale->next)
711 {
712 attr_str = GNUNET_RECLAIM_attribute_value_to_string (
713 ale->attribute->type,
714 ale->attribute->data,
715 ale->attribute->data_size);
716 fprintf (stdout,
717 "\t %s: %s\n", ale->attribute->name, attr_str);
718 GNUNET_free (attr_str);
719 }
720 GNUNET_RECLAIM_attribute_list_destroy (attrs);
721 }
722 GNUNET_free (id);
723 }
724 GNUNET_RECLAIM_get_credentials_next (cred_iterator);
725}
726
727
728static void
729start_process ()
730{
731 if (NULL == pkey)
732 {
733 fprintf (stderr, "Ego %s not found\n", ego_name);
734 cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
735 return;
736 }
737 if (NULL == credential_type)
738 credential_type = GNUNET_strdup ("JWT");
739 credential = GNUNET_RECLAIM_ID_ZERO;
740 if (NULL != credential_id)
741 GNUNET_STRINGS_string_to_data (credential_id,
742 strlen (credential_id),
743 &credential, sizeof(credential));
744 credential_exists = GNUNET_NO;
745 if (list_tickets)
746 {
747 ticket_iterator = GNUNET_RECLAIM_ticket_iteration_start (reclaim_handle,
748 pkey,
749 &ticket_iter_err,
750 NULL,
751 &ticket_iter,
752 NULL,
753 &ticket_iter_fin,
754 NULL);
755 return;
756 }
757
758 if (NULL != consume_ticket)
759 memcpy (ticket.gns_name, consume_ticket, strlen (consume_ticket) + 1);
760 if (NULL != revoke_ticket)
761 GNUNET_STRINGS_string_to_data (revoke_ticket,
762 strlen (revoke_ticket),
763 &ticket,
764 sizeof(struct GNUNET_RECLAIM_Ticket));
765
766 attr_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
767 claim = NULL;
768 cred_iterator = GNUNET_RECLAIM_get_credentials_start (reclaim_handle,
769 pkey,
770 &iter_error,
771 NULL,
772 &cred_iter_cb,
773 NULL,
774 &cred_iter_finished,
775 NULL);
776
777}
778
779
780static int init = GNUNET_YES;
781
782static void
783ego_cb (void *cls,
784 struct GNUNET_IDENTITY_Ego *ego,
785 void **ctx,
786 const char *name)
787{
788 if (NULL == name)
789 {
790 if (GNUNET_YES == init)
791 {
792 init = GNUNET_NO;
793 start_process ();
794 }
795 return;
796 }
797 if (0 != strcmp (name, ego_name))
798 return;
799 pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
800}
801
802
803static void
804run (void *cls,
805 char *const *args,
806 const char *cfgfile,
807 const struct GNUNET_CONFIGURATION_Handle *c)
808{
809 ret = 0;
810 if (NULL == ego_name)
811 {
812 ret = 1;
813 fprintf (stderr, _ ("Ego is required\n"));
814 return;
815 }
816
817 if ((NULL == attr_value) && (NULL != attr_name))
818 {
819 ret = 1;
820 fprintf (stderr, _ ("Attribute value missing!\n"));
821 return;
822 }
823
824 if ((NULL == rp) && (NULL != issue_attrs))
825 {
826 ret = 1;
827 fprintf (stderr, _ ("Requesting party key is required!\n"));
828 return;
829 }
830
831 reclaim_handle = GNUNET_RECLAIM_connect (c);
832 // Get Ego
833 identity_handle = GNUNET_IDENTITY_connect (c, &ego_cb, NULL);
834}
835
836
837int
838main (int argc, char *const argv[])
839{
840 exp_interval = GNUNET_TIME_UNIT_HOURS;
841 struct GNUNET_GETOPT_CommandLineOption options[] = {
842 GNUNET_GETOPT_option_string ('a',
843 "add",
844 "NAME",
845 gettext_noop (
846 "Add or update an attribute NAME"),
847 &attr_name),
848 GNUNET_GETOPT_option_string ('d',
849 "delete",
850 "ID",
851 gettext_noop ("Delete the attribute with ID"),
852 &attr_delete),
853 GNUNET_GETOPT_option_string ('V',
854 "value",
855 "VALUE",
856 gettext_noop ("The attribute VALUE"),
857 &attr_value),
858 GNUNET_GETOPT_option_string ('e',
859 "ego",
860 "EGO",
861 gettext_noop ("The EGO to use"),
862 &ego_name),
863 GNUNET_GETOPT_option_string ('r',
864 "rp",
865 "RP",
866 gettext_noop (
867 "Specify the relying party for issue"),
868 &rp),
869 GNUNET_GETOPT_option_string ('U',
870 "rpuri",
871 "RPURI",
872 gettext_noop (
873 "Specify the relying party URI for a ticket to consume"),
874 &ex_rp_uri),
875 GNUNET_GETOPT_option_flag ('D',
876 "dump",
877 gettext_noop ("List attributes for EGO"),
878 &list),
879 GNUNET_GETOPT_option_flag ('A',
880 "credentials",
881 gettext_noop ("List credentials for EGO"),
882 &list_credentials),
883 GNUNET_GETOPT_option_string ('I',
884 "credential-id",
885 "CREDENTIAL_ID",
886 gettext_noop (
887 "Credential to use for attribute"),
888 &credential_id),
889 GNUNET_GETOPT_option_string ('N',
890 "credential-name",
891 "NAME",
892 gettext_noop ("Credential name"),
893 &credential_name),
894 GNUNET_GETOPT_option_string ('i',
895 "issue",
896 "A1,A2,...",
897 gettext_noop (
898 "Issue a ticket for a set of attributes separated by comma"),
899 &issue_attrs),
900 GNUNET_GETOPT_option_string ('C',
901 "consume",
902 "TICKET",
903 gettext_noop ("Consume a ticket"),
904 &consume_ticket),
905 GNUNET_GETOPT_option_string ('R',
906 "revoke",
907 "TICKET",
908 gettext_noop ("Revoke a ticket"),
909 &revoke_ticket),
910 GNUNET_GETOPT_option_string ('t',
911 "type",
912 "TYPE",
913 gettext_noop ("Type of attribute"),
914 &type_str),
915 GNUNET_GETOPT_option_string ('u',
916 "credential-type",
917 "TYPE",
918 gettext_noop ("Type of credential"),
919 &credential_type),
920 GNUNET_GETOPT_option_flag ('T',
921 "tickets",
922 gettext_noop ("List tickets of ego"),
923 &list_tickets),
924 GNUNET_GETOPT_option_relative_time ('E',
925 "expiration",
926 "INTERVAL",
927 gettext_noop (
928 "Expiration interval of the attribute"),
929 &exp_interval),
930
931 GNUNET_GETOPT_OPTION_END
932 };
933 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
934 argv,
935 "gnunet-reclaim",
936 _ ("re:claimID command line tool"),
937 options,
938 &run,
939 NULL))
940 return 1;
941 else
942 return ret;
943}
diff --git a/src/cli/reclaim/meson.build b/src/cli/reclaim/meson.build
new file mode 100644
index 000000000..53ce13edb
--- /dev/null
+++ b/src/cli/reclaim/meson.build
@@ -0,0 +1,22 @@
1executable ('gnunet-reclaim',
2 'gnunet-reclaim.c',
3 dependencies: [libgnunetreclaim_dep,
4 libgnunetidentity_dep,
5 libgnunetutil_dep],
6 include_directories: [incdir, configuration_inc],
7 install: true,
8 install_dir: get_option('bindir'))
9executable ('gnunet-did',
10 'gnunet-did.c',
11 dependencies: [libgnunetreclaim_dep,
12 libgnunetdid_dep,
13 libgnunetgns_dep,
14 libgnunetnamestore_dep,
15 libgnunetidentity_dep,
16 libgnunetutil_dep],
17 include_directories: [incdir,
18 configuration_inc,
19 include_directories ('../../service/reclaim')],
20 install: true,
21 install_dir: get_option('bindir'))
22
diff --git a/src/cli/reclaim/test_reclaim.conf b/src/cli/reclaim/test_reclaim.conf
new file mode 100644
index 000000000..a8d2c808a
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim.conf
@@ -0,0 +1,44 @@
1@INLINE@ test_reclaim_defaults.conf
2
3[PATHS]
4GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-reclaim-peer-1/
5
6[dht]
7START_ON_DEMAND = YES
8
9[rest]
10START_ON_DEMAND = YES
11# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=$GNUNET_TMP/restlog
12BASIC_AUTH_ENABLED = NO
13
14[transport]
15PLUGINS =
16
17[zonemaster]
18START_ON_DEMAND = YES
19IMMEDIATE_START = YES
20
21[reclaim]
22IMMEDIATE_START = YES
23START_ON_DEMAND = YES
24TICKET_REFRESH_INTERVAL = 1 h
25#PREFIX = valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=$GNUNET_TMP/idplog
26
27[gns]
28#PREFIX = valgrind --leak-check=full --track-origins=yes
29START_ON_DEMAND = YES
30AUTO_IMPORT_PKEY = YES
31MAX_PARALLEL_BACKGROUND_QUERIES = 10
32DEFAULT_LOOKUP_TIMEOUT = 15 s
33RECORD_PUT_INTERVAL = 1 h
34ZONE_PUBLISH_TIME_WINDOW = 1 h
35DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0
36
37[reclaim-rest-plugin]
38expiration_time = 3600
39JWT_SECRET = secret
40OIDC_USERINFO_CONSUME_TIMEOUT = 5s
41OIDC_DIR = $GNUNET_DATA_HOME/oidc
42OIDC_CLIENT_HMAC_SECRET = secret
43OIDC_JSON_WEB_ALGORITHM = RS256
44ADDRESS = https://ui.reclaim/#/login
diff --git a/src/cli/reclaim/test_reclaim.sh b/src/cli/reclaim/test_reclaim.sh
new file mode 100755
index 000000000..da93b10f7
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim.sh
@@ -0,0 +1,31 @@
1#!/bin/sh
2#trap "gnunet-arm -e -c test_reclaim_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_reclaim.conf
27gnunet-identity -C testego -c test_reclaim.conf
28valgrind gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
29gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
30gnunet-reclaim -e testego -D -c test_reclaim.conf
31gnunet-arm -e -c test_reclaim.conf
diff --git a/src/cli/reclaim/test_reclaim_attribute.sh b/src/cli/reclaim/test_reclaim_attribute.sh
new file mode 100755
index 000000000..17f7863d4
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim_attribute.sh
@@ -0,0 +1,40 @@
1#!/bin/bash
2trap "gnunet-arm -e -c test_reclaim.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout &> /dev/null && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_reclaim.conf
27#gnunet-arm -i rest -c test_reclaim.conf
28gnunet-identity -C testego -c test_reclaim.conf
29gnunet-identity -C rpego -c test_reclaim.conf
30TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf)
31gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
32gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
33if test $? != 0
34then
35 echo "Failed."
36 exit 1
37fi
38
39#curl localhost:7776/reclaim/attributes/testego
40gnunet-arm -e -c test_reclaim.conf
diff --git a/src/cli/reclaim/test_reclaim_consume.sh b/src/cli/reclaim/test_reclaim_consume.sh
new file mode 100755
index 000000000..00076fbf8
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim_consume.sh
@@ -0,0 +1,51 @@
1#!/bin/bash
2trap "gnunet-arm -e -c test_reclaim.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1>/dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_reclaim.conf
27#gnunet-arm -i rest -c test_reclaim.conf
28gnunet-arm -I
29gnunet-identity -C testego -c test_reclaim.conf
30gnunet-identity -C rpego -c test_reclaim.conf
31SUBJECT_KEY=$(gnunet-identity -d -e rpego -q -c test_reclaim.conf)
32TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf)
33gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
34gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
35TICKET=$(gnunet-reclaim -e testego -U "urn:gns:$TEST_KEY" -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}')
36echo "Ticket: $TICKET"
37gnunet-gns -u $TICKET -c test_reclaim.conf
38gnunet-namestore -z testego -D -c test_reclaim.conf
39gnunet-identity -d -c test_reclaim.conf
40sleep 1
41gnunet-reclaim -e rpego -U "urn:gns:$TEST_KEY" -C $TICKET -c test_reclaim.conf
42
43RES=$?
44gnunet-identity -D testego -c test_reclaim.conf
45gnunet-identity -D rpego -c test_reclaim.conf
46gnunet-arm -e -c test_reclaim.conf
47if test $RES != 0
48then
49 echo "Failed."
50fi
51
diff --git a/src/cli/reclaim/test_reclaim_defaults.conf b/src/cli/reclaim/test_reclaim_defaults.conf
new file mode 100644
index 000000000..02372563d
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim_defaults.conf
@@ -0,0 +1,24 @@
1@INLINE@ ../../../contrib/conf/gnunet/no_forcestart.conf
2
3[PATHS]
4GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-idp-testing/
5
6[namestore-sqlite]
7FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db
8
9[namecache-sqlite]
10FILENAME=$GNUNET_TEST_HOME/namecache/namecache.db
11
12[identity]
13# Directory where we store information about our egos
14EGODIR = $GNUNET_TEST_HOME/identity/egos/
15
16[dhtcache]
17DATABASE = heap
18
19[transport]
20PLUGINS = tcp
21
22[transport-tcp]
23BINDTO = 127.0.0.1
24
diff --git a/src/cli/reclaim/test_reclaim_issue.sh b/src/cli/reclaim/test_reclaim_issue.sh
new file mode 100755
index 000000000..39e614d19
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim_issue.sh
@@ -0,0 +1,42 @@
1#!/bin/bash
2trap "gnunet-arm -e -c test_reclaim.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_reclaim.conf
27#gnunet-arm -i rest -c test_reclaim.conf
28gnunet-identity -C testego -c test_reclaim.conf
29gnunet-identity -C rpego -c test_reclaim.conf
30SUBJECT_KEY=$(gnunet-identity -d -e rpego -q -c test_reclaim.conf)
31TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf)
32gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
33gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
34#gnunet-reclaim -e testego -D -c test_reclaim.conf
35gnunet-reclaim -e testego -u "urn:gns:$TEST_KEY" -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf > /dev/null 2>&1
36if test $? != 0
37then
38 echo "Failed."
39 exit 1
40fi
41#curl http://localhost:7776/reclaim/attributes/testego
42gnunet-arm -e -c test_reclaim.conf
diff --git a/src/cli/reclaim/test_reclaim_oidc.sh b/src/cli/reclaim/test_reclaim_oidc.sh
new file mode 100755
index 000000000..cdea61a03
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim_oidc.sh
@@ -0,0 +1,57 @@
1#!/bin/bash
2trap "gnunet-arm -e -c test_reclaim.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1>/dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30"
19
20RES=0
21TEST_ATTR="test"
22REDIRECT_URI="https://example.gns.alt/my_cb"
23SCOPE="\"openid email name\""
24gnunet-arm -s -c test_reclaim.conf
25gnunet-arm -i rest -c test_reclaim.conf
26gnunet-arm -I
27gnunet-identity -C testego -c test_reclaim.conf
28gnunet-identity -C rpego -c test_reclaim.conf
29TEST_KEY=$(gnunet-identity -d -e rpego -q -c test_reclaim.conf)
30SUBJECT_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf)
31gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
32gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
33
34# Register client
35gnunet-namestore -z rpego -a -n @ -t RECLAIM_OIDC_CLIENT -V "My RP" -e 1d -p -c test_reclaim.conf
36gnunet-namestore -z rpego -a -n @ -t RECLAIM_OIDC_REDIRECT -V $REDIRECT_URI -e 1d -p -c test_reclaim.conf
37
38gnunet-gns -u @.$TEST_KEY -t RECLAIM_OIDC_REDIRECT -c test_reclaim.conf
39curl -v -X POST -H -v "http://localhost:7776/openid/login" --data "{\"identity\": \"$SUBJECT_KEY\"}"
40
41PKCE_CHALLENGE=$(echo -n secret | openssl dgst -binary -sha256 | openssl base64 | sed 's/\=//g' | sed 's/+/-/g' | sed 's/\//_/g')
42
43CODE=$(curl -H "Cookie: Identity=$SUBJECT_KEY" "http://localhost:7776/openid/authorize?client_id=$TEST_KEY&response_type=code&redirect_uri=$REDIRECT_URI&scope=openid&claims=%7B%22userinfo%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%20%20%20%20%3A%20true%7D%7D%2C%22id_token%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D&state=xyz&code_challenge=$PKCE_CHALLENGE&code_challenge_method=S256" \
44 -sS -D - -o /dev/null | grep "Location: " | cut -d" " -f2 | cut -d"?" -f2 | cut -d"&" -f1 | cut -d"=" -f2)
45
46echo "Code: $CODE"
47
48curl -v -X POST -u$TEST_KEY:"secret" "http://localhost:7776/openid/token?client_id=$TEST_KEY&response_type=code&redirect_uri=$REDIRECT_URI&scope=openid&claims=%7B%22userinfo%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%20%20%20%20%3A%20true%7D%7D%2C%22id_token%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D&state=xyz&grant_type=authorization_code&code=$CODE&code_verifier=secret"
49
50gnunet-identity -D testego -c test_reclaim.conf
51gnunet-identity -D rpego -c test_reclaim.conf
52gnunet-arm -e -c test_reclaim.conf
53if test $RES != 0
54then
55 echo "Failed."
56fi
57
diff --git a/src/cli/reclaim/test_reclaim_revoke.sh b/src/cli/reclaim/test_reclaim_revoke.sh
new file mode 100755
index 000000000..da091a1ee
--- /dev/null
+++ b/src/cli/reclaim/test_reclaim_revoke.sh
@@ -0,0 +1,65 @@
1#!/bin/bash
2trap "gnunet-arm -e -c test_reclaim.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout >/dev/null 2&>1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_reclaim.conf >/dev/null 2&>1
27gnunet-identity -C alice -c test_reclaim.conf
28gnunet-identity -C bob -c test_reclaim.conf
29gnunet-identity -C eve -c test_reclaim.conf
30ALICE_KEY=$(gnunet-identity -d -e alice -q -c test_reclaim.conf)
31BOB_KEY=$(gnunet-identity -d -e bob -q -c test_reclaim.conf)
32EVE_KEY=$(gnunet-identity -d -e eve -q -c test_reclaim.conf)
33gnunet-reclaim -e alice -E 15s -a email -V john@doe.gnu -c test_reclaim.conf
34gnunet-reclaim -e alice -E 15s -a name -V John -c test_reclaim.conf
35TICKET_BOB=$(gnunet-reclaim -e alice -i "email,name" -r $BOB_KEY -c test_reclaim.conf | awk '{print $1}')
36#gnunet-reclaim -e bob -C $TICKET_BOB -c test_reclaim.conf
37TICKET_EVE=$(gnunet-reclaim -e alice -i "email" -r $EVE_KEY -c test_reclaim.conf | awk '{print $1}')
38gnunet-namestore -z alice -D
39echo "Revoking $TICKET"
40gnunet-reclaim -e alice -R $TICKET_EVE -c test_reclaim.conf
41gnunet-namestore -z alice -D
42sleep 16
43echo "Consuming $TICKET"
44
45gnunet-reclaim -e eve -C $TICKET_EVE -c test_reclaim.conf
46if test $? = 0
47then
48 echo "Eve can still resolve attributes..."
49 gnunet-arm -e -c test_reclaim.conf
50 exit 1
51fi
52
53gnunet-arm -e -c test_reclaim.conf
54gnunet-arm -s -c test_reclaim.conf >/dev/null 2&>1
55
56gnunet-reclaim -e bob -C $TICKET_BOB -c test_reclaim.conf
57#gnunet-reclaim -e bob -C $TICKET_BOB -c test_reclaim.conf >/dev/null 2&>1
58if test $? != 0
59then
60 echo "Bob cannot resolve attributes..."
61 gnunet-arm -e -c test_reclaim.conf
62 exit 1
63fi
64
65gnunet-arm -e -c test_reclaim.conf