diff options
Diffstat (limited to 'src/identity/gnunet-identity.c')
-rw-r--r-- | src/identity/gnunet-identity.c | 534 |
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 | */ | ||
41 | static struct GNUNET_IDENTITY_Handle *sh; | ||
42 | |||
43 | /** | ||
44 | * Was "list" specified? | ||
45 | */ | ||
46 | static int list; | ||
47 | |||
48 | /** | ||
49 | * Was "monitor" specified? | ||
50 | */ | ||
51 | static int monitor; | ||
52 | |||
53 | /** | ||
54 | * Was "private" specified? | ||
55 | */ | ||
56 | static int private_keys; | ||
57 | |||
58 | /** | ||
59 | * Was "verbose" specified? | ||
60 | */ | ||
61 | static unsigned int verbose; | ||
62 | |||
63 | /** | ||
64 | * Was "quiet" specified? | ||
65 | */ | ||
66 | static int quiet; | ||
67 | |||
68 | /** | ||
69 | * Was "eddsa" specified? | ||
70 | */ | ||
71 | static int type_eddsa; | ||
72 | |||
73 | /** | ||
74 | * -C option | ||
75 | */ | ||
76 | static char *create_ego; | ||
77 | |||
78 | /** | ||
79 | * -D option | ||
80 | */ | ||
81 | static char *delete_ego; | ||
82 | |||
83 | /** | ||
84 | * -P option | ||
85 | */ | ||
86 | static char *privkey_ego; | ||
87 | |||
88 | /** | ||
89 | * -s option. | ||
90 | */ | ||
91 | static char *set_ego; | ||
92 | |||
93 | /** | ||
94 | * -S option. | ||
95 | */ | ||
96 | static char *set_subsystem; | ||
97 | |||
98 | /** | ||
99 | * Operation handle for set operation. | ||
100 | */ | ||
101 | static struct GNUNET_IDENTITY_Operation *set_op; | ||
102 | |||
103 | /** | ||
104 | * Handle for create operation. | ||
105 | */ | ||
106 | static struct GNUNET_IDENTITY_Operation *create_op; | ||
107 | |||
108 | /** | ||
109 | * Handle for delete operation. | ||
110 | */ | ||
111 | static struct GNUNET_IDENTITY_Operation *delete_op; | ||
112 | |||
113 | /** | ||
114 | * Private key from command line option, or NULL. | ||
115 | */ | ||
116 | struct GNUNET_IDENTITY_PrivateKey pk; | ||
117 | |||
118 | /** | ||
119 | * Value to return from #main(). | ||
120 | */ | ||
121 | static int global_ret; | ||
122 | |||
123 | |||
124 | /** | ||
125 | * Task run on shutdown. | ||
126 | * | ||
127 | * @param cls NULL | ||
128 | */ | ||
129 | static void | ||
130 | shutdown_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 | */ | ||
160 | static void | ||
161 | test_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 | */ | ||
183 | static void | ||
184 | delete_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 | */ | ||
203 | static void | ||
204 | create_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 | */ | ||
249 | static void | ||
250 | set_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 | */ | ||
294 | static void | ||
295 | print_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 | */ | ||
389 | static void | ||
390 | run (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 | */ | ||
454 | int | ||
455 | main (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 */ | ||