diff options
Diffstat (limited to 'src/gns/gnunet-gns.c')
-rw-r--r-- | src/gns/gnunet-gns.c | 253 |
1 files changed, 124 insertions, 129 deletions
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c index c0de0f30c..202e02a50 100644 --- a/src/gns/gnunet-gns.c +++ b/src/gns/gnunet-gns.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012-2013, 2017 GNUnet e.V. | 3 | Copyright (C) 2012-2013, 2017-2018 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -56,16 +56,6 @@ static char *lookup_name; | |||
56 | static char *lookup_type; | 56 | static char *lookup_type; |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Identity of the zone to use for the lookup (-z option) | ||
60 | */ | ||
61 | static char *zone_ego_name; | ||
62 | |||
63 | /** | ||
64 | * Public key of the zone to use for the lookup (-p option) | ||
65 | */ | ||
66 | static char *public_key; | ||
67 | |||
68 | /** | ||
69 | * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone. | 59 | * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone. |
70 | */ | 60 | */ |
71 | static enum GNUNET_GNS_LocalOptions local_options; | 61 | static enum GNUNET_GNS_LocalOptions local_options; |
@@ -105,6 +95,15 @@ static struct GNUNET_IDENTITY_Operation *id_op; | |||
105 | */ | 95 | */ |
106 | static struct GNUNET_SCHEDULER_Task *tt; | 96 | static struct GNUNET_SCHEDULER_Task *tt; |
107 | 97 | ||
98 | /** | ||
99 | * Global return value. | ||
100 | * 0 on success (default), | ||
101 | * 1 on internal failures, 2 on launch failure, | ||
102 | * 3 if the name is not a GNS-supported TLD, | ||
103 | * 4 on timeout | ||
104 | */ | ||
105 | static int global_ret; | ||
106 | |||
108 | 107 | ||
109 | /** | 108 | /** |
110 | * Task run on shutdown. Cleans up everything. | 109 | * Task run on shutdown. Cleans up everything. |
@@ -157,6 +156,7 @@ do_timeout (void *cls) | |||
157 | { | 156 | { |
158 | tt = NULL; | 157 | tt = NULL; |
159 | GNUNET_SCHEDULER_shutdown (); | 158 | GNUNET_SCHEDULER_shutdown (); |
159 | global_ret = 4; | ||
160 | } | 160 | } |
161 | 161 | ||
162 | 162 | ||
@@ -173,7 +173,6 @@ process_lookup_result (void *cls, | |||
173 | const struct GNUNET_GNSRECORD_Data *rd) | 173 | const struct GNUNET_GNSRECORD_Data *rd) |
174 | { | 174 | { |
175 | const char *name = cls; | 175 | const char *name = cls; |
176 | uint32_t i; | ||
177 | const char *typename; | 176 | const char *typename; |
178 | char* string_val; | 177 | char* string_val; |
179 | 178 | ||
@@ -186,7 +185,7 @@ process_lookup_result (void *cls, | |||
186 | printf ("%s:\n", | 185 | printf ("%s:\n", |
187 | name); | 186 | name); |
188 | } | 187 | } |
189 | for (i=0; i<rd_count; i++) | 188 | for (uint32_t i=0; i<rd_count; i++) |
190 | { | 189 | { |
191 | if ( (rd[i].record_type != rtype) && | 190 | if ( (rd[i].record_type != rtype) && |
192 | (GNUNET_GNSRECORD_TYPE_ANY != rtype) ) | 191 | (GNUNET_GNSRECORD_TYPE_ANY != rtype) ) |
@@ -272,62 +271,58 @@ identity_zone_cb (void *cls, | |||
272 | el = NULL; | 271 | el = NULL; |
273 | if (NULL == ego) | 272 | if (NULL == ego) |
274 | { | 273 | { |
275 | fprintf (stderr, | 274 | global_ret = 3; /* Not a GNS TLD */ |
276 | _("Ego for `%s' not found, cannot perform lookup.\n"), | ||
277 | zone_ego_name); | ||
278 | GNUNET_SCHEDULER_shutdown (); | 275 | GNUNET_SCHEDULER_shutdown (); |
279 | } | 276 | } |
280 | else | 277 | else |
281 | { | 278 | { |
282 | GNUNET_IDENTITY_ego_get_public_key (ego, &pkey); | 279 | GNUNET_IDENTITY_ego_get_public_key (ego, |
280 | &pkey); | ||
283 | lookup_with_public_key (&pkey); | 281 | lookup_with_public_key (&pkey); |
284 | } | 282 | } |
285 | GNUNET_free_non_null (zone_ego_name); | ||
286 | zone_ego_name = NULL; | ||
287 | } | 283 | } |
288 | 284 | ||
289 | 285 | ||
290 | /** | 286 | /** |
291 | * Method called to with the ego we are to use for the lookup, | 287 | * Obtain the TLD of the given @a name. |
292 | * when the ego is the one for the default master zone. | ||
293 | * | 288 | * |
294 | * @param cls closure (NULL, unused) | 289 | * @param name a name |
295 | * @param ego ego handle, NULL if not found | 290 | * @return the part of @a name after the last ".", |
296 | * @param ctx context for application to store data for this ego | 291 | * or @a name if @a name does not contain a "." |
297 | * (during the lifetime of this process, initially NULL) | ||
298 | * @param name name assigned by the user for this ego, | ||
299 | * NULL if the user just deleted the ego and it | ||
300 | * must thus no longer be used | ||
301 | */ | 292 | */ |
302 | static void | 293 | static const char * |
303 | identity_master_cb (void *cls, | 294 | get_tld (const char *name) |
304 | struct GNUNET_IDENTITY_Ego *ego, | ||
305 | void **ctx, | ||
306 | const char *name) | ||
307 | { | 295 | { |
308 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | 296 | const char *tld; |
309 | const char *dot; | ||
310 | 297 | ||
311 | id_op = NULL; | 298 | tld = strrchr (name, |
312 | if (NULL == ego) | 299 | (unsigned char) '.'); |
313 | { | 300 | if (NULL == tld) |
314 | fprintf (stderr, | 301 | tld = name; |
315 | _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); | 302 | else |
316 | GNUNET_SCHEDULER_shutdown (); | 303 | tld++; /* skip the '.' */ |
317 | return; | 304 | return tld; |
318 | } | 305 | } |
319 | GNUNET_IDENTITY_ego_get_public_key (ego, &pkey); | ||
320 | /* main name is our own master zone, do no look for that in the DHT */ | ||
321 | local_options = GNUNET_GNS_LO_LOCAL_MASTER; | ||
322 | 306 | ||
323 | /* if the name is of the form 'label.gnu', never go to the DHT */ | 307 | |
324 | dot = NULL; | 308 | /** |
325 | if (NULL != lookup_name) | 309 | * Eat the TLD of the given @a name. |
326 | dot = strchr (lookup_name, '.'); | 310 | * |
327 | if ( (NULL != dot) && | 311 | * @param name a name |
328 | (0 == strcasecmp (dot, ".gnu")) ) | 312 | */ |
329 | local_options = GNUNET_GNS_LO_NO_DHT; | 313 | static void |
330 | lookup_with_public_key (&pkey); | 314 | eat_tld (char *name) |
315 | { | ||
316 | char *tld; | ||
317 | |||
318 | GNUNET_assert (0 < strlen (name)); | ||
319 | tld = strrchr (name, | ||
320 | (unsigned char) '.'); | ||
321 | if (NULL == tld) | ||
322 | strcpy (name, | ||
323 | GNUNET_GNS_MASTERZONE_STR); | ||
324 | else | ||
325 | *tld = '\0'; | ||
331 | } | 326 | } |
332 | 327 | ||
333 | 328 | ||
@@ -346,6 +341,9 @@ run (void *cls, | |||
346 | const struct GNUNET_CONFIGURATION_Handle *c) | 341 | const struct GNUNET_CONFIGURATION_Handle *c) |
347 | { | 342 | { |
348 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | 343 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; |
344 | const char *tld; | ||
345 | char *dot_tld; | ||
346 | char *zonestr; | ||
349 | 347 | ||
350 | cfg = c; | 348 | cfg = c; |
351 | gns = GNUNET_GNS_connect (cfg); | 349 | gns = GNUNET_GNS_connect (cfg); |
@@ -360,52 +358,64 @@ run (void *cls, | |||
360 | NULL); | 358 | NULL); |
361 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 359 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
362 | NULL); | 360 | NULL); |
363 | identity = GNUNET_IDENTITY_connect (cfg, | 361 | /* start with trivial case: TLD is zkey */ |
364 | NULL, | 362 | tld = get_tld (lookup_name); |
365 | NULL); | 363 | if (GNUNET_OK == |
366 | if (NULL != public_key) | 364 | GNUNET_CRYPTO_ecdsa_public_key_from_string (tld, |
365 | strlen (tld), | ||
366 | &pkey)) | ||
367 | { | ||
368 | eat_tld (lookup_name); | ||
369 | lookup_with_public_key (&pkey); | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | /* second case: TLD is mapped in our configuration file */ | ||
374 | GNUNET_asprintf (&dot_tld, | ||
375 | ".%s", | ||
376 | tld); | ||
377 | if (GNUNET_OK == | ||
378 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
379 | "gns", | ||
380 | dot_tld, | ||
381 | &zonestr)) | ||
367 | { | 382 | { |
368 | if (GNUNET_OK != | 383 | if (GNUNET_OK != |
369 | GNUNET_CRYPTO_ecdsa_public_key_from_string (public_key, | 384 | GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr, |
370 | strlen (public_key), | 385 | strlen (zonestr), |
371 | &pkey)) | 386 | &pkey)) |
372 | { | 387 | { |
373 | fprintf (stderr, | 388 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, |
374 | _("Public key `%s' is not well-formed\n"), | 389 | "gns", |
375 | public_key); | 390 | dot_tld, |
391 | _("Expected a base32-encoded public zone key\n")); | ||
392 | GNUNET_free (zonestr); | ||
393 | GNUNET_free (dot_tld); | ||
376 | GNUNET_SCHEDULER_shutdown (); | 394 | GNUNET_SCHEDULER_shutdown (); |
377 | return; | 395 | return; |
378 | } | 396 | } |
397 | GNUNET_free (dot_tld); | ||
398 | GNUNET_free (zonestr); | ||
399 | eat_tld (lookup_name); | ||
379 | lookup_with_public_key (&pkey); | 400 | lookup_with_public_key (&pkey); |
380 | return; | 401 | return; |
381 | } | 402 | } |
382 | if (NULL != zone_ego_name) | 403 | GNUNET_free (dot_tld); |
383 | { | 404 | |
384 | el = GNUNET_IDENTITY_ego_lookup (cfg, | 405 | /* Final case: TLD matches one of our egos */ |
385 | zone_ego_name, | 406 | eat_tld (lookup_name); |
386 | &identity_zone_cb, | 407 | |
387 | NULL); | 408 | /* if the name is of the form 'label.gnu', never go to the DHT */ |
388 | return; | 409 | if (NULL == strchr (lookup_name, |
389 | } | 410 | (unsigned char) '.')) |
390 | if ( (NULL != lookup_name) && | 411 | local_options = GNUNET_GNS_LO_NO_DHT; |
391 | (strlen (lookup_name) > 4) && | 412 | identity = GNUNET_IDENTITY_connect (cfg, |
392 | (0 == strcmp (".zkey", | 413 | NULL, |
393 | &lookup_name[strlen (lookup_name) - 4])) ) | 414 | NULL); |
394 | { | 415 | el = GNUNET_IDENTITY_ego_lookup (cfg, |
395 | /* no zone required, use 'anonymous' zone */ | 416 | tld, |
396 | GNUNET_CRYPTO_ecdsa_key_get_public (GNUNET_CRYPTO_ecdsa_key_get_anonymous (), | 417 | &identity_zone_cb, |
397 | &pkey); | 418 | NULL); |
398 | lookup_with_public_key (&pkey); | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | GNUNET_break (NULL == id_op); | ||
403 | id_op = GNUNET_IDENTITY_get (identity, | ||
404 | "gns-master", | ||
405 | &identity_master_cb, | ||
406 | NULL); | ||
407 | GNUNET_assert (NULL != id_op); | ||
408 | } | ||
409 | } | 419 | } |
410 | 420 | ||
411 | 421 | ||
@@ -421,63 +431,48 @@ main (int argc, | |||
421 | char *const *argv) | 431 | char *const *argv) |
422 | { | 432 | { |
423 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 433 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
424 | 434 | GNUNET_GETOPT_option_mandatory | |
425 | GNUNET_GETOPT_option_string ('u', | 435 | (GNUNET_GETOPT_option_string ('u', |
426 | "lookup", | 436 | "lookup", |
427 | "NAME", | 437 | "NAME", |
428 | gettext_noop ("Lookup a record for the given name"), | 438 | gettext_noop ("Lookup a record for the given name"), |
429 | &lookup_name), | 439 | &lookup_name)), |
430 | |||
431 | GNUNET_GETOPT_option_string ('t', | 440 | GNUNET_GETOPT_option_string ('t', |
432 | "type", | 441 | "type", |
433 | "TYPE", | 442 | "TYPE", |
434 | gettext_noop ("Specify the type of the record to lookup"), | 443 | gettext_noop ("Specify the type of the record to lookup"), |
435 | &lookup_type), | 444 | &lookup_type), |
436 | |||
437 | GNUNET_GETOPT_option_relative_time ('T', | 445 | GNUNET_GETOPT_option_relative_time ('T', |
438 | "timeout", | 446 | "timeout", |
439 | "DELAY", | 447 | "DELAY", |
440 | gettext_noop ("Specify timeout for the lookup"), | 448 | gettext_noop ("Specify timeout for the lookup"), |
441 | &timeout), | 449 | &timeout), |
442 | |||
443 | GNUNET_GETOPT_option_flag ('r', | 450 | GNUNET_GETOPT_option_flag ('r', |
444 | "raw", | 451 | "raw", |
445 | gettext_noop ("No unneeded output"), | 452 | gettext_noop ("No unneeded output"), |
446 | &raw), | 453 | &raw), |
447 | |||
448 | GNUNET_GETOPT_option_string ('p', | ||
449 | "public-key", | ||
450 | "PKEY", | ||
451 | gettext_noop ("Specify the public key of the zone to lookup the record in"), | ||
452 | &public_key), | ||
453 | |||
454 | GNUNET_GETOPT_option_string ('z', | ||
455 | "zone", | ||
456 | "NAME", | ||
457 | gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), | ||
458 | &zone_ego_name), | ||
459 | |||
460 | GNUNET_GETOPT_OPTION_END | 454 | GNUNET_GETOPT_OPTION_END |
461 | }; | 455 | }; |
462 | int ret; | 456 | int ret; |
463 | 457 | ||
464 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 458 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
465 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, | 459 | if (GNUNET_OK != |
466 | &argc, &argv)) | 460 | GNUNET_STRINGS_get_utf8_args (argc, argv, |
461 | &argc, &argv)) | ||
467 | return 2; | 462 | return 2; |
468 | 463 | ||
469 | GNUNET_log_setup ("gnunet-gns", | 464 | GNUNET_log_setup ("gnunet-gns", |
470 | "WARNING", | 465 | "WARNING", |
471 | NULL); | 466 | NULL); |
472 | ret = | 467 | ret = GNUNET_PROGRAM_run (argc, argv, |
473 | (GNUNET_OK == | 468 | "gnunet-gns", |
474 | GNUNET_PROGRAM_run (argc, argv, | 469 | _("GNUnet GNS resolver tool"), |
475 | "gnunet-gns", | 470 | options, |
476 | _("GNUnet GNS resolver tool"), | 471 | &run, NULL); |
477 | options, | ||
478 | &run, NULL)) ? 0 : 1; | ||
479 | GNUNET_free ((void*) argv); | 472 | GNUNET_free ((void*) argv); |
480 | return ret; | 473 | if (GNUNET_OK != ret) |
474 | return 1; | ||
475 | return global_ret; | ||
481 | } | 476 | } |
482 | 477 | ||
483 | /* end of gnunet-gns.c */ | 478 | /* end of gnunet-gns.c */ |