aboutsummaryrefslogtreecommitdiff
path: root/src/identity/gnunet-identity.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity/gnunet-identity.c')
-rw-r--r--src/identity/gnunet-identity.c534
1 files changed, 0 insertions, 534 deletions
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c
deleted file mode 100644
index d8dc936d3..000000000
--- a/src/identity/gnunet-identity.c
+++ /dev/null
@@ -1,534 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2018, 2019 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 identity/gnunet-identity.c
22 * @brief IDENTITY management command line tool
23 * @author Christian Grothoff
24 *
25 * Todo:
26 * - add options to get default egos
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_identity_service.h"
31
32
33/**
34 * Return value from main on timeout.
35 */
36#define TIMEOUT_STATUS_CODE 40
37
38/**
39 * Handle to IDENTITY service.
40 */
41static struct GNUNET_IDENTITY_Handle *sh;
42
43/**
44 * Was "list" specified?
45 */
46static int list;
47
48/**
49 * Was "monitor" specified?
50 */
51static int monitor;
52
53/**
54 * Was "private" specified?
55 */
56static int private_keys;
57
58/**
59 * Was "verbose" specified?
60 */
61static unsigned int verbose;
62
63/**
64 * Was "quiet" specified?
65 */
66static int quiet;
67
68/**
69 * Was "eddsa" specified?
70 */
71static int type_eddsa;
72
73/**
74 * -C option
75 */
76static char *create_ego;
77
78/**
79 * -D option
80 */
81static char *delete_ego;
82
83/**
84 * -P option
85 */
86static char *privkey_ego;
87
88/**
89 * -s option.
90 */
91static char *set_ego;
92
93/**
94 * -S option.
95 */
96static char *set_subsystem;
97
98/**
99 * Operation handle for set operation.
100 */
101static struct GNUNET_IDENTITY_Operation *set_op;
102
103/**
104 * Handle for create operation.
105 */
106static struct GNUNET_IDENTITY_Operation *create_op;
107
108/**
109 * Handle for delete operation.
110 */
111static struct GNUNET_IDENTITY_Operation *delete_op;
112
113/**
114 * Private key from command line option, or NULL.
115 */
116struct GNUNET_IDENTITY_PrivateKey pk;
117
118/**
119 * Value to return from #main().
120 */
121static int global_ret;
122
123
124/**
125 * Task run on shutdown.
126 *
127 * @param cls NULL
128 */
129static void
130shutdown_task (void *cls)
131{
132 if (NULL != set_op)
133 {
134 GNUNET_IDENTITY_cancel (set_op);
135 set_op = NULL;
136 }
137 if (NULL != create_op)
138 {
139 GNUNET_IDENTITY_cancel (create_op);
140 create_op = NULL;
141 }
142 if (NULL != delete_op)
143 {
144 GNUNET_IDENTITY_cancel (delete_op);
145 delete_op = NULL;
146 }
147 if (NULL != set_ego)
148 {
149 GNUNET_free (set_ego);
150 set_ego = NULL;
151 }
152 GNUNET_IDENTITY_disconnect (sh);
153 sh = NULL;
154}
155
156
157/**
158 * Test if we are finished yet.
159 */
160static void
161test_finished (void)
162{
163 if ( (NULL == create_op) &&
164 (NULL == delete_op) &&
165 (NULL == set_op) &&
166 (NULL == set_subsystem) &&
167 (! list) &&
168 (! monitor))
169 {
170 if (TIMEOUT_STATUS_CODE == global_ret)
171 global_ret = 0;
172 GNUNET_SCHEDULER_shutdown ();
173 }
174}
175
176
177/**
178 * Deletion operation finished.
179 *
180 * @param cls pointer to operation handle
181 * @param emsg NULL on success, otherwise an error message
182 */
183static void
184delete_finished (void *cls,
185 const char *emsg)
186{
187 struct GNUNET_IDENTITY_Operation **op = cls;
188
189 *op = NULL;
190 if (NULL != emsg)
191 fprintf (stderr, "%s\n", gettext (emsg));
192 test_finished ();
193}
194
195
196/**
197 * Creation operation finished.
198 *
199 * @param cls pointer to operation handle
200 * @param pk private key of the ego, or NULL on error
201 * @param emsg error message, NULL on success
202 */
203static void
204create_finished (void *cls,
205 const struct GNUNET_IDENTITY_PrivateKey *pk,
206 const char *emsg)
207{
208 struct GNUNET_IDENTITY_Operation **op = cls;
209
210 *op = NULL;
211 if (NULL == pk)
212 {
213 fprintf (stderr,
214 _ ("Failed to create ego: %s\n"),
215 emsg);
216 global_ret = 1;
217 }
218 else if (verbose)
219 {
220 struct GNUNET_IDENTITY_PublicKey pub;
221 char *pubs;
222
223 GNUNET_IDENTITY_key_get_public (pk, &pub);
224 pubs = GNUNET_IDENTITY_public_key_to_string (&pub);
225 if (private_keys)
226 {
227 char *privs;
228
229 privs = GNUNET_IDENTITY_private_key_to_string (pk);
230 fprintf (stdout, "%s - %s\n", pubs, privs);
231 GNUNET_free (privs);
232 }
233 else
234 {
235 fprintf (stdout, "%s\n", pubs);
236 }
237 GNUNET_free (pubs);
238 }
239 test_finished ();
240}
241
242
243/**
244 * Function called by #GNUNET_IDENTITY_set up on completion.
245 *
246 * @param cls NULL
247 * @param emsg error message (NULL on success)
248 */
249static void
250set_done (void *cls, const char *emsg)
251{
252 set_op = NULL;
253 if (NULL != emsg)
254 {
255 fprintf (stderr, _ ("Failed to set default ego: %s\n"), emsg);
256 global_ret = 1;
257 }
258 test_finished ();
259}
260
261
262/**
263 * If listing is enabled, prints information about the egos.
264 *
265 * This function is initially called for all egos and then again
266 * whenever a ego's identifier changes or if it is deleted. At the
267 * end of the initial pass over all egos, the function is once called
268 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
269 * be invoked in the future or that there was an error.
270 *
271 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', this
272 * function is only called ONCE, and 'NULL' being passed in 'ego' does
273 * indicate an error (for example because name is taken or no default value is
274 * known). If 'ego' is non-NULL and if '*ctx' is set in those callbacks, the
275 * value WILL be passed to a subsequent call to the identity callback of
276 * 'GNUNET_IDENTITY_connect' (if that one was not NULL).
277 *
278 * When an identity is renamed, this function is called with the
279 * (known) ego but the NEW identifier.
280 *
281 * When an identity is deleted, this function is called with the
282 * (known) ego and "NULL" for the 'identifier'. In this case,
283 * the 'ego' is henceforth invalid (and the 'ctx' should also be
284 * cleaned up).
285 *
286 * @param cls closure
287 * @param ego ego handle
288 * @param ctx context for application to store data for this ego
289 * (during the lifetime of this process, initially NULL)
290 * @param identifier identifier assigned by the user for this ego,
291 * NULL if the user just deleted the ego and it
292 * must thus no longer be used
293 */
294static void
295print_ego (void *cls,
296 struct GNUNET_IDENTITY_Ego *ego,
297 void **ctx,
298 const char *identifier)
299{
300 struct GNUNET_IDENTITY_PublicKey pk;
301 char *s;
302 char *privs;
303
304 if ( (NULL != set_ego) &&
305 (NULL != set_subsystem) &&
306 (NULL != ego) &&
307 (NULL != identifier) &&
308 (0 == strcmp (identifier, set_ego)))
309 {
310 set_op = GNUNET_IDENTITY_set (sh,
311 set_subsystem,
312 ego,
313 &set_done,
314 NULL);
315 GNUNET_free (set_subsystem);
316 set_subsystem = NULL;
317 GNUNET_free (set_ego);
318 set_ego = NULL;
319 }
320 if ( (NULL == ego) &&
321 (NULL != set_ego) &&
322 (NULL != set_subsystem) )
323 {
324 fprintf (stderr,
325 "Could not set ego to `%s' for subsystem `%s', ego not known\n",
326 set_ego,
327 set_subsystem);
328 GNUNET_free (set_subsystem);
329 set_subsystem = NULL;
330 GNUNET_free (set_ego);
331 set_ego = NULL;
332 }
333 if ((NULL == ego) && (! monitor))
334 {
335 list = 0;
336 test_finished ();
337 return;
338 }
339 if (! (list | monitor))
340 return;
341 if ( (NULL == ego) ||
342 (NULL == identifier) )
343 return;
344 if ( (NULL != set_ego) &&
345 (0 != strcmp (identifier,
346 set_ego)) )
347 return;
348 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
349 s = GNUNET_IDENTITY_public_key_to_string (&pk);
350 privs = GNUNET_IDENTITY_private_key_to_string (
351 GNUNET_IDENTITY_ego_get_private_key (ego));
352 if ((monitor) || (NULL != identifier))
353 {
354 if (quiet)
355 {
356 if (private_keys)
357 fprintf (stdout, "%s - %s\n", s, privs);
358 else
359 fprintf (stdout, "%s\n", s);
360 }
361 else
362 {
363 if (private_keys)
364 fprintf (stdout, "%s - %s - %s - %s\n",
365 identifier, s, privs,
366 (ntohl (pk.type) == GNUNET_IDENTITY_TYPE_ECDSA) ?
367 "ECDSA" : "EdDSA");
368 else
369 fprintf (stdout, "%s - %s - %s\n",
370 identifier, s,
371 (ntohl (pk.type) == GNUNET_IDENTITY_TYPE_ECDSA) ?
372 "ECDSA" : "EdDSA");
373
374 }
375 }
376 GNUNET_free (privs);
377 GNUNET_free (s);
378}
379
380
381/**
382 * Main function that will be run by the scheduler.
383 *
384 * @param cls closure
385 * @param args remaining command-line arguments
386 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
387 * @param cfg configuration
388 */
389static void
390run (void *cls,
391 char *const *args,
392 const char *cfgfile,
393 const struct GNUNET_CONFIGURATION_Handle *cfg)
394{
395 if ((NULL != set_subsystem) && (NULL == set_ego))
396 {
397 fprintf (stderr, "Option -s requires option -e to be specified as well.\n");
398 return;
399 }
400 sh = GNUNET_IDENTITY_connect (cfg,
401 (monitor | list) ||
402 (NULL != set_ego) ||
403 (NULL != set_subsystem)
404 ? &print_ego
405 : NULL,
406 NULL);
407 if (NULL != delete_ego)
408 delete_op =
409 GNUNET_IDENTITY_delete (sh,
410 delete_ego,
411 &delete_finished,
412 &delete_op);
413 if (NULL != create_ego)
414 {
415 if (NULL != privkey_ego)
416 {
417 GNUNET_STRINGS_string_to_data (privkey_ego,
418 strlen (privkey_ego),
419 &pk,
420 sizeof(struct
421 GNUNET_IDENTITY_PrivateKey));
422 create_op =
423 GNUNET_IDENTITY_create (sh,
424 create_ego,
425 &pk,
426 0, // Ignored
427 &create_finished,
428 &create_op);
429 }
430 else
431 create_op =
432 GNUNET_IDENTITY_create (sh,
433 create_ego,
434 NULL,
435 (type_eddsa) ?
436 GNUNET_IDENTITY_TYPE_EDDSA :
437 GNUNET_IDENTITY_TYPE_ECDSA,
438 &create_finished,
439 &create_op);
440 }
441 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
442 NULL);
443 test_finished ();
444}
445
446
447/**
448 * The main function.
449 *
450 * @param argc number of arguments from the command line
451 * @param argv command line arguments
452 * @return 0 ok, 1 on error
453 */
454int
455main (int argc, char *const *argv)
456{
457 struct GNUNET_GETOPT_CommandLineOption options[] = {
458 GNUNET_GETOPT_option_string ('C',
459 "create",
460 "NAME",
461 gettext_noop ("create ego NAME"),
462 &create_ego),
463 GNUNET_GETOPT_option_string ('D',
464 "delete",
465 "NAME",
466 gettext_noop ("delete ego NAME "),
467 &delete_ego),
468 GNUNET_GETOPT_option_string ('P',
469 "privkey",
470 "PRIVATE_KEY",
471 gettext_noop (
472 "set the private key for the identity to PRIVATE_KEY (use together with -C)"),
473 &privkey_ego),
474 GNUNET_GETOPT_option_flag ('X',
475 "eddsa",
476 gettext_noop (
477 "generate an EdDSA identity. (use together with -C) EXPERIMENTAL"),
478 &type_eddsa),
479 GNUNET_GETOPT_option_flag ('d',
480 "display",
481 gettext_noop ("display all egos"),
482 &list),
483 GNUNET_GETOPT_option_flag ('q',
484 "quiet",
485 gettext_noop ("reduce output"),
486 &quiet),
487 GNUNET_GETOPT_option_string (
488 'e',
489 "ego",
490 "NAME",
491 gettext_noop (
492 "set default identity to NAME for a subsystem SUBSYSTEM (use together with -s) or restrict results to NAME (use together with -d)"),
493 &set_ego),
494 GNUNET_GETOPT_option_flag ('m',
495 "monitor",
496 gettext_noop ("run in monitor mode egos"),
497 &monitor),
498 GNUNET_GETOPT_option_flag ('p',
499 "private-keys",
500 gettext_noop ("display private keys as well"),
501 &private_keys),
502 GNUNET_GETOPT_option_string (
503 's',
504 "set",
505 "SUBSYSTEM",
506 gettext_noop (
507 "set default identity to EGO for a subsystem SUBSYSTEM (use together with -e)"),
508 &set_subsystem),
509 GNUNET_GETOPT_option_verbose (&verbose),
510 GNUNET_GETOPT_OPTION_END
511 };
512 int res;
513
514 if (GNUNET_OK !=
515 GNUNET_STRINGS_get_utf8_args (argc, argv,
516 &argc, &argv))
517 return 4;
518 global_ret = TIMEOUT_STATUS_CODE; /* timeout */
519 res = GNUNET_PROGRAM_run (argc,
520 argv,
521 "gnunet-identity",
522 gettext_noop ("Maintain egos"),
523 options,
524 &run,
525 NULL);
526 GNUNET_free_nz ((void *) argv);
527
528 if (GNUNET_OK != res)
529 return 3;
530 return global_ret;
531}
532
533
534/* end of gnunet-identity.c */