GNUnet  0.19.5
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"
33 #include <inttypes.h>
34 
35 
45 static char *
47  uint32_t type,
48  const void *data,
49  size_t data_size)
50 {
51  const char *cdata;
53 
54  switch (type)
55  {
58  if (GNUNET_OK !=
60  data_size,
61  type,
62  &pk))
63  return NULL;
65 
69  return GNUNET_strndup (data, data_size);
70 
72  char *ns;
73  char *ip;
74  size_t off;
75  char *nstr;
76 
77  off = 0;
79  if (NULL == ns)
80  {
81  GNUNET_break_op (0);
82  GNUNET_free (ns);
83  return NULL;
84  }
85  /* DNS server IP/name must be UTF-8 */
86  ip = GNUNET_strdup (&((const char*) data)[off]);
87  GNUNET_asprintf (&nstr, "%s@%s", ns, ip);
88  GNUNET_free (ns);
89  GNUNET_free (ip);
90  return nstr;
91  }
92 
94  struct GNUNET_TUN_GnsVpnRecord vpn;
95  char *vpn_str;
96 
97  cdata = data;
98  if ((data_size <= sizeof(vpn)) || ('\0' != cdata[data_size - 1]))
99  return NULL; /* malformed */
100  /* need to memcpy for alignment */
101  GNUNET_memcpy (&vpn, data, sizeof(vpn));
102  GNUNET_asprintf (&vpn_str,
103  "%u %s %s",
104  (unsigned int) ntohs (vpn.proto),
105  (const char *) GNUNET_i2s_full (&vpn.peer),
106  (const char *) &cdata[sizeof(vpn)]);
107  return vpn_str;
108  }
109 
111  struct GNUNET_GNSRECORD_BoxRecord box;
112  uint32_t rt;
113  char *box_str;
114  char *ival;
115 
116  cdata = data;
117  if (data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
118  return NULL; /* malformed */
119  GNUNET_memcpy (&box, data, sizeof(box));
120  rt = ntohl (box.record_type);
122  &cdata[sizeof(box)],
123  data_size - sizeof(box));
124  if (NULL == ival)
125  return NULL; /* malformed */
126  GNUNET_asprintf (&box_str,
127  "%u %u %u %s",
128  (unsigned int) ntohs (box.protocol),
129  (unsigned int) ntohs (box.service),
130  (unsigned int) rt,
131  ival);
132  GNUNET_free (ival);
133  return box_str;
134  }
136  return GNUNET_strdup (_ (
137  "This is a memento of an older block for internal maintenance."));
138  }
139  default:
140  return NULL;
141  }
142 }
143 
144 
156 static int
158  uint32_t type,
159  const char *s,
160  void **data,
161  size_t *data_size)
162 {
164  uint32_t record_type;
165 
166  if (NULL == s)
167  return GNUNET_SYSERR;
168  switch (type)
169  {
172  if (GNUNET_OK !=
174  {
176  _ ("Unable to parse zone key record `%s'\n"),
177  s);
178  return GNUNET_SYSERR;
179  }
181  if (GNUNET_OK !=
183  (char **) data,
184  data_size,
185  &record_type))
186  return GNUNET_SYSERR;
187  if (record_type != type)
188  {
190  _ ("Record type does not match parsed record type\n"));
191  return GNUNET_SYSERR;
192  }
193  return GNUNET_OK;
194 
198  *data = GNUNET_strdup (s);
199  *data_size = strlen (s);
200  return GNUNET_OK;
201 
203  char nsbuf[514];
204  char *cpy;
205  char *at;
206  size_t off;
207 
208  cpy = GNUNET_strdup (s);
209  at = strchr (cpy, '@');
210  if (NULL == at)
211  {
213  _ ("Unable to parse GNS2DNS record `%s'\n"),
214  s);
215  GNUNET_free (cpy);
216  return GNUNET_SYSERR;
217  }
218  *at = '\0';
219  at++;
220 
221  off = 0;
222  if (GNUNET_OK !=
224  sizeof(nsbuf),
225  &off,
226  cpy))
227  {
229  _ (
230  "Failed to serialize GNS2DNS record with value `%s': Not a DNS name.\n"),
231  s);
232  GNUNET_free (cpy);
233  return GNUNET_SYSERR;
234  }
235  /* The DNS server location/name is in UTF-8 */
236  GNUNET_memcpy (&nsbuf[off], at, strlen (at) + 1);
237  off += strlen (at) + 1;
238  GNUNET_free (cpy);
239  *data_size = off;
240  *data = GNUNET_malloc (off);
241  GNUNET_memcpy (*data, nsbuf, off);
242  return GNUNET_OK;
243  }
244 
246  struct GNUNET_TUN_GnsVpnRecord *vpn;
247  char s_peer[103 + 1];
248  char s_serv[253 + 1];
249  unsigned int proto;
250 
251  if (3 != sscanf (s, "%u %103s %253s", &proto, s_peer, s_serv))
252  {
254  _ ("Unable to parse VPN record string `%s'\n"),
255  s);
256  return GNUNET_SYSERR;
257  }
258  *data_size = sizeof(struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
259  *data = vpn = GNUNET_malloc (*data_size);
260  if (GNUNET_OK !=
262  strlen (s_peer),
263  &vpn->peer.public_key))
264  {
265  GNUNET_free (vpn);
266  *data_size = 0;
267  return GNUNET_SYSERR;
268  }
269  vpn->proto = htons ((uint16_t) proto);
270  strcpy ((char *) &vpn[1], s_serv);
271  return GNUNET_OK;
272  }
273 
275  struct GNUNET_GNSRECORD_BoxRecord *box;
276  size_t rest;
277  unsigned int protocol;
278  unsigned int service;
279  unsigned int record_type;
280  void *bval;
281  size_t bval_size;
282 
283  if (3 != sscanf (s, "%u %u %u ", &protocol, &service, &record_type))
284  {
286  _ ("Unable to parse BOX record string `%s'\n"),
287  s);
288  return GNUNET_SYSERR;
289  }
290  rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, record_type);
292  &s[rest],
293  &bval,
294  &bval_size))
295  return GNUNET_SYSERR;
296  *data_size = sizeof(struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
297  *data = box = GNUNET_malloc (*data_size);
298  box->protocol = htons (protocol);
299  box->service = htons (service);
300  box->record_type = htonl (record_type);
301  GNUNET_memcpy (&box[1], bval, bval_size);
302  GNUNET_free (bval);
303  return GNUNET_OK;
304  }
306  *data_size = 0;
307  *data = NULL;
308  return GNUNET_OK;
309  }
310 
311  default:
312  return GNUNET_SYSERR;
313  }
314 }
315 
316 
321 static struct
322 {
323  const char *name;
324  uint32_t number;
325 } gns_name_map[] = {
326  { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
327  { "EDKEY", GNUNET_GNSRECORD_TYPE_EDKEY },
328  { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
329  { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
330  { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
331  { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
332  { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
333  { "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT },
334  /* Tombstones should never be added manually
335  * so this makes sense, kind of */
336  { "\u271E", GNUNET_GNSRECORD_TYPE_TOMBSTONE },
337  { NULL, UINT32_MAX }
338 };
339 
340 
348 static uint32_t
350  const char *gns_typename)
351 {
352  unsigned int i;
353 
354  i = 0;
355  while ((NULL != gns_name_map[i].name) &&
356  (0 != strcasecmp (gns_typename, gns_name_map[i].name)))
357  i++;
358  return gns_name_map[i].number;
359 }
360 
361 
369 static const char *
371  uint32_t type)
372 {
373  unsigned int i;
374 
375  i = 0;
376  while ( (NULL != gns_name_map[i].name) &&
377  (type != gns_name_map[i].number) )
378  i++;
379  return gns_name_map[i].name;
380 }
381 
382 
383 static enum GNUNET_GenericReturnValue
384 gns_is_critical (void *cls, uint32_t type)
385 {
386  return ((type == GNUNET_GNSRECORD_TYPE_PKEY) ||
391 }
392 
393 
400 void *
402 {
404 
411  return api;
412 }
413 
414 
421 void *
423 {
425 
426  GNUNET_free (api);
427  return NULL;
428 }
429 
430 
431 /* end of plugin_gnsrecord_gns.c */
#define GNUNET_GNSRECORD_TYPE_BOX
Boxed records (see TLSA/SRV handling in GNS)
#define GNUNET_GNSRECORD_TYPE_NICK
GNS nick names.
#define GNUNET_GNSRECORD_TYPE_TOMBSTONE
Record type to indicate a previously delete record (PRIVATE only)
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
#define GNUNET_GNSRECORD_TYPE_REDIRECT
Resolver redirects.
#define GNUNET_GNSRECORD_TYPE_VPN
VPN resolution.
#define GNUNET_GNSRECORD_TYPE_LEHO
legacy hostnames
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
#define GNUNET_GNSRECORD_TYPE_EDKEY
Record type for EDKEY zone delegations.
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t data
The data value.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
API that can be used to manipulate GNS record data.
Plugin API for GNS record types.
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
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
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_IDENTITY_PublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the 'value' of a record to a string.
Definition: gnsrecord.c:155
int GNUNET_GNSRECORD_string_to_value(uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of the value s of a record of type type to the respective binary repre...
Definition: gnsrecord.c:177
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_data_from_identity(const struct GNUNET_IDENTITY_PublicKey *key, char **data, size_t *data_size, uint32_t *type)
Create record data and size from an identity key.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_public_key_from_string(const char *str, struct GNUNET_IDENTITY_PublicKey *key)
Parses a (Base32) string representation of the public key.
ssize_t GNUNET_IDENTITY_public_key_get_length(const struct GNUNET_IDENTITY_PublicKey *key)
Get the compacted length of a GNUNET_IDENTITY_PublicKey.
Definition: identity_api.c:830
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
#define GNUNET_log(kind,...)
enum GNUNET_GenericReturnValue 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:357
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_ERROR
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
void * libgnunet_plugin_gnsrecord_gns_init(void *cls)
Entry point for the plugin.
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 'value' of a record to the binary representation.
static struct @22 gns_name_map[]
Mapping of record type numbers to human-readable record type names.
const char * name
static const char * gns_number_to_typename(void *cls, uint32_t type)
Convert a type number to the corresponding type string (e.g.
uint32_t number
static uint32_t gns_typename_to_number(void *cls, const char *gns_typename)
Convert a type name (e.g.
static char * gns_value_to_string(void *cls, uint32_t type, const void *data, size_t data_size)
Convert the 'value' of a record to a string.
static enum GNUNET_GenericReturnValue gns_is_critical(void *cls, uint32_t type)
void * libgnunet_plugin_gnsrecord_gns_done(void *cls)
Exit point from the plugin.
Record type used to box up SRV and TLSA records.
uint32_t record_type
GNS record type of the boxed record.
uint16_t service
Service of the boxed record (aka port number), in NBO.
uint16_t protocol
Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
GNUNET_GNSRECORD_IsCriticalFunction is_critical
Is critical.
GNUNET_GNSRECORD_TypenameToNumberFunction typename_to_number
Typename to number.
GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename
Number to typename.
GNUNET_GNSRECORD_ValueToStringFunction value_to_string
Conversion to string.
void * cls
Closure for all of the callbacks.
GNUNET_GNSRECORD_StringToValueFunction string_to_value
Conversion to binary.
An identity key as per LSD0001.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Payload of GNS VPN record.
struct GNUNET_PeerIdentity peer
The peer to contact.
uint16_t proto
The protocol to use.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model