GNUnet 0.25.0
 
Loading...
Searching...
No Matches
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"
33#include <inttypes.h>
34
35
45static 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 !=
61 type,
62 &pk))
63 return NULL;
65
70
71 // See https://www.rfc-editor.org/rfc/rfc9498.html#name-gns2dns
73 const char *name;
74 const char *dns_server_name;
75 char *nstr;
76
77 name = (const char *) data;
78 /* DNS server IP/name must be UTF-8 */
79 dns_server_name = name + strlen (name) + 1;
80 GNUNET_asprintf (&nstr, "%s@%s", name, dns_server_name);
81 return nstr;
82 }
83
85 struct GNUNET_TUN_GnsVpnRecord vpn;
86 char *vpn_str;
87
88 cdata = data;
89 if ((data_size <= sizeof(vpn)) || ('\0' != cdata[data_size - 1]))
90 return NULL; /* malformed */
91 /* need to memcpy for alignment */
92 GNUNET_memcpy (&vpn, data, sizeof(vpn));
93 GNUNET_asprintf (&vpn_str,
94 "%u %s %s",
95 (unsigned int) ntohs (vpn.proto),
96 (const char *) GNUNET_i2s_full (&vpn.peer),
97 (const char *) &cdata[sizeof(vpn)]);
98 return vpn_str;
99 }
100
103 uint32_t rt;
104 char *box_str;
105 char *ival;
106
107 cdata = data;
108 if (data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
109 return NULL; /* malformed */
110 GNUNET_memcpy (&box, data, sizeof(box));
111 rt = ntohl (box.record_type);
113 &cdata[sizeof(box)],
114 data_size - sizeof(box));
115 if (NULL == ival)
116 return NULL; /* malformed */
117 GNUNET_asprintf (&box_str,
118 "%u %u %u %s",
119 (unsigned int) ntohs (box.protocol),
120 (unsigned int) ntohs (box.service),
121 (unsigned int) rt,
122 ival);
123 GNUNET_free (ival);
124 return box_str;
125 }
128 uint32_t rt;
129 char *box_str;
130 char *ival;
131 char *prefix;
132
133 cdata = data;
134 if (data_size < sizeof(struct GNUNET_GNSRECORD_SBoxRecord))
135 return NULL; /* malformed */
136 GNUNET_memcpy (&box, data, sizeof(box));
137 rt = ntohl (box.record_type);
138
139 prefix = GNUNET_strdup (&cdata[sizeof(box)]);
140 ival = GNUNET_GNSRECORD_value_to_string (rt, &cdata[sizeof(box)
141 + strlen (prefix)
142 + 1],
143 data_size - sizeof(box)
144 - strlen (prefix) - 1);
145 if (NULL == ival)
146 return NULL; /* malformed */
147 GNUNET_asprintf (&box_str,
148 "%s %u %s",
149 prefix,
150 (unsigned int) rt,
151 ival);
153 GNUNET_free (ival);
154 return box_str;
155 }
157 return GNUNET_strdup (_ (
158 "This is a memento of an older block for internal maintenance."));
159 }
160 default:
161 return NULL;
162 }
163}
164
165
177static int
179 uint32_t type,
180 const char *s,
181 void **data,
182 size_t *data_size)
183{
185 uint32_t record_type;
186
187 if (NULL == s)
188 return GNUNET_SYSERR;
189 switch (type)
190 {
193 if (GNUNET_OK !=
195 {
197 _ ("Unable to parse zone key record `%s'\n"),
198 s);
199 return GNUNET_SYSERR;
200 }
202 if (GNUNET_OK !=
204 (char **) data,
205 data_size,
206 &record_type))
207 return GNUNET_SYSERR;
208 if (record_type != type)
209 {
211 _ ("Record type does not match parsed record type\n"));
212 return GNUNET_SYSERR;
213 }
214 return GNUNET_OK;
215
219 *data = GNUNET_strdup (s);
220 *data_size = strlen (s);
221 return GNUNET_OK;
222
223 // See https://www.rfc-editor.org/rfc/rfc9498.html#name-gns2dns
225 char *cpy;
226 char *at;
227
228 cpy = GNUNET_strdup (s);
229 at = strchr (cpy, '@');
230 if (NULL == at)
231 {
233 _ ("Unable to parse GNS2DNS record `%s'\n"),
234 s);
235 GNUNET_free (cpy);
236 return GNUNET_SYSERR;
237 }
238 *at = '\0';
239 at++;
240
241 /* The DNS server location/name is in UTF-8 */
242 *data_size = strlen (s) + 1;
243 *data = cpy;
244 return GNUNET_OK;
245 }
246
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, "%u %103s %253s", &proto, s_peer, s_serv))
254 {
256 _ ("Unable to parse VPN record string `%s'\n"),
257 s);
258 return GNUNET_SYSERR;
259 }
260 *data_size = sizeof(struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
261 *data = vpn = GNUNET_malloc (*data_size);
262 if (GNUNET_OK !=
264 strlen (s_peer),
265 &vpn->peer.public_key))
266 {
267 GNUNET_free (vpn);
268 *data_size = 0;
269 return GNUNET_SYSERR;
270 }
271 vpn->proto = htons ((uint16_t) proto);
272 strcpy ((char *) &vpn[1], s_serv);
273 return GNUNET_OK;
274 }
275
277 struct GNUNET_GNSRECORD_BoxRecord *box;
278 size_t rest;
279 unsigned int protocol;
280 unsigned int service;
281 unsigned int rrtype;
282 void *bval;
283 size_t bval_size;
284
285 if (3 != sscanf (s, "%u %u %u ", &protocol, &service, &rrtype))
286 {
288 _ ("Unable to parse BOX record string `%s'\n"),
289 s);
290 return GNUNET_SYSERR;
291 }
292 rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, rrtype);
294 &s[rest],
295 &bval,
296 &bval_size))
297 return GNUNET_SYSERR;
298 *data_size = sizeof(struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
299 *data = box = GNUNET_malloc (*data_size);
300 box->protocol = htons (protocol);
301 box->service = htons (service);
302 box->record_type = htonl (rrtype);
303 GNUNET_memcpy (&box[1], bval, bval_size);
304 GNUNET_free (bval);
305 return GNUNET_OK;
306 }
308 struct GNUNET_GNSRECORD_SBoxRecord *box;
309 size_t rest;
310 char *prefix;
311 char *p;
312 char *underscore_prefix;
313 unsigned int rrtype;
314 void *bval;
315 size_t bval_size;
316 size_t prefix_size;
317
318 prefix = GNUNET_malloc (strlen (s) + 1);
319 if (2 != sscanf (s, "%s %u ", prefix, &rrtype))
320 {
322 _ ("Unable to parse SBOX record string `%s'\n"),
323 s);
325 return GNUNET_SYSERR;
326 }
327 underscore_prefix = strrchr (prefix, '.');
328 if (underscore_prefix == NULL)
329 {
330 underscore_prefix = prefix;
331 }
332 else
333 {
334 underscore_prefix++;
335 }
336 if ('_' != underscore_prefix[0])
337 {
339 _ (
340 "Unable to parse SBOX record string `%s', the rightmost label `%s' does not start with an underscore\n"),
341 prefix, underscore_prefix);
343 return GNUNET_SYSERR;
344 }
345 rest = snprintf (NULL, 0, "%s %u ", prefix, rrtype);
347 &s[rest],
348 &bval,
349 &bval_size))
350 {
352 return GNUNET_SYSERR;
353 }
354 prefix_size = strlen (prefix) + 1;
355 *data_size = sizeof(struct GNUNET_GNSRECORD_SBoxRecord) + prefix_size
356 + bval_size;
358 p = *data;
359 box = *data;
360 box->record_type = htonl (rrtype);
361 p += sizeof(struct GNUNET_GNSRECORD_SBoxRecord);
362 GNUNET_memcpy (p, prefix, prefix_size);
363 p += prefix_size;
364 GNUNET_memcpy (p, bval, bval_size);
365 GNUNET_free (bval);
367 return GNUNET_OK;
368 }
370 *data_size = 0;
371 *data = NULL;
372 return GNUNET_OK;
373 }
374
375 default:
376 return GNUNET_SYSERR;
377 }
378}
379
380
385static struct
386{
387 const char *name;
388 uint32_t number;
389} gns_name_map[] = {
390 { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
391 { "EDKEY", GNUNET_GNSRECORD_TYPE_EDKEY },
392 { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
393 { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
394 { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
395 { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
396 { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
397 { "SBOX", GNUNET_GNSRECORD_TYPE_SBOX },
398 { "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT },
399 /* Tombstones should never be added manually
400 * so this makes sense, kind of */
402 { NULL, UINT32_MAX }
404
405
413static uint32_t
415 const char *gns_typename)
416{
417 unsigned int i;
418
419 i = 0;
420 while ((NULL != gns_name_map[i].name) &&
421 (0 != strcasecmp (gns_typename, gns_name_map[i].name)))
422 i++;
423 return gns_name_map[i].number;
424}
425
426
434static const char *
436 uint32_t type)
437{
438 unsigned int i;
439
440 i = 0;
441 while ( (NULL != gns_name_map[i].name) &&
442 (type != gns_name_map[i].number) )
443 i++;
444 return gns_name_map[i].name;
445}
446
447
457
458
459void *
461
468void *
481
482
483void *
485
492void *
494{
496
497 GNUNET_free (api);
498 return NULL;
499}
500
501
502/* end of plugin_gnsrecord_gns.c */
#define GNUNET_GNSRECORD_TYPE_BOX
Box record.
#define GNUNET_GNSRECORD_TYPE_NICK
GNS zone nickname.
#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
Redirection record.
#define GNUNET_GNSRECORD_TYPE_VPN
VPN resolution.
#define GNUNET_GNSRECORD_TYPE_LEHO
GNS legacy hostname.
#define GNUNET_GNSRECORD_TYPE_SBOX
SBox record.
#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
GNS zone delegation (EDKEY)
static int prefix
If printing the value of PREFIX has been requested.
static char * data
The data to insert into the dht.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static uint8_t proto
Protocol to use.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
API that can be used to manipulate GNS record data.
Plugin API for GNS record types.
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:169
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_data_from_identity(const struct GNUNET_CRYPTO_PublicKey *key, char **data, size_t *data_size, uint32_t *type)
Create record data and size from an identity key.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_CRYPTO_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 binary value data of a record of type type to a human-readable string.
Definition gnsrecord.c:147
ssize_t GNUNET_CRYPTO_public_key_get_length(const struct GNUNET_CRYPTO_PublicKey *key)
Get the compacted length of a GNUNET_CRYPTO_PublicKey.
Definition crypto_pkey.c:85
#define GNUNET_log(kind,...)
char * GNUNET_CRYPTO_public_key_to_string(const struct GNUNET_CRYPTO_PublicKey *key)
Creates a (Base32) string representation of the public key.
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:361
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_public_key_from_string(const char *str, struct GNUNET_CRYPTO_PublicKey *key)
Parses a (Base32) string representation of the public key.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
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:179
void * libgnunet_plugin_gnsrecord_gns_init(void *cls)
Entry point for the plugin.
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 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 const char * gns_number_to_typename(void *cls, uint32_t type)
Convert a type number to the corresponding type string (e.g.
static struct @37 gns_name_map[]
Mapping of record type numbers to human-readable record type names.
const char * name
uint32_t number
static uint32_t gns_typename_to_number(void *cls, const char *gns_typename)
Convert a type name (e.g.
void * libgnunet_plugin_gnsrecord_gns_done(void *cls)
Exit point from the plugin.
static enum GNUNET_GenericReturnValue gns_is_critical(void *cls, uint32_t type)
An identity key as per LSD0001.
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.
Record type used to box up SMIMEA records.
uint32_t record_type
GNS record type of the boxed record.
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.