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;
54 
55  switch (type)
56  {
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 (_("This is a memento of an older block for internal maintenance."));
137  }
138  default:
139  return NULL;
140  }
141 }
142 
143 
155 static int
157  uint32_t type,
158  const char *s,
159  void **data,
160  size_t *data_size)
161 {
163  uint32_t record_type;
164 
165  if (NULL == s)
166  return GNUNET_SYSERR;
167  switch (type)
168  {
171  if (GNUNET_OK !=
173  {
175  _ ("Unable to parse zone key record `%s'\n"),
176  s);
177  return GNUNET_SYSERR;
178  }
181  (char **) data,
182  data_size,
183  &record_type))
184  return GNUNET_SYSERR;
185  if (record_type != type)
186  {
188  _ ("Record type does not match parsed record type\n"));
189  return GNUNET_SYSERR;
190  }
191  return GNUNET_OK;
192 
196  *data = GNUNET_strdup (s);
197  *data_size = strlen (s);
198  return GNUNET_OK;
199 
201  char nsbuf[514];
202  char *cpy;
203  char *at;
204  size_t off;
205 
206  cpy = GNUNET_strdup (s);
207  at = strchr (cpy, '@');
208  if (NULL == at)
209  {
211  _ ("Unable to parse GNS2DNS record `%s'\n"),
212  s);
213  GNUNET_free (cpy);
214  return GNUNET_SYSERR;
215  }
216  *at = '\0';
217  at++;
218 
219  off = 0;
221  sizeof(nsbuf),
222  &off,
223  cpy))
224  {
226  _ (
227  "Failed to serialize GNS2DNS record with value `%s': Not a DNS name.\n"),
228  s);
229  GNUNET_free (cpy);
230  return GNUNET_SYSERR;
231  }
232  /* The DNS server location/name is in UTF-8 */
233  GNUNET_memcpy (&nsbuf[off], at, strlen (at) + 1);
234  off += strlen (at) + 1;
235  GNUNET_free (cpy);
236  *data_size = off;
237  *data = GNUNET_malloc (off);
238  GNUNET_memcpy (*data, nsbuf, off);
239  return GNUNET_OK;
240  }
241 
243  struct GNUNET_TUN_GnsVpnRecord *vpn;
244  char s_peer[103 + 1];
245  char s_serv[253 + 1];
246  unsigned int proto;
247 
248  if (3 != sscanf (s, "%u %103s %253s", &proto, s_peer, s_serv))
249  {
251  _ ("Unable to parse VPN record string `%s'\n"),
252  s);
253  return GNUNET_SYSERR;
254  }
255  *data_size = sizeof(struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
256  *data = vpn = GNUNET_malloc (*data_size);
257  if (GNUNET_OK !=
259  strlen (s_peer),
260  &vpn->peer.public_key))
261  {
262  GNUNET_free (vpn);
263  *data_size = 0;
264  return GNUNET_SYSERR;
265  }
266  vpn->proto = htons ((uint16_t) proto);
267  strcpy ((char *) &vpn[1], s_serv);
268  return GNUNET_OK;
269  }
270 
272  struct GNUNET_GNSRECORD_BoxRecord *box;
273  size_t rest;
274  unsigned int protocol;
275  unsigned int service;
276  unsigned int record_type;
277  void *bval;
278  size_t bval_size;
279 
280  if (3 != sscanf (s, "%u %u %u ", &protocol, &service, &record_type))
281  {
283  _ ("Unable to parse BOX record string `%s'\n"),
284  s);
285  return GNUNET_SYSERR;
286  }
287  rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, record_type);
289  &s[rest],
290  &bval,
291  &bval_size))
292  return GNUNET_SYSERR;
293  *data_size = sizeof(struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
294  *data = box = GNUNET_malloc (*data_size);
295  box->protocol = htons (protocol);
296  box->service = htons (service);
297  box->record_type = htonl (record_type);
298  GNUNET_memcpy (&box[1], bval, bval_size);
299  GNUNET_free (bval);
300  return GNUNET_OK;
301  }
303  *data_size = 0;
304  *data = NULL;
305  return GNUNET_OK;
306  }
307 
308 
309  default:
310  return GNUNET_SYSERR;
311  }
312 }
313 
314 
319 static struct
320 {
321  const char *name;
322  uint32_t number;
323 } gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
324  { "EDKEY", GNUNET_GNSRECORD_TYPE_EDKEY },
325  { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
326  { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
327  { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
328  { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
329  { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
330  { "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT },
331  /* Tombstones should never be added manually
332  * so this makes sense, kind of */
333  { "\u271E", GNUNET_GNSRECORD_TYPE_TOMBSTONE },
334  { NULL, UINT32_MAX } };
335 
336 
344 static uint32_t
345 gns_typename_to_number (void *cls, const char *gns_typename)
346 {
347  unsigned int i;
348 
349  i = 0;
350  while ((NULL != gns_name_map[i].name) &&
351  (0 != strcasecmp (gns_typename, gns_name_map[i].name)))
352  i++;
353  return gns_name_map[i].number;
354 }
355 
356 
364 static const char *
365 gns_number_to_typename (void *cls, uint32_t type)
366 {
367  unsigned int i;
368 
369  i = 0;
370  while ((NULL != gns_name_map[i].name) && (type != gns_name_map[i].number))
371  i++;
372  return gns_name_map[i].name;
373 }
374 
375 
376 static enum GNUNET_GenericReturnValue
377 gns_is_critical (void *cls, uint32_t type)
378 {
379  return ((type == GNUNET_GNSRECORD_TYPE_PKEY) ||
384 }
385 
386 
387 
388 
395 void *
397 {
399 
406  return api;
407 }
408 
409 
416 void *
418 {
420 
421  GNUNET_free (api);
422  return NULL;
423 }
424 
425 
426 /* 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.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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
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:156
int GNUNET_GNSRECORD_string_to_value(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.
Definition: gnsrecord.c:188
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.
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
ssize_t GNUNET_IDENTITY_key_get_length(const struct GNUNET_IDENTITY_PublicKey *key)
Get the compacted length of a GNUNET_IDENTITY_PublicKey.
Definition: identity_api.c:991
#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:177
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