aboutsummaryrefslogtreecommitdiff
path: root/src/abd/gnunet-abd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/abd/gnunet-abd.c')
-rw-r--r--src/abd/gnunet-abd.c1108
1 files changed, 0 insertions, 1108 deletions
diff --git a/src/abd/gnunet-abd.c b/src/abd/gnunet-abd.c
deleted file mode 100644
index 9f5fef958..000000000
--- a/src/abd/gnunet-abd.c
+++ /dev/null
@@ -1,1108 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2013 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 * @file gnunet-abd.c
22 * @brief command line tool to access command line Credential service
23 * @author Martin Schanzenbach
24 */
25#include "platform.h"
26#include <gnunet_util_lib.h>
27#include <gnunet_abd_service.h>
28#include <gnunet_gnsrecord_lib.h>
29#include <gnunet_namestore_service.h>
30#include "delegate_misc.h"
31#include "abd_serialization.h"
32
33/**
34 * Configuration we are using.
35 */
36static const struct GNUNET_CONFIGURATION_Handle *cfg;
37
38/**
39 * Handle to the namestore.
40 */
41static struct GNUNET_NAMESTORE_Handle *ns;
42
43/**
44 * Private key for the our zone.
45 */
46static struct GNUNET_IDENTITY_PrivateKey zone_pkey;
47
48/**
49 * EgoLookup
50 */
51static struct GNUNET_IDENTITY_EgoLookup *el;
52
53/**
54 * Handle to Credential service.
55 */
56static struct GNUNET_ABD_Handle *abd;
57
58/**
59 * Desired timeout for the lookup (default is no timeout).
60 */
61static struct GNUNET_TIME_Relative timeout;
62
63/**
64 * Handle to verify request
65 */
66static struct GNUNET_ABD_Request *verify_request;
67
68/**
69 * Handle to collect request
70 */
71static struct GNUNET_ABD_Request *collect_request;
72
73/**
74 * Task scheduled to handle timeout.
75 */
76static struct GNUNET_SCHEDULER_Task *tt;
77
78/**
79 * Return value of the commandline.
80 */
81static int ret = 0;
82
83/**
84 * Subject pubkey string
85 */
86static char *subject;
87
88/**
89 * Subject delegate string
90 */
91static char *subject_delegate;
92
93/**
94 * Credential TTL
95 */
96static char *expiration;
97
98/**
99 * Subject key
100 */
101struct GNUNET_IDENTITY_PublicKey subject_pkey;
102
103/**
104 * Issuer key
105 */
106struct GNUNET_IDENTITY_PublicKey issuer_pkey;
107
108
109/**
110 * Issuer pubkey string
111 */
112static char *issuer_key;
113
114/**
115 * ego
116 */
117static char *ego_name;
118
119/**
120 * Issuer attribute
121 */
122static char *issuer_attr;
123
124/**
125 * Verify mode
126 */
127static int verify;
128
129/**
130 * Collect mode
131 */
132static int collect;
133
134/**
135 * Create mode
136 */
137static int create_is;
138
139/**
140 * Create mode
141 */
142static int create_ss;
143
144/**
145 * Create mode
146 */
147static int sign_ss;
148
149/**
150 * Signed issue credentials
151 */
152static char *import;
153
154/**
155 * Is record private
156 */
157static int is_private;
158
159/**
160 * Search direction: forward
161 */
162static int forward;
163
164/**
165 * Search direction: backward
166 */
167static int backward;
168
169/**
170 * API enum, filled and passed for collect/verify
171 */
172enum GNUNET_ABD_AlgoDirectionFlags direction = 0;
173
174/**
175 * Queue entry for the 'add' operation.
176 */
177static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
178
179/**
180 * Value in binary format.
181 */
182static void *data;
183
184/**
185 * Number of bytes in #data.
186 */
187static size_t data_size;
188
189/**
190 * Type string converted to DNS type value.
191 */
192static uint32_t type;
193
194/**
195 * Type of the record to add/remove, NULL to remove all.
196 */
197static char *typestring;
198/**
199 * Expiration string converted to numeric value.
200 */
201static uint64_t etime;
202
203/**
204 * Is expiration time relative or absolute time?
205 */
206static int etime_is_rel = GNUNET_SYSERR;
207
208/**
209 * Record label for storing delegations
210 */
211static char *record_label;
212
213/**
214 * Task run on shutdown. Cleans up everything.
215 *
216 * @param cls unused
217 */
218static void
219do_shutdown (void *cls)
220{
221 if (NULL != verify_request)
222 {
223 GNUNET_ABD_request_cancel (verify_request);
224 verify_request = NULL;
225 }
226 if (NULL != abd)
227 {
228 GNUNET_ABD_disconnect (abd);
229 abd = NULL;
230 }
231 if (NULL != tt)
232 {
233 GNUNET_SCHEDULER_cancel (tt);
234 tt = NULL;
235 }
236 if (NULL != el)
237 {
238 GNUNET_IDENTITY_ego_lookup_cancel (el);
239 el = NULL;
240 }
241 if (NULL != add_qe)
242 {
243 GNUNET_NAMESTORE_cancel (add_qe);
244 add_qe = NULL;
245 }
246 if (NULL != ns)
247 {
248 GNUNET_NAMESTORE_disconnect (ns);
249 ns = NULL;
250 }
251}
252
253
254/**
255 * Task run on timeout. Triggers shutdown.
256 *
257 * @param cls unused
258 */
259static void
260do_timeout (void *cls)
261{
262 tt = NULL;
263 GNUNET_SCHEDULER_shutdown ();
264}
265
266
267static void
268handle_intermediate_result (void *cls,
269 struct GNUNET_ABD_Delegation *dd,
270 bool is_bw)
271{
272 char *prefix = "";
273 if (is_bw)
274 prefix = "Backward -";
275 else
276 prefix = "Forward -";
277
278 printf ("%s Intermediate result: %s.%s <- %s.%s\n",
279 prefix,
280 GNUNET_IDENTITY_public_key_to_string (&dd->issuer_key),
281 dd->issuer_attribute,
282 GNUNET_IDENTITY_public_key_to_string (&dd->subject_key),
283 dd->subject_attribute);
284}
285
286
287static void
288handle_collect_result (void *cls,
289 unsigned int d_count,
290 struct GNUNET_ABD_Delegation *dc,
291 unsigned int c_count,
292 struct GNUNET_ABD_Delegate *dele)
293{
294 int i;
295 char *line;
296
297 verify_request = NULL;
298 if (NULL != dele)
299 {
300 for (i = 0; i < c_count; i++)
301 {
302 line = GNUNET_ABD_delegate_to_string (&dele[i]);
303 printf ("%s\n", line);
304 GNUNET_free (line);
305 }
306 }
307 else
308 {
309 printf ("Received NULL\n");
310 }
311
312 GNUNET_SCHEDULER_shutdown ();
313}
314
315
316static void
317handle_verify_result (void *cls,
318 unsigned int d_count,
319 struct GNUNET_ABD_Delegation *dc,
320 unsigned int c_count,
321 struct GNUNET_ABD_Delegate *dele)
322{
323 int i;
324 char *iss_key;
325 char *sub_key;
326
327 verify_request = NULL;
328 if (NULL == dele)
329 ret = 1;
330 else
331 {
332 printf ("Delegation Chain:\n");
333 for (i = 0; i < d_count; i++)
334 {
335 iss_key = GNUNET_IDENTITY_public_key_to_string (&dc[i].issuer_key);
336 sub_key = GNUNET_IDENTITY_public_key_to_string (&dc[i].subject_key);
337
338 if (0 != dc[i].subject_attribute_len)
339 {
340 printf ("(%d) %s.%s <- %s.%s\n",
341 i,
342 iss_key,
343 dc[i].issuer_attribute,
344 sub_key,
345 dc[i].subject_attribute);
346 }
347 else
348 {
349 printf ("(%d) %s.%s <- %s\n",
350 i,
351 iss_key,
352 dc[i].issuer_attribute,
353 sub_key);
354 }
355 GNUNET_free (iss_key);
356 GNUNET_free (sub_key);
357 }
358 printf ("\nDelegate(s):\n");
359 for (i = 0; i < c_count; i++)
360 {
361 iss_key = GNUNET_IDENTITY_public_key_to_string (&dele[i].issuer_key);
362 sub_key = GNUNET_IDENTITY_public_key_to_string (&dele[i].subject_key);
363 printf ("%s.%s <- %s\n", iss_key, dele[i].issuer_attribute, sub_key);
364 GNUNET_free (iss_key);
365 GNUNET_free (sub_key);
366 }
367 printf ("Successful.\n");
368 }
369
370 GNUNET_SCHEDULER_shutdown ();
371}
372
373
374/**
375 * Callback invoked from identity service with ego information.
376 * An @a ego of NULL means the ego was not found.
377 *
378 * @param cls closure with the configuration
379 * @param ego an ego known to identity service, or NULL
380 */
381static void
382identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
383{
384 const struct GNUNET_IDENTITY_PrivateKey *privkey;
385
386 el = NULL;
387 if (NULL == ego)
388 {
389 if (NULL != ego_name)
390 {
391 fprintf (stderr,
392 _ ("Ego `%s' not known to identity service\n"),
393 ego_name);
394 }
395 GNUNET_SCHEDULER_shutdown ();
396 return;
397 }
398
399 if (GNUNET_YES == collect)
400 {
401
402 if (GNUNET_OK !=
403 GNUNET_IDENTITY_public_key_from_string (issuer_key,
404 &issuer_pkey))
405 {
406 fprintf (stderr,
407 _ ("Issuer public key `%s' is not well-formed\n"),
408 issuer_key);
409 GNUNET_SCHEDULER_shutdown ();
410 }
411 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
412
413 collect_request = GNUNET_ABD_collect (abd,
414 &issuer_pkey,
415 issuer_attr,
416 privkey,
417 direction,
418 &handle_collect_result,
419 NULL,
420 &handle_intermediate_result,
421 NULL);
422 return;
423 }
424 GNUNET_SCHEDULER_shutdown ();
425}
426
427
428/**
429 * Parse expiration time.
430 *
431 * @param expirationstring text to parse
432 * @param etime_is_rel[out] set to #GNUNET_YES if time is relative
433 * @param etime[out] set to expiration time (abs or rel)
434 * @return #GNUNET_OK on success
435 */
436static int
437parse_expiration (const char *expirationstring,
438 int *etime_is_rel,
439 uint64_t *etime)
440{
441 // copied from namestore/gnunet-namestore.c
442 struct GNUNET_TIME_Relative etime_rel;
443 struct GNUNET_TIME_Absolute etime_abs;
444
445 if (0 == strcmp (expirationstring, "never"))
446 {
447 *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
448 *etime_is_rel = GNUNET_NO;
449 return GNUNET_OK;
450 }
451 if (GNUNET_OK ==
452 GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
453 {
454 *etime_is_rel = GNUNET_YES;
455 *etime = etime_rel.rel_value_us;
456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
457 "Storing record with relative expiration time of %s\n",
458 GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
459 return GNUNET_OK;
460 }
461 if (GNUNET_OK ==
462 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
463 {
464 *etime_is_rel = GNUNET_NO;
465 *etime = etime_abs.abs_value_us;
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
467 "Storing record with absolute expiration time of %s\n",
468 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
469 return GNUNET_OK;
470 }
471 return GNUNET_SYSERR;
472}
473
474
475/**
476 * Function called if lookup fails.
477 */
478static void
479error_cb (void *cls)
480{
481 fprintf (stderr, "Error occurred during lookup, shutting down.\n");
482 GNUNET_SCHEDULER_shutdown ();
483 return;
484}
485
486
487static void
488add_continuation (void *cls, int32_t success, const char *emsg)
489{
490 struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
491 *qe = NULL;
492
493 if (GNUNET_OK == success)
494 printf ("Adding successful.\n");
495 else
496 fprintf (stderr, "Error occurred during adding, shutting down.\n");
497
498 GNUNET_SCHEDULER_shutdown ();
499}
500
501
502static void
503get_existing_record (void *cls,
504 const struct GNUNET_IDENTITY_PrivateKey *zone_key,
505 const char *rec_name,
506 unsigned int rd_count,
507 const struct GNUNET_GNSRECORD_Data *rd)
508{
509 struct GNUNET_GNSRECORD_Data *rde;
510 struct GNUNET_GNSRECORD_Data*rdn =
511 GNUNET_malloc (sizeof(*rdn) * (rd_count + 1));
512
513 memset (rdn, 0, sizeof (struct GNUNET_GNSRECORD_Data));
514 GNUNET_memcpy (&rdn[1], rd,
515 rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
516 rde = &rdn[0];
517 rde->data = data;
518 rde->data_size = data_size;
519 rde->record_type = type;
520
521 // Set flags
522 if (GNUNET_YES == is_private)
523 rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
524 rde->expiration_time = etime;
525 if (GNUNET_YES == etime_is_rel)
526 rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
527 else if (GNUNET_NO != etime_is_rel)
528 rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
529
530 GNUNET_assert (NULL != rec_name);
531 add_qe = GNUNET_NAMESTORE_records_store (ns,
532 &zone_pkey,
533 rec_name,
534 rd_count + 1,
535 rde,
536 &add_continuation,
537 &add_qe);
538 GNUNET_free (rdn);
539 return;
540}
541
542
543static void
544store_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
545{
546 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
547 struct GNUNET_ABD_Delegate *cred;
548 struct GNUNET_IDENTITY_PublicKey zone_pubkey;
549 char *subject_pubkey_str;
550 char *zone_pubkey_str;
551
552 el = NULL;
553
554 ns = GNUNET_NAMESTORE_connect (cfg);
555 if (NULL == ns)
556 {
557 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
558 _ ("Failed to connect to namestore\n"));
559 GNUNET_SCHEDULER_shutdown ();
560 return;
561 }
562
563 if (NULL == ego)
564 {
565 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
566 _("Ego does not exist!\n"));
567 GNUNET_SCHEDULER_shutdown ();
568 return;
569 }
570
571 // Key handling
572 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
573
574 if (GNUNET_GNSRECORD_TYPE_DELEGATE == type)
575 {
576 // Parse import
577 cred = GNUNET_ABD_delegate_from_string (import);
578
579 if (NULL == cred)
580 {
581 fprintf (stderr,
582 "%s is not a valid credential\n", import);
583 GNUNET_SCHEDULER_shutdown();
584 return;
585 }
586
587 // Get import subject public key string
588 subject_pubkey_str =
589 GNUNET_IDENTITY_public_key_to_string (&cred->subject_key);
590
591 // Get zone public key string
592 GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
593 zone_pubkey_str =
594 GNUNET_IDENTITY_public_key_to_string (&zone_pubkey);
595
596 // Check if the subject key in the signed import matches the zone's key it is issued to
597 if (strcmp (zone_pubkey_str, subject_pubkey_str) != 0)
598 {
599 fprintf (stderr,
600 "Import signed delegate does not match this ego's public key.\n");
601 GNUNET_free (cred);
602 GNUNET_SCHEDULER_shutdown ();
603 return;
604 }
605
606 // Expiration
607 etime = cred->expiration.abs_value_us;
608 etime_is_rel = GNUNET_NO;
609
610 // Prepare the data to be store in the record
611 data_size = GNUNET_ABD_delegate_serialize (cred, (char **) &data);
612 GNUNET_free (cred);
613 }
614 else
615 {
616 // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
617 if (GNUNET_OK !=
618 GNUNET_GNSRECORD_string_to_value (type, subject, &data, &data_size))
619 {
620 if (typestring == NULL)
621 {
622 fputs ("Value for unknown record type not well-formed.\n", stderr);
623 }
624 else if (subject == NULL)
625 {
626 fprintf (stderr,
627 "Value for record type `%s' not well-formed.\n",
628 typestring);
629 }
630 else
631 {
632 fprintf (stderr,
633 "Value `%s' invalid for record type `%s'\n",
634 subject,
635 typestring);
636 }
637 GNUNET_SCHEDULER_shutdown ();
638 return;
639 }
640
641 // Take care of expiration
642 if (NULL == expiration)
643 {
644 fprintf (stderr, "Missing option -e for operation 'create'\n");
645 GNUNET_SCHEDULER_shutdown ();
646 return;
647 }
648 if (GNUNET_OK != parse_expiration (expiration, &etime_is_rel, &etime))
649 {
650 fprintf (stderr, "Invalid time format `%s'\n", expiration);
651 GNUNET_SCHEDULER_shutdown ();
652 return;
653 }
654 }
655
656 // Start lookup
657 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
658 &zone_pkey,
659 record_label,
660 &error_cb,
661 NULL,
662 &get_existing_record,
663 NULL);
664 return;
665}
666
667
668static void
669sign_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
670{
671 const struct GNUNET_IDENTITY_PrivateKey *privkey;
672 struct GNUNET_ABD_Delegate *dele;
673 struct GNUNET_TIME_Absolute etime_abs;
674 char *res;
675
676 el = NULL;
677
678 // work on expiration time
679 if (NULL == expiration)
680 {
681 fprintf (stderr, "Please specify a TTL\n");
682 GNUNET_SCHEDULER_shutdown ();
683 return;
684 }
685 else if (GNUNET_OK !=
686 GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
687 {
688 fprintf (stderr,
689 "%s is not a valid ttl! Only absolute times are accepted!\n",
690 expiration);
691 GNUNET_SCHEDULER_shutdown ();
692 return;
693 }
694
695 // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
696 char *subject_pubkey_str;
697 char *subject_attr = NULL;
698 char *token;
699
700 // Subject Public Key
701 token = strtok (subject, " ");
702 subject_pubkey_str = token;
703 // Subject Attribute(s)
704 token = strtok (NULL, " ");
705 if (NULL != token)
706 {
707 subject_attr = token;
708 }
709
710 // work on keys
711 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
712
713 if (NULL == subject_pubkey_str)
714 {
715 fprintf (stderr,
716 "Subject pubkey not given\n");
717 GNUNET_SCHEDULER_shutdown ();
718 return;
719 }
720 if (GNUNET_OK !=
721 GNUNET_IDENTITY_public_key_from_string (subject_pubkey_str,
722 &subject_pkey))
723 {
724 fprintf (stderr,
725 "Subject public key `%s' is not well-formed\n",
726 subject_pubkey_str);
727 GNUNET_SCHEDULER_shutdown ();
728 return;
729 }
730
731 // Sign delegate
732 dele = GNUNET_ABD_delegate_issue (privkey,
733 &subject_pkey,
734 issuer_attr,
735 subject_attr,
736 &etime_abs);
737 res = GNUNET_ABD_delegate_to_string (dele);
738 GNUNET_free (dele);
739 printf ("%s\n", res);
740
741 GNUNET_free (ego_name);
742 ego_name = NULL;
743
744 GNUNET_SCHEDULER_shutdown ();
745}
746
747
748/**
749 * Main function that will be run.
750 *
751 * @param cls closure
752 * @param args remaining command-line arguments
753 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
754 * @param c configuration
755 */
756static void
757run (void *cls,
758 char *const *args,
759 const char *cfgfile,
760 const struct GNUNET_CONFIGURATION_Handle *c)
761{
762 cfg = c;
763
764 tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL);
765 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
766
767 // Check relevant cmdline parameters
768 if (GNUNET_YES == create_is)
769 {
770 if (NULL == ego_name)
771 {
772 fprintf (stderr, "Missing option '-ego'\n");
773 GNUNET_SCHEDULER_shutdown ();
774 return;
775 }
776 if (NULL == issuer_attr)
777 {
778 fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
779 GNUNET_SCHEDULER_shutdown ();
780 return;
781 }
782 if (NULL == subject)
783 {
784 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
785 GNUNET_SCHEDULER_shutdown ();
786 return;
787 }
788
789 // Lookup ego, on success call store_cb and store as ATTRIBUTE type
790 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
791 record_label = issuer_attr;
792 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
793 return;
794 }
795
796 if (GNUNET_YES == create_ss)
797 {
798
799 // check if signed parameter has been passed in cmd line call
800 if (NULL == import)
801 {
802 fprintf (stderr, "'import' required\n");
803 GNUNET_SCHEDULER_shutdown ();
804 return;
805 }
806
807 type = GNUNET_GNSRECORD_TYPE_DELEGATE;
808 record_label = GNUNET_GNS_EMPTY_LABEL_AT;
809 // Store subject side
810 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
811
812 return;
813 }
814
815 if (GNUNET_YES == sign_ss)
816 {
817 if (NULL == ego_name)
818 {
819 fprintf (stderr, "ego required\n");
820 GNUNET_SCHEDULER_shutdown ();
821 return;
822 }
823 if (NULL == subject)
824 {
825 fprintf (stderr, "Subject public key needed\n");
826 GNUNET_SCHEDULER_shutdown ();
827 return;
828 }
829
830 // lookup ego and call function sign_cb on success
831 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &sign_cb, (void *) cfg);
832 return;
833 }
834
835 if ((GNUNET_NO == forward) && (GNUNET_NO == backward))
836 {
837 // set default: bidirectional
838 forward = GNUNET_YES;
839 backward = GNUNET_YES;
840 }
841 if (GNUNET_YES == forward)
842 direction |= GNUNET_ABD_FLAG_FORWARD;
843 if (GNUNET_YES == backward)
844 direction |= GNUNET_ABD_FLAG_BACKWARD;
845
846 if (GNUNET_YES == collect)
847 {
848 if (NULL == issuer_key)
849 {
850 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
851 GNUNET_SCHEDULER_shutdown ();
852 return;
853 }
854
855 abd = GNUNET_ABD_connect (cfg);
856
857 if (NULL == abd)
858 {
859 fprintf (stderr, _ ("Failed to connect to ABD\n"));
860 GNUNET_SCHEDULER_shutdown ();
861 return;
862 }
863 if (NULL == issuer_attr)
864 {
865 fprintf (stderr, _ ("You must provide issuer the attribute\n"));
866 GNUNET_SCHEDULER_shutdown ();
867 return;
868 }
869
870 if (NULL == ego_name)
871 {
872 fprintf (stderr, _ ("ego required\n"));
873 GNUNET_SCHEDULER_shutdown ();
874 return;
875 }
876 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg);
877 return;
878 }
879
880 if (NULL == subject)
881 {
882 fprintf (stderr, _ ("Subject public key needed\n"));
883 GNUNET_SCHEDULER_shutdown ();
884 return;
885 }
886 if (GNUNET_OK != GNUNET_IDENTITY_public_key_from_string (subject,
887 &subject_pkey))
888 {
889 fprintf (stderr,
890 _ ("Subject public key `%s' is not well-formed\n"),
891 subject);
892 GNUNET_SCHEDULER_shutdown ();
893 return;
894 }
895
896 if (GNUNET_YES == verify)
897 {
898 if (NULL == issuer_key)
899 {
900 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
901 GNUNET_SCHEDULER_shutdown ();
902 return;
903 }
904 if (GNUNET_OK !=
905 GNUNET_IDENTITY_public_key_from_string (issuer_key,
906 &issuer_pkey))
907 {
908 fprintf (stderr,
909 _ ("Issuer public key `%s' is not well-formed\n"),
910 issuer_key);
911 GNUNET_SCHEDULER_shutdown ();
912 return;
913 }
914 abd = GNUNET_ABD_connect (cfg);
915
916 if (NULL == abd)
917 {
918 fprintf (stderr, _ ("Failed to connect to ABD\n"));
919 GNUNET_SCHEDULER_shutdown ();
920 return;
921 }
922 if ((NULL == issuer_attr) || (NULL == subject_delegate))
923 {
924 fprintf (stderr, _ ("You must provide issuer and subject attributes\n"));
925 GNUNET_SCHEDULER_shutdown ();
926 return;
927 }
928
929 // Subject credentials are comma separated
930 char *tmp = GNUNET_strdup (subject_delegate);
931 char *tok = strtok (tmp, ",");
932 if (NULL == tok)
933 {
934 fprintf (stderr, "Invalid subject credentials\n");
935 GNUNET_free (tmp);
936 GNUNET_SCHEDULER_shutdown ();
937 return;
938 }
939 int count = 1;
940 int i;
941 while (NULL != (tok = strtok (NULL, ",")))
942 count++;
943 struct GNUNET_ABD_Delegate*delegates =
944 GNUNET_malloc (sizeof(*delegates) * count);
945 struct GNUNET_ABD_Delegate *dele;
946 GNUNET_free (tmp);
947 tmp = GNUNET_strdup (subject_delegate);
948 tok = strtok (tmp, ",");
949 for (i = 0; i < count; i++)
950 {
951 dele = GNUNET_ABD_delegate_from_string (tok);
952 GNUNET_memcpy (&delegates[i],
953 dele,
954 sizeof (struct GNUNET_ABD_Delegate));
955 delegates[i].issuer_attribute = GNUNET_strdup (dele->issuer_attribute);
956 tok = strtok (NULL, ",");
957 GNUNET_free (dele);
958 }
959
960 verify_request = GNUNET_ABD_verify (abd,
961 &issuer_pkey,
962 issuer_attr,
963 &subject_pkey,
964 count,
965 delegates,
966 direction,
967 &handle_verify_result,
968 NULL,
969 &handle_intermediate_result,
970 NULL);
971 for (i = 0; i < count; i++)
972 {
973 GNUNET_free_nz ((char *) delegates[i].issuer_attribute);
974 delegates[i].issuer_attribute = NULL;
975 }
976 GNUNET_free (tmp);
977 GNUNET_free (delegates);
978 }
979 else
980 {
981 fprintf (stderr,
982 _ (
983 "Please specify name to lookup, subject key and issuer key!\n"));
984 GNUNET_SCHEDULER_shutdown ();
985 }
986 return;
987}
988
989
990/**
991 * The main function for gnunet-gns.
992 *
993 * @param argc number of arguments from the command line
994 * @param argv command line arguments
995 * @return 0 ok, 1 on error
996 */
997int
998main (int argc, char *const *argv)
999{
1000 struct GNUNET_GETOPT_CommandLineOption options[] =
1001 {GNUNET_GETOPT_option_flag ('V',
1002 "verify",
1003 gettext_noop (
1004 "verify credential against attribute"),
1005 &verify),
1006 GNUNET_GETOPT_option_string (
1007 's',
1008 "subject",
1009 "PKEY",
1010 gettext_noop (
1011 "The public key of the subject to lookup the"
1012 "credential for, or for issuer side storage: subject and its attributes"),
1013 &subject),
1014 GNUNET_GETOPT_option_string (
1015 'd',
1016 "delegate",
1017 "DELE",
1018 gettext_noop ("The private, signed delegate presented by the subject"),
1019 &subject_delegate),
1020 GNUNET_GETOPT_option_string (
1021 'i',
1022 "issuer",
1023 "PKEY",
1024 gettext_noop (
1025 "The public key of the authority to verify the credential against"),
1026 &issuer_key),
1027 GNUNET_GETOPT_option_string ('e',
1028 "ego",
1029 "EGO",
1030 gettext_noop ("The ego/zone name to use"),
1031 &ego_name),
1032 GNUNET_GETOPT_option_string (
1033 'a',
1034 "attribute",
1035 "ATTR",
1036 gettext_noop ("The issuer attribute to verify against or to issue"),
1037 &issuer_attr),
1038 GNUNET_GETOPT_option_string ('T',
1039 "ttl",
1040 "EXP",
1041 gettext_noop (
1042 "The time to live for the credential."
1043 "e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
1044 &expiration),
1045 GNUNET_GETOPT_option_flag ('g',
1046 "collect",
1047 gettext_noop ("collect credentials"),
1048 &collect),
1049 GNUNET_GETOPT_option_flag ('U',
1050 "createIssuerSide",
1051 gettext_noop (
1052 "Create and issue a credential issuer side."),
1053 &create_is),
1054 GNUNET_GETOPT_option_flag ('C',
1055 "createSubjectSide",
1056 gettext_noop (
1057 "Issue a credential subject side."),
1058 &create_ss),
1059 GNUNET_GETOPT_option_flag (
1060 'S',
1061 "signSubjectSide",
1062 gettext_noop ("Create, sign and return a credential subject side."),
1063 &sign_ss),
1064 GNUNET_GETOPT_option_string (
1065 'x',
1066 "import",
1067 "IMP",
1068 gettext_noop (
1069 "Import signed credentials that should be issued to a zone/ego"),
1070 &import),
1071 GNUNET_GETOPT_option_flag ('P',
1072 "private",
1073 gettext_noop ("Create private record entry."),
1074 &is_private),
1075 GNUNET_GETOPT_option_flag (
1076 'F',
1077 "forward",
1078 gettext_noop (
1079 "Indicates that the collect/verify process is done via forward search."),
1080 &forward),
1081 GNUNET_GETOPT_option_flag (
1082 'B',
1083 "backward",
1084 gettext_noop (
1085 "Indicates that the collect/verify process is done via forward search."),
1086 &backward),
1087 GNUNET_GETOPT_OPTION_END};
1088
1089
1090 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1091 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1092 return 2;
1093
1094 GNUNET_log_setup ("gnunet-abd", "WARNING", NULL);
1095 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
1096 argv,
1097 "gnunet-abd",
1098 _ ("GNUnet abd resolver tool"),
1099 options,
1100 &run,
1101 NULL))
1102 ret = 1;
1103 GNUNET_free_nz ((void *) argv);
1104 return ret;
1105}
1106
1107
1108/* end of gnunet-abd.c */