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  struct GNUNET_IDENTITY_PublicKey pk;
54 
55  switch (type)
56  {
60  data_size,
61  type,
62  &pk))
63  return NULL;
65 
67  return GNUNET_strndup (data, data_size);
68 
70  return GNUNET_strndup (data, data_size);
71 
73  char *ns;
74  char *ip;
75  size_t off;
76  char *nstr;
77 
78  off = 0;
79  ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
80  if (NULL == ns)
81  {
82  GNUNET_break_op (0);
83  GNUNET_free (ns);
84  return NULL;
85  }
86  /* DNS server IP/name must be UTF-8 */
87  ip = GNUNET_strdup (&((const char*) data)[off]);
88  GNUNET_asprintf (&nstr, "%s@%s", ns, ip);
89  GNUNET_free (ns);
90  GNUNET_free (ip);
91  return nstr;
92  }
93 
95  struct GNUNET_TUN_GnsVpnRecord vpn;
96  char *vpn_str;
97 
98  cdata = data;
99  if ((data_size <= sizeof(vpn)) || ('\0' != cdata[data_size - 1]))
100  return NULL; /* malformed */
101  /* need to memcpy for alignment */
102  GNUNET_memcpy (&vpn, data, sizeof(vpn));
103  GNUNET_asprintf (&vpn_str,
104  "%u %s %s",
105  (unsigned int) ntohs (vpn.proto),
106  (const char *) GNUNET_i2s_full (&vpn.peer),
107  (const char *) &cdata[sizeof(vpn)]);
108  return vpn_str;
109  }
110 
112  struct GNUNET_GNSRECORD_BoxRecord box;
113  uint32_t rt;
114  char *box_str;
115  char *ival;
116 
117  cdata = data;
118  if (data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
119  return NULL; /* malformed */
120  GNUNET_memcpy (&box, data, sizeof(box));
121  rt = ntohl (box.record_type);
123  &cdata[sizeof(box)],
124  data_size - sizeof(box));
125  if (NULL == ival)
126  return NULL; /* malformed */
127  GNUNET_asprintf (&box_str,
128  "%u %u %u %s",
129  (unsigned int) ntohs (box.protocol),
130  (unsigned int) ntohs (box.service),
131  (unsigned int) rt,
132  ival);
133  GNUNET_free (ival);
134  return box_str;
135  }
136 
137  default:
138  return NULL;
139  }
140 }
141 
142 
154 static int
156  uint32_t type,
157  const char *s,
158  void **data,
159  size_t *data_size)
160 {
161  struct GNUNET_IDENTITY_PublicKey pk;
162  uint32_t record_type;
163 
164  if (NULL == s)
165  return GNUNET_SYSERR;
166  switch (type)
167  {
170  if (GNUNET_OK !=
172  {
174  _ ("Unable to parse zone key record `%s'\n"),
175  s);
176  return GNUNET_SYSERR;
177  }
178  *data_size = GNUNET_IDENTITY_key_get_length (&pk);
180  (char **) data,
181  data_size,
182  &record_type))
183  return GNUNET_SYSERR;
184  if (record_type != type)
185  {
187  _("Record type does not match parsed record type\n"));
188  return GNUNET_SYSERR;
189  }
190  return GNUNET_OK;
191 
193  *data = GNUNET_strdup (s);
194  *data_size = strlen (s);
195  return GNUNET_OK;
196 
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;
223  sizeof(nsbuf),
224  &off,
225  cpy))
226  {
228  _ (
229  "Failed to serialize GNS2DNS record with value `%s': Not a DNS name.\n"),
230  s);
231  GNUNET_free (cpy);
232  return GNUNET_SYSERR;
233  }
234  /* The DNS server location/name is in UTF-8 */
235  GNUNET_memcpy (&nsbuf[off], at, strlen (at) + 1);
236  off += strlen (at) + 1;
237  GNUNET_free (cpy);
238  *data_size = off;
239  *data = GNUNET_malloc (off);
240  GNUNET_memcpy (*data, nsbuf, off);
241  return GNUNET_OK;
242  }
243 
245  struct GNUNET_TUN_GnsVpnRecord *vpn;
246  char s_peer[103 + 1];
247  char s_serv[253 + 1];
248  unsigned int proto;
249 
250  if (3 != sscanf (s, "%u %103s %253s", &proto, s_peer, s_serv))
251  {
253  _ ("Unable to parse VPN record string `%s'\n"),
254  s);
255  return GNUNET_SYSERR;
256  }
257  *data_size = sizeof(struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
258  *data = vpn = GNUNET_malloc (*data_size);
259  if (GNUNET_OK !=
261  strlen (s_peer),
262  &vpn->peer.public_key))
263  {
264  GNUNET_free (vpn);
265  *data_size = 0;
266  return GNUNET_SYSERR;
267  }
268  vpn->proto = htons ((uint16_t) proto);
269  strcpy ((char *) &vpn[1], s_serv);
270  return GNUNET_OK;
271  }
272 
274  struct GNUNET_GNSRECORD_BoxRecord *box;
275  size_t rest;
276  unsigned int protocol;
277  unsigned int service;
278  unsigned int record_type;
279  void *bval;
280  size_t bval_size;
281 
282  if (3 != sscanf (s, "%u %u %u ", &protocol, &service, &record_type))
283  {
285  _ ("Unable to parse BOX record string `%s'\n"),
286  s);
287  return GNUNET_SYSERR;
288  }
289  rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, record_type);
290  if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record_type,
291  &s[rest],
292  &bval,
293  &bval_size))
294  return GNUNET_SYSERR;
295  *data_size = sizeof(struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
296  *data = box = GNUNET_malloc (*data_size);
297  box->protocol = htons (protocol);
298  box->service = htons (service);
299  box->record_type = htonl (record_type);
300  GNUNET_memcpy (&box[1], bval, bval_size);
301  GNUNET_free (bval);
302  return GNUNET_OK;
303  }
304 
305  default:
306  return GNUNET_SYSERR;
307  }
308 }
309 
310 
315 static struct
316 {
317  const char *name;
318  uint32_t number;
319 } gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
320  { "EDKEY", GNUNET_GNSRECORD_TYPE_PKEY },
321  { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
322  { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
323  { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
324  { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
325  { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
326  { NULL, UINT32_MAX } };
327 
328 
336 static uint32_t
337 gns_typename_to_number (void *cls, const char *gns_typename)
338 {
339  unsigned int i;
340 
341  i = 0;
342  while ((NULL != gns_name_map[i].name) &&
343  (0 != strcasecmp (gns_typename, gns_name_map[i].name)))
344  i++;
345  return gns_name_map[i].number;
346 }
347 
348 
356 static const char *
357 gns_number_to_typename (void *cls, uint32_t type)
358 {
359  unsigned int i;
360 
361  i = 0;
362  while ((NULL != gns_name_map[i].name) && (type != gns_name_map[i].number))
363  i++;
364  return gns_name_map[i].name;
365 }
366 
367 
374 void *
376 {
378 
384  return api;
385 }
386 
387 
394 void *
396 {
398 
399  GNUNET_free (api);
400  return NULL;
401 }
402 
403 
404 /* 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.
#define GNUNET_GNSRECORD_TYPE_EDKEY
Record type for EDKEY delegations.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
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.
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:976
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_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:184
static uint32_t gns_typename_to_number(void *cls, const char *gns_typename)
Convert a type name (i.e.
#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:191
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.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
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.
struct GNUNET_PeerIdentity peer
The peer to contact.
uint16_t proto
The protocol to use.
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:399
An identity key as per LSD0001.
static const char * gns_number_to_typename(void *cls, uint32_t type)
Convert a type number (i.e.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
#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:159
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
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.