diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-10-06 15:54:30 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-10-06 15:54:30 +0000 |
commit | 810bc9ef12ddcc67cfc7cd762759ee13ecd14a8d (patch) | |
tree | e6950609e302c8cee5dd49cd75a890e660dde02a /src/gns/plugin_gnsrecord_gns.c | |
parent | 16f524720ce08aadb35912731217eaeafc690dba (diff) | |
download | gnunet-810bc9ef12ddcc67cfc7cd762759ee13ecd14a8d.tar.gz gnunet-810bc9ef12ddcc67cfc7cd762759ee13ecd14a8d.zip |
- Add reverse resolution with limited functionality
Diffstat (limited to 'src/gns/plugin_gnsrecord_gns.c')
-rw-r--r-- | src/gns/plugin_gnsrecord_gns.c | 319 |
1 files changed, 191 insertions, 128 deletions
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 360500af7..5faca4578 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "gnunet_gnsrecord_lib.h" | 31 | #include "gnunet_gnsrecord_lib.h" |
32 | #include "gnunet_dnsparser_lib.h" | 32 | #include "gnunet_dnsparser_lib.h" |
33 | #include "gnunet_gnsrecord_plugin.h" | 33 | #include "gnunet_gnsrecord_plugin.h" |
34 | #include <inttypes.h> | ||
34 | 35 | ||
35 | 36 | ||
36 | /** | 37 | /** |
@@ -139,6 +140,30 @@ gns_value_to_string (void *cls, | |||
139 | GNUNET_free (ival); | 140 | GNUNET_free (ival); |
140 | return box_str; | 141 | return box_str; |
141 | } | 142 | } |
143 | case GNUNET_GNSRECORD_TYPE_REVERSE: | ||
144 | { | ||
145 | struct GNUNET_GNSRECORD_ReverseRecord rev; | ||
146 | char *rev_str; | ||
147 | char *pkey_str; | ||
148 | |||
149 | if (data_size < sizeof (struct GNUNET_GNSRECORD_ReverseRecord)) | ||
150 | return NULL; /* malformed */ | ||
151 | |||
152 | memcpy (&rev, | ||
153 | data, | ||
154 | sizeof (rev)); | ||
155 | cdata = data; | ||
156 | pkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&rev.pkey); | ||
157 | |||
158 | GNUNET_asprintf (&rev_str, | ||
159 | "%s %s %"SCNu64, | ||
160 | &cdata[sizeof (rev)], | ||
161 | pkey_str, | ||
162 | rev.expiration.abs_value_us); | ||
163 | GNUNET_free (pkey_str); | ||
164 | return rev_str; | ||
165 | |||
166 | } | ||
142 | default: | 167 | default: |
143 | return NULL; | 168 | return NULL; |
144 | } | 169 | } |
@@ -170,147 +195,184 @@ gns_string_to_value (void *cls, | |||
170 | switch (type) | 195 | switch (type) |
171 | { | 196 | { |
172 | 197 | ||
173 | case GNUNET_GNSRECORD_TYPE_PKEY: | 198 | case GNUNET_GNSRECORD_TYPE_PKEY: |
174 | if (GNUNET_OK != | 199 | if (GNUNET_OK != |
175 | GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) | 200 | GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) |
176 | { | ||
177 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
178 | _("Unable to parse PKEY record `%s'\n"), | ||
179 | s); | ||
180 | return GNUNET_SYSERR; | ||
181 | } | ||
182 | *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
183 | GNUNET_memcpy (*data, &pkey, sizeof (pkey)); | ||
184 | *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
185 | return GNUNET_OK; | ||
186 | |||
187 | case GNUNET_GNSRECORD_TYPE_NICK: | ||
188 | *data = GNUNET_strdup (s); | ||
189 | *data_size = strlen (s); | ||
190 | return GNUNET_OK; | ||
191 | case GNUNET_GNSRECORD_TYPE_LEHO: | ||
192 | *data = GNUNET_strdup (s); | ||
193 | *data_size = strlen (s); | ||
194 | return GNUNET_OK; | ||
195 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: | ||
196 | { | ||
197 | char nsbuf[514]; | ||
198 | char *cpy; | ||
199 | char *at; | ||
200 | size_t off; | ||
201 | |||
202 | cpy = GNUNET_strdup (s); | ||
203 | at = strchr (cpy, '@'); | ||
204 | if (NULL == at) | ||
205 | { | 201 | { |
206 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 202 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
207 | _("Unable to parse GNS2DNS record `%s'\n"), | 203 | _("Unable to parse PKEY record `%s'\n"), |
208 | s); | 204 | s); |
209 | GNUNET_free (cpy); | ||
210 | return GNUNET_SYSERR; | 205 | return GNUNET_SYSERR; |
211 | } | 206 | } |
212 | *at = '\0'; | 207 | *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); |
213 | at++; | 208 | GNUNET_memcpy (*data, &pkey, sizeof (pkey)); |
209 | *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
210 | return GNUNET_OK; | ||
214 | 211 | ||
215 | off = 0; | 212 | case GNUNET_GNSRECORD_TYPE_NICK: |
216 | if ( (GNUNET_OK != | 213 | *data = GNUNET_strdup (s); |
217 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | 214 | *data_size = strlen (s); |
218 | sizeof (nsbuf), | 215 | return GNUNET_OK; |
219 | &off, | 216 | case GNUNET_GNSRECORD_TYPE_LEHO: |
220 | cpy)) || | 217 | *data = GNUNET_strdup (s); |
221 | (GNUNET_OK != | 218 | *data_size = strlen (s); |
222 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | 219 | return GNUNET_OK; |
223 | sizeof (nsbuf), | 220 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: |
224 | &off, | ||
225 | at)) ) | ||
226 | { | 221 | { |
227 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 222 | char nsbuf[514]; |
228 | _("Failed to serialize GNS2DNS record with value `%s'\n"), | 223 | char *cpy; |
229 | s); | 224 | char *at; |
225 | size_t off; | ||
226 | |||
227 | cpy = GNUNET_strdup (s); | ||
228 | at = strchr (cpy, '@'); | ||
229 | if (NULL == at) | ||
230 | { | ||
231 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
232 | _("Unable to parse GNS2DNS record `%s'\n"), | ||
233 | s); | ||
234 | GNUNET_free (cpy); | ||
235 | return GNUNET_SYSERR; | ||
236 | } | ||
237 | *at = '\0'; | ||
238 | at++; | ||
239 | |||
240 | off = 0; | ||
241 | if ( (GNUNET_OK != | ||
242 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | ||
243 | sizeof (nsbuf), | ||
244 | &off, | ||
245 | cpy)) || | ||
246 | (GNUNET_OK != | ||
247 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | ||
248 | sizeof (nsbuf), | ||
249 | &off, | ||
250 | at)) ) | ||
251 | { | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
253 | _("Failed to serialize GNS2DNS record with value `%s'\n"), | ||
254 | s); | ||
255 | GNUNET_free (cpy); | ||
256 | return GNUNET_SYSERR; | ||
257 | } | ||
230 | GNUNET_free (cpy); | 258 | GNUNET_free (cpy); |
231 | return GNUNET_SYSERR; | 259 | *data_size = off; |
260 | *data = GNUNET_malloc (off); | ||
261 | GNUNET_memcpy (*data, nsbuf, off); | ||
262 | return GNUNET_OK; | ||
232 | } | 263 | } |
233 | GNUNET_free (cpy); | 264 | case GNUNET_GNSRECORD_TYPE_VPN: |
234 | *data_size = off; | ||
235 | *data = GNUNET_malloc (off); | ||
236 | GNUNET_memcpy (*data, nsbuf, off); | ||
237 | return GNUNET_OK; | ||
238 | } | ||
239 | case GNUNET_GNSRECORD_TYPE_VPN: | ||
240 | { | ||
241 | struct GNUNET_TUN_GnsVpnRecord *vpn; | ||
242 | char s_peer[103 + 1]; | ||
243 | char s_serv[253 + 1]; | ||
244 | unsigned int proto; | ||
245 | |||
246 | if (3 != SSCANF (s, | ||
247 | "%u %103s %253s", | ||
248 | &proto, s_peer, s_serv)) | ||
249 | { | 265 | { |
250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 266 | struct GNUNET_TUN_GnsVpnRecord *vpn; |
251 | _("Unable to parse VPN record string `%s'\n"), | 267 | char s_peer[103 + 1]; |
252 | s); | 268 | char s_serv[253 + 1]; |
253 | return GNUNET_SYSERR; | 269 | unsigned int proto; |
270 | |||
271 | if (3 != SSCANF (s, | ||
272 | "%u %103s %253s", | ||
273 | &proto, s_peer, s_serv)) | ||
274 | { | ||
275 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
276 | _("Unable to parse VPN record string `%s'\n"), | ||
277 | s); | ||
278 | return GNUNET_SYSERR; | ||
279 | } | ||
280 | *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; | ||
281 | *data = vpn = GNUNET_malloc (*data_size); | ||
282 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, | ||
283 | strlen (s_peer), | ||
284 | &vpn->peer.public_key)) | ||
285 | { | ||
286 | GNUNET_free (vpn); | ||
287 | *data_size = 0; | ||
288 | return GNUNET_SYSERR; | ||
289 | } | ||
290 | vpn->proto = htons ((uint16_t) proto); | ||
291 | strcpy ((char*)&vpn[1], s_serv); | ||
292 | return GNUNET_OK; | ||
254 | } | 293 | } |
255 | *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; | 294 | case GNUNET_GNSRECORD_TYPE_BOX: |
256 | *data = vpn = GNUNET_malloc (*data_size); | ||
257 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, | ||
258 | strlen (s_peer), | ||
259 | &vpn->peer.public_key)) | ||
260 | { | 295 | { |
261 | GNUNET_free (vpn); | 296 | struct GNUNET_GNSRECORD_BoxRecord *box; |
262 | *data_size = 0; | 297 | size_t rest; |
263 | return GNUNET_SYSERR; | 298 | unsigned int protocol; |
299 | unsigned int service; | ||
300 | unsigned int record_type; | ||
301 | void *bval; | ||
302 | size_t bval_size; | ||
303 | |||
304 | if (3 != SSCANF (s, | ||
305 | "%u %u %u ", | ||
306 | &protocol, | ||
307 | &service, | ||
308 | &record_type)) | ||
309 | { | ||
310 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
311 | _("Unable to parse BOX record string `%s'\n"), | ||
312 | s); | ||
313 | return GNUNET_SYSERR; | ||
314 | } | ||
315 | rest = snprintf (NULL, 0, | ||
316 | "%u %u %u ", | ||
317 | protocol, | ||
318 | service, | ||
319 | record_type); | ||
320 | if (GNUNET_OK != | ||
321 | GNUNET_GNSRECORD_string_to_value (record_type, | ||
322 | &s[rest], | ||
323 | &bval, | ||
324 | &bval_size)) | ||
325 | return GNUNET_SYSERR; | ||
326 | *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; | ||
327 | *data = box = GNUNET_malloc (*data_size); | ||
328 | box->protocol = htons (protocol); | ||
329 | box->service = htons (service); | ||
330 | box->record_type = htonl (record_type); | ||
331 | GNUNET_memcpy (&box[1], | ||
332 | bval, | ||
333 | bval_size); | ||
334 | GNUNET_free (bval); | ||
335 | return GNUNET_OK; | ||
264 | } | 336 | } |
265 | vpn->proto = htons ((uint16_t) proto); | 337 | case GNUNET_GNSRECORD_TYPE_REVERSE: |
266 | strcpy ((char*)&vpn[1], s_serv); | ||
267 | return GNUNET_OK; | ||
268 | } | ||
269 | case GNUNET_GNSRECORD_TYPE_BOX: | ||
270 | { | ||
271 | struct GNUNET_GNSRECORD_BoxRecord *box; | ||
272 | size_t rest; | ||
273 | unsigned int protocol; | ||
274 | unsigned int service; | ||
275 | unsigned int record_type; | ||
276 | void *bval; | ||
277 | size_t bval_size; | ||
278 | |||
279 | if (3 != SSCANF (s, | ||
280 | "%u %u %u ", | ||
281 | &protocol, | ||
282 | &service, | ||
283 | &record_type)) | ||
284 | { | 338 | { |
285 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 339 | struct GNUNET_GNSRECORD_ReverseRecord *rev; |
286 | _("Unable to parse BOX record string `%s'\n"), | 340 | char known_by[253 + 1]; |
287 | s); | 341 | struct GNUNET_TIME_Absolute expiration; |
288 | return GNUNET_SYSERR; | 342 | |
343 | /* TODO: From crypto_ecc.c | ||
344 | * Why is this not a constant??? | ||
345 | */ | ||
346 | size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | ||
347 | if (enclen % 5 > 0) | ||
348 | enclen += 5 - enclen % 5; | ||
349 | enclen /= 5; /* 260/5 = 52 */ | ||
350 | char pkey_str[enclen + 1]; | ||
351 | |||
352 | if (3 != SSCANF (s, | ||
353 | "%253s %52s %"SCNu64, | ||
354 | known_by, | ||
355 | pkey_str, | ||
356 | &expiration.abs_value_us)) | ||
357 | { | ||
358 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
359 | _("Unable to parse REVERSE record string `%s'\n"), | ||
360 | s); | ||
361 | return GNUNET_SYSERR; | ||
362 | } | ||
363 | *data_size = sizeof (struct GNUNET_GNSRECORD_ReverseRecord) + strlen (known_by) + 1; | ||
364 | *data = rev = GNUNET_malloc (*data_size); | ||
365 | GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey_str, | ||
366 | strlen (pkey_str), | ||
367 | &rev->pkey); | ||
368 | rev->expiration = expiration; | ||
369 | GNUNET_memcpy (&rev[1], | ||
370 | known_by, | ||
371 | strlen (known_by)); | ||
372 | return GNUNET_OK; | ||
289 | } | 373 | } |
290 | rest = snprintf (NULL, 0, | 374 | default: |
291 | "%u %u %u ", | 375 | return GNUNET_SYSERR; |
292 | protocol, | ||
293 | service, | ||
294 | record_type); | ||
295 | if (GNUNET_OK != | ||
296 | GNUNET_GNSRECORD_string_to_value (record_type, | ||
297 | &s[rest], | ||
298 | &bval, | ||
299 | &bval_size)) | ||
300 | return GNUNET_SYSERR; | ||
301 | *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; | ||
302 | *data = box = GNUNET_malloc (*data_size); | ||
303 | box->protocol = htons (protocol); | ||
304 | box->service = htons (service); | ||
305 | box->record_type = htonl (record_type); | ||
306 | GNUNET_memcpy (&box[1], | ||
307 | bval, | ||
308 | bval_size); | ||
309 | GNUNET_free (bval); | ||
310 | return GNUNET_OK; | ||
311 | } | ||
312 | default: | ||
313 | return GNUNET_SYSERR; | ||
314 | } | 376 | } |
315 | } | 377 | } |
316 | 378 | ||
@@ -329,6 +391,7 @@ static struct { | |||
329 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, | 391 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, |
330 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, | 392 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, |
331 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, | 393 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, |
394 | { "REVERSE", GNUNET_GNSRECORD_TYPE_REVERSE }, | ||
332 | { NULL, UINT32_MAX } | 395 | { NULL, UINT32_MAX } |
333 | }; | 396 | }; |
334 | 397 | ||
@@ -348,7 +411,7 @@ gns_typename_to_number (void *cls, | |||
348 | 411 | ||
349 | i=0; | 412 | i=0; |
350 | while ( (NULL != gns_name_map[i].name) && | 413 | while ( (NULL != gns_name_map[i].name) && |
351 | (0 != strcasecmp (gns_typename, | 414 | (0 != strcasecmp (gns_typename, |
352 | gns_name_map[i].name)) ) | 415 | gns_name_map[i].name)) ) |
353 | i++; | 416 | i++; |
354 | return gns_name_map[i].number; | 417 | return gns_name_map[i].number; |
@@ -370,7 +433,7 @@ gns_number_to_typename (void *cls, | |||
370 | 433 | ||
371 | i=0; | 434 | i=0; |
372 | while ( (NULL != gns_name_map[i].name) && | 435 | while ( (NULL != gns_name_map[i].name) && |
373 | (type != gns_name_map[i].number) ) | 436 | (type != gns_name_map[i].number) ) |
374 | i++; | 437 | i++; |
375 | return gns_name_map[i].name; | 438 | return gns_name_map[i].name; |
376 | } | 439 | } |