aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-gns.c')
-rw-r--r--src/gns/gnunet-gns.c253
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;
56static char *lookup_type; 56static char *lookup_type;
57 57
58/** 58/**
59 * Identity of the zone to use for the lookup (-z option)
60 */
61static char *zone_ego_name;
62
63/**
64 * Public key of the zone to use for the lookup (-p option)
65 */
66static 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 */
71static enum GNUNET_GNS_LocalOptions local_options; 61static enum GNUNET_GNS_LocalOptions local_options;
@@ -105,6 +95,15 @@ static struct GNUNET_IDENTITY_Operation *id_op;
105 */ 95 */
106static struct GNUNET_SCHEDULER_Task *tt; 96static 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 */
105static 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 */
302static void 293static const char *
303identity_master_cb (void *cls, 294get_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; 313static void
330 lookup_with_public_key (&pkey); 314eat_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 */