GNUnet  0.11.x
plugin_gnsrecord_gns.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2013, 2014, 2016 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  */
20 
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_gnsrecord_lib.h"
32 #include "gnunet_dnsparser_lib.h"
34 #include <inttypes.h>
35 
36 
46 static char *
48  uint32_t type,
49  const void *data,
50  size_t data_size)
51 {
52  const char *cdata;
53 
54  switch (type)
55  {
57  if (data_size != sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))
58  return NULL;
60 
62  return GNUNET_strndup (data, data_size);
63 
65  return GNUNET_strndup (data, data_size);
66 
68  char *ns;
69  char *ip;
70  size_t off;
71  char *nstr;
72 
73  off = 0;
74  ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
75  ip = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
76  if ((NULL == ns) || (NULL == ip) || (off != data_size))
77  {
78  GNUNET_break_op (0);
81  return NULL;
82  }
83  GNUNET_asprintf (&nstr, "%s@%s", ns, ip);
86  return nstr;
87  }
88 
90  struct GNUNET_TUN_GnsVpnRecord vpn;
91  char *vpn_str;
92 
93  cdata = data;
94  if ((data_size <= sizeof(vpn)) || ('\0' != cdata[data_size - 1]))
95  return NULL; /* malformed */
96  /* need to memcpy for alignment */
97  GNUNET_memcpy (&vpn, data, sizeof(vpn));
98  GNUNET_asprintf (&vpn_str,
99  "%u %s %s",
100  (unsigned int) ntohs (vpn.proto),
101  (const char *) GNUNET_i2s_full (&vpn.peer),
102  (const char *) &cdata[sizeof(vpn)]);
103  return vpn_str;
104  }
105 
107  struct GNUNET_GNSRECORD_BoxRecord box;
108  uint32_t rt;
109  char *box_str;
110  char *ival;
111 
112  cdata = data;
113  if (data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
114  return NULL; /* malformed */
115  GNUNET_memcpy (&box, data, sizeof(box));
116  rt = ntohl (box.record_type);
118  &cdata[sizeof(box)],
119  data_size - sizeof(box));
120  if (NULL == ival)
121  return NULL; /* malformed */
122  GNUNET_asprintf (&box_str,
123  "%u %u %u %s",
124  (unsigned int) ntohs (box.protocol),
125  (unsigned int) ntohs (box.service),
126  (unsigned int) rt,
127  ival);
128  GNUNET_free (ival);
129  return box_str;
130  }
131 
132  default:
133  return NULL;
134  }
135 }
136 
137 
149 static int
151  uint32_t type,
152  const char *s,
153  void **data,
154  size_t *data_size)
155 {
156  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
157 
158  if (NULL == s)
159  return GNUNET_SYSERR;
160  switch (type)
161  {
163  if (GNUNET_OK !=
164  GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey))
165  {
167  _ ("Unable to parse PKEY record `%s'\n"),
168  s);
169  return GNUNET_SYSERR;
170  }
171  *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
172  GNUNET_memcpy (*data, &pkey, sizeof(pkey));
173  *data_size = sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey);
174  return GNUNET_OK;
175 
177  *data = GNUNET_strdup (s);
178  *data_size = strlen (s);
179  return GNUNET_OK;
180 
182  *data = GNUNET_strdup (s);
183  *data_size = strlen (s);
184  return GNUNET_OK;
185 
187  char nsbuf[514];
188  char *cpy;
189  char *at;
190  size_t off;
191 
192  cpy = GNUNET_strdup (s);
193  at = strchr (cpy, '@');
194  if (NULL == at)
195  {
197  _ ("Unable to parse GNS2DNS record `%s'\n"),
198  s);
199  GNUNET_free (cpy);
200  return GNUNET_SYSERR;
201  }
202  *at = '\0';
203  at++;
204 
205  off = 0;
207  sizeof(nsbuf),
208  &off,
209  cpy)) ||
210  (GNUNET_OK !=
211  GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof(nsbuf), &off, at)))
212  {
214  _ ("Failed to serialize GNS2DNS record with value `%s'\n"),
215  s);
216  GNUNET_free (cpy);
217  return GNUNET_SYSERR;
218  }
219  GNUNET_free (cpy);
220  *data_size = off;
221  *data = GNUNET_malloc (off);
222  GNUNET_memcpy (*data, nsbuf, off);
223  return GNUNET_OK;
224  }
225 
227  struct GNUNET_TUN_GnsVpnRecord *vpn;
228  char s_peer[103 + 1];
229  char s_serv[253 + 1];
230  unsigned int proto;
231 
232  if (3 != sscanf (s, "%u %103s %253s", &proto, s_peer, s_serv))
233  {
235  _ ("Unable to parse VPN record string `%s'\n"),
236  s);
237  return GNUNET_SYSERR;
238  }
239  *data_size = sizeof(struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
240  *data = vpn = GNUNET_malloc (*data_size);
241  if (GNUNET_OK !=
243  strlen (s_peer),
244  &vpn->peer.public_key))
245  {
246  GNUNET_free (vpn);
247  *data_size = 0;
248  return GNUNET_SYSERR;
249  }
250  vpn->proto = htons ((uint16_t) proto);
251  strcpy ((char *) &vpn[1], s_serv);
252  return GNUNET_OK;
253  }
254 
256  struct GNUNET_GNSRECORD_BoxRecord *box;
257  size_t rest;
258  unsigned int protocol;
259  unsigned int service;
260  unsigned int record_type;
261  void *bval;
262  size_t bval_size;
263 
264  if (3 != sscanf (s, "%u %u %u ", &protocol, &service, &record_type))
265  {
267  _ ("Unable to parse BOX record string `%s'\n"),
268  s);
269  return GNUNET_SYSERR;
270  }
271  rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, record_type);
272  if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record_type,
273  &s[rest],
274  &bval,
275  &bval_size))
276  return GNUNET_SYSERR;
277  *data_size = sizeof(struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
278  *data = box = GNUNET_malloc (*data_size);
279  box->protocol = htons (protocol);
280  box->service = htons (service);
281  box->record_type = htonl (record_type);
282  GNUNET_memcpy (&box[1], bval, bval_size);
283  GNUNET_free (bval);
284  return GNUNET_OK;
285  }
286 
287  default:
288  return GNUNET_SYSERR;
289  }
290 }
291 
292 
297 static struct
298 {
299  const char *name;
300  uint32_t number;
301 } gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
302  { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
303  { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
304  { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
305  { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
306  { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
307  { NULL, UINT32_MAX } };
308 
309 
317 static uint32_t
318 gns_typename_to_number (void *cls, const char *gns_typename)
319 {
320  unsigned int i;
321 
322  i = 0;
323  while ((NULL != gns_name_map[i].name) &&
324  (0 != strcasecmp (gns_typename, gns_name_map[i].name)))
325  i++;
326  return gns_name_map[i].number;
327 }
328 
329 
337 static const char *
338 gns_number_to_typename (void *cls, uint32_t type)
339 {
340  unsigned int i;
341 
342  i = 0;
343  while ((NULL != gns_name_map[i].name) && (type != gns_name_map[i].number))
344  i++;
345  return gns_name_map[i].name;
346 }
347 
348 
355 void *
357 {
359 
365  return api;
366 }
367 
368 
375 void *
377 {
379 
380  GNUNET_free (api);
381  return NULL;
382 }
383 
384 
385 /* end of plugin_gnsrecord_gns.c */
GNUNET_GNSRECORD_TypenameToNumberFunction typename_to_number
Typename to number.
Payload of GNS VPN record.
GNUNET_GNSRECORD_ValueToStringFunction value_to_string
Conversion to string.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
uint16_t service
Service of the boxed record (aka port number), in NBO.
static struct @22 gns_name_map[]
Mapping of record type numbers to human-readable record type names.
Record type used to box up SRV and TLSA records.
char * GNUNET_DNSPARSER_parse_name(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse name inside of a DNS query or record.
Definition: dnsparser.c:334
GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename
Number to typename.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
GNUNET_GNSRECORD_StringToValueFunction string_to_value
Conversion to binary.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t number
void * libgnunet_plugin_gnsrecord_gns_init(void *cls)
Entry point for the plugin.
void * cls
Closure for all of the callbacks.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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.
#define GNUNET_GNSRECORD_TYPE_BOX
Record type for a boxed record (see TLSA/SRV handling in GNS).
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
const char * name
#define GNUNET_GNSRECORD_TYPE_NICK
Record type for GNS nick names ("NICK").
void * libgnunet_plugin_gnsrecord_gns_done(void *cls)
Exit point from the plugin.
#define GNUNET_GNSRECORD_TYPE_VPN
Record type for VPN resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static uint32_t gns_typename_to_number(void *cls, const char *gns_typename)
Convert a type name (i.e.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_GNSRECORD_TYPE_PKEY
Record type for GNS zone transfer ("PKEY").
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Record type for delegation to DNS.
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
uint16_t protocol
Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
int GNUNET_GNSRECORD_string_to_value(uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of a &#39;value&#39; of a record to the binary representation.
Definition: gnsrecord.c:175
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:332
struct GNUNET_PeerIdentity peer
The peer to contact.
uint16_t proto
The protocol to use.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
uint32_t record_type
GNS record type of the boxed record.
static char * gns_value_to_string(void *cls, uint32_t type, const void *data, size_t data_size)
Convert the &#39;value&#39; of a record to a string.
#define GNUNET_GNSRECORD_TYPE_LEHO
Record type for GNS legacy hostnames ("LEHO").
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:499
static const char * gns_number_to_typename(void *cls, uint32_t type)
Convert a type number (i.e.
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
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
int GNUNET_DNSPARSER_builder_add_name(char *dst, size_t dst_len, size_t *off, const char *name)
Add a DNS name to the UDP packet at the given location, converting the name to IDNA notation as neces...
Definition: dnsparser.c:889
static int gns_string_to_value(void *cls, uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of a &#39;value&#39; of a record to the binary representation.
void * cls
Closure for all of the callbacks.
uint32_t data
The data value.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;value&#39; of a record to a string.
Definition: gnsrecord.c:143
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key