1 /**
2  *
3  * /brief getdns contect management functions
4  *
5  * This is the meat of the API
6  * Originally taken from the getdns API description pseudo implementation.
7  *
8  */
9 /*
10  * Copyright (c) 2013, NLnet Labs, Verisign, Inc.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in the
19  *   documentation and/or other materials provided with the distribution.
20  * * Neither the names of the copyright holders nor the
21  *   names of its contributors may be used to endorse or promote products
22  *   derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
28  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "config.h"
37 #include "types-internal.h"
38 #include "util-internal.h"
39 #include "gldns/rrdef.h"
40 #include "gldns/str2wire.h"
41 #include "gldns/gbuffer.h"
42 #include "gldns/pkthdr.h"
43 #include "dict.h"
44 #include "debug.h"
45 #include "convert.h"
46 #include "general.h"
47 #include "tls.h"
48 
49 /* MAXIMUM_TSIG_SPACE = TSIG name      (dname)    : 256
50  *                      TSIG type      (uint16_t) :   2
51  *                      TSIG class     (uint16_t) :   2
52  *                      TSIG TTL       (uint32_t) :   4
53  *                      RdLen          (uint16_t) :   2
54  *                      Algorithm name (dname)    : 256
55  *                      Time Signed    (uint48_t) :   6
56  *                      Fudge          (uint16_t) :   2
57  *                      Mac Size       (uint16_t) :   2
58  *                      Mac            (variable) :   GETDNS_TLS_MAX_DIGEST_LENGTH
59  *                      Original Id    (uint16_t) :   2
60  *                      Error          (uint16_t) :   2
61  *                      Other Len      (uint16_t) :   2
62  *                      Other Data     (nothing)  :   0
63  *                                                 ---- +
64  *                                                  538 + GETDNS_TLS_MAX_DIGEST_LENGTH
65  */
66 #define MAXIMUM_TSIG_SPACE (538 + GETDNS_TLS_MAX_DIGEST_LENGTH)
67 
68 getdns_dict  dnssec_ok_checking_disabled_spc = {
69 	{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
70 	{ NULL, {{ NULL, NULL, NULL }}}
71 };
72 getdns_dict *dnssec_ok_checking_disabled = &dnssec_ok_checking_disabled_spc;
73 
74 getdns_dict  dnssec_ok_checking_disabled_roadblock_avoidance_spc = {
75 	{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
76 	{ NULL, {{ NULL, NULL, NULL }}}
77 };
78 getdns_dict *dnssec_ok_checking_disabled_roadblock_avoidance
79     = &dnssec_ok_checking_disabled_roadblock_avoidance_spc;
80 
81 getdns_dict  dnssec_ok_checking_disabled_avoid_roadblocks_spc = {
82 	{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
83 	{ NULL, {{ NULL, NULL, NULL }}}
84 };
85 getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks
86     = &dnssec_ok_checking_disabled_avoid_roadblocks_spc;
87 
88 getdns_dict  no_dnssec_checking_disabled_opportunistic_spc = {
89 	{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
90 	{ NULL, {{ NULL, NULL, NULL }}}
91 };
92 getdns_dict *no_dnssec_checking_disabled_opportunistic
93     = &no_dnssec_checking_disabled_opportunistic_spc;
94 
95 static int
is_extension_set(const getdns_dict * extensions,const char * name,int default_value)96 is_extension_set(const getdns_dict *extensions, const char *name, int default_value)
97 {
98 	getdns_return_t r;
99 	uint32_t value;
100 
101 	if ( ! extensions
102 	    || extensions == dnssec_ok_checking_disabled
103 	    || extensions == dnssec_ok_checking_disabled_roadblock_avoidance
104 	    || extensions == dnssec_ok_checking_disabled_avoid_roadblocks
105 	    || extensions == no_dnssec_checking_disabled_opportunistic)
106 		return 0;
107 
108 	r = getdns_dict_get_int(extensions, name, &value);
109 	return r == GETDNS_RETURN_GOOD ? ( value == GETDNS_EXTENSION_TRUE )
110 	                               : default_value;
111 }
112 
113 static void
network_req_cleanup(getdns_network_req * net_req)114 network_req_cleanup(getdns_network_req *net_req)
115 {
116 	assert(net_req);
117 
118 	if (net_req->query_id_registered) {
119 		(void) _getdns_rbtree_delete(
120 		    net_req->query_id_registered, net_req->node.key);
121 		net_req->query_id_registered = NULL;
122 		net_req->node.key = NULL;
123 	}
124 	if (net_req->response && (net_req->response < net_req->wire_data ||
125 	    net_req->response > net_req->wire_data+ net_req->wire_data_sz))
126 		GETDNS_FREE(net_req->owner->my_mf, net_req->response);
127 	if (net_req->debug_tls_peer_cert.size &&
128 	    net_req->debug_tls_peer_cert.data)
129 		GETDNS_FREE(net_req->owner->my_mf, net_req->debug_tls_peer_cert.data);
130 }
131 
132 static uint8_t *
netreq_reset(getdns_network_req * net_req)133 netreq_reset(getdns_network_req *net_req)
134 {
135 	uint8_t *buf;
136 	/* variables that need to be reset on reinit
137 	 */
138 	net_req->first_upstream = NULL;
139 	net_req->unbound_id = -1;
140 	_getdns_netreq_change_state(net_req, NET_REQ_NOT_SENT);
141 	if (net_req->query_id_registered) {
142 		(void) _getdns_rbtree_delete(net_req->query_id_registered,
143 		    (void *)(intptr_t)GLDNS_ID_WIRE(net_req->query));
144 		net_req->query_id_registered = NULL;
145 		net_req->node.key = NULL;
146 	}
147 	net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
148 	net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
149 	net_req->response_len = 0;
150 	/* Some fields to record info for return_call_reporting */
151 	net_req->debug_start_time = 0;
152 	net_req->debug_end_time = 0;
153 	if (!net_req->query)
154 		return NULL;
155 
156 	buf = net_req->query + GLDNS_HEADER_SIZE;
157 	(void) memcpy(buf, net_req->owner->name, net_req->owner->name_len);
158 	buf += net_req->owner->name_len;
159 
160 	gldns_write_uint16(buf, net_req->request_type);
161 	gldns_write_uint16(buf + 2, net_req->owner->request_class);
162 	return buf + 4;
163 }
164 
165 static int
network_req_init(getdns_network_req * net_req,getdns_dns_req * owner,uint16_t request_type,int checking_disabled,int opportunistic,int with_opt,int edns_maximum_udp_payload_size,uint8_t edns_extended_rcode,uint8_t edns_version,int edns_do_bit,uint16_t opt_options_size,size_t noptions,getdns_list * options,size_t wire_data_sz,size_t max_query_sz,const getdns_dict * extensions)166 network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
167     uint16_t request_type, int checking_disabled, int opportunistic,
168     int with_opt, int edns_maximum_udp_payload_size,
169     uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit,
170     uint16_t opt_options_size, size_t noptions, getdns_list *options,
171     size_t wire_data_sz, size_t max_query_sz, const getdns_dict *extensions)
172 {
173 	uint8_t *buf;
174 	getdns_dict    *option;
175 	uint32_t        option_code;
176 	getdns_bindata *option_data;
177 	size_t i;
178 	int r = 0;
179 	gldns_buffer gbuf;
180 
181 	/* variables that stay the same on reinit, don't touch
182 	 */
183 	net_req->request_type = request_type;
184 	net_req->owner = owner;
185 	net_req->edns_maximum_udp_payload_size = edns_maximum_udp_payload_size;
186 	net_req->max_udp_payload_size = edns_maximum_udp_payload_size != -1
187 	                              ? edns_maximum_udp_payload_size : 1432;
188         net_req->base_query_option_sz = opt_options_size;
189 	net_req->wire_data_sz = wire_data_sz;
190 
191 	net_req->transport_count = owner->context->dns_transport_count;
192 	memcpy(net_req->transports, owner->context->dns_transports,
193 	    net_req->transport_count * sizeof(getdns_transport_list_t));
194 	net_req->tls_auth_min =
195 	       owner->context->tls_auth == GETDNS_AUTHENTICATION_REQUIRED
196 	    && owner->context->dns_transport_count == 1
197 	    && owner->context->dns_transports[0] == GETDNS_TRANSPORT_TLS
198 	    && !opportunistic
199 	    ? GETDNS_AUTHENTICATION_REQUIRED
200 	    : GETDNS_AUTHENTICATION_NONE;
201 
202 	net_req->follow_redirects = owner->context->follow_redirects;
203 
204 	/* state variables from the resolver, don't touch
205 	 */
206 	net_req->upstream = NULL;
207 	net_req->fd = -1;
208 	net_req->transport_current = 0;
209 	memset(&net_req->event, 0, sizeof(net_req->event));
210 	net_req->keepalive_sent = 0;
211 	net_req->write_queue_tail = NULL;
212 	/* Some fields to record info for return_call_reporting */
213 	net_req->debug_tls_auth_status = GETDNS_AUTH_NONE;
214 	net_req->debug_tls_peer_cert.size = 0;
215 	net_req->debug_tls_peer_cert.data = NULL;
216 	net_req->debug_tls_version = NULL;
217 	net_req->debug_udp = 0;
218 
219 	/* Scheduling, touch only via _getdns_netreq_change_state!
220 	 */
221 	net_req->state = NET_REQ_NOT_SENT;
222 	/* A registered netreq (on a statefull transport)
223 	 * Deregister on reset and cleanup.
224 	 */
225 	net_req->query_id_registered = NULL;
226 	net_req->node.key = NULL;
227 
228 	if (max_query_sz == 0) {
229 		net_req->query    = NULL;
230 		net_req->opt      = NULL;
231 		net_req->response = net_req->wire_data;
232 		netreq_reset(net_req);
233 		return r;
234 	}
235 	/* first two bytes will contain query length (for tcp) */
236 	net_req->query = net_req->wire_data + 2;
237 
238 	buf = net_req->query;
239 	gldns_write_uint16(buf + 2, 0); /* reset all flags */
240 	GLDNS_RD_SET(buf);
241 	GLDNS_OPCODE_SET(buf, GLDNS_PACKET_QUERY);
242 	gldns_write_uint16(buf + GLDNS_QDCOUNT_OFF, 1); /* 1 query */
243 	gldns_write_uint16(buf + GLDNS_ANCOUNT_OFF, 0); /* 0 answers */
244 	gldns_write_uint16(buf + GLDNS_NSCOUNT_OFF, 0); /* 0 authorities */
245 	gldns_write_uint16(buf + GLDNS_ARCOUNT_OFF, with_opt ? 1 : 0);
246 
247 	buf = netreq_reset(net_req);
248 	gldns_buffer_init_frm_data(
249 	    &gbuf, net_req->query, net_req->wire_data_sz - 2);
250 	if (owner->context->header)
251 		_getdns_reply_dict2wire(owner->context->header, &gbuf, 1);
252 	gldns_buffer_rewind(&gbuf);
253 	_getdns_reply_dict2wire(extensions, &gbuf, 1);
254 	if (checking_disabled) /* We will do validation ourselves */
255 		GLDNS_CD_SET(net_req->query);
256 
257 	if (with_opt) {
258 		net_req->opt = buf;
259 		buf[0] = 0; /* dname for . */
260 		gldns_write_uint16(buf + 1, GLDNS_RR_TYPE_OPT);
261 		gldns_write_uint16(net_req->opt + 3,
262 		    net_req->max_udp_payload_size);
263 		buf[5] = edns_extended_rcode;
264 		buf[6] = edns_version;
265 		buf[7] = edns_do_bit ? 0x80 : 0;
266 		buf[8] = 0;
267 		gldns_write_uint16(buf + 9, opt_options_size);
268 		buf += 11;
269 		for (i = 0; i < noptions; i++) {
270 			if (getdns_list_get_dict(options, i, &option))
271 				continue;
272 			if (getdns_dict_get_int(
273 			    option, "option_code", &option_code))
274 				continue;
275 			if (getdns_dict_get_bindata(
276 			    option, "option_data", &option_data))
277 				continue;
278 
279 			gldns_write_uint16(buf, (uint16_t) option_code);
280 			gldns_write_uint16(buf + 2,
281 			    (uint16_t) option_data->size);
282 			(void) memcpy(buf + 4, option_data->data,
283 			    option_data->size);
284 
285 			buf += option_data->size + 4;
286 		}
287 	} else
288 		net_req->opt = NULL;
289 
290 	net_req->response = buf;
291 	gldns_write_uint16(net_req->wire_data, net_req->response - net_req->query);
292 
293 	return r;
294 }
295 
296 /* req->opt + 9 is the length; req->opt + 11 is the start of the
297    options.
298 
299    clear_upstream_options() goes back to the per-query options.
300  */
301 
302 void
_getdns_network_req_clear_upstream_options(getdns_network_req * req)303 _getdns_network_req_clear_upstream_options(getdns_network_req * req)
304 {
305   size_t pktlen;
306   if (req->opt) {
307 	  gldns_write_uint16(req->opt + 9, (uint16_t) req->base_query_option_sz);
308 	  req->response = req->opt + 11 + req->base_query_option_sz;
309 	  pktlen = req->response - req->query;
310 	  gldns_write_uint16(req->query - 2, (uint16_t) pktlen);
311   }
312 }
313 
314 void
_getdns_netreq_reinit(getdns_network_req * netreq)315 _getdns_netreq_reinit(getdns_network_req *netreq)
316 {
317 	uint8_t *base_opt_backup;
318 	size_t base_opt_rr_sz;
319 
320 	if (!netreq->query) {
321 		(void) netreq_reset(netreq);
322 		return;
323 
324 	} else if (!netreq->opt) {
325 		/* Remove TSIG (if any) */
326 		gldns_write_uint16(netreq->query + GLDNS_ARCOUNT_OFF,  0);
327 		netreq->response = netreq_reset(netreq);
328 		gldns_write_uint16(netreq->wire_data,
329 		    netreq->response - netreq->query);
330 		return;
331 	}
332 	_getdns_network_req_clear_upstream_options(netreq);
333 	base_opt_rr_sz = netreq->base_query_option_sz + 11;
334 	base_opt_backup = netreq->wire_data + netreq->wire_data_sz
335 	    - base_opt_rr_sz;
336 	(void) memcpy(base_opt_backup, netreq->opt, base_opt_rr_sz);
337 	netreq->opt = netreq_reset(netreq);
338 	(void) memcpy(netreq->opt, base_opt_backup, base_opt_rr_sz);
339 	netreq->response = netreq->opt + base_opt_rr_sz;
340 	/* Remove TSIG (if any), but leave the opt RR */
341 	gldns_write_uint16(netreq->query + GLDNS_ARCOUNT_OFF,  1);
342 	gldns_write_uint16(netreq->wire_data,
343 	    netreq->response - netreq->query);
344 }
345 
346 
347 /* add_upstream_option appends an option that is derived at send time.
348     (you can send data as NULL and it will fill with all zeros) */
349 getdns_return_t
_getdns_network_req_add_upstream_option(getdns_network_req * req,uint16_t code,uint16_t sz,const void * data)350 _getdns_network_req_add_upstream_option(getdns_network_req * req, uint16_t code, uint16_t sz, const void* data)
351 {
352   uint16_t oldlen;
353   uint32_t newlen;
354   uint32_t pktlen;
355   size_t cur_upstream_option_sz;
356 
357   /* if no options are set, we can't add upstream options */
358   if (!req->opt)
359 	  return GETDNS_RETURN_GENERIC_ERROR;
360 
361   /* if TCP, no overflow allowed for length field
362      https://tools.ietf.org/html/rfc1035#section-4.2.2 */
363   pktlen = req->response - req->query;
364   pktlen += 4 + sz;
365   if (pktlen > UINT16_MAX)
366     return GETDNS_RETURN_GENERIC_ERROR;
367 
368   /* no overflow allowed for OPT size either (maybe this is overkill
369      given the above check?) */
370   oldlen = gldns_read_uint16(req->opt + 9);
371   newlen = oldlen + 4 + sz;
372   if (newlen > UINT16_MAX)
373     return GETDNS_RETURN_GENERIC_ERROR;
374 
375   /* avoid overflowing MAXIMUM_UPSTREAM_OPTION_SPACE */
376   cur_upstream_option_sz = (size_t)oldlen - req->base_query_option_sz;
377   if (cur_upstream_option_sz  + 4 + sz > MAXIMUM_UPSTREAM_OPTION_SPACE)
378     return GETDNS_RETURN_GENERIC_ERROR;
379 
380   /* actually add the option: */
381   gldns_write_uint16(req->opt + 11 + oldlen, code);
382   gldns_write_uint16(req->opt + 11 + oldlen + 2, sz);
383   if (data != NULL)
384 	  memcpy(req->opt + 11 + oldlen + 4, data, sz);
385   else
386 	  memset(req->opt + 11 + oldlen + 4, 0, sz);
387   gldns_write_uint16(req->opt + 9, newlen);
388 
389   /* the response should start right after the options end: */
390   req->response = req->opt + 11 + newlen;
391 
392   /* for TCP, adjust the size of the wire format itself: */
393   gldns_write_uint16(req->query - 2, pktlen);
394 
395   return GETDNS_RETURN_GOOD;
396 }
397 
398 size_t
_getdns_network_req_add_tsig(getdns_network_req * req)399 _getdns_network_req_add_tsig(getdns_network_req *req)
400 {
401 	getdns_upstream *upstream = req->upstream;
402 	gldns_buffer gbuf;
403 	uint16_t arcount;
404 	const getdns_tsig_info *tsig_info;
405 	unsigned char* md_buf;
406 	size_t md_len;
407 
408 	/* Should only be called when in stub mode */
409 	assert(req->query);
410 
411 	if (upstream->tsig_alg == GETDNS_NO_TSIG || !upstream->tsig_dname_len)
412 		return req->response - req->query;
413 
414 	arcount = gldns_read_uint16(req->query + 10);
415 
416 #if defined(STUB_DEBUG) && STUB_DEBUG
417 	/* TSIG should not have been written yet. */
418 	if (req->opt) {
419 		assert(arcount == 1);
420 		assert(req->opt + 11 + gldns_read_uint16(req->opt + 9)
421 		    == req->response);
422 	} else
423 		assert(arcount == 0);
424 #endif
425 	tsig_info = _getdns_get_tsig_info(upstream->tsig_alg);
426 
427 	gldns_buffer_init_vfixed_frm_data(&gbuf, req->response, MAXIMUM_TSIG_SPACE);
428 	gldns_buffer_write(&gbuf,
429 	    upstream->tsig_dname, upstream->tsig_dname_len);	/* Name */
430 	gldns_buffer_write_u16(&gbuf, GETDNS_RRCLASS_ANY);	/* Class */
431 	gldns_buffer_write_u32(&gbuf, 0);			/* TTL */
432 	gldns_buffer_write(&gbuf,
433 	    tsig_info->dname, tsig_info->dname_len);	/* Algorithm Name */
434 	gldns_buffer_write_u48(&gbuf, time(NULL));	/* Time Signed */
435 	gldns_buffer_write_u16(&gbuf, 300);		/* Fudge */
436 	gldns_buffer_write_u16(&gbuf, 0);		/* Error */
437 	gldns_buffer_write_u16(&gbuf, 0);		/* Other len */
438 
439 	md_buf = _getdns_tls_hmac_hash(&req->owner->my_mf, upstream->tsig_alg, upstream->tsig_key, upstream->tsig_size, (void *)req->query, gldns_buffer_current(&gbuf) - req->query, &md_len);
440 	if (!md_buf)
441 		return req->response - req->query;
442 
443 	gldns_buffer_rewind(&gbuf);
444 	gldns_buffer_write(&gbuf,
445 	    upstream->tsig_dname, upstream->tsig_dname_len);	/* Name */
446 	gldns_buffer_write_u16(&gbuf, GETDNS_RRTYPE_TSIG);	/* Type*/
447 	gldns_buffer_write_u16(&gbuf, GETDNS_RRCLASS_ANY);	/* Class */
448 	gldns_buffer_write_u32(&gbuf, 0);			/* TTL */
449 	gldns_buffer_write_u16(&gbuf,
450 	    (uint16_t)(tsig_info->dname_len + 10 + md_len + 6));	/* RdLen */
451 	gldns_buffer_write(&gbuf,
452 	    tsig_info->dname, tsig_info->dname_len);	/* Algorithm Name */
453 	gldns_buffer_write_u48(&gbuf, time(NULL));	/* Time Signed */
454 	gldns_buffer_write_u16(&gbuf, 300);		/* Fudge */
455 	gldns_buffer_write_u16(&gbuf, md_len);		/* MAC Size */
456 	gldns_buffer_write(&gbuf, md_buf, md_len);	/* MAC*/
457 	gldns_buffer_write(&gbuf, req->query, 2);	/* Original ID */
458 	gldns_buffer_write_u16(&gbuf, 0);		/* Error */
459 	gldns_buffer_write_u16(&gbuf, 0);		/* Other len */
460 
461 	GETDNS_FREE(req->owner->my_mf, md_buf);
462 
463 	if (gldns_buffer_position(&gbuf) > gldns_buffer_limit(&gbuf))
464 		return req->response - req->query;
465 
466 	DEBUG_STUB("Sending with TSIG, mac length: %d\n", (int)md_len);
467 	req->tsig_status = GETDNS_DNSSEC_INSECURE;
468 	gldns_write_uint16(req->query + 10, arcount + 1);
469 	req->response = gldns_buffer_current(&gbuf);
470 	return req->response - req->query;
471 }
472 
473 
474 
475 void
_getdns_network_validate_tsig(getdns_network_req * req)476 _getdns_network_validate_tsig(getdns_network_req *req)
477 {
478 #if defined(HAVE_NSS) || defined(HAVE_NETTLE)
479 	(void)req;
480 #else
481 	_getdns_rr_iter  rr_spc, *rr;
482 	_getdns_rdf_iter rdf_spc, *rdf;
483 	const uint8_t *request_mac;
484 	uint16_t       request_mac_len;
485 	uint8_t   tsig_vars[MAXIMUM_TSIG_SPACE];
486 	gldns_buffer gbuf;
487 	const uint8_t  *dname;
488 	size_t    dname_len;
489 	const uint8_t  *response_mac;
490 	uint16_t  response_mac_len;
491 	uint8_t   other_len;
492 	unsigned char  *result_mac;
493 	size_t result_mac_len;
494 	uint16_t original_id;
495 	_getdns_tls_hmac *hmac;
496 
497 	DEBUG_STUB("%s %-35s: Validate TSIG\n", STUB_DEBUG_TSIG, __FUNC__);
498 	for ( rr = _getdns_rr_iter_init(&rr_spc, req->query,
499 	                                (req->response - req->query))
500 	    ; rr
501 	    ; rr = _getdns_rr_iter_next(rr)) {
502 
503 		if (_getdns_rr_iter_section(rr) == SECTION_ADDITIONAL &&
504 		    gldns_read_uint16(rr->rr_type) == GETDNS_RRTYPE_TSIG)
505 			break;
506 	}
507 	if (!rr || !(rdf = _getdns_rdf_iter_init_at(&rdf_spc, rr, 3)))
508 		return; /* No good TSIG sent, so nothing expected on reply */
509 
510 	request_mac_len = gldns_read_uint16(rdf->pos);
511 	if (request_mac_len != rdf->nxt - rdf->pos - 2)
512 		return;
513 	DEBUG_STUB("%s %-35s: Request MAC found length %d\n",
514 	           STUB_DEBUG_TSIG, __FUNC__, (int)(request_mac_len));
515 
516 	request_mac = rdf->pos + 2;
517 
518 	/* Now we expect a TSIG on the response! */
519 	req->tsig_status = GETDNS_DNSSEC_BOGUS;
520 
521 	for ( rr = _getdns_rr_iter_init(
522 	            &rr_spc, req->response, req->response_len)
523 	    ; rr
524 	    ; rr = _getdns_rr_iter_next(rr)) {
525 
526 		if (_getdns_rr_iter_section(rr) == SECTION_ADDITIONAL &&
527 		    gldns_read_uint16(rr->rr_type) == GETDNS_RRTYPE_TSIG)
528 			break;
529 	}
530 	if (!rr || !(rdf = _getdns_rdf_iter_init(&rdf_spc, rr)))
531 		return;
532 	gldns_buffer_init_frm_data(&gbuf, tsig_vars, MAXIMUM_TSIG_SPACE);
533 
534 	dname_len = gldns_buffer_remaining(&gbuf);
535 	if (!(dname = _getdns_owner_if_or_as_decompressed(
536 	    rr, gldns_buffer_current(&gbuf), &dname_len)))
537 		return;
538 	if (dname == gldns_buffer_current(&gbuf))
539 		gldns_buffer_skip(&gbuf, dname_len);
540 	else
541 		gldns_buffer_write(&gbuf, dname, dname_len);
542 
543 	gldns_buffer_write(&gbuf, rr->rr_type + 2, 2);	/* Class */
544 	gldns_buffer_write(&gbuf, rr->rr_type + 4, 4);	/* TTL */
545 
546 	dname_len = gldns_buffer_remaining(&gbuf);
547 	if (!(dname = _getdns_rdf_if_or_as_decompressed(
548 	    rdf, gldns_buffer_current(&gbuf), &dname_len)))
549 		return;
550 	if (dname == gldns_buffer_current(&gbuf))
551 		gldns_buffer_skip(&gbuf, dname_len);
552 	else
553 		gldns_buffer_write(&gbuf, dname, dname_len);
554 
555 	if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
556 	    rdf->nxt - rdf->pos != 6)
557 		return;
558 	gldns_buffer_write(&gbuf, rdf->pos, 6);		/* Time Signed */
559 
560 	if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
561 	    rdf->nxt - rdf->pos != 2)
562 		return;
563 	gldns_buffer_write(&gbuf, rdf->pos, 2);		/* Fudge */
564 
565 	if (!(rdf = _getdns_rdf_iter_next(rdf)))	/* mac */
566 		return;
567 	response_mac_len = gldns_read_uint16(rdf->pos);
568 	if (response_mac_len != rdf->nxt - rdf->pos - 2)
569 		return;
570 	DEBUG_STUB("%s %-35s: Response MAC found length: %d\n",
571 	           STUB_DEBUG_TSIG, __FUNC__, (int)(response_mac_len));
572 	response_mac = rdf->pos + 2;
573 
574 	if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
575 	    rdf->nxt -rdf->pos != 2)			/* Original ID */
576 		return;
577 	original_id = gldns_read_uint16(rdf->pos);
578 
579 	if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
580 	    rdf->nxt - rdf->pos != 2)
581 		return;
582 	gldns_buffer_write(&gbuf, rdf->pos, 2);		/* Error */
583 
584 	if (!(rdf = _getdns_rdf_iter_next(rdf)))	/* Other */
585 		return;
586 
587 	gldns_buffer_write_u16(&gbuf, 0);		/* Other len */
588 	other_len = (uint8_t) gldns_read_uint16(rdf->pos);
589 	if (other_len != rdf->nxt - rdf->pos - 2)
590 		return;
591 	if (other_len)
592 		gldns_buffer_write(&gbuf, rdf->pos, other_len);
593 
594 	/* TSIG found */
595 	DEBUG_STUB("%s %-35s: TSIG found, original ID: %d\n",
596 	           STUB_DEBUG_TSIG, __FUNC__, (int)original_id);
597 
598 	gldns_write_uint16(req->response + 10,
599 	    gldns_read_uint16(req->response + 10) - 1);
600 	gldns_write_uint16(req->response, original_id);
601 
602 	hmac = _getdns_tls_hmac_new(&req->owner->my_mf, req->upstream->tsig_alg, req->upstream->tsig_key, req->upstream->tsig_size);
603 	if (!hmac)
604 		return;
605 
606 	_getdns_tls_hmac_add(hmac, request_mac - 2, request_mac_len + 2);
607 	_getdns_tls_hmac_add(hmac, req->response, rr->pos - req->response);
608 	_getdns_tls_hmac_add(hmac, tsig_vars, gldns_buffer_position(&gbuf));
609 	result_mac = _getdns_tls_hmac_end(&req->owner->my_mf, hmac, &result_mac_len);
610 	if (!result_mac)
611 		return;
612 
613 	DEBUG_STUB("%s %-35s: Result MAC length: %d\n",
614 	           STUB_DEBUG_TSIG, __FUNC__, (int)(result_mac_len));
615 	if (result_mac_len == response_mac_len &&
616 	    memcmp(result_mac, response_mac, result_mac_len) == 0)
617 		req->tsig_status = GETDNS_DNSSEC_SECURE;
618 
619 	GETDNS_FREE(req->owner->my_mf, result_mac);
620 
621 	gldns_write_uint16(req->response, gldns_read_uint16(req->query));
622 	gldns_write_uint16(req->response + 10,
623 	    gldns_read_uint16(req->response + 10) + 1);
624 #endif
625 }
626 
627 void
_getdns_dns_req_free(getdns_dns_req * req)628 _getdns_dns_req_free(getdns_dns_req * req)
629 {
630 	getdns_network_req **net_req;
631 	if (!req) {
632 		return;
633 	}
634 
635 	_getdns_upstreams_dereference(req->upstreams);
636 
637 	/* cleanup network requests */
638 	for (net_req = req->netreqs; *net_req; net_req++)
639 		network_req_cleanup(*net_req);
640 
641 	/* clear timeout event */
642 	if (req->loop && req->loop->vmt && req->timeout.timeout_cb) {
643 		req->loop->vmt->clear(req->loop, &req->timeout);
644 		req->timeout.timeout_cb = NULL;
645 	}
646 	if (req->freed)
647 		*req->freed = 1;
648 	GETDNS_FREE(req->my_mf, req);
649 }
650 
651 static const uint8_t no_suffixes[] = { 1, 0 };
652 
653 /* create a new dns req to be submitted */
654 getdns_dns_req *
_getdns_dns_req_new(getdns_context * context,getdns_eventloop * loop,const char * name,uint16_t request_type,const getdns_dict * extensions,uint64_t * now_ms)655 _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
656     const char *name, uint16_t request_type, const getdns_dict *extensions,
657     uint64_t *now_ms)
658 {
659 	int dnssec                               = is_extension_set(
660 	    extensions, "dnssec",
661 	        context->dnssec);
662 	int dnssec_return_status                 = is_extension_set(
663 	    extensions, "dnssec_return_status",
664 	        context->dnssec_return_status);
665 	int dnssec_return_only_secure            = is_extension_set(
666 	    extensions, "dnssec_return_only_secure",
667 	        context->dnssec_return_only_secure);
668 	int dnssec_return_all_statuses           = is_extension_set(
669 	    extensions, "dnssec_return_all_statuses",
670 	        context->dnssec_return_all_statuses);
671 	int  dnssec_return_full_validation_chain = is_extension_set(
672 	    extensions, "dnssec_return_full_validation_chain",
673 	        context->dnssec_return_full_validation_chain);
674 	int dnssec_return_validation_chain       = is_extension_set(
675 	    extensions, "dnssec_return_validation_chain",
676 	        context->dnssec_return_validation_chain);
677 	int edns_cookies                         = is_extension_set(
678 	    extensions, "edns_cookies",
679 	        context->edns_cookies);
680 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
681 	int avoid_dnssec_roadblocks
682 	    =  (extensions == dnssec_ok_checking_disabled_avoid_roadblocks);
683 	int dnssec_roadblock_avoidance = avoid_dnssec_roadblocks
684 	    || (extensions == dnssec_ok_checking_disabled_roadblock_avoidance)
685 	    || is_extension_set(extensions, "dnssec_roadblock_avoidance",
686 	                            context->dnssec_roadblock_avoidance);
687 #endif
688 	int dnssec_extension_set = dnssec || dnssec_return_status
689 	    || dnssec_return_only_secure || dnssec_return_all_statuses
690 	    || dnssec_return_validation_chain
691 	    || dnssec_return_full_validation_chain
692 	    || (extensions == dnssec_ok_checking_disabled)
693 	    || (extensions == dnssec_ok_checking_disabled_roadblock_avoidance)
694 	    || (extensions == dnssec_ok_checking_disabled_avoid_roadblocks)
695 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
696 	    || dnssec_roadblock_avoidance
697 #endif
698 	    ;
699 
700 	uint32_t edns_do_bit;
701 	int      edns_maximum_udp_payload_size;
702 	uint32_t get_edns_maximum_udp_payload_size;
703 	uint32_t edns_extended_rcode;
704 	uint32_t edns_version;
705 
706 	getdns_dict *add_opt_parameters;
707 	int     have_add_opt_parameters;
708 
709 	getdns_list *options = NULL;
710 	size_t      noptions = 0;
711 	size_t       i;
712 
713 	getdns_dict    *option;
714 	uint32_t        option_code;
715 	getdns_bindata *option_data;
716 	size_t opt_options_size = 0;
717 
718 	int with_opt;
719 
720 	getdns_dns_req *result = NULL;
721         uint32_t klass = context->specify_class;
722 	int a_aaaa_query = is_extension_set(extensions,
723 	    "return_both_v4_and_v6", context->return_both_v4_and_v6) &&
724 	    ( request_type == GETDNS_RRTYPE_A ||
725 	      request_type == GETDNS_RRTYPE_AAAA );
726 	/* Reserve for the buffer at least one more byte
727 	 * (to test for udp overflow) (hence the + 1),
728 	 * And align on the 8 byte boundary  (hence the (x + 7) / 8 * 8)
729 	 */
730 	size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz;
731 	uint8_t *region, *suffixes;
732 	int    checking_disabled = dnssec_extension_set;
733 	int    opportunistic = 0;
734 
735 	if (extensions == no_dnssec_checking_disabled_opportunistic) {
736 		dnssec = 0;
737 		dnssec_return_status = 0;
738 		dnssec_return_only_secure = 0;
739 		dnssec_return_all_statuses = 0;
740 		dnssec_return_full_validation_chain = 0;
741 		dnssec_return_validation_chain = 0;
742 		dnssec_extension_set = 0;
743 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
744 		dnssec_roadblock_avoidance = 0;
745 		avoid_dnssec_roadblocks = 0;
746 #endif
747 		extensions = NULL;
748 		checking_disabled = 1;
749 		opportunistic = 1;
750 	} else if (extensions == dnssec_ok_checking_disabled ||
751 	    extensions == dnssec_ok_checking_disabled_roadblock_avoidance ||
752 	    extensions == dnssec_ok_checking_disabled_avoid_roadblocks)
753 		extensions = NULL;
754 
755 	have_add_opt_parameters = getdns_dict_get_dict(extensions,
756 	    "add_opt_parameters", &add_opt_parameters) == GETDNS_RETURN_GOOD;
757 	if (!have_add_opt_parameters && context->add_opt_parameters) {
758 		add_opt_parameters = context->add_opt_parameters;
759 		have_add_opt_parameters = 1;
760 	}
761 	if (dnssec_extension_set) {
762 		edns_maximum_udp_payload_size = -1;
763 		edns_extended_rcode = 0;
764 		edns_version = 0;
765 		edns_do_bit = 1;
766 	} else {
767 		edns_maximum_udp_payload_size =
768 		    context->edns_maximum_udp_payload_size;
769 		edns_extended_rcode = context->edns_extended_rcode;
770 		edns_version = context->edns_version;
771 		edns_do_bit = context->edns_do_bit;
772 
773 		if (have_add_opt_parameters) {
774 			if (getdns_dict_get_int(add_opt_parameters,
775 			    "maximum_udp_payload_size",
776 			    &get_edns_maximum_udp_payload_size)) {
777 				if (!getdns_dict_get_int(
778 				    add_opt_parameters, "udp_payload_size",
779 				    &get_edns_maximum_udp_payload_size))
780 					edns_maximum_udp_payload_size =
781 					    get_edns_maximum_udp_payload_size;
782 			} else
783 				edns_maximum_udp_payload_size =
784 				    get_edns_maximum_udp_payload_size;
785 
786 			(void) getdns_dict_get_int(add_opt_parameters,
787 			    "extended_rcode", &edns_extended_rcode);
788 			(void) getdns_dict_get_int(add_opt_parameters,
789 			    "version", &edns_version);
790 			if (getdns_dict_get_int(add_opt_parameters,
791 			    "do_bit", &edns_do_bit))
792 				(void) getdns_dict_get_int(
793 				    add_opt_parameters, "do", &edns_do_bit);
794 		}
795 	}
796 	if (have_add_opt_parameters && getdns_dict_get_list(
797 	    add_opt_parameters, "options", &options) == GETDNS_RETURN_GOOD)
798 		(void) getdns_list_get_length(options, &noptions);
799 
800 	with_opt = edns_do_bit != 0 || edns_maximum_udp_payload_size != 512 ||
801 	    edns_extended_rcode != 0 || edns_version != 0 || noptions ||
802 	    edns_cookies || context->edns_client_subnet_private ||
803 	    context->tls_query_padding_blocksize > 1;
804 
805 	edns_maximum_udp_payload_size = with_opt &&
806 	    ( edns_maximum_udp_payload_size == -1 ||
807 	      edns_maximum_udp_payload_size > 512 )
808 	    ? edns_maximum_udp_payload_size : 512;
809 
810 	/* (x + 7) / 8 * 8 to align on 8 byte boundries */
811 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
812 	if (context->resolution_type == GETDNS_RESOLUTION_RECURSING
813 	    && (!dnssec_roadblock_avoidance || avoid_dnssec_roadblocks))
814 #else
815 	if (context->resolution_type == GETDNS_RESOLUTION_RECURSING)
816 #endif
817 		max_query_sz = 0;
818 	else {
819 		for (i = 0; i < noptions; i++) {
820 			if (getdns_list_get_dict(options, i, &option)) continue;
821 			if (getdns_dict_get_int(
822 			    option, "option_code", &option_code)) continue;
823 			if (getdns_dict_get_bindata(
824 			    option, "option_data", &option_data)) continue;
825 
826 			opt_options_size += option_data->size
827 			    + 2 /* option-code   */
828 			    + 2 /* option-length */
829 			    ;
830 		}
831 		max_query_sz = ( GLDNS_HEADER_SIZE
832 		    + 256 + 4 /* dname maximum 255 bytes (256 with mdns)*/
833 		    + 12 + opt_options_size /* space needed for OPT (if needed) */
834 		    + MAXIMUM_UPSTREAM_OPTION_SPACE
835 		    + MAXIMUM_TSIG_SPACE
836 		    + 7) / 8 * 8;
837 	}
838 	max_response_sz = (( edns_maximum_udp_payload_size != -1
839 	                   ? edns_maximum_udp_payload_size : 1432
840 	                   ) + 1 /* +1 for udp overflow detection */
841 	                     + 7 ) / 8 * 8;
842 
843 	netreq_sz = ( sizeof(getdns_network_req)
844 	            + max_query_sz + max_response_sz  + 7 ) / 8 * 8;
845 	dnsreq_base_sz = (( sizeof(getdns_dns_req)
846 	                  + (a_aaaa_query ? 3 : 2) * sizeof(getdns_network_req*)
847 			  + context->suffixes_len
848 			  ) + 7) / 8 * 8;
849 
850 	if (! (region = GETDNS_XMALLOC(context->mf, uint8_t,
851 	    dnsreq_base_sz + (a_aaaa_query ? 2 : 1) * netreq_sz)))
852 		return NULL;
853 	(void) memset(region, 0, sizeof(getdns_dns_req));
854 
855 	result = (getdns_dns_req *)region;
856 	result->netreqs[0] = (getdns_network_req *)(region + dnsreq_base_sz);
857 	if (a_aaaa_query) {
858 		result->netreqs[1] = (getdns_network_req *)
859 		    (region + dnsreq_base_sz + netreq_sz);
860 		result->netreqs[2] = NULL;
861 	} else
862 		result->netreqs[1] = NULL;
863 
864 	result->my_mf = context->mf;
865 
866 	suffixes = region + dnsreq_base_sz - context->suffixes_len;
867 	assert(context->suffixes);
868 	assert(context->suffixes_len);
869 	memcpy(suffixes, context->suffixes, context->suffixes_len);
870 
871 	result->append_name = context->append_name;
872 	if (!strlen(name) || name[strlen(name)-1] == '.' ||
873 	    result->append_name == GETDNS_APPEND_NAME_NEVER) {
874 		/* Absolute query string, no appending */
875 		result->suffix_len = no_suffixes[0];
876 		result->suffix = no_suffixes + 1;
877 		result->suffix_appended = 1;
878 	} else {
879 		result->suffix_len = suffixes[0];
880 		result->suffix = suffixes + 1;
881 		result->suffix_appended = 0;
882 	}
883 	result->name_len = sizeof(result->name);
884 	if (gldns_str2wire_dname_buf(name, result->name, &result->name_len)) {
885 		GETDNS_FREE(result->my_mf, result);
886 		return NULL;
887 	}
888 	if (result->append_name == GETDNS_APPEND_NAME_ALWAYS ||
889 	    (  result->append_name == GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST
890 	    && result->name[0] && result->name[result->name[0]+1] == 0)){
891 		for (
892 		    ; result->suffix_len > 1 && *result->suffix
893 		    ; result->suffix += result->suffix_len
894 		    , result->suffix_len = *result->suffix++) {
895 
896 			if (result->suffix_len + result->name_len - 1 <
897 			    sizeof(result->name)) {
898 				memcpy(result->name + result->name_len - 1,
899 				    result->suffix, result->suffix_len);
900 				result->name_len += result->suffix_len - 1;
901 				result->suffix_appended = 1;
902 				break;
903 			}
904 		}
905 	} else if (result->append_name ==
906 	    GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE &&
907 	    result->name[0] &&
908 	    result->name[result->name[0]+1] != 0) {
909 		/* We have multiple labels, no appending */
910 		result->suffix_len = no_suffixes[0];
911 		result->suffix = no_suffixes + 1;
912 		result->suffix_appended = 1;
913 	}
914 	result->context = context;
915 	result->loop = loop;
916 	result->trans_id = (uint64_t) (intptr_t) result;
917 	result->dnssec                         = dnssec;
918 	result->dnssec_return_status           = dnssec_return_status;
919 	result->dnssec_return_only_secure      = dnssec_return_only_secure;
920 	result->dnssec_return_all_statuses     = dnssec_return_all_statuses;
921 	result->dnssec_return_full_validation_chain =
922 		dnssec_return_full_validation_chain;
923 	result->dnssec_return_validation_chain = dnssec_return_validation_chain
924 	     || dnssec_return_full_validation_chain;
925 	result->dnssec_extension_set           = dnssec_extension_set;
926 	result->edns_cookies                   = edns_cookies;
927 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
928 	result->dnssec_roadblock_avoidance     = dnssec_roadblock_avoidance;
929 	result->avoid_dnssec_roadblocks        = avoid_dnssec_roadblocks;
930 #endif
931 	result->edns_client_subnet_private     = context->edns_client_subnet_private;
932 	result->tls_query_padding_blocksize    = context->tls_query_padding_blocksize;
933 	result->return_call_reporting          = is_extension_set(extensions,
934 	    "return_call_reporting"  , context->return_call_reporting);
935 	result->add_warning_for_bad_dns        = is_extension_set(extensions,
936 	    "add_warning_for_bad_dns", context->add_warning_for_bad_dns);
937 
938 	/* will be set by caller */
939 	result->user_pointer = NULL;
940 	result->user_callback = NULL;
941 	memset(&result->timeout, 0, sizeof(result->timeout));
942 
943         /* check the specify_class extension */
944         (void) getdns_dict_get_int(extensions, "specify_class", &klass);
945 	result->request_class = klass;
946 
947 	result->upstreams = context->upstreams;
948 	if (result->upstreams)
949 		result->upstreams->referenced++;
950 
951 	result->finished_next = NULL;
952 	result->ta_notify = NULL;
953 	result->freed = NULL;
954 	result->validating = 0;
955 	result->waiting_for_ta = 0;
956 	result->is_dns_request = 1;
957 	result->request_timed_out = 0;
958 	result->chain = NULL;
959 
960 	network_req_init(result->netreqs[0], result,
961 	    request_type, checking_disabled, opportunistic,
962 	    with_opt, edns_maximum_udp_payload_size,
963 	    edns_extended_rcode, edns_version, edns_do_bit,
964 	    (uint16_t) opt_options_size, noptions, options,
965 	    netreq_sz - sizeof(getdns_network_req), max_query_sz,
966 	    extensions);
967 
968 	if (a_aaaa_query)
969 		network_req_init(result->netreqs[1], result,
970 		    ( request_type == GETDNS_RRTYPE_A
971 		    ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ),
972 		    checking_disabled, opportunistic, with_opt,
973 		    edns_maximum_udp_payload_size,
974 		    edns_extended_rcode, edns_version, edns_do_bit,
975 		    (uint16_t) opt_options_size, noptions, options,
976 		    netreq_sz - sizeof(getdns_network_req), max_query_sz,
977 		    extensions);
978 
979 	if (*now_ms == 0 && (*now_ms = _getdns_get_now_ms()) == 0)
980 		result->expires = 0;
981 	else
982 		result->expires = *now_ms + context->timeout;
983 
984 	return result;
985 }
986