1 /**
2  *
3  * \file util-internal.c
4  * @brief private library routines
5  *
6  * These routines are not intended to be used by applications calling into
7  * the library.
8  *
9  */
10 
11 /*
12  * Copyright (c) 2013, NLnet Labs, Verisign, Inc.
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions are met:
17  * * Redistributions of source code must retain the above copyright
18  *   notice, this list of conditions and the following disclaimer.
19  * * Redistributions in binary form must reproduce the above copyright
20  *   notice, this list of conditions and the following disclaimer in the
21  *   documentation and/or other materials provided with the distribution.
22  * * Neither the names of the copyright holders nor the
23  *   names of its contributors may be used to endorse or promote products
24  *   derived from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29  * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
30  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <stdint.h>
39 #include <stdlib.h>
40 #include "config.h"
41 #include "getdns/getdns.h"
42 #include "dict.h"
43 #include "list.h"
44 #include "util-internal.h"
45 #include "types-internal.h"
46 #include "rr-dict.h"
47 #if defined(WIRE_DEBUG) && WIRE_DEBUG
48 #include "gldns/wire2str.h"
49 #endif
50 #include "gldns/str2wire.h"
51 #include "gldns/gbuffer.h"
52 #include "gldns/pkthdr.h"
53 #include "dnssec.h"
54 
55 
56 getdns_return_t
getdns_dict_util_get_string(const getdns_dict * dict,const char * name,char ** result)57 getdns_dict_util_get_string(const getdns_dict *dict,
58     const char *name, char **result)
59 {
60 	struct getdns_bindata *bindata = NULL;
61 	if (!result) {
62 		return GETDNS_RETURN_GENERIC_ERROR;
63 	}
64 	*result = NULL;
65 	getdns_dict_get_bindata(dict, name, &bindata);
66 	if (!bindata) {
67 		return GETDNS_RETURN_GENERIC_ERROR;
68 	}
69 	*result = (char *) bindata->data;
70 	return GETDNS_RETURN_GOOD;
71 }
72 
73 getdns_return_t
_getdns_dict_to_sockaddr(struct getdns_dict * ns,struct sockaddr_storage * output)74 _getdns_dict_to_sockaddr(struct getdns_dict * ns, struct sockaddr_storage * output)
75 {
76 	char *address_type = NULL;
77 	struct getdns_bindata *address_data = NULL;
78 	uint32_t port = 53;
79 	memset(output, 0, sizeof(struct sockaddr_storage));
80 	output->ss_family = AF_UNSPEC;
81 
82 	uint32_t prt = 0;
83 	if (getdns_dict_get_int(ns, GETDNS_STR_PORT,
84 		&prt) == GETDNS_RETURN_GOOD) {
85 		port = prt;
86 	}
87 
88 	getdns_dict_util_get_string(ns, GETDNS_STR_ADDRESS_TYPE,
89 	    &address_type);
90 	getdns_dict_get_bindata(ns, GETDNS_STR_ADDRESS_DATA, &address_data);
91 	if (!address_type || !address_data) {
92 		return GETDNS_RETURN_GENERIC_ERROR;
93 	}
94 	if (strncmp(GETDNS_STR_IPV4, address_type,
95 		strlen(GETDNS_STR_IPV4)) == 0) {
96 		/* data is an in_addr_t */
97 		struct sockaddr_in *addr = (struct sockaddr_in *) output;
98 		addr->sin_family = AF_INET;
99 		addr->sin_port = htons((uint16_t) port);
100 		memcpy(&(addr->sin_addr), address_data->data,
101 		    address_data->size);
102 	} else {
103 		/* data is a v6 addr in host order */
104 		struct sockaddr_in6 *addr = (struct sockaddr_in6 *) output;
105 		addr->sin6_family = AF_INET6;
106 		addr->sin6_port = htons((uint16_t) port);
107 		memcpy(&(addr->sin6_addr), address_data->data,
108 		    address_data->size);
109 	}
110 	return GETDNS_RETURN_GOOD;
111 }
112 
113 getdns_return_t
_getdns_sockaddr_to_dict(struct getdns_context * context,struct sockaddr_storage * address,struct getdns_dict ** output)114 _getdns_sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage *address,
115     struct getdns_dict ** output)
116 {
117 	if (!output || !address) {
118 		return GETDNS_RETURN_GENERIC_ERROR;
119 	}
120 	struct getdns_bindata addr_data;
121 	*output = NULL;
122 	struct getdns_dict *result = getdns_dict_create_with_context(context);
123 	if (address->ss_family == AF_INET) {
124 		struct sockaddr_in *addr = (struct sockaddr_in *) address;
125 		getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE,
126 		    GETDNS_STR_IPV4);
127 		addr_data.size = sizeof(addr->sin_addr);
128 		addr_data.data = (uint8_t *) & (addr->sin_addr);
129 		getdns_dict_set_bindata(result, GETDNS_STR_ADDRESS_DATA,
130 		    &addr_data);
131 	} else if (address->ss_family == AF_INET6) {
132 		struct sockaddr_in6 *addr = (struct sockaddr_in6 *) address;
133 		getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE,
134 		    GETDNS_STR_IPV6);
135 		addr_data.size = sizeof(addr->sin6_addr);
136 		addr_data.data = (uint8_t *) & (addr->sin6_addr);
137 		getdns_dict_set_bindata(result, GETDNS_STR_ADDRESS_DATA,
138 		    &addr_data);
139 	} else {
140 		// invalid
141 		getdns_dict_destroy(result);
142 		return GETDNS_RETURN_GENERIC_ERROR;
143 	}
144 	*output = result;
145 	return GETDNS_RETURN_GOOD;
146 }
147 
148 getdns_dict *
_getdns_rr_iter2rr_dict_canonical(struct mem_funcs * mf,_getdns_rr_iter * i,uint32_t * orig_ttl)149 _getdns_rr_iter2rr_dict_canonical(
150     struct mem_funcs *mf, _getdns_rr_iter *i, uint32_t *orig_ttl)
151 {
152 	getdns_dict *rr_dict, *rdata_dict;
153 	const uint8_t *bin_data;
154 	size_t bin_size, owner_len = 0, rdata_sz;
155 	uint32_t int_val = 0;
156 	enum wf_data_type { wf_int, wf_bindata, wf_special } val_type;
157 	_getdns_rdf_iter rdf_storage, *rdf;
158 	getdns_list *repeat_list = NULL;
159 	getdns_dict *repeat_dict = NULL;
160 	uint8_t ff_bytes[256];
161 	uint16_t rr_type;
162 	int canonicalize;
163 	gldns_buffer gbuf;
164 	getdns_bindata *bindata;
165 	uint8_t *data;
166 
167 	assert(i);
168 	if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
169 		return NULL;
170 
171 	bin_data = _getdns_owner_if_or_as_decompressed(
172 	    i, ff_bytes, &bin_size);
173 
174 	if (orig_ttl) {
175 		if (bin_data != ff_bytes)
176 			bin_data = memcpy(ff_bytes, bin_data, bin_size);
177 		_dname_canonicalize2(ff_bytes);
178 		owner_len = bin_size;
179 	}
180 	/* question */
181 	if (_getdns_rr_iter_section(i) == SECTION_QUESTION) {
182 
183 		if (getdns_dict_set_int(rr_dict, "qtype",
184 		    (uint32_t) gldns_read_uint16(i->rr_type)) ||
185 
186 		    getdns_dict_set_int(rr_dict, "qclass",
187 		    (uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
188 
189 		    _getdns_dict_set_const_bindata(
190 		    rr_dict, "qname", bin_size, bin_data)) {
191 
192 			goto error;
193 		}
194 		return rr_dict;
195 	}
196 	if (getdns_dict_set_int(rr_dict, "type",
197 	    (uint32_t)(rr_type = gldns_read_uint16(i->rr_type)))) {
198 
199 		goto error;
200 	}
201 	canonicalize = orig_ttl && _dnssec_rdata_to_canonicalize(rr_type)
202 	    && (i->rr_type + 12 <= i->nxt) /* To estimate rdata size */;
203 
204 	if (rr_type == GETDNS_RRTYPE_OPT) {
205 		int_val = gldns_read_uint16(i->rr_type + 6);
206 
207 		if (getdns_dict_set_int(rr_dict, "udp_payload_size",
208 		    (uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
209 
210 		    getdns_dict_set_int(rr_dict, "extended_rcode",
211 		    (uint32_t) *(i->rr_type + 4)) ||
212 
213 		    getdns_dict_set_int(rr_dict, "version",
214 		    (uint32_t) *(i->rr_type + 5)) ||
215 
216 		    getdns_dict_set_int(rr_dict, "do",
217 		    (uint32_t) ((int_val & 0x8000) >> 15)) ||
218 
219 		    getdns_dict_set_int(rr_dict, "z",
220 		    (uint32_t) (int_val & 0x7FF))) {
221 
222 			goto error;
223 		}
224 	} else if (getdns_dict_set_int(rr_dict, "class",
225 	    (uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
226 
227 	    getdns_dict_set_int(rr_dict, "ttl",
228 	    (  orig_ttl && rr_type != GETDNS_RRTYPE_RRSIG
229 	    ? *orig_ttl : (uint32_t) gldns_read_uint32(i->rr_type + 4))) ||
230 
231 	    _getdns_dict_set_const_bindata(
232 	    rr_dict, "name", bin_size, bin_data)) {
233 
234 		goto error;
235 	}
236 	if (!(rdata_dict = _getdns_dict_create_with_mf(mf)))
237 		return NULL;
238 
239 	if (i->rr_type + 10 <= i->nxt && !canonicalize) {
240 		bin_size = i->nxt - (i->rr_type + 10);
241 		bin_data = i->rr_type + 10;
242 		if (_getdns_dict_set_const_bindata(
243 		    rdata_dict, "rdata_raw", bin_size, bin_data))
244 			goto rdata_error;
245 	}
246 	if (canonicalize)
247 		rdata_sz = 0;
248 
249 	for ( rdf = _getdns_rdf_iter_init(&rdf_storage, i)
250 	    ; rdf; rdf = _getdns_rdf_iter_next(rdf)) {
251 		if (canonicalize && !(rdf->rdd_pos->type & GETDNS_RDF_DNAME)) {
252 			rdata_sz += rdf->nxt - rdf->pos;
253 		}
254 		if (rdf->rdd_pos->type & GETDNS_RDF_INTEGER) {
255 			val_type = wf_int;
256 			switch (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) {
257 			case 1:	int_val = *rdf->pos;
258 				break;
259 			case 2:	int_val = gldns_read_uint16(rdf->pos);
260 				break;
261 			case 4:	int_val = gldns_read_uint32(rdf->pos);
262 				break;
263 			default:
264 				goto rdata_error;
265 			}
266 		} else if (rdf->rdd_pos->type & GETDNS_RDF_DNAME) {
267 			val_type = wf_bindata;
268 
269 			bin_data = _getdns_rdf_if_or_as_decompressed(
270 			    rdf, ff_bytes, &bin_size);
271 
272 			if (canonicalize) {
273 				if (bin_data != ff_bytes)
274 					bin_data = memcpy(ff_bytes, bin_data, bin_size);
275 				_dname_canonicalize2(ff_bytes);
276 				rdata_sz += bin_size;
277 			}
278 		} else if (rdf->rdd_pos->type & GETDNS_RDF_BINDATA) {
279 			val_type = wf_bindata;
280 			if (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) {
281 				bin_size = rdf->rdd_pos->type
282 				    & GETDNS_RDF_FIXEDSZ;
283 				bin_data = rdf->pos;
284 
285 			} else switch(rdf->rdd_pos->type & GETDNS_RDF_LEN_VAL){
286 			case 0x100:
287 				bin_size = *rdf->pos;
288 				bin_data = rdf->pos + 1;
289 				break;
290 			case 0x200:
291 				bin_size = gldns_read_uint16(rdf->pos);
292 				bin_data = rdf->pos + 2;
293 				break;
294 			default:
295 				bin_size = rdf->nxt - rdf->pos;
296 				bin_data = rdf->pos;
297 				break;
298 			}
299 		} else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL)
300 			val_type = wf_special;
301 		else
302 			assert(((val_type = wf_int), 0));
303 
304 		if (! rdf->rdd_repeat) {
305 			switch (val_type) {
306 			case wf_int:
307 				if (getdns_dict_set_int(rdata_dict,
308 				    rdf->rdd_pos->name, int_val))
309 					goto rdata_error;
310 				break;
311 			case wf_bindata:
312 				if (_getdns_dict_set_const_bindata(rdata_dict,
313 				    rdf->rdd_pos->name, bin_size, bin_data))
314 					goto rdata_error;
315 				break;
316 			case wf_special:
317 				if (rdf->rdd_pos->special->wire2dict(
318 				    rdata_dict, rdf->pos))
319 					goto rdata_error;
320 			default:
321 				break;
322 			}
323 			continue;
324 		}
325 		if (rdf->rdd_pos == rdf->rdd_repeat) {
326 			/* list with rdf values */
327 
328 			if (! repeat_list && !(repeat_list =
329 			    _getdns_list_create_with_mf(mf)))
330 
331 				goto rdata_error;
332 
333 			switch (val_type) {
334 			case wf_int:
335 				if (_getdns_list_append_int(repeat_list,
336 				    int_val))
337 					goto rdata_error;
338 				break;
339 			case wf_bindata:
340 				if (_getdns_list_append_const_bindata(
341 				    repeat_list, bin_size, bin_data))
342 					goto rdata_error;
343 				break;
344 
345 			/* Repetitive special types do not exist (yet)
346 			 *
347 			 * LCOV_EXCL_START
348 			 */
349 			case wf_special:
350 				/* Repetitive special types
351 				 * must have this function
352 				 */
353 				assert(rdf->rdd_pos->special->wire2list);
354 
355 				if (rdf->rdd_pos->special->wire2list(
356 				    repeat_list, rdf->pos))
357 					goto rdata_error;
358 			/* LCOV_EXCL_STOP */
359 
360 			default:
361 				break;
362 			}
363 			continue;
364 		}
365 		if (rdf->rdd_pos == rdf->rdd_repeat + 1) {
366 
367 			if (repeat_dict) {
368 				if (! repeat_list && !(repeat_list =
369 				    _getdns_list_create_with_mf(mf)))
370 					goto rdata_error;
371 
372 				if (_getdns_list_append_this_dict(
373 				    repeat_list, repeat_dict))
374 					goto rdata_error;
375 
376 				repeat_dict = NULL;
377 			}
378 			if (!(repeat_dict =
379 			    _getdns_dict_create_with_mf(mf)))
380 				goto rdata_error;
381 		}
382 		assert(repeat_dict);
383 		switch (val_type) {
384 		case wf_int:
385 			if (getdns_dict_set_int(repeat_dict,
386 			    rdf->rdd_pos->name, int_val))
387 				goto rdata_error;
388 			break;
389 		case wf_bindata:
390 			if (_getdns_dict_set_const_bindata(repeat_dict,
391 			    rdf->rdd_pos->name, bin_size, bin_data))
392 				goto rdata_error;
393 			break;
394 		case wf_special:
395 			if (rdf->rdd_pos->special->wire2dict(
396 			    repeat_dict, rdf->pos))
397 				goto rdata_error;
398 		default:
399 			break;
400 		}
401 	}
402 	if (repeat_dict) {
403 		if (!repeat_list && !(repeat_list =
404 		    _getdns_list_create_with_mf(mf)))
405 			goto rdata_error;
406 		if (_getdns_list_append_this_dict(repeat_list, repeat_dict))
407 			goto rdata_error;
408 		repeat_dict = NULL;
409 	}
410 	if (repeat_list) {
411 		if (_getdns_dict_set_this_list(rdata_dict,
412 		    rdf_storage.rdd_repeat->name, repeat_list))
413 			goto rdata_error;
414 		repeat_list = NULL;
415 	}
416 	if (_getdns_dict_set_this_dict(rr_dict, "rdata", rdata_dict))
417 		goto rdata_error;
418 
419 	if (canonicalize && rdata_sz) {
420 		if (!(data = GETDNS_XMALLOC(
421 		    *mf, uint8_t, owner_len + 10 + rdata_sz)))
422 			return rr_dict;
423 
424 		gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz);
425 		if (_getdns_rr_dict2wire(rr_dict, &gbuf) ||
426 		    gldns_buffer_position(&gbuf) != owner_len + 10 + rdata_sz ||
427 		    !(bindata = GETDNS_MALLOC(*mf, struct getdns_bindata))) {
428 			GETDNS_FREE(*mf, data);
429 			return rr_dict;
430 		}
431 		bindata->size = rdata_sz;
432 		bindata->data = memmove(data, data + owner_len + 10, rdata_sz);
433 		(void) _getdns_dict_set_this_bindata(rr_dict,
434 		    "/rdata/rdata_raw", bindata);
435 	}
436 	return rr_dict;
437 
438 rdata_error:
439 	getdns_list_destroy(repeat_list);
440 	getdns_dict_destroy(repeat_dict);
441 	getdns_dict_destroy(rdata_dict);
442 error:
443 	getdns_dict_destroy(rr_dict);
444 	return NULL;
445 }
446 
447 getdns_dict *
_getdns_rr_iter2rr_dict(struct mem_funcs * mf,_getdns_rr_iter * i)448 _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
449 {
450 	return _getdns_rr_iter2rr_dict_canonical(mf, i, NULL);
451 }
452 
453 
454 static inline getdns_dict *
set_dict(getdns_dict ** var,getdns_dict * value)455 set_dict(getdns_dict **var, getdns_dict *value)
456 {
457 	if (*var)
458 		getdns_dict_destroy(*var);
459 	return *var = value;
460 }
461 
has_all_numeric_label(const uint8_t * dname)462 static inline int has_all_numeric_label(const uint8_t *dname)
463 {
464 	size_t i;
465 
466 	while (*dname && !(*dname & 0xc0)) {
467 		for (i = 1; i <= *dname; i++) {
468 			if (!isdigit(dname[i]))
469 				break;
470 		}
471 		if (i > *dname)
472 			return 1;
473 		dname += *dname + 1;
474 	}
475 	return 0;
476 }
477 
478 typedef struct _srv_rr {
479 	_getdns_rr_iter i;
480 	unsigned        running_sum;
481 } _srv_rr;
482 
483 typedef struct _srvs {
484 	size_t  capacity;
485 	size_t  count;
486 	_srv_rr *rrs;
487 } _srvs;
488 
_grow_srvs(struct mem_funcs * mf,_srvs * srvs)489 static int _grow_srvs(struct mem_funcs *mf, _srvs *srvs)
490 {
491 	_srv_rr *new_rrs;
492 
493 	if (!(new_rrs = GETDNS_XREALLOC(
494 	    *mf, srvs->rrs, _srv_rr, srvs->capacity * 2)))
495 		return 0; /* Memory error */
496 
497 	srvs->capacity *= 2;
498 	srvs->rrs = new_rrs;
499 	return 1; /* Success */
500 }
501 
502 #define SET_WIRE_INT(X,Y) if (getdns_dict_set_int(header, #X , (int) \
503                               GLDNS_ ## Y ## _WIRE(req->response))) goto error
504 #define SET_WIRE_BIT(X,Y) if (getdns_dict_set_int(header, #X , \
505                               GLDNS_ ## Y ## _WIRE(req->response) ? 1 : 0)) goto error
506 #define SET_WIRE_CNT(X,Y) if (getdns_dict_set_int(header, #X , (int) \
507                               GLDNS_ ## Y (req->response))) goto error
508 
509 static getdns_dict *
_getdns_create_reply_dict(getdns_context * context,getdns_network_req * req,getdns_list * just_addrs,int * rrsigs_in_answer,_srvs * srvs)510 _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
511     getdns_list *just_addrs, int *rrsigs_in_answer, _srvs *srvs)
512 {
513 	/* turn a packet into this glorious structure
514 	 *
515 	 * {     # This is the first reply
516 	 * "header": { "id": 23456, "qr": 1, "opcode": 0, ... },
517 	 * "question": { "qname": <bindata for "www.example.com">, "qtype": 1, "qclass": 1 },
518 	 * "answer":
519 	 * [
520 	 * {
521 	 * "name": <bindata for "www.example.com">,
522 	 * "type": 1,
523 	 * "class": 1,
524 	 * "ttl": 33000,
525 	 * "rdata":
526 	 * {
527 	 * "ipv4_address": <bindata of 0x0a0b0c01>
528 	 * "rdata_raw": <bindata of 0x0a0b0c01>
529 	 * }
530 	 * }
531 	 * ],
532 	 * "authority":
533 	 * [
534 	 * {
535 	 * "name": <bindata for "ns1.example.com">,
536 	 * "type": 1,
537 	 * "class": 1,
538 	 * "ttl": 600,
539 	 * "rdata":
540 	 * {
541 	 * "ipv4_address": <bindata of 0x65439876>
542 	 * "rdata_raw": <bindata of 0x65439876>
543 	 * }
544 	 * }
545 	 * ]
546 	 * "additional": [],
547 	 * "canonical_name": <bindata for "www.example.com">,
548 	 * "answer_type": GETDNS_NAMETYPE_DNS
549 	 * }
550 	 *
551 	 */
552 	getdns_return_t r = GETDNS_RETURN_GOOD;
553 	getdns_dict *result = getdns_dict_create_with_context(context);
554 	getdns_dict *question = NULL;
555 	getdns_list *sections[16] = { NULL, NULL
556 	                            , getdns_list_create_with_context(context)
557 	                            , NULL
558 	                            , getdns_list_create_with_context(context)
559 				    , NULL, NULL, NULL
560 	                            , getdns_list_create_with_context(context)
561 				    , NULL, NULL, NULL, NULL, NULL, NULL, NULL
562 	                            };
563 	getdns_dict *rr_dict = NULL;
564 	_getdns_rr_iter rr_iter_storage, *rr_iter;
565 	_getdns_rdf_iter rdf_iter_storage, *rdf_iter;
566 	size_t bin_size;
567 	const uint8_t *bin_data;
568 	_getdns_section section;
569 	uint8_t owner_name_space[256], query_name_space[256];
570 	const uint8_t *owner_name, *query_name;
571 	size_t owner_name_len = sizeof(owner_name_space),
572 	       query_name_len = sizeof(query_name_space);
573 	int all_numeric_label;
574 	uint16_t rr_type;
575 	getdns_dict *header = NULL;
576 	getdns_list *bad_dns = NULL;
577 	_getdns_rrset_spc answer_spc;
578 	_getdns_rrset *answer;
579 
580 	if (!result)
581 		goto error;
582 
583 	if (!(header = getdns_dict_create_with_context(context)))
584 		goto error;
585 
586 	SET_WIRE_INT(id, ID);
587 	SET_WIRE_BIT(qr, QR);
588 	SET_WIRE_BIT(aa, AA);
589 	SET_WIRE_BIT(tc, TC);
590 	SET_WIRE_BIT(rd, RD);
591 	SET_WIRE_BIT(cd, CD);
592 	SET_WIRE_BIT(ra, RA);
593 	SET_WIRE_BIT(ad, AD);
594 	SET_WIRE_INT(opcode, OPCODE);
595 	SET_WIRE_INT(rcode, RCODE);
596 	SET_WIRE_BIT(z, Z);
597 
598 	SET_WIRE_CNT(qdcount, QDCOUNT);
599 	SET_WIRE_CNT(ancount, ANCOUNT);
600 	SET_WIRE_CNT(nscount, NSCOUNT);
601 	SET_WIRE_CNT(arcount, ARCOUNT);
602 
603 	/* header */
604     	if ((r = _getdns_dict_set_this_dict(result, "header", header)))
605 		goto error;
606 	header = NULL;
607 
608 	if (req->query &&
609 	    (rr_iter = _getdns_rr_iter_init(&rr_iter_storage, req->query
610 	                                   , req->response  - req->query)))
611 
612 		query_name = _getdns_owner_if_or_as_decompressed(
613 		    rr_iter, query_name_space, &query_name_len);
614 	else
615 		query_name = NULL;
616 
617 	for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
618 	                                        , req->response
619 	                                        , req->response_len)
620 	    ; rr_iter
621 	    ; rr_iter = _getdns_rr_iter_next(rr_iter)) {
622 
623 		if (!set_dict(&rr_dict,
624 		    _getdns_rr_iter2rr_dict(&context->mf, rr_iter)))
625 			continue;
626 
627 		section = _getdns_rr_iter_section(rr_iter);
628 		if (section == SECTION_QUESTION) {
629 			if (!query_name)
630 				query_name
631 				    = _getdns_owner_if_or_as_decompressed(
632 				    rr_iter, query_name_space, &query_name_len);
633 
634 			if (_getdns_dict_set_this_dict(result, "question", rr_dict))
635 				goto error;
636 			else 	rr_dict = NULL;
637 			continue;
638 		}
639 		rr_type = gldns_read_uint16(rr_iter->rr_type);
640 		if (section > SECTION_QUESTION &&
641 		    rr_type == GETDNS_RRTYPE_RRSIG && rrsigs_in_answer)
642 			*rrsigs_in_answer = 1;
643 
644 		if (section != SECTION_ANSWER) {
645 			if (_getdns_list_append_this_dict(
646 			    sections[section], rr_dict))
647 				goto error;
648 			else	rr_dict = NULL;
649 			continue;
650 		}
651 		if (req->follow_redirects == GETDNS_REDIRECTS_DO_NOT_FOLLOW) {
652 			owner_name_len = sizeof(owner_name_space);
653 			owner_name = _getdns_owner_if_or_as_decompressed(
654 			    rr_iter, owner_name_space, &owner_name_len);
655 
656 			if (!_getdns_dname_equal(query_name, owner_name))
657 				continue;
658 		}
659 		if (_getdns_list_append_this_dict(
660 		    sections[SECTION_ANSWER], rr_dict))
661 			goto error;
662 		else	rr_dict = NULL;
663 
664 		if (srvs->capacity && rr_type == GETDNS_RRTYPE_SRV) {
665 			if (srvs->count >= srvs->capacity &&
666 			    !_grow_srvs(&context->mf, srvs))
667 				goto error;
668 
669 			srvs->rrs[srvs->count++].i = *rr_iter;
670 			continue;
671 		}
672 		if (rr_type != GETDNS_RRTYPE_A && rr_type != GETDNS_RRTYPE_AAAA)
673 			continue;
674 
675 		if (!just_addrs)
676 			continue;
677 
678 		if (!(rdf_iter = _getdns_rdf_iter_init(
679 		     &rdf_iter_storage, rr_iter)))
680 			continue;
681 
682 		bin_size = rdf_iter->nxt - rdf_iter->pos;
683 		bin_data = rdf_iter->pos;
684 		if (!set_dict(&rr_dict, getdns_dict_create_with_context(context)) ||
685 
686 		    getdns_dict_util_set_string(rr_dict, "address_type",
687 			    rr_type == GETDNS_RRTYPE_A ? "IPv4" : "IPv6" ) ||
688 
689 		    _getdns_dict_set_const_bindata(
690 		    rr_dict, "address_data", bin_size, bin_data) ||
691 
692 		    _getdns_list_append_this_dict(just_addrs, rr_dict)) {
693 
694 			goto error;
695 		}
696 		rr_dict = NULL;
697 	}
698 	if (!_getdns_dict_set_this_list(result, "answer",
699 	    sections[SECTION_ANSWER]))
700 		sections[SECTION_ANSWER] = NULL;
701 	else	goto error;
702 
703 	if (!_getdns_dict_set_this_list(result, "authority",
704 	    sections[SECTION_AUTHORITY]))
705 		sections[SECTION_AUTHORITY] = NULL;
706 	else	goto error;
707 
708 	if (!_getdns_dict_set_this_list(result, "additional",
709 	    sections[SECTION_ADDITIONAL]))
710 		sections[SECTION_ADDITIONAL] = NULL;
711 	else	goto error;
712 
713 	/* other stuff
714 	 * Note that spec doesn't explicitly mention these.
715 	 * They are only showcased in the response dict example */
716 	if (getdns_dict_set_int(result, "answer_type", GETDNS_NAMETYPE_DNS))
717 		goto error;
718 
719 	answer = _getdns_rrset_answer(&answer_spc, req->response
720 	                                         , req->response_len);
721 
722 	if (answer_spc.rrset.name &&
723 	    _getdns_dict_set_const_bindata(result, "canonical_name"
724 	                                         , answer_spc.name_len
725 	                                         , answer_spc.rrset.name))
726 		goto error;
727 
728 	if (!req->owner->add_warning_for_bad_dns)
729 		goto success;
730 
731 	if (!(bad_dns = getdns_list_create_with_context(context)))
732 		goto error;
733 
734 	if (   !answer
735 	    && req->request_type != GETDNS_RRTYPE_CNAME
736 	    && query_name
737 	    && answer_spc.rrset.name
738 	    && !_getdns_dname_equal(query_name, answer_spc.rrset.name)
739 	    && _getdns_list_append_int(bad_dns
740 		    , GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE))
741 		goto error;
742 
743 	all_numeric_label = 0;
744 	for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
745 					    , req->response
746 					    , req->response_len)
747 	    ; rr_iter && !all_numeric_label
748 	    ; rr_iter = _getdns_rr_iter_next(rr_iter)) {
749 
750 		owner_name = _getdns_owner_if_or_as_decompressed(
751 		    rr_iter, owner_name_space, &owner_name_len);
752 
753 		if (has_all_numeric_label(owner_name)) {
754 			all_numeric_label = 1;
755 			break;
756 		}
757 		if (_getdns_rr_iter_section(rr_iter) ==
758 		    SECTION_QUESTION)
759 			continue;
760 
761 		for ( rdf_iter = _getdns_rdf_iter_init(&rdf_iter_storage, rr_iter)
762 		    ; rdf_iter; rdf_iter = _getdns_rdf_iter_next(rdf_iter)) {
763 
764 			if (!(rdf_iter->rdd_pos->type & GETDNS_RDF_DNAME))
765 				continue;
766 
767 			owner_name = _getdns_rdf_if_or_as_decompressed(
768 			    rdf_iter, owner_name_space, &owner_name_len);
769 
770 			if (has_all_numeric_label(owner_name)) {
771 				all_numeric_label = 1;
772 				break;
773 			}
774 		}
775 	}
776 	if (all_numeric_label &&
777 	    _getdns_list_append_int(bad_dns, GETDNS_BAD_DNS_ALL_NUMERIC_LABEL))
778 		goto error;
779 
780 	if (_getdns_dict_set_this_list(result, "bad_dns", bad_dns))
781 		goto error;
782 	else	bad_dns = NULL;
783 
784 	goto success;
785 error:
786 	getdns_dict_destroy(result);
787 	result = NULL;
788 success:
789 	getdns_dict_destroy(header);
790 	getdns_dict_destroy(rr_dict);
791 	getdns_list_destroy(sections[SECTION_ADDITIONAL]);
792 	getdns_list_destroy(sections[SECTION_AUTHORITY]);
793 	getdns_list_destroy(sections[SECTION_ANSWER]);
794 	getdns_dict_destroy(question);
795 	getdns_list_destroy(bad_dns);
796 	return result;
797 }
798 
799 static getdns_dict *
_getdns_create_call_reporting_dict(getdns_context * context,getdns_network_req * netreq)800 _getdns_create_call_reporting_dict(
801     getdns_context *context, getdns_network_req *netreq)
802 {
803 	getdns_bindata  qname;
804 	getdns_dict    *netreq_debug;
805 	getdns_dict    *address_debug = NULL;
806 
807 	assert(netreq);
808 
809 	/* It is the responsibility of the caller to free this */
810 	if (!(netreq_debug = getdns_dict_create_with_context(context)))
811 		return NULL;
812 
813 	qname.data = netreq->owner->name;
814 	qname.size = netreq->owner->name_len;
815 
816 	if (getdns_dict_set_bindata(netreq_debug, "query_name", &qname) ||
817 	    getdns_dict_set_int( netreq_debug, "query_type"
818 	                       , netreq->request_type ) ||
819 
820 	    /* Safe, because uint32_t facilitates RRT's of almost 50 days*/
821 	    getdns_dict_set_int(netreq_debug, "run_time/ms",
822 		    (uint32_t)(( netreq->debug_end_time
823 	                       - netreq->debug_start_time)/1000))) {
824 
825 		getdns_dict_destroy(netreq_debug);
826 		return NULL;
827 
828 	} else if (!netreq->upstream) {
829 		if (getdns_dict_set_int( netreq_debug, "resolution_type", GETDNS_RESOLUTION_RECURSING)) {
830 			getdns_dict_destroy(netreq_debug);
831 			return NULL;
832 		}
833 		/* Nothing more for full recursion */
834 		return netreq_debug;
835 	}
836 
837 	if (getdns_dict_set_int( netreq_debug, "resolution_type", GETDNS_RESOLUTION_STUB)) {
838 		getdns_dict_destroy(netreq_debug);
839 		return NULL;
840 	}
841 	/* Stub resolver debug data */
842 	_getdns_sockaddr_to_dict(
843 	    context, &netreq->upstream->addr, &address_debug);
844 
845 	if (_getdns_dict_set_this_dict(netreq_debug,"query_to",address_debug)){
846 		getdns_dict_destroy(address_debug);
847 		return NULL;
848 	}
849 	getdns_transport_list_t transport = netreq->upstream->transport;
850 	/* Same upstream is used for UDP and TCP, so netreq keeps track of what
851 	   was actually used for the last successful query.*/
852 	if (transport == GETDNS_TRANSPORT_TCP && netreq->debug_udp == 1) {
853 		transport = GETDNS_TRANSPORT_UDP;
854 		if (getdns_dict_set_int( netreq_debug, "udp_responses_for_this_upstream",
855 		                         netreq->upstream->udp_responses)) {
856 			getdns_dict_destroy(netreq_debug);
857 			return NULL;
858 		}
859 		if (getdns_dict_set_int( netreq_debug, "udp_timeouts_for_this_upstream",
860 		                         netreq->upstream->udp_timeouts)) {
861 			getdns_dict_destroy(netreq_debug);
862 			return NULL;
863 		}
864 	}
865 	if (getdns_dict_set_int( netreq_debug, "transport", transport)) {
866 		getdns_dict_destroy(netreq_debug);
867 		return NULL;
868 	}
869 	if (transport != GETDNS_TRANSPORT_UDP) {
870 		/* Report the idle timeout actually used on the connection. Must trim,
871 		maximum used in practice is 6553500ms, but this is stored in a uint64_t.*/
872 		if (netreq->upstream->keepalive_timeout > UINT32_MAX) {
873 			if (getdns_dict_set_int( netreq_debug, "idle timeout in ms (overflow)", UINT32_MAX)) {
874 				getdns_dict_destroy(netreq_debug);
875 				return NULL;
876 			}
877 		} else{
878 			uint32_t idle_timeout = (uint32_t) netreq->upstream->keepalive_timeout;
879 			if (getdns_dict_set_int( netreq_debug, "idle timeout in ms", idle_timeout)) {
880 				getdns_dict_destroy(netreq_debug);
881 				return NULL;
882 			}
883 		}
884 		if (getdns_dict_set_int( netreq_debug, "server_keepalive_received", netreq->upstream->server_keepalive_received)) {
885 			getdns_dict_destroy(netreq_debug);
886 			return NULL;
887 		}
888 		/* The running totals are only updated when a connection is closed.
889 		   Since it is open as we have just used it, calcualte the value on the fly */
890 		if (getdns_dict_set_int( netreq_debug, "responses_on_this_connection",
891 		                         netreq->upstream->responses_received)) {
892 			getdns_dict_destroy(netreq_debug);
893 			return NULL;
894 		}
895 		if (getdns_dict_set_int( netreq_debug, "timeouts_on_this_connection",
896 		                         netreq->upstream->responses_timeouts)) {
897 			getdns_dict_destroy(netreq_debug);
898 			return NULL;
899 		}
900 		if (getdns_dict_set_int( netreq_debug, "responses_for_this_upstream",
901 		                         netreq->upstream->responses_received +
902 		                         netreq->upstream->total_responses)) {
903 			getdns_dict_destroy(netreq_debug);
904 			return NULL;
905 		}
906 		if (getdns_dict_set_int( netreq_debug, "timeouts_for_this_upstream",
907 		                         netreq->upstream->responses_timeouts +
908 		                         netreq->upstream->total_timeouts)) {
909 			getdns_dict_destroy(netreq_debug);
910 			return NULL;
911 		}
912 	}
913 
914 	if (netreq->upstream->transport != GETDNS_TRANSPORT_TLS)
915 		return netreq_debug;
916 
917 	/* Only include the auth status if TLS was used */
918 	if (getdns_dict_util_set_string(netreq_debug, "tls_auth_status",
919 	    _getdns_auth_str(netreq->debug_tls_auth_status))){
920 
921 		getdns_dict_destroy(netreq_debug);
922 		return NULL;
923 	}
924 	if (getdns_dict_util_set_string(netreq_debug, "tls_version",
925 	    netreq->debug_tls_version)){
926 
927 		getdns_dict_destroy(netreq_debug);
928 		return NULL;
929 	}
930 	if (getdns_dict_set_bindata(netreq_debug, "tls_peer_cert",
931 	    &netreq->debug_tls_peer_cert)) {
932 
933 		getdns_dict_destroy(netreq_debug);
934 		return NULL;
935 	}
936 	netreq->debug_tls_peer_cert.size = 0;
937 	GETDNS_FREE(context->my_mf, netreq->debug_tls_peer_cert.data);
938 	netreq->debug_tls_peer_cert.data = NULL;
939 	return netreq_debug;
940 }
941 
_srv_prio(_getdns_rr_iter * x)942 static inline int _srv_prio(_getdns_rr_iter *x)
943 { return x->nxt < x->rr_type+12
944        ? 65536 : (int)gldns_read_uint16(x->rr_type+10); }
945 
_srv_weight(_getdns_rr_iter * x)946 static inline int _srv_weight(_getdns_rr_iter *x)
947 { return x->nxt < x->rr_type+14 ? 0 : (int)gldns_read_uint16(x->rr_type+12); }
948 
949 
_srv_cmp(const void * a,const void * b)950 static int _srv_cmp(const void *a, const void *b)
951 {
952 	return _srv_prio((_getdns_rr_iter *)a)
953 	     - _srv_prio((_getdns_rr_iter *)b);
954 }
955 
_rfc2782_sort(_srv_rr * start,_srv_rr * end)956 static void _rfc2782_sort(_srv_rr *start, _srv_rr *end)
957 {
958 	uint32_t running_sum, n;
959 	_srv_rr *i, *j, swap;
960 
961 	/* First move all SRVs with weight 0 to the beginning of the list */
962 
963 	for (i = start; i < end && _srv_weight(&i->i) == 0; i++)
964 		; /* pass */
965 
966 	for (j = i + 1; j < end; j++) {
967 		if (_srv_weight(&j->i) == 0) {
968 			swap = *i;
969 			*i = *j;
970 			*j = swap;
971 			i++;
972 		}
973 	}
974 	/* Now all SRVs are at the beginning, calculate running_sum */
975 	running_sum = 0;
976 	for (i = start; i < end; i++) {
977 		running_sum += _srv_weight(&i->i);
978 		i->running_sum = running_sum;
979 	}
980 	n = arc4random_uniform(running_sum);
981 	for (i = start; i < end; i++) {
982 		if (i->running_sum >= n)
983 			break;
984 	}
985 	if (i > start && i < end) {
986 		swap = *start;
987 		*start = *i;
988 		*i = swap;
989 		_rfc2782_sort(start + 1, end);
990 	}
991 }
992 
993 static getdns_list *
_create_srv_addrs(getdns_context * context,_srvs * srvs)994 _create_srv_addrs(getdns_context *context, _srvs *srvs)
995 {
996 	getdns_list *srv_addrs;
997 	size_t i, j;
998 
999 	qsort(srvs->rrs, srvs->count, sizeof(_srv_rr), _srv_cmp);
1000 	/* The SRVs are now sorted by priority (lowest first).  Now determine
1001 	 * server selection order for the SRVs with the same priority with
1002 	 * the algorithm described in RFC2782:
1003 	 *
1004 	 *   To select a target to be contacted next, arrange all SRV RRs
1005 	 *   (that have not been ordered yet) in any order, except that all
1006 	 *   those with weight 0 are placed at the beginning of the list.
1007 	 *
1008 	 *   Compute the sum of the weights of those RRs, and with each RR
1009 	 *   associate the running sum in the selected order. Then choose a
1010 	 *   uniform random number between 0 and the sum computed
1011 	 *   (inclusive), and select the RR whose running sum value is the
1012 	 *   first in the selected order which is greater than or equal to
1013 	 *   the random number selected. The target host specified in the
1014 	 *   selected SRV RR is the next one to be contacted by the client.
1015 	 *   Remove this SRV RR from the set of the unordered SRV RRs and
1016 	 *   apply the described algorithm to the unordered SRV RRs to select
1017 	 *   the next target host.  Continue the ordering process until there
1018 	 *   are no unordered SRV RRs.  This process is repeated for each
1019 	 *   Priority.
1020 	 */
1021 	for (i = 0; i < srvs->count; i = j) {
1022 		/* Determine range of SRVs with same priority */
1023 		for ( j = i + 1
1024 		    ; j < srvs->count && _srv_prio(&srvs->rrs[i].i)
1025 		                      == _srv_prio(&srvs->rrs[j].i)
1026 		    ; j++)
1027 			; /* pass */
1028 
1029 		if (j == i + 1)
1030 			continue;
1031 
1032 		/* SRVs with same prio range from i till j (exclusive). */
1033 		_rfc2782_sort(srvs->rrs + i, srvs->rrs + j);
1034 	}
1035 	if (!(srv_addrs = getdns_list_create_with_context(context)))
1036 		return NULL;
1037 
1038 	for (i = 0; i < srvs->count; i++) {
1039 		_getdns_rr_iter *rr = &srvs->rrs[i].i;
1040 		getdns_dict *d;
1041 		_getdns_rdf_iter rdf_storage, *rdf;
1042 
1043 		const uint8_t *dname;
1044 		uint8_t dname_spc[256];
1045 		size_t dname_sz = sizeof(dname_spc);
1046 
1047 		_getdns_rrset a;
1048 		_getdns_rrtype_iter a_rr_spc, *a_rr;
1049 		int addresses_found = 0;
1050 
1051 		if (   !(d = getdns_dict_create_with_context(context))
1052 		    || !(rdf = _getdns_rdf_iter_init_at(&rdf_storage, rr, 2))
1053 		    || !(rdf->rdd_pos->type & GETDNS_RDF_INTEGER)
1054 		    ||  (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) != 2
1055 		    || getdns_dict_set_int(d, "port", (uint32_t)
1056 		                           gldns_read_uint16(rdf->pos))
1057 
1058 		    || !(rdf = _getdns_rdf_iter_init_at(&rdf_storage, rr, 3))
1059 		    || !(rdf->rdd_pos->type & GETDNS_RDF_DNAME)
1060 		    || !(dname = _getdns_rdf_if_or_as_decompressed(
1061 				    rdf, dname_spc, &dname_sz))
1062 		    || _getdns_dict_set_const_bindata(
1063 			    d, "domain_name", dname_sz, dname)) {
1064 
1065 			/* error */
1066 			getdns_dict_destroy(d);
1067 			continue;
1068 		}
1069 
1070 		a.name = dname;
1071 		a.rr_class = rr_iter_class(rr);
1072 		a.rr_type = GETDNS_RRTYPE_AAAA;
1073 		a.pkt = rr->pkt;
1074 		a.pkt_len = rr->pkt_end - rr->pkt;
1075 		a.sections = SECTION_ADDITIONAL;
1076 
1077 		for ( a_rr = _getdns_rrtype_iter_init(&a_rr_spc, &a)
1078 		    ; a_rr ; a_rr = _getdns_rrtype_iter_next(a_rr)) {
1079 
1080 			if (   a_rr->rr_i.nxt - (a_rr->rr_i.rr_type + 10) == 16
1081 			    && !getdns_dict_util_set_string(
1082 					d, "address_type", "IPv6")
1083 			    && !_getdns_dict_set_const_bindata(
1084 					d, "address_data", 16,
1085 					a_rr->rr_i.rr_type + 10)
1086 			    && !_getdns_list_append_dict(srv_addrs, d))
1087 				addresses_found++;
1088 		}
1089 		a.rr_type = GETDNS_RRTYPE_A;
1090 
1091 		for ( a_rr = _getdns_rrtype_iter_init(&a_rr_spc, &a)
1092 		    ; a_rr ; a_rr = _getdns_rrtype_iter_next(a_rr)) {
1093 
1094 			if (   a_rr->rr_i.nxt - (a_rr->rr_i.rr_type + 10) ==4
1095 			    && !getdns_dict_util_set_string(
1096 					d, "address_type", "IPv4")
1097 			    && !_getdns_dict_set_const_bindata(
1098 					d, "address_data", 4,
1099 					a_rr->rr_i.rr_type + 10)
1100 			    && !_getdns_list_append_dict(srv_addrs, d))
1101 				addresses_found++;
1102 		}
1103 		if (   addresses_found
1104 		    || _getdns_list_append_this_dict(srv_addrs, d))
1105 			getdns_dict_destroy(d);
1106 	}
1107 	return srv_addrs;
1108 }
1109 
1110 getdns_dict *
_getdns_create_getdns_response(getdns_dns_req * completed_request)1111 _getdns_create_getdns_response(getdns_dns_req *completed_request)
1112 {
1113 	getdns_dict *result;
1114 	getdns_list *just_addrs = NULL;
1115 	getdns_list *srv_addrs = NULL;
1116 	getdns_list *replies_full;
1117 	getdns_list *replies_tree;
1118 	getdns_list *call_reporting = NULL;
1119 	getdns_network_req *netreq, **netreq_p;
1120 	int rrsigs_in_answer = 0;
1121 	getdns_dict *reply;
1122 	getdns_bindata *canonical_name = NULL;
1123 	int nreplies = 0, nanswers = 0;
1124 	int nsecure = 0, ninsecure = 0, nindeterminate = 0, nbogus = 0;
1125 	getdns_dict   *netreq_debug;
1126 	_srvs srvs = { 0, 0, NULL };
1127 	_getdns_rrset_spc answer_spc;
1128 
1129 	/* info (bools) about dns_req */
1130 	int dnssec_return_status;
1131 	getdns_context *context;
1132 
1133 	assert(completed_request);
1134 
1135 	context = completed_request->context;
1136 	if (!(result = getdns_dict_create_with_context(context)))
1137 		return NULL;
1138 
1139 	dnssec_return_status = completed_request->dnssec ||
1140 	                       completed_request->dnssec_return_status ||
1141 	                       completed_request->dnssec_return_only_secure ||
1142 	                       completed_request->dnssec_return_all_statuses
1143 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
1144 	                    || completed_request->dnssec_roadblock_avoidance
1145 #endif
1146 	                       ;
1147 
1148 	if (completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_A ||
1149 	    completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA)
1150 		just_addrs = getdns_list_create_with_context(
1151 		    completed_request->context);
1152 
1153 	else if (
1154 	    completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_SRV) {
1155 
1156 		srvs.capacity = 100;
1157 		if (!(srvs.rrs = GETDNS_XMALLOC(
1158 		    context->mf, _srv_rr, srvs.capacity))) {
1159 			srvs.capacity = 0;
1160 			goto error_free_result;
1161 		}
1162 	}
1163 	if (getdns_dict_set_int(result, GETDNS_STR_KEY_ANSWER_TYPE,
1164 	    GETDNS_NAMETYPE_DNS))
1165 		goto error_free_result;
1166 
1167 	if (!(replies_full = getdns_list_create_with_context(context)))
1168 		goto error_free_result;
1169 
1170 	if (!(replies_tree = getdns_list_create_with_context(context)))
1171 		goto error_free_replies_full;
1172 
1173 	if (completed_request->return_call_reporting &&
1174 	    !(call_reporting = getdns_list_create_with_context(context)))
1175 		goto error_free_replies_full;
1176 
1177 	for ( netreq_p = completed_request->netreqs
1178 	    ; (netreq = *netreq_p) ; netreq_p++) {
1179 
1180 		if (call_reporting && (  netreq->response_len
1181 		                      || netreq->state == NET_REQ_TIMED_OUT)) {
1182 			if (!(netreq_debug =
1183 			   _getdns_create_call_reporting_dict(context,netreq)))
1184 				goto error;
1185 
1186 			if (_getdns_list_append_this_dict(
1187 			    call_reporting, netreq_debug))
1188 				goto error;
1189 
1190 			netreq_debug = NULL;
1191 		}
1192 		if (! netreq->response_len)
1193 			continue;
1194 
1195 		if (netreq->tsig_status == GETDNS_DNSSEC_INSECURE)
1196 			_getdns_network_validate_tsig(netreq);
1197 
1198 		nreplies++;
1199 		switch (netreq->dnssec_status) {
1200 		case GETDNS_DNSSEC_SECURE       : nsecure++;
1201 						  break;
1202 		case GETDNS_DNSSEC_INSECURE     : ninsecure++;
1203 						  break;
1204 		case GETDNS_DNSSEC_INDETERMINATE: nindeterminate++;
1205 						  ninsecure++;
1206 						  break;
1207 		case GETDNS_DNSSEC_BOGUS        : if (dnssec_return_status)
1208 							  nbogus++;
1209 						  break;
1210 		}
1211 		if (! completed_request->dnssec_return_all_statuses &&
1212 		    ! completed_request->dnssec_return_validation_chain) {
1213 			if (dnssec_return_status &&
1214 			    netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
1215 				continue;
1216 			else if (completed_request->dnssec_return_only_secure
1217 			    && netreq->dnssec_status != GETDNS_DNSSEC_SECURE)
1218 				continue;
1219 			else if (completed_request->dnssec &&
1220 			    netreq->dnssec_status == GETDNS_DNSSEC_INDETERMINATE)
1221 				continue;
1222 			else if (netreq->tsig_status == GETDNS_DNSSEC_BOGUS)
1223 				continue;
1224 		}
1225     		if (!(reply = _getdns_create_reply_dict(context,
1226 		    netreq, just_addrs, &rrsigs_in_answer, &srvs)))
1227 			goto error;
1228 
1229 		if (!canonical_name) {
1230 			if (!getdns_dict_get_bindata(
1231 			    reply, "canonical_name", &canonical_name) &&
1232 			    getdns_dict_set_bindata(
1233 			    result, "canonical_name", canonical_name))
1234 				goto error;
1235 		}
1236 		/* TODO: Check instead if canonical_name for request_type
1237 		 *       is in the answer section.
1238 		 */
1239 		if (_getdns_rrset_answer(&answer_spc, netreq->response
1240 		                                    , netreq->response_len))
1241 			nanswers++;
1242 
1243 		if (dnssec_return_status ||
1244 		    completed_request->dnssec_return_validation_chain) {
1245 
1246 			if (getdns_dict_set_int(reply, "dnssec_status",
1247 			    netreq->dnssec_status))
1248 				goto error;
1249 		}
1250 		if (netreq->tsig_status != GETDNS_DNSSEC_INDETERMINATE) {
1251 			if (getdns_dict_set_int(reply, "tsig_status",
1252 			    netreq->tsig_status))
1253 				goto error;
1254 		}
1255     		if (_getdns_list_append_this_dict(replies_tree, reply)) {
1256     			getdns_dict_destroy(reply);
1257 			goto error;
1258 		}
1259 		if (_getdns_list_append_const_bindata(replies_full,
1260 		    netreq->response_len, netreq->response))
1261 			goto error;
1262     	}
1263     	if (_getdns_dict_set_this_list(result, "replies_tree", replies_tree))
1264 		goto error;
1265 	replies_tree = NULL;
1266 
1267 	if (!canonical_name &&
1268 	    _getdns_dict_set_const_bindata(result, "canonical_name",
1269 		    completed_request->name_len, completed_request->name))
1270 		goto error;
1271 
1272 	if (call_reporting) {
1273 		if (_getdns_dict_set_this_list(
1274 		   result, "call_reporting", call_reporting))
1275 			goto error_free_call_reporting;
1276 		call_reporting = NULL;
1277 	}
1278 	if (_getdns_dict_set_this_list(result, "replies_full", replies_full))
1279 		goto error_free_replies_full;
1280 	replies_full = NULL;
1281 
1282 	if (just_addrs) {
1283 	       if (_getdns_dict_set_this_list(
1284 		    result, GETDNS_STR_KEY_JUST_ADDRS, just_addrs))
1285 			goto error_free_result;
1286 		just_addrs = NULL;
1287 	}
1288 	if (srvs.capacity) {
1289 		if (!(srv_addrs = _create_srv_addrs(context, &srvs)) ||
1290 		    _getdns_dict_set_this_list(
1291 		    result, "srv_addresses", srv_addrs))
1292 			goto error_free_result;
1293 
1294 		GETDNS_FREE(context->mf, srvs.rrs);
1295 	}
1296 	if (getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
1297 	    completed_request->request_timed_out ||
1298 	    nreplies == 0   ? GETDNS_RESPSTATUS_ALL_TIMEOUT :
1299 	    (  completed_request->dnssec
1300 	    && nsecure == 0 && nindeterminate ) > 0
1301 	                    ? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
1302 	    (  completed_request->dnssec_return_only_secure
1303 	    && nsecure == 0 && ninsecure ) > 0
1304 	                    ? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
1305 	    (  completed_request->dnssec_return_only_secure
1306 	    || completed_request->dnssec ) && nsecure == 0 && nbogus > 0
1307 	                    ? GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS :
1308 	    nanswers == 0   ? GETDNS_RESPSTATUS_NO_NAME
1309 	                    : GETDNS_RESPSTATUS_GOOD))
1310 		goto error_free_result;
1311 
1312 	return result;
1313 error:
1314 	/* cleanup */
1315 	getdns_list_destroy(replies_tree);
1316 error_free_call_reporting:
1317 	getdns_list_destroy(call_reporting);
1318 error_free_replies_full:
1319 	getdns_list_destroy(replies_full);
1320 error_free_result:
1321 	if (srvs.capacity)
1322 		GETDNS_FREE(context->mf, srvs.rrs);
1323 	getdns_list_destroy(srv_addrs);
1324 	getdns_list_destroy(just_addrs);
1325 	getdns_dict_destroy(result);
1326 	return NULL;
1327 }
1328 
1329 
1330 #ifdef HAVE_LIBUNBOUND
1331 getdns_return_t
getdns_apply_network_result(getdns_network_req * netreq,int rcode,void * pkt,int pkt_len,int sec,char * why_bogus)1332 getdns_apply_network_result(getdns_network_req* netreq,
1333     int rcode, void *pkt, int pkt_len, int sec, char* why_bogus)
1334 {
1335 	(void)why_bogus;
1336 
1337 	netreq->dnssec_status = sec == 0 ? GETDNS_DNSSEC_INSECURE
1338 	                      : sec == 2 ? GETDNS_DNSSEC_SECURE
1339 			      :            GETDNS_DNSSEC_BOGUS;
1340 
1341 	if (pkt) {
1342 		if (netreq->max_udp_payload_size < pkt_len)
1343 			netreq->response = GETDNS_XMALLOC(
1344 			    netreq->owner->context->mf,
1345 			    uint8_t, pkt_len
1346 			);
1347 		(void) memcpy(netreq->response, pkt,
1348 		    (netreq->response_len = pkt_len));
1349 		return GETDNS_RETURN_GOOD;
1350 	}
1351 
1352 	if (rcode == GETDNS_RCODE_SERVFAIL) {
1353 		/* Likely to be caused by timeout from a synchronous
1354 		 * lookup.  Don't forge a packet.
1355 		 */
1356 		return GETDNS_RETURN_GOOD;
1357 	}
1358 	/* Likely to be because libunbound refused the request
1359 	 * so ub_res->answer_packet=NULL, ub_res->answer_len=0
1360 	 * So we need to create an answer packet.
1361 	 */
1362 	gldns_write_uint16(netreq->response    , 0); /* query_id */
1363 	gldns_write_uint16(netreq->response + 2, 0); /* reset all flags */
1364 	gldns_write_uint16(netreq->response + GLDNS_QDCOUNT_OFF, 1);
1365 	gldns_write_uint16(netreq->response + GLDNS_ANCOUNT_OFF, 0);
1366 	gldns_write_uint16(netreq->response + GLDNS_NSCOUNT_OFF, 0);
1367 	gldns_write_uint16(netreq->response + GLDNS_ARCOUNT_OFF, 0);
1368 
1369 	GLDNS_OPCODE_SET(netreq->response, 3);
1370 	GLDNS_QR_SET(netreq->response);
1371 	GLDNS_RD_SET(netreq->response);
1372 	GLDNS_RA_SET(netreq->response);
1373 	GLDNS_RCODE_SET(netreq->response, rcode);
1374 
1375 	(void) memcpy( netreq->response + GLDNS_HEADER_SIZE
1376 	             , netreq->owner->name, netreq->owner->name_len);
1377 
1378 	gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
1379 	                                     + netreq->owner->name_len
1380 	                  , netreq->request_type);
1381 	gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
1382 	                                     + netreq->owner->name_len + 2
1383 	                  , netreq->owner->request_class);
1384 
1385 	netreq->response_len = GLDNS_HEADER_SIZE + netreq->owner->name_len + 4;
1386 
1387 	return GETDNS_RETURN_GOOD;
1388 }
1389 #endif
1390 
1391 
1392 getdns_return_t
_getdns_validate_dname(const char * dname)1393 _getdns_validate_dname(const char* dname) {
1394     int len;
1395     int label_len;
1396     const char* s;
1397     if (dname == NULL) {
1398         return GETDNS_RETURN_INVALID_PARAMETER;
1399     }
1400     len = strlen(dname);
1401     if (len > GETDNS_MAX_DNAME_LEN * 4 || len == 0) {
1402         return GETDNS_RETURN_BAD_DOMAIN_NAME;
1403     }
1404     if (len == 1 && dname[0] == '.') {
1405         /* root is ok */
1406         return GETDNS_RETURN_GOOD;
1407     }
1408 	/* By specification [RFC1035] the total length of a DNS label is
1409 	 * restricted to 63 octets and must be larger than 0 (except for the
1410 	 * final root-label).  The total length of a domain name (i.e., label
1411 	 * octets and label length octets) is restricted to 255 octets or less.
1412 	 * With a fully qualified domain name this includes the last label
1413 	 * length octet for the root label.  In a normalized representation the
1414 	 * number of labels (including the root) plus the number of octets in
1415 	 * each label may not be larger than 255.
1416 	 */
1417     len = 0;
1418     label_len = 0;
1419     for (s = dname; *s; ++s) {
1420         switch (*s) {
1421             case '.':
1422                 if (label_len > GETDNS_MAX_LABEL_LEN ||
1423                     label_len == 0) {
1424                     return GETDNS_RETURN_BAD_DOMAIN_NAME;
1425                 }
1426                 label_len = 0;
1427 		len += 1;
1428                 break;
1429 	    case '\\':
1430 		s += 1;
1431 		if (isdigit((unsigned char)s[0])) {
1432 			/* octet value */
1433 			if (! isdigit((unsigned char)s[1]) && ! isdigit((unsigned char)s[2]))
1434 				return GETDNS_RETURN_BAD_DOMAIN_NAME;
1435 
1436 			if ((s[0] - '0') * 100 +
1437 			    (s[1] - '0') * 10 + (s[2] - '0') > 255)
1438 				return GETDNS_RETURN_BAD_DOMAIN_NAME;
1439 
1440 			s += 2;
1441 		}
1442 		/* else literal char (1 octet) */
1443 		label_len++;
1444 		len += 1;
1445 		break;
1446             default:
1447                 label_len++;
1448 		len += 1;
1449                 break;
1450         }
1451     }
1452     if (len > GETDNS_MAX_DNAME_LEN || label_len > GETDNS_MAX_LABEL_LEN) {
1453         return GETDNS_RETURN_BAD_DOMAIN_NAME;
1454     }
1455     return GETDNS_RETURN_GOOD;
1456 } /* _getdns_validate_dname */
1457 
1458 
_getdns_reply2wire_buf(gldns_buffer * buf,const getdns_dict * reply)1459 static void _getdns_reply2wire_buf(gldns_buffer *buf, const getdns_dict *reply)
1460 {
1461 	getdns_dict *rr_dict, *q_dict, *h_dict;
1462 	getdns_list *section;
1463 	size_t i, pkt_start;
1464 	uint16_t ancount, nscount;
1465 	uint32_t qtype, qclass = GETDNS_RRCLASS_IN, rcode = GETDNS_RCODE_NOERROR;
1466 	getdns_bindata *qname;
1467 
1468 
1469 	pkt_start = gldns_buffer_position(buf);
1470 	/* Empty header */
1471 	gldns_buffer_write_u32(buf, 0);
1472 	gldns_buffer_write_u32(buf, 0);
1473 	gldns_buffer_write_u32(buf, 0);
1474 
1475 	if (   !getdns_dict_get_dict(reply, "question", &q_dict)
1476 	    && !getdns_dict_get_int(q_dict, "qtype", &qtype)
1477 	    && !getdns_dict_get_bindata(q_dict, "qname", &qname)) {
1478 
1479 		gldns_buffer_write(buf, qname->data, qname->size);
1480 		gldns_buffer_write_u16(buf, (uint16_t)qtype);
1481 		gldns_buffer_write_u16(buf, (uint16_t)qclass);
1482 		gldns_buffer_write_u16_at(
1483 		    buf, pkt_start + GLDNS_QDCOUNT_OFF, 1);
1484 	}
1485 
1486 	if (   !getdns_dict_get_dict(reply, "header", &h_dict)
1487 	    && !getdns_dict_get_int(h_dict, "rcode", &rcode)) {
1488 
1489 		GLDNS_RCODE_SET(gldns_buffer_at(buf, pkt_start), rcode);
1490 	}
1491 	if (!getdns_dict_get_list(reply, "answer", &section)) {
1492 		for ( i = 0, ancount = 0
1493 		    ; !getdns_list_get_dict(section, i, &rr_dict)
1494 		    ; i++ ) {
1495 
1496 			if (!_getdns_rr_dict2wire(rr_dict, buf))
1497 				ancount++;
1498 		}
1499 		gldns_buffer_write_u16_at(
1500 		    buf, pkt_start + GLDNS_ANCOUNT_OFF, ancount);
1501 	}
1502 	if (!getdns_dict_get_list(reply, "authority", &section)) {
1503 		for ( i = 0, nscount = 0
1504 		    ; !getdns_list_get_dict(section, i, &rr_dict)
1505 		    ; i++ ) {
1506 
1507 			if (!_getdns_rr_dict2wire(rr_dict, buf))
1508 				nscount++;
1509 		}
1510 		gldns_buffer_write_u16_at(
1511 		    buf, pkt_start + GLDNS_NSCOUNT_OFF, nscount);
1512 	}
1513 }
1514 
_getdns_list2wire_buf(gldns_buffer * buf,const getdns_list * l)1515 static void _getdns_list2wire_buf(gldns_buffer *buf, const getdns_list *l)
1516 {
1517 	getdns_dict *rr_dict;
1518 	size_t i, pkt_start;
1519 	uint16_t ancount;
1520 	uint32_t qtype, qclass = GETDNS_RRCLASS_IN;
1521 	getdns_bindata *qname;
1522 
1523 	pkt_start = gldns_buffer_position(buf);
1524 	/* Empty header */
1525 	gldns_buffer_write_u32(buf, 0);
1526 	gldns_buffer_write_u32(buf, 0);
1527 	gldns_buffer_write_u32(buf, 0);
1528 
1529 	for ( i = 0
1530 	    ; !getdns_list_get_dict(l, i, &rr_dict)
1531 	    ; i++ ) {
1532 
1533 		if (getdns_dict_get_int(rr_dict, "qtype", &qtype) ||
1534 		    getdns_dict_get_bindata(rr_dict, "qname", &qname))
1535 			continue;
1536 		(void) getdns_dict_get_int(rr_dict, "qclass", &qclass);
1537 		gldns_buffer_write(buf, qname->data, qname->size);
1538 		gldns_buffer_write_u16(buf, (uint16_t)qtype);
1539 		gldns_buffer_write_u16(buf, (uint16_t)qclass);
1540 		gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
1541 		break;
1542 	}
1543 	for ( i = 0, ancount = 0
1544 	    ; !getdns_list_get_dict(l, i, &rr_dict)
1545 	    ; i++ ) {
1546 
1547 		if (!_getdns_rr_dict2wire(rr_dict, buf))
1548 			ancount++;
1549 	}
1550 	gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount);
1551 }
1552 
_getdns_list2wire(const getdns_list * l,uint8_t * buf,size_t * buf_len,const struct mem_funcs * mf)1553 uint8_t *_getdns_list2wire(const getdns_list *l,
1554     uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf)
1555 {
1556 	gldns_buffer gbuf;
1557 	size_t sz;
1558 
1559 	gldns_buffer_init_vfixed_frm_data(&gbuf, buf, *buf_len);
1560 	_getdns_list2wire_buf(&gbuf, l);
1561 
1562 	if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len) {
1563 		*buf_len = sz;
1564 		return buf;
1565 	}
1566 	if (!(buf = GETDNS_XMALLOC(*mf, uint8_t, (*buf_len = sz))))
1567 		return NULL;
1568 
1569 	gldns_buffer_init_frm_data(&gbuf, buf, sz);
1570 	_getdns_list2wire_buf(&gbuf, l);
1571 	return buf;
1572 }
1573 
_getdns_reply2wire(const getdns_dict * r,uint8_t * buf,size_t * buf_len,const struct mem_funcs * mf)1574 uint8_t *_getdns_reply2wire(const getdns_dict *r,
1575     uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf)
1576 {
1577 	gldns_buffer gbuf;
1578 	size_t sz;
1579 
1580 	gldns_buffer_init_vfixed_frm_data(&gbuf, buf, *buf_len);
1581 	_getdns_reply2wire_buf(&gbuf, r);
1582 
1583 	if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len) {
1584 		*buf_len = sz;
1585 		return buf;
1586 	}
1587 	if (!(buf = GETDNS_XMALLOC(*mf, uint8_t, (*buf_len = sz))))
1588 		return NULL;
1589 
1590 	gldns_buffer_init_frm_data(&gbuf, buf, sz);
1591 	_getdns_reply2wire_buf(&gbuf, r);
1592 	return buf;
1593 }
1594 
_getdns_wire2list(const uint8_t * pkt,size_t pkt_len,getdns_list * l)1595 void _getdns_wire2list(const uint8_t *pkt, size_t pkt_len, getdns_list *l)
1596 {
1597 	_getdns_rr_iter rr_spc, *rr;
1598 	getdns_dict *rr_dict;
1599 
1600 	for ( rr = _getdns_rr_iter_init(&rr_spc, pkt, pkt_len)
1601 	    ; rr ; rr = _getdns_rr_iter_next(rr)) {
1602 
1603 		if (!(rr_dict = _getdns_rr_iter2rr_dict(&l->mf, rr)))
1604 			continue;
1605 
1606 		if (_getdns_list_append_this_dict(l, rr_dict))
1607 			getdns_dict_destroy(rr_dict);
1608 	}
1609 }
1610 
_getdns_auth_str(getdns_auth_state_t auth)1611 const char * _getdns_auth_str(getdns_auth_state_t auth) {
1612 	static const char*
1613 	getdns_auth_str_array[] = {
1614 		GETDNS_STR_AUTH_NONE,
1615 		GETDNS_STR_AUTH_FAILED,
1616 		GETDNS_STR_AUTH_OK
1617 	};
1618 	return getdns_auth_str_array[auth];
1619 }
1620 
1621 /* util-internal.c */
1622