GNUnet  0.10.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 {
46 
51 
56 
60  char *name;
61 
66 
71 
76 
82 
87 
91  uint32_t type;
92 
97 };
98 
99 
107 static const char *
108 get_tld (const char *name)
109 {
110  const char *tld;
111 
112  tld = strrchr (name, (unsigned char) '.');
113  if (NULL == tld)
114  tld = name;
115  else
116  tld++; /* skip the '.' */
117  return tld;
118 }
119 
120 
127 static void
128 eat_tld (char *name, const char *tld)
129 {
130  GNUNET_assert (0 < strlen (name));
131  if ((NULL == tld) || (strlen (name) == strlen (tld)))
132  {
133  strcpy (name, GNUNET_GNS_EMPTY_LABEL_AT);
134  }
135  else
136  {
137  GNUNET_assert (strlen (tld) < strlen (name));
138  name[strlen (name) - strlen (tld) - 1] = '\0';
139  }
140 }
141 
142 
150 static void
152  uint32_t rd_count,
153  const struct GNUNET_GNSRECORD_Data *rd)
154 {
155  struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
156 
157  ltr->lr = NULL;
158  ltr->lookup_proc (ltr->lookup_proc_cls, GNUNET_YES, rd_count, rd);
160 }
161 
162 
169 static void
171  const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
172 {
173  ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle,
174  ltr->name,
175  pkey,
176  ltr->type,
177  ltr->options,
179  ltr);
180 }
181 
182 
192 static void
193 identity_zone_cb (void *cls,
194  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
195  const char *ego_name)
196 {
197  struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
198  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
199 
200  ltr->id_co = NULL;
201  if (NULL == priv)
202  {
203  /* no matching ego found */
204  ltr->lookup_proc (ltr->lookup_proc_cls, GNUNET_NO, 0, NULL);
205  return;
206  }
207  /* Final case: TLD matches one of our egos */
208  if (0 == strcmp (ltr->name, ego_name))
209  {
210  /* name matches ego name perfectly, only "@" remains */
211  strcpy (ltr->name, GNUNET_GNS_EMPTY_LABEL_AT);
212  }
213  else
214  {
215  GNUNET_assert (strlen (ego_name) < strlen (ltr->name));
216  ltr->name[strlen (ltr->name) - strlen (ego_name) - 1] = '\0';
217  }
218  /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
219  if (NULL == strchr (ltr->name, (unsigned char) '.'))
221  else
224  lookup_with_public_key (ltr, &pkey);
225 }
226 
227 
243  const char *name,
244  uint32_t type,
247  void *proc_cls)
248 {
250  const char *tld;
251  char *dot_tld;
252  char *zonestr;
253  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
254 
256  ltr->gns_handle = handle;
257  ltr->name = GNUNET_strdup (name);
258  ltr->type = type;
259  ltr->options = options;
260  ltr->lookup_proc = proc;
261  ltr->lookup_proc_cls = proc_cls;
262  /* start with trivial case: TLD is zkey */
263  tld = get_tld (ltr->name);
264  if (GNUNET_OK ==
265  GNUNET_CRYPTO_ecdsa_public_key_from_string (tld, strlen (tld), &pkey))
266  {
267  eat_tld (ltr->name, tld);
268  lookup_with_public_key (ltr, &pkey);
269  return ltr;
270  }
271 
272  /* second case: domain is mapped in our configuration file */
273  for (const char *domain = name; NULL != domain;
274  domain = strchr (domain, (unsigned char) '.'))
275  {
276  if ('.' == domain[0])
277  domain++;
278  GNUNET_asprintf (&dot_tld, ".%s", domain);
280  "gns",
281  dot_tld,
282  &zonestr))
283  {
284  if (GNUNET_OK !=
286  strlen (zonestr),
287  &pkey))
288  {
291  "gns",
292  dot_tld,
293  _ ("Expected a base32-encoded public zone key\n"));
294  GNUNET_free (zonestr);
295  GNUNET_free (dot_tld);
296  GNUNET_free (ltr->name);
297  GNUNET_free (ltr);
298  return NULL;
299  }
300  eat_tld (ltr->name, &dot_tld[1]);
301  GNUNET_free (zonestr);
302  GNUNET_free (dot_tld);
303  lookup_with_public_key (ltr, &pkey);
304  return ltr;
305  }
306  GNUNET_free (dot_tld);
307  }
308  ltr->id_co =
309  GNUNET_IDENTITY_ego_lookup_by_suffix (ltr->gns_handle->cfg,
310  ltr->name,
312  ltr);
313  if (NULL == ltr->id_co)
314  {
315  GNUNET_free (ltr->name);
316  GNUNET_free (ltr);
317  return NULL;
318  }
319  return ltr;
320 }
321 
322 
329 void *
331 {
332  void *ret = ltr->lookup_proc_cls;
333 
334  if (NULL != ltr->id_co)
335  {
337  ltr->id_co = NULL;
338  }
339  if (NULL != ltr->lr)
340  {
342  ltr->lr = NULL;
343  }
345  GNUNET_free (ltr->name);
346  GNUNET_free (ltr);
347  return ret;
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:41
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:128
void * GNUNET_GNS_lookup_with_tld_cancel(struct GNUNET_GNS_LookupWithTldRequest *ltr)
Cancel pending lookup request.
Definition: gns_tld_api.c:330
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
shared data structures of libgnunetgns
static char * ego_name
Name of our ego.
struct GNUNET_GNS_LookupRequest * lr
Underlying GNS lookup.
Definition: gns_tld_api.c:70
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:242
GNUNET_GNS_LocalOptions
Options for the GNS lookup.
static const char * get_tld(const char *name)
Obtain the TLD of the given name.
Definition: gns_tld_api.c:108
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:75
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.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#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:208
uint32_t type
Desired result record type.
Definition: gns_tld_api.c:91
struct GNUNET_GNS_Handle * gns_handle
handle to gns
Definition: gns_tld_api.c:50
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:193
Handle for an ego.
Definition: identity.h:245
enum GNUNET_GNS_LocalOptions options
Lookup options.
Definition: gns_tld_api.c:96
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:86
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:60
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:241
char * longest_match
Name of the longest matching ego found so far.
Definition: gns_tld_api.c:81
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:151
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:468
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:309
GNUNET_GNS_LookupResultProcessor2 lookup_proc
processor to call on lookup result
Definition: gns_tld_api.c:55
#define GNUNET_YES
Definition: gnunet_common.h:80
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:170
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:337
Handle to a lookup request.
Definition: gns_tld_api.c:44
void * lookup_proc_cls
lookup_proc closure
Definition: gns_tld_api.c:65
#define GNUNET_free(ptr)
Wrapper around free.