GNUnet  0.10.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;
61  return GNUNET_strndup (data, data_size);
63  return GNUNET_strndup (data, data_size);
65  {
66  char *ns;
67  char *ip;
68  size_t off;
69  char *nstr;
70 
71  off = 0;
72  ns = GNUNET_DNSPARSER_parse_name (data,
73  data_size,
74  &off);
75  ip = GNUNET_DNSPARSER_parse_name (data,
76  data_size,
77  &off);
78  if ( (NULL == ns) ||
79  (NULL == ip) ||
80  (off != data_size) )
81  {
82  GNUNET_break_op (0);
85  return NULL;
86  }
87  GNUNET_asprintf (&nstr,
88  "%s@%s",
89  ns,
90  ip);
93  return nstr;
94  }
96  {
97  struct GNUNET_TUN_GnsVpnRecord vpn;
98  char* vpn_str;
99 
100  cdata = data;
101  if ( (data_size <= sizeof (vpn)) ||
102  ('\0' != cdata[data_size - 1]) )
103  return NULL; /* malformed */
104  /* need to memcpy for alignment */
105  GNUNET_memcpy (&vpn,
106  data,
107  sizeof (vpn));
108  GNUNET_asprintf (&vpn_str,
109  "%u %s %s",
110  (unsigned int) ntohs (vpn.proto),
111  (const char*) GNUNET_i2s_full (&vpn.peer),
112  (const char*) &cdata[sizeof (vpn)]);
113  return vpn_str;
114  }
116  {
117  struct GNUNET_GNSRECORD_BoxRecord box;
118  uint32_t rt;
119  char *box_str;
120  char *ival;
121 
122  cdata = data;
123  if (data_size < sizeof (struct GNUNET_GNSRECORD_BoxRecord))
124  return NULL; /* malformed */
125  GNUNET_memcpy (&box,
126  data,
127  sizeof (box));
128  rt = ntohl (box.record_type);
130  &cdata[sizeof (box)],
131  data_size - sizeof (box));
132  if (NULL == ival)
133  return NULL; /* malformed */
134  GNUNET_asprintf (&box_str,
135  "%u %u %u %s",
136  (unsigned int) ntohs (box.protocol),
137  (unsigned int) ntohs (box.service),
138  (unsigned int) rt,
139  ival);
140  GNUNET_free (ival);
141  return box_str;
142  }
143  default:
144  return NULL;
145  }
146 }
147 
148 
160 static int
162  uint32_t type,
163  const char *s,
164  void **data,
165  size_t *data_size)
166 {
167  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
168 
169  if (NULL == s)
170  return GNUNET_SYSERR;
171  switch (type)
172  {
173 
175  if (GNUNET_OK !=
177  strlen (s),
178  &pkey))
179  {
181  _("Unable to parse PKEY record `%s'\n"),
182  s);
183  return GNUNET_SYSERR;
184  }
185  *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
186  GNUNET_memcpy (*data,
187  &pkey,
188  sizeof (pkey));
189  *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
190  return GNUNET_OK;
191 
193  *data = GNUNET_strdup (s);
194  *data_size = strlen (s);
195  return GNUNET_OK;
197  *data = GNUNET_strdup (s);
198  *data_size = strlen (s);
199  return GNUNET_OK;
201  {
202  char nsbuf[514];
203  char *cpy;
204  char *at;
205  size_t off;
206 
207  cpy = GNUNET_strdup (s);
208  at = strchr (cpy, '@');
209  if (NULL == at)
210  {
212  _("Unable to parse GNS2DNS record `%s'\n"),
213  s);
214  GNUNET_free (cpy);
215  return GNUNET_SYSERR;
216  }
217  *at = '\0';
218  at++;
219 
220  off = 0;
221  if ( (GNUNET_OK !=
223  sizeof (nsbuf),
224  &off,
225  cpy)) ||
226  (GNUNET_OK !=
228  sizeof (nsbuf),
229  &off,
230  at)) )
231  {
233  _("Failed to serialize GNS2DNS record with value `%s'\n"),
234  s);
235  GNUNET_free (cpy);
236  return GNUNET_SYSERR;
237  }
238  GNUNET_free (cpy);
239  *data_size = off;
240  *data = GNUNET_malloc (off);
241  GNUNET_memcpy (*data,
242  nsbuf,
243  off);
244  return GNUNET_OK;
245  }
247  {
248  struct GNUNET_TUN_GnsVpnRecord *vpn;
249  char s_peer[103 + 1];
250  char s_serv[253 + 1];
251  unsigned int proto;
252 
253  if (3 != SSCANF (s,
254  "%u %103s %253s",
255  &proto, s_peer, s_serv))
256  {
258  _("Unable to parse VPN record string `%s'\n"),
259  s);
260  return GNUNET_SYSERR;
261  }
262  *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
263  *data = vpn = GNUNET_malloc (*data_size);
264  if (GNUNET_OK !=
266  strlen (s_peer),
267  &vpn->peer.public_key))
268  {
269  GNUNET_free (vpn);
270  *data_size = 0;
271  return GNUNET_SYSERR;
272  }
273  vpn->proto = htons ((uint16_t) proto);
274  strcpy ((char*)&vpn[1], s_serv);
275  return GNUNET_OK;
276  }
278  {
279  struct GNUNET_GNSRECORD_BoxRecord *box;
280  size_t rest;
281  unsigned int protocol;
282  unsigned int service;
283  unsigned int record_type;
284  void *bval;
285  size_t bval_size;
286 
287  if (3 != SSCANF (s,
288  "%u %u %u ",
289  &protocol,
290  &service,
291  &record_type))
292  {
294  _("Unable to parse BOX record string `%s'\n"),
295  s);
296  return GNUNET_SYSERR;
297  }
298  rest = snprintf (NULL, 0,
299  "%u %u %u ",
300  protocol,
301  service,
302  record_type);
303  if (GNUNET_OK !=
305  &s[rest],
306  &bval,
307  &bval_size))
308  return GNUNET_SYSERR;
309  *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
310  *data = box = GNUNET_malloc (*data_size);
311  box->protocol = htons (protocol);
312  box->service = htons (service);
313  box->record_type = htonl (record_type);
314  GNUNET_memcpy (&box[1],
315  bval,
316  bval_size);
317  GNUNET_free (bval);
318  return GNUNET_OK;
319  }
320  default:
321  return GNUNET_SYSERR;
322  }
323 }
324 
325 
330 static struct {
331  const char *name;
332  uint32_t number;
333 } gns_name_map[] = {
334  { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
335  { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
336  { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
337  { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
338  { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
339  { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
340  { NULL, UINT32_MAX }
341 };
342 
343 
351 static uint32_t
353  const char *gns_typename)
354 {
355  unsigned int i;
356 
357  i=0;
358  while ( (NULL != gns_name_map[i].name) &&
359  (0 != strcasecmp (gns_typename,
360  gns_name_map[i].name)) )
361  i++;
362  return gns_name_map[i].number;
363 }
364 
365 
373 static const char *
375  uint32_t type)
376 {
377  unsigned int i;
378 
379  i=0;
380  while ( (NULL != gns_name_map[i].name) &&
381  (type != gns_name_map[i].number) )
382  i++;
383  return gns_name_map[i].name;
384 }
385 
386 
393 void *
395 {
397 
403  return api;
404 }
405 
406 
413 void *
415 {
417 
418  GNUNET_free (api);
419  return NULL;
420 }
421 
422 /* 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.
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:344
GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename
Number to typename.
static struct @25 gns_name_map[]
Mapping of record type numbers to human-readable record type names.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
GNUNET_GNSRECORD_StringToValueFunction string_to_value
Conversion to binary.
uint32_t number
void * libgnunet_plugin_gnsrecord_gns_init(void *cls)
Entry point for the plugin.
void * cls
Closure for all of the callbacks.
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: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.
#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:208
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_memcpy(dst, src, n)
#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.
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:334
struct GNUNET_PeerIdentity peer
The peer to contact.
uint16_t proto
The protocol to use.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
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:501
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:468
#define SSCANF
Definition: plibc.h:691
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
static size_t data_size
Number of bytes in data.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key