GNUnet  0.11.x
gns_tld_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013, 2016, 2018 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  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_arm_service.h"
31 #include "gnunet_hello_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_dht_service.h"
34 #include "gns.h"
35 #include "gns_api.h"
36 
37 
38 #define LOG(kind, ...) GNUNET_log_from (kind, "gns-tld-api", __VA_ARGS__)
39 
40 
45 {
50 
55 
59  char *name;
60 
65 
70 
75 
81 
86 
90  uint32_t type;
91 
96 };
97 
98 
106 static const char *
107 get_tld (const char *name)
108 {
109  const char *tld;
110 
111  tld = strrchr (name, (unsigned char) '.');
112  if (NULL == tld)
113  tld = name;
114  else
115  tld++; /* skip the '.' */
116  return tld;
117 }
118 
119 
126 static void
127 eat_tld (char *name, const char *tld)
128 {
129  GNUNET_assert (0 < strlen (name));
130  if ((NULL == tld) || (strlen (name) == strlen (tld)))
131  {
132  strcpy (name, GNUNET_GNS_EMPTY_LABEL_AT);
133  }
134  else
135  {
136  GNUNET_assert (strlen (tld) < strlen (name));
137  name[strlen (name) - strlen (tld) - 1] = '\0';
138  }
139 }
140 
141 
149 static void
151  uint32_t rd_count,
152  const struct GNUNET_GNSRECORD_Data *rd)
153 {
154  struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
155 
156  ltr->lr = NULL;
157  ltr->lookup_proc (ltr->lookup_proc_cls, GNUNET_YES, rd_count, rd);
159 }
160 
161 
168 static void
170  const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
171 {
172  ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle,
173  ltr->name,
174  pkey,
175  ltr->type,
176  ltr->options,
178  ltr);
179 }
180 
181 
191 static void
192 identity_zone_cb (void *cls,
193  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
194  const char *ego_name)
195 {
196  struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
197  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
198 
199  ltr->id_co = NULL;
200  if (NULL == priv)
201  {
202  /* no matching ego found */
203  ltr->lookup_proc (ltr->lookup_proc_cls, GNUNET_NO, 0, NULL);
204  return;
205  }
206  /* Final case: TLD matches one of our egos */
207  if (0 == strcmp (ltr->name, ego_name))
208  {
209  /* name matches ego name perfectly, only "@" remains */
210  strcpy (ltr->name, GNUNET_GNS_EMPTY_LABEL_AT);
211  }
212  else
213  {
214  GNUNET_assert (strlen (ego_name) < strlen (ltr->name));
215  ltr->name[strlen (ltr->name) - strlen (ego_name) - 1] = '\0';
216  }
217  /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
218  if (NULL == strchr (ltr->name, (unsigned char) '.'))
220  else
223  lookup_with_public_key (ltr, &pkey);
224 }
225 
226 
242  const char *name,
243  uint32_t type,
246  void *proc_cls)
247 {
249  const char *tld;
250  char *dot_tld;
251  char *zonestr;
252  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
253 
255  ltr->gns_handle = handle;
256  ltr->name = GNUNET_strdup (name);
257  ltr->type = type;
258  ltr->options = options;
259  ltr->lookup_proc = proc;
260  ltr->lookup_proc_cls = proc_cls;
261  /* start with trivial case: TLD is zkey */
262  tld = get_tld (ltr->name);
263  if (GNUNET_OK ==
264  GNUNET_CRYPTO_ecdsa_public_key_from_string (tld, strlen (tld), &pkey))
265  {
266  eat_tld (ltr->name, tld);
267  lookup_with_public_key (ltr, &pkey);
268  return ltr;
269  }
270 
271  /* second case: domain is mapped in our configuration file */
272  for (const char *domain = name; NULL != domain;
273  domain = strchr (domain, (unsigned char) '.'))
274  {
275  if ('.' == domain[0])
276  domain++;
277  GNUNET_asprintf (&dot_tld, ".%s", domain);
279  "gns",
280  dot_tld,
281  &zonestr))
282  {
283  if (GNUNET_OK !=
285  strlen (zonestr),
286  &pkey))
287  {
290  "gns",
291  dot_tld,
292  _ ("Expected a base32-encoded public zone key\n"));
293  GNUNET_free (zonestr);
294  GNUNET_free (dot_tld);
295  GNUNET_free (ltr->name);
296  GNUNET_free (ltr);
297  return NULL;
298  }
299  eat_tld (ltr->name, &dot_tld[1]);
300  GNUNET_free (zonestr);
301  GNUNET_free (dot_tld);
302  lookup_with_public_key (ltr, &pkey);
303  return ltr;
304  }
305  GNUNET_free (dot_tld);
306  }
307  ltr->id_co =
308  GNUNET_IDENTITY_ego_lookup_by_suffix (ltr->gns_handle->cfg,
309  ltr->name,
311  ltr);
312  if (NULL == ltr->id_co)
313  {
314  GNUNET_free (ltr->name);
315  GNUNET_free (ltr);
316  return NULL;
317  }
318  return ltr;
319 }
320 
321 
328 void *
330 {
331  void *ret = ltr->lookup_proc_cls;
332 
333  if (NULL != ltr->id_co)
334  {
336  ltr->id_co = NULL;
337  }
338  if (NULL != ltr->lr)
339  {
341  ltr->lr = NULL;
342  }
344  GNUNET_free (ltr->name);
345  GNUNET_free (ltr);
346  return ret;
347 }
348 
349 
350 /* end of gns_tld_api.c */
Connection to the GNS service.
Definition: gns_api.h:35
For the rightmost label, only look in the cache (it is our local namestore), for the others...
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: gns_api.h:40
static char * pkey
Public key of the zone to look in, in ASCII.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
static void eat_tld(char *name, const char *tld)
Eat the "TLD" (last bit) of the given name.
Definition: gns_tld_api.c:127
void * GNUNET_GNS_lookup_with_tld_cancel(struct GNUNET_GNS_LookupWithTldRequest *ltr)
Cancel pending lookup request.
Definition: gns_tld_api.c:329
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
shared data structures of libgnunetgns
struct GNUNET_GNS_LookupRequest * lr
Underlying GNS lookup.
Definition: gns_tld_api.c:69
Handle to a lookup request.
Definition: gns_api.c:42
struct GNUNET_GNS_LookupWithTldRequest * GNUNET_GNS_lookup_with_tld(struct GNUNET_GNS_Handle *handle, const char *name, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor2 proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS, determining the zone using the TLD of the given ...
Definition: gns_tld_api.c:241
GNUNET_GNS_LocalOptions
Options for the GNS lookup.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static const char * get_tld(const char *name)
Obtain the TLD of the given name.
Definition: gns_tld_api.c:107
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
struct GNUNET_IDENTITY_EgoSuffixLookup * id_co
Lookup an ego with the identity service.
Definition: gns_tld_api.c:74
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
IPC messages between GNS API and GNS service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint32_t type
Desired result record type.
Definition: gns_tld_api.c:90
struct GNUNET_GNS_Handle * gns_handle
handle to gns
Definition: gns_tld_api.c:49
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static void identity_zone_cb(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const char *ego_name)
Method called to with the ego we are to use for the lookup, when the ego is determined by a name...
Definition: gns_tld_api.c:192
Handle for an ego.
Definition: identity.h:245
enum GNUNET_GNS_LocalOptions options
Lookup options.
Definition: gns_tld_api.c:95
struct GNUNET_IDENTITY_EgoSuffixLookup * GNUNET_IDENTITY_ego_lookup_by_suffix(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *suffix, GNUNET_IDENTITY_EgoSuffixCallback cb, void *cb_cls)
Lookup an ego by name.
void GNUNET_IDENTITY_ego_lookup_by_suffix_cancel(struct GNUNET_IDENTITY_EgoSuffixLookup *el)
Abort ego lookup attempt.
struct GNUNET_IDENTITY_Ego * longest_match_ego
Ego corresponding to longest_match.
Definition: gns_tld_api.c:85
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
Never look in the DHT, keep request to local cache.
char * name
Domain name we are resolving.
Definition: gns_tld_api.c:59
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:239
char * longest_match
Name of the longest matching ego found so far.
Definition: gns_tld_api.c:80
static void process_lookup_result(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called with the result of a GNS lookup.
Definition: gns_tld_api.c:150
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:466
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
void(* GNUNET_GNS_LookupResultProcessor2)(void *cls, int gns_tld, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Iterator called on obtained result for a GNS lookup where "not GNS" is a valid answer.
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:308
GNUNET_GNS_LookupResultProcessor2 lookup_proc
processor to call on lookup result
Definition: gns_tld_api.c:54
#define GNUNET_YES
Definition: gnunet_common.h:77
static void lookup_with_public_key(struct GNUNET_GNS_LookupWithTldRequest *ltr, const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
Perform the actual resolution, starting with the zone identified by the given public key...
Definition: gns_tld_api.c:169
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS.
Definition: gns_api.c:336
Handle to a lookup request.
Definition: gns_tld_api.c:44
static char * ego_name
ego
Definition: gnunet-abd.c:117
void * lookup_proc_cls
lookup_proc closure
Definition: gns_tld_api.c:64
#define GNUNET_free(ptr)
Wrapper around free.