aboutsummaryrefslogtreecommitdiff
path: root/src/gns/plugin_gnsrecord_gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/plugin_gnsrecord_gns.c')
-rw-r--r--src/gns/plugin_gnsrecord_gns.c404
1 files changed, 0 insertions, 404 deletions
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c
deleted file mode 100644
index 391144925..000000000
--- a/src/gns/plugin_gnsrecord_gns.c
+++ /dev/null
@@ -1,404 +0,0 @@
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
21/**
22 * @file gns/plugin_gnsrecord_gns.c
23 * @brief gnsrecord plugin to provide the API for fundamental GNS records
24 * This includes the VPN record because GNS resolution
25 * is expected to understand VPN records and (if needed)
26 * map the result to A/AAAA.
27 * @author Christian Grothoff
28 */
29#include "platform.h"
30#include "gnunet_util_lib.h"
31#include "gnunet_gnsrecord_lib.h"
32#include "gnunet_dnsparser_lib.h"
33#include "gnunet_gnsrecord_plugin.h"
34#include <inttypes.h>
35
36
37/**
38 * Convert the 'value' of a record to a string.
39 *
40 * @param cls closure, unused
41 * @param type type of the record
42 * @param data value in binary encoding
43 * @param data_size number of bytes in @a data
44 * @return NULL on error, otherwise human-readable representation of the value
45 */
46static char *
47gns_value_to_string (void *cls,
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 {
57 case GNUNET_GNSRECORD_TYPE_PKEY:
58 case GNUNET_GNSRECORD_TYPE_EDKEY:
59 if (GNUNET_OK != GNUNET_GNSRECORD_identity_from_data (data,
60 data_size,
61 type,
62 &pk))
63 return NULL;
64 return GNUNET_IDENTITY_public_key_to_string (&pk);
65
66 case GNUNET_GNSRECORD_TYPE_NICK:
67 return GNUNET_strndup (data, data_size);
68
69 case GNUNET_GNSRECORD_TYPE_LEHO:
70 return GNUNET_strndup (data, data_size);
71
72 case GNUNET_GNSRECORD_TYPE_GNS2DNS: {
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
94 case GNUNET_GNSRECORD_TYPE_VPN: {
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
111 case GNUNET_GNSRECORD_TYPE_BOX: {
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);
122 ival = GNUNET_GNSRECORD_value_to_string (rt,
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
143/**
144 * Convert human-readable version of a 'value' of a record to the binary
145 * representation.
146 *
147 * @param cls closure, unused
148 * @param type type of the record
149 * @param s human-readable string
150 * @param data set to value in binary encoding (will be allocated)
151 * @param data_size set to number of bytes in @a data
152 * @return #GNUNET_OK on success
153 */
154static int
155gns_string_to_value (void *cls,
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 {
168 case GNUNET_GNSRECORD_TYPE_PKEY:
169 case GNUNET_GNSRECORD_TYPE_EDKEY:
170 if (GNUNET_OK !=
171 GNUNET_IDENTITY_public_key_from_string (s, &pk))
172 {
173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
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);
179 if (GNUNET_OK != GNUNET_GNSRECORD_data_from_identity (&pk,
180 (char **) data,
181 data_size,
182 &record_type))
183 return GNUNET_SYSERR;
184 if (record_type != type)
185 {
186 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
187 _("Record type does not match parsed record type\n"));
188 return GNUNET_SYSERR;
189 }
190 return GNUNET_OK;
191
192 case GNUNET_GNSRECORD_TYPE_NICK:
193 *data = GNUNET_strdup (s);
194 *data_size = strlen (s);
195 return GNUNET_OK;
196
197 case GNUNET_GNSRECORD_TYPE_LEHO:
198 *data = GNUNET_strdup (s);
199 *data_size = strlen (s);
200 return GNUNET_OK;
201
202 case GNUNET_GNSRECORD_TYPE_GNS2DNS: {
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 {
212 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
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 != GNUNET_DNSPARSER_builder_add_name (nsbuf,
223 sizeof(nsbuf),
224 &off,
225 cpy))
226 {
227 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
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
244 case GNUNET_GNSRECORD_TYPE_VPN: {
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 {
252 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
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 !=
260 GNUNET_CRYPTO_eddsa_public_key_from_string ((char *) s_peer,
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
273 case GNUNET_GNSRECORD_TYPE_BOX: {
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 {
284 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
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
311/**
312 * Mapping of record type numbers to human-readable
313 * record type names.
314 */
315static 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
329/**
330 * Convert a type name (e.g. "AAAA") to the corresponding number.
331 *
332 * @param cls closure, unused
333 * @param gns_typename name to convert
334 * @return corresponding number, UINT32_MAX on error
335 */
336static uint32_t
337gns_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
349/**
350 * Convert a type number to the corresponding type string (e.g. 1 to "A")
351 *
352 * @param cls closure, unused
353 * @param type number of a type to convert
354 * @return corresponding typestring, NULL on error
355 */
356static const char *
357gns_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
368/**
369 * Entry point for the plugin.
370 *
371 * @param cls NULL
372 * @return the exported block API
373 */
374void *
375libgnunet_plugin_gnsrecord_gns_init (void *cls)
376{
377 struct GNUNET_GNSRECORD_PluginFunctions *api;
378
379 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
380 api->value_to_string = &gns_value_to_string;
381 api->string_to_value = &gns_string_to_value;
382 api->typename_to_number = &gns_typename_to_number;
383 api->number_to_typename = &gns_number_to_typename;
384 return api;
385}
386
387
388/**
389 * Exit point from the plugin.
390 *
391 * @param cls the return value from #libgnunet_plugin_block_test_init()
392 * @return NULL
393 */
394void *
395libgnunet_plugin_gnsrecord_gns_done (void *cls)
396{
397 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
398
399 GNUNET_free (api);
400 return NULL;
401}
402
403
404/* end of plugin_gnsrecord_gns.c */