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 
49 
54 
58  char *name;
59 
64 
69 
74 
80 
85 
89  uint32_t type;
90 
95 };
96 
97 
105 static const char *
106 get_tld(const char *name)
107 {
108  const char *tld;
109 
110  tld = strrchr(name, (unsigned char)'.');
111  if (NULL == tld)
112  tld = name;
113  else
114  tld++; /* skip the '.' */
115  return tld;
116 }
117 
118 
125 static void
126 eat_tld(char *name, const char *tld)
127 {
128  GNUNET_assert(0 < strlen(name));
129  if ((NULL == tld) || (strlen(name) == strlen(tld)))
130  {
131  strcpy(name, GNUNET_GNS_EMPTY_LABEL_AT);
132  }
133  else
134  {
135  GNUNET_assert(strlen(tld) < strlen(name));
136  name[strlen(name) - strlen(tld) - 1] = '\0';
137  }
138 }
139 
140 
148 static void
150  uint32_t rd_count,
151  const struct GNUNET_GNSRECORD_Data *rd)
152 {
153  struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
154 
155  ltr->lr = NULL;
156  ltr->lookup_proc(ltr->lookup_proc_cls, GNUNET_YES, rd_count, rd);
158 }
159 
160 
167 static void
169  const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
170 {
171  ltr->lr = GNUNET_GNS_lookup(ltr->gns_handle,
172  ltr->name,
173  pkey,
174  ltr->type,
175  ltr->options,
177  ltr);
178 }
179 
180 
190 static void
192  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
193  const char *ego_name)
194 {
195  struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
196  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
197 
198  ltr->id_co = NULL;
199  if (NULL == priv)
200  {
201  /* no matching ego found */
202  ltr->lookup_proc(ltr->lookup_proc_cls, GNUNET_NO, 0, NULL);
203  return;
204  }
205  /* Final case: TLD matches one of our egos */
206  if (0 == strcmp(ltr->name, ego_name))
207  {
208  /* name matches ego name perfectly, only "@" remains */
209  strcpy(ltr->name, GNUNET_GNS_EMPTY_LABEL_AT);
210  }
211  else
212  {
213  GNUNET_assert(strlen(ego_name) < strlen(ltr->name));
214  ltr->name[strlen(ltr->name) - strlen(ego_name) - 1] = '\0';
215  }
216  /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
217  if (NULL == strchr(ltr->name, (unsigned char)'.'))
219  else
222  lookup_with_public_key(ltr, &pkey);
223 }
224 
225 
241  const char *name,
242  uint32_t type,
245  void *proc_cls)
246 {
248  const char *tld;
249  char *dot_tld;
250  char *zonestr;
251  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
252 
254  ltr->gns_handle = handle;
255  ltr->name = GNUNET_strdup(name);
256  ltr->type = type;
257  ltr->options = options;
258  ltr->lookup_proc = proc;
259  ltr->lookup_proc_cls = proc_cls;
260  /* start with trivial case: TLD is zkey */
261  tld = get_tld(ltr->name);
262  if (GNUNET_OK ==
263  GNUNET_CRYPTO_ecdsa_public_key_from_string(tld, strlen(tld), &pkey))
264  {
265  eat_tld(ltr->name, tld);
266  lookup_with_public_key(ltr, &pkey);
267  return ltr;
268  }
269 
270  /* second case: domain is mapped in our configuration file */
271  for (const char *domain = name; NULL != domain;
272  domain = strchr(domain, (unsigned char)'.'))
273  {
274  if ('.' == domain[0])
275  domain++;
276  GNUNET_asprintf(&dot_tld, ".%s", domain);
278  "gns",
279  dot_tld,
280  &zonestr))
281  {
282  if (GNUNET_OK !=
284  strlen(zonestr),
285  &pkey))
286  {
289  "gns",
290  dot_tld,
291  _("Expected a base32-encoded public zone key\n"));
292  GNUNET_free(zonestr);
293  GNUNET_free(dot_tld);
294  GNUNET_free(ltr->name);
295  GNUNET_free(ltr);
296  return NULL;
297  }
298  eat_tld(ltr->name, &dot_tld[1]);
299  GNUNET_free(zonestr);
300  GNUNET_free(dot_tld);
301  lookup_with_public_key(ltr, &pkey);
302  return ltr;
303  }
304  GNUNET_free(dot_tld);
305  }
306  ltr->id_co =
307  GNUNET_IDENTITY_ego_lookup_by_suffix(ltr->gns_handle->cfg,
308  ltr->name,
310  ltr);
311  if (NULL == ltr->id_co)
312  {
313  GNUNET_free(ltr->name);
314  GNUNET_free(ltr);
315  return NULL;
316  }
317  return ltr;
318 }
319 
320 
327 void *
329 {
330  void *ret = ltr->lookup_proc_cls;
331 
332  if (NULL != ltr->id_co)
333  {
335  ltr->id_co = NULL;
336  }
337  if (NULL != ltr->lr)
338  {
340  ltr->lr = NULL;
341  }
343  GNUNET_free(ltr->name);
344  GNUNET_free(ltr);
345  return ret;
346 }
347 
348 /* 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:39
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:126
void * GNUNET_GNS_lookup_with_tld_cancel(struct GNUNET_GNS_LookupWithTldRequest *ltr)
Cancel pending lookup request.
Definition: gns_tld_api.c:328
#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:68
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:240
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:106
#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:73
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:181
uint32_t type
Desired result record type.
Definition: gns_tld_api.c:89
struct GNUNET_GNS_Handle * gns_handle
handle to gns
Definition: gns_tld_api.c:48
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:191
Handle for an ego.
Definition: identity.h:237
enum GNUNET_GNS_LocalOptions options
Lookup options.
Definition: gns_tld_api.c:94
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:84
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:58
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:79
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:149
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:306
GNUNET_GNS_LookupResultProcessor2 lookup_proc
processor to call on lookup result
Definition: gns_tld_api.c:53
#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:168
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:334
Handle to a lookup request.
Definition: gns_tld_api.c:44
void * lookup_proc_cls
lookup_proc closure
Definition: gns_tld_api.c:63
#define GNUNET_free(ptr)
Wrapper around free.