xref: /freebsd/contrib/unbound/services/rpz.c (revision 335c7cda)
1 /*
2  * services/rpz.c - rpz service
3  *
4  * Copyright (c) 2019, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * 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 /**
37  * \file
38  *
39  * This file contains functions to enable RPZ service.
40  */
41 
42 #include "config.h"
43 #include "services/rpz.h"
44 #include "util/config_file.h"
45 #include "sldns/wire2str.h"
46 #include "sldns/str2wire.h"
47 #include "util/data/dname.h"
48 #include "util/net_help.h"
49 #include "util/log.h"
50 #include "util/data/dname.h"
51 #include "util/locks.h"
52 #include "util/regional.h"
53 #include "util/data/msgencode.h"
54 #include "services/cache/dns.h"
55 #include "iterator/iterator.h"
56 #include "iterator/iter_delegpt.h"
57 #include "daemon/worker.h"
58 
59 typedef struct resp_addr rpz_aclnode_type;
60 
61 struct matched_delegation_point {
62 	uint8_t* dname;
63 	size_t dname_len;
64 };
65 
66 /** string for RPZ action enum */
67 const char*
rpz_action_to_string(enum rpz_action a)68 rpz_action_to_string(enum rpz_action a)
69 {
70 	switch(a) {
71 	case RPZ_NXDOMAIN_ACTION: return "rpz-nxdomain";
72 	case RPZ_NODATA_ACTION: return "rpz-nodata";
73 	case RPZ_PASSTHRU_ACTION: return "rpz-passthru";
74 	case RPZ_DROP_ACTION: return "rpz-drop";
75 	case RPZ_TCP_ONLY_ACTION: return "rpz-tcp-only";
76 	case RPZ_INVALID_ACTION: return "rpz-invalid";
77 	case RPZ_LOCAL_DATA_ACTION: return "rpz-local-data";
78 	case RPZ_DISABLED_ACTION: return "rpz-disabled";
79 	case RPZ_CNAME_OVERRIDE_ACTION: return "rpz-cname-override";
80 	case RPZ_NO_OVERRIDE_ACTION: return "rpz-no-override";
81 	default: return "rpz-unknown-action";
82 	}
83 }
84 
85 /** RPZ action enum for config string */
86 static enum rpz_action
rpz_config_to_action(char * a)87 rpz_config_to_action(char* a)
88 {
89 	if(strcmp(a, "nxdomain") == 0) return RPZ_NXDOMAIN_ACTION;
90 	else if(strcmp(a, "nodata") == 0) return RPZ_NODATA_ACTION;
91 	else if(strcmp(a, "passthru") == 0) return RPZ_PASSTHRU_ACTION;
92 	else if(strcmp(a, "drop") == 0) return RPZ_DROP_ACTION;
93 	else if(strcmp(a, "tcp_only") == 0) return RPZ_TCP_ONLY_ACTION;
94 	else if(strcmp(a, "cname") == 0) return RPZ_CNAME_OVERRIDE_ACTION;
95 	else if(strcmp(a, "disabled") == 0) return RPZ_DISABLED_ACTION;
96 	else return RPZ_INVALID_ACTION;
97 }
98 
99 /** string for RPZ trigger enum */
100 static const char*
rpz_trigger_to_string(enum rpz_trigger r)101 rpz_trigger_to_string(enum rpz_trigger r)
102 {
103 	switch(r) {
104 	case RPZ_QNAME_TRIGGER: return "rpz-qname";
105 	case RPZ_CLIENT_IP_TRIGGER: return "rpz-client-ip";
106 	case RPZ_RESPONSE_IP_TRIGGER: return "rpz-response-ip";
107 	case RPZ_NSDNAME_TRIGGER: return "rpz-nsdname";
108 	case RPZ_NSIP_TRIGGER: return "rpz-nsip";
109 	case RPZ_INVALID_TRIGGER: return "rpz-invalid";
110 	default: return "rpz-unknown-trigger";
111 	}
112 }
113 
114 /**
115  * Get the label that is just before the root label.
116  * @param dname: dname to work on
117  * @param maxdnamelen: maximum length of the dname
118  * @return: pointer to TLD label, NULL if not found or invalid dname
119  */
120 static uint8_t*
get_tld_label(uint8_t * dname,size_t maxdnamelen)121 get_tld_label(uint8_t* dname, size_t maxdnamelen)
122 {
123 	uint8_t* prevlab = dname;
124 	size_t dnamelen = 0;
125 
126 	/* one byte needed for label length */
127 	if(dnamelen+1 > maxdnamelen)
128 		return NULL;
129 
130 	/* only root label */
131 	if(*dname == 0)
132 		return NULL;
133 
134 	while(*dname) {
135 		dnamelen += ((size_t)*dname)+1;
136 		if(dnamelen+1 > maxdnamelen)
137 			return NULL;
138 		dname = dname+((size_t)*dname)+1;
139 		if(*dname != 0)
140 			prevlab = dname;
141 	}
142 	return prevlab;
143 }
144 
145 /**
146  * The RR types that are to be ignored.
147  * DNSSEC RRs at the apex, and SOA and NS are ignored.
148  */
149 static int
rpz_type_ignored(uint16_t rr_type)150 rpz_type_ignored(uint16_t rr_type)
151 {
152 	switch(rr_type) {
153 		case LDNS_RR_TYPE_SOA:
154 		case LDNS_RR_TYPE_NS:
155 		case LDNS_RR_TYPE_DNAME:
156 		/* all DNSSEC-related RRs must be ignored */
157 		case LDNS_RR_TYPE_DNSKEY:
158 		case LDNS_RR_TYPE_DS:
159 		case LDNS_RR_TYPE_RRSIG:
160 		case LDNS_RR_TYPE_NSEC:
161 		case LDNS_RR_TYPE_NSEC3:
162 		case LDNS_RR_TYPE_NSEC3PARAM:
163 			return 1;
164 		default:
165 			break;
166 	}
167 	return 0;
168 }
169 
170 /**
171  * Classify RPZ action for RR type/rdata
172  * @param rr_type: the RR type
173  * @param rdatawl: RDATA with 2 bytes length
174  * @param rdatalen: the length of rdatawl (including its 2 bytes length)
175  * @return: the RPZ action
176  */
177 static enum rpz_action
rpz_rr_to_action(uint16_t rr_type,uint8_t * rdatawl,size_t rdatalen)178 rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
179 {
180 	char* endptr;
181 	uint8_t* rdata;
182 	int rdatalabs;
183 	uint8_t* tldlab = NULL;
184 
185 	switch(rr_type) {
186 		case LDNS_RR_TYPE_SOA:
187 		case LDNS_RR_TYPE_NS:
188 		case LDNS_RR_TYPE_DNAME:
189 		/* all DNSSEC-related RRs must be ignored */
190 		case LDNS_RR_TYPE_DNSKEY:
191 		case LDNS_RR_TYPE_DS:
192 		case LDNS_RR_TYPE_RRSIG:
193 		case LDNS_RR_TYPE_NSEC:
194 		case LDNS_RR_TYPE_NSEC3:
195 		case LDNS_RR_TYPE_NSEC3PARAM:
196 			return RPZ_INVALID_ACTION;
197 		case LDNS_RR_TYPE_CNAME:
198 			break;
199 		default:
200 			return RPZ_LOCAL_DATA_ACTION;
201 	}
202 
203 	/* use CNAME target to determine RPZ action */
204 	log_assert(rr_type == LDNS_RR_TYPE_CNAME);
205 	if(rdatalen < 3)
206 		return RPZ_INVALID_ACTION;
207 
208 	rdata = rdatawl + 2; /* 2 bytes of rdata length */
209 	if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
210 		return RPZ_INVALID_ACTION;
211 
212 	rdatalabs = dname_count_labels(rdata);
213 	if(rdatalabs == 1)
214 		return RPZ_NXDOMAIN_ACTION;
215 	else if(rdatalabs == 2) {
216 		if(dname_subdomain_c(rdata, (uint8_t*)&"\001*\000"))
217 			return RPZ_NODATA_ACTION;
218 		else if(dname_subdomain_c(rdata,
219 			(uint8_t*)&"\014rpz-passthru\000"))
220 			return RPZ_PASSTHRU_ACTION;
221 		else if(dname_subdomain_c(rdata, (uint8_t*)&"\010rpz-drop\000"))
222 			return RPZ_DROP_ACTION;
223 		else if(dname_subdomain_c(rdata,
224 			(uint8_t*)&"\014rpz-tcp-only\000"))
225 			return RPZ_TCP_ONLY_ACTION;
226 	}
227 
228 	/* all other TLDs starting with "rpz-" are invalid */
229 	tldlab = get_tld_label(rdata, rdatalen-2);
230 	if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
231 		return RPZ_INVALID_ACTION;
232 
233 	/* no special label found */
234 	return RPZ_LOCAL_DATA_ACTION;
235 }
236 
237 static enum localzone_type
rpz_action_to_localzone_type(enum rpz_action a)238 rpz_action_to_localzone_type(enum rpz_action a)
239 {
240 	switch(a) {
241 	case RPZ_NXDOMAIN_ACTION: return local_zone_always_nxdomain;
242 	case RPZ_NODATA_ACTION: return local_zone_always_nodata;
243 	case RPZ_DROP_ACTION: return local_zone_always_deny;
244 	case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
245 	case RPZ_LOCAL_DATA_ACTION:	/* fallthrough */
246 	case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
247 	case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
248 	case RPZ_INVALID_ACTION: /* fallthrough */
249 	default: return local_zone_invalid;
250 	}
251 }
252 
253 enum respip_action
rpz_action_to_respip_action(enum rpz_action a)254 rpz_action_to_respip_action(enum rpz_action a)
255 {
256 	switch(a) {
257 	case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
258 	case RPZ_NODATA_ACTION: return respip_always_nodata;
259 	case RPZ_DROP_ACTION: return respip_always_deny;
260 	case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
261 	case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
262 	case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
263 	case RPZ_TCP_ONLY_ACTION: return respip_truncate;
264 	case RPZ_INVALID_ACTION: /* fallthrough */
265 	default: return respip_invalid;
266 	}
267 }
268 
269 static enum rpz_action
localzone_type_to_rpz_action(enum localzone_type lzt)270 localzone_type_to_rpz_action(enum localzone_type lzt)
271 {
272 	switch(lzt) {
273 	case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
274 	case local_zone_always_nodata: return RPZ_NODATA_ACTION;
275 	case local_zone_always_deny: return RPZ_DROP_ACTION;
276 	case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
277 	case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
278 	case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
279 	case local_zone_invalid: /* fallthrough */
280 	default: return RPZ_INVALID_ACTION;
281 	}
282 }
283 
284 enum rpz_action
respip_action_to_rpz_action(enum respip_action a)285 respip_action_to_rpz_action(enum respip_action a)
286 {
287 	switch(a) {
288 	case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
289 	case respip_always_nodata: return RPZ_NODATA_ACTION;
290 	case respip_always_deny: return RPZ_DROP_ACTION;
291 	case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
292 	case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
293 	case respip_truncate: return RPZ_TCP_ONLY_ACTION;
294 	case respip_invalid: /* fallthrough */
295 	default: return RPZ_INVALID_ACTION;
296 	}
297 }
298 
299 /**
300  * Get RPZ trigger for dname
301  * @param dname: dname containing RPZ trigger
302  * @param dname_len: length of the dname
303  * @return: RPZ trigger enum
304  */
305 static enum rpz_trigger
rpz_dname_to_trigger(uint8_t * dname,size_t dname_len)306 rpz_dname_to_trigger(uint8_t* dname, size_t dname_len)
307 {
308 	uint8_t* tldlab;
309 	char* endptr;
310 
311 	if(dname_valid(dname, dname_len) != dname_len)
312 		return RPZ_INVALID_TRIGGER;
313 
314 	tldlab = get_tld_label(dname, dname_len);
315 	if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr))
316 		return RPZ_QNAME_TRIGGER;
317 
318 	if(dname_subdomain_c(tldlab,
319 		(uint8_t*)&"\015rpz-client-ip\000"))
320 		return RPZ_CLIENT_IP_TRIGGER;
321 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000"))
322 		return RPZ_RESPONSE_IP_TRIGGER;
323 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000"))
324 		return RPZ_NSDNAME_TRIGGER;
325 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000"))
326 		return RPZ_NSIP_TRIGGER;
327 
328 	return RPZ_QNAME_TRIGGER;
329 }
330 
331 static inline struct clientip_synthesized_rrset*
rpz_clientip_synthesized_set_create(void)332 rpz_clientip_synthesized_set_create(void)
333 {
334 	struct clientip_synthesized_rrset* set = calloc(1, sizeof(*set));
335 	if(set == NULL) {
336 		return NULL;
337 	}
338 	set->region = regional_create();
339 	if(set->region == NULL) {
340 		free(set);
341 		return NULL;
342 	}
343 	addr_tree_init(&set->entries);
344 	lock_rw_init(&set->lock);
345 	return set;
346 }
347 
348 static void
rpz_clientip_synthesized_rr_delete(rbnode_type * n,void * ATTR_UNUSED (arg))349 rpz_clientip_synthesized_rr_delete(rbnode_type* n, void* ATTR_UNUSED(arg))
350 {
351 	struct clientip_synthesized_rr* r = (struct clientip_synthesized_rr*)n->key;
352 	lock_rw_destroy(&r->lock);
353 #ifdef THREADS_DISABLED
354 	(void)r;
355 #endif
356 }
357 
358 static inline void
rpz_clientip_synthesized_set_delete(struct clientip_synthesized_rrset * set)359 rpz_clientip_synthesized_set_delete(struct clientip_synthesized_rrset* set)
360 {
361 	if(set == NULL) {
362 		return;
363 	}
364 	lock_rw_destroy(&set->lock);
365 	traverse_postorder(&set->entries, rpz_clientip_synthesized_rr_delete, NULL);
366 	regional_destroy(set->region);
367 	free(set);
368 }
369 
370 void
rpz_delete(struct rpz * r)371 rpz_delete(struct rpz* r)
372 {
373 	if(!r)
374 		return;
375 	local_zones_delete(r->local_zones);
376 	local_zones_delete(r->nsdname_zones);
377 	respip_set_delete(r->respip_set);
378 	rpz_clientip_synthesized_set_delete(r->client_set);
379 	rpz_clientip_synthesized_set_delete(r->ns_set);
380 	regional_destroy(r->region);
381 	free(r->taglist);
382 	free(r->log_name);
383 	free(r);
384 }
385 
386 int
rpz_clear(struct rpz * r)387 rpz_clear(struct rpz* r)
388 {
389 	/* must hold write lock on auth_zone */
390 	local_zones_delete(r->local_zones);
391 	r->local_zones = NULL;
392 	local_zones_delete(r->nsdname_zones);
393 	r->nsdname_zones = NULL;
394 	respip_set_delete(r->respip_set);
395 	r->respip_set = NULL;
396 	rpz_clientip_synthesized_set_delete(r->client_set);
397 	r->client_set = NULL;
398 	rpz_clientip_synthesized_set_delete(r->ns_set);
399 	r->ns_set = NULL;
400 	if(!(r->local_zones = local_zones_create())){
401 		return 0;
402 	}
403 	r->nsdname_zones = local_zones_create();
404 	if(r->nsdname_zones == NULL) {
405 		return 0;
406 	}
407 	if(!(r->respip_set = respip_set_create())) {
408 		return 0;
409 	}
410 	if(!(r->client_set = rpz_clientip_synthesized_set_create())) {
411 		return 0;
412 	}
413 	if(!(r->ns_set = rpz_clientip_synthesized_set_create())) {
414 		return 0;
415 	}
416 	return 1;
417 }
418 
419 void
rpz_finish_config(struct rpz * r)420 rpz_finish_config(struct rpz* r)
421 {
422 	lock_rw_wrlock(&r->respip_set->lock);
423 	addr_tree_init_parents(&r->respip_set->ip_tree);
424 	lock_rw_unlock(&r->respip_set->lock);
425 
426 	lock_rw_wrlock(&r->client_set->lock);
427 	addr_tree_init_parents(&r->client_set->entries);
428 	lock_rw_unlock(&r->client_set->lock);
429 
430 	lock_rw_wrlock(&r->ns_set->lock);
431 	addr_tree_init_parents(&r->ns_set->entries);
432 	lock_rw_unlock(&r->ns_set->lock);
433 }
434 
435 /** new rrset containing CNAME override, does not yet contain a dname */
436 static struct ub_packed_rrset_key*
new_cname_override(struct regional * region,uint8_t * ct,size_t ctlen)437 new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen)
438 {
439 	struct ub_packed_rrset_key* rrset;
440 	struct packed_rrset_data* pd;
441 	uint16_t rdlength = htons(ctlen);
442 	rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region,
443 		sizeof(*rrset));
444 	if(!rrset) {
445 		log_err("out of memory");
446 		return NULL;
447 	}
448 	rrset->entry.key = rrset;
449 	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
450 	if(!pd) {
451 		log_err("out of memory");
452 		return NULL;
453 	}
454 	pd->trust = rrset_trust_prim_noglue;
455 	pd->security = sec_status_insecure;
456 
457 	pd->count = 1;
458 	pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len));
459 	pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl));
460 	pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data));
461 	if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
462 		log_err("out of memory");
463 		return NULL;
464 	}
465 	pd->rr_len[0] = ctlen+2;
466 	pd->rr_ttl[0] = 3600;
467 	pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen);
468 	if(!pd->rr_data[0]) {
469 		log_err("out of memory");
470 		return NULL;
471 	}
472 	memmove(pd->rr_data[0], &rdlength, 2);
473 	memmove(pd->rr_data[0]+2, ct, ctlen);
474 
475 	rrset->entry.data = pd;
476 	rrset->rk.type = htons(LDNS_RR_TYPE_CNAME);
477 	rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN);
478 	return rrset;
479 }
480 
481 /** delete the cname override */
482 static void
delete_cname_override(struct rpz * r)483 delete_cname_override(struct rpz* r)
484 {
485 	if(r->cname_override) {
486 		/* The cname override is what is allocated in the region. */
487 		regional_free_all(r->region);
488 		r->cname_override = NULL;
489 	}
490 }
491 
492 /** Apply rpz config elements to the rpz structure, false on failure. */
493 static int
rpz_apply_cfg_elements(struct rpz * r,struct config_auth * p)494 rpz_apply_cfg_elements(struct rpz* r, struct config_auth* p)
495 {
496 	if(p->rpz_taglist && p->rpz_taglistlen) {
497 		r->taglistlen = p->rpz_taglistlen;
498 		r->taglist = memdup(p->rpz_taglist, r->taglistlen);
499 		if(!r->taglist) {
500 			log_err("malloc failure on RPZ taglist alloc");
501 			return 0;
502 		}
503 	}
504 
505 	if(p->rpz_action_override) {
506 		r->action_override = rpz_config_to_action(p->rpz_action_override);
507 	}
508 	else
509 		r->action_override = RPZ_NO_OVERRIDE_ACTION;
510 
511 	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
512 		uint8_t nm[LDNS_MAX_DOMAINLEN+1];
513 		size_t nmlen = sizeof(nm);
514 
515 		if(!p->rpz_cname) {
516 			log_err("rpz: override with cname action found, but no "
517 				"rpz-cname-override configured");
518 			return 0;
519 		}
520 
521 		if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) {
522 			log_err("rpz: cannot parse cname override: %s",
523 				p->rpz_cname);
524 			return 0;
525 		}
526 		r->cname_override = new_cname_override(r->region, nm, nmlen);
527 		if(!r->cname_override) {
528 			return 0;
529 		}
530 	}
531 	r->log = p->rpz_log;
532 	r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra;
533 	if(p->rpz_log_name) {
534 		if(!(r->log_name = strdup(p->rpz_log_name))) {
535 			log_err("malloc failure on RPZ log_name strdup");
536 			return 0;
537 		}
538 	}
539 	return 1;
540 }
541 
542 struct rpz*
rpz_create(struct config_auth * p)543 rpz_create(struct config_auth* p)
544 {
545 	struct rpz* r = calloc(1, sizeof(*r));
546 	if(!r)
547 		goto err;
548 
549 	r->region = regional_create_custom(sizeof(struct regional));
550 	if(!r->region) {
551 		goto err;
552 	}
553 
554 	if(!(r->local_zones = local_zones_create())){
555 		goto err;
556 	}
557 
558 	r->nsdname_zones = local_zones_create();
559 	if(r->local_zones == NULL){
560 		goto err;
561 	}
562 
563 	if(!(r->respip_set = respip_set_create())) {
564 		goto err;
565 	}
566 
567 	r->client_set = rpz_clientip_synthesized_set_create();
568 	if(r->client_set == NULL) {
569 		goto err;
570 	}
571 
572 	r->ns_set = rpz_clientip_synthesized_set_create();
573 	if(r->ns_set == NULL) {
574 		goto err;
575 	}
576 
577 	if(!rpz_apply_cfg_elements(r, p))
578 		goto err;
579 	return r;
580 err:
581 	if(r) {
582 		if(r->local_zones)
583 			local_zones_delete(r->local_zones);
584 		if(r->nsdname_zones)
585 			local_zones_delete(r->nsdname_zones);
586 		if(r->respip_set)
587 			respip_set_delete(r->respip_set);
588 		if(r->client_set != NULL)
589 			rpz_clientip_synthesized_set_delete(r->client_set);
590 		if(r->ns_set != NULL)
591 			rpz_clientip_synthesized_set_delete(r->ns_set);
592 		if(r->taglist)
593 			free(r->taglist);
594 		if(r->region)
595 			regional_destroy(r->region);
596 		free(r);
597 	}
598 	return NULL;
599 }
600 
601 int
rpz_config(struct rpz * r,struct config_auth * p)602 rpz_config(struct rpz* r, struct config_auth* p)
603 {
604 	/* If the zonefile changes, it is read later, after which
605 	 * rpz_clear and rpz_finish_config is called. */
606 
607 	/* free taglist, if any */
608 	if(r->taglist) {
609 		free(r->taglist);
610 		r->taglist = NULL;
611 		r->taglistlen = 0;
612 	}
613 
614 	/* free logname, if any */
615 	if(r->log_name) {
616 		free(r->log_name);
617 		r->log_name = NULL;
618 	}
619 
620 	delete_cname_override(r);
621 
622 	if(!rpz_apply_cfg_elements(r, p))
623 		return 0;
624 	return 1;
625 }
626 
627 /**
628  * Remove RPZ zone name from dname
629  * Copy dname to newdname, without the originlen number of trailing bytes
630  */
631 static size_t
strip_dname_origin(uint8_t * dname,size_t dnamelen,size_t originlen,uint8_t * newdname,size_t maxnewdnamelen)632 strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
633 	uint8_t* newdname, size_t maxnewdnamelen)
634 {
635 	size_t newdnamelen;
636 	if(dnamelen < originlen)
637 		return 0;
638 	newdnamelen = dnamelen - originlen;
639 	if(newdnamelen+1 > maxnewdnamelen)
640 		return 0;
641 	memmove(newdname, dname, newdnamelen);
642 	newdname[newdnamelen] = 0;
643 	return newdnamelen + 1;	/* + 1 for root label */
644 }
645 
646 static void
rpz_insert_local_zones_trigger(struct local_zones * lz,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)647 rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
648 	size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass,
649 	uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
650 {
651 	struct local_zone* z;
652 	enum localzone_type tp = local_zone_always_transparent;
653 	int dnamelabs = dname_count_labels(dname);
654 	int newzone = 0;
655 
656 	if(a == RPZ_INVALID_ACTION) {
657 		char str[255+1];
658 		if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS ||
659 			rrtype == LDNS_RR_TYPE_DNAME ||
660 			rrtype == LDNS_RR_TYPE_DNSKEY ||
661 			rrtype == LDNS_RR_TYPE_RRSIG ||
662 			rrtype == LDNS_RR_TYPE_NSEC ||
663 			rrtype == LDNS_RR_TYPE_NSEC3PARAM ||
664 			rrtype == LDNS_RR_TYPE_NSEC3 ||
665 			rrtype == LDNS_RR_TYPE_DS) {
666 			free(dname);
667 			return; /* no need to log these types as unsupported */
668 		}
669 		dname_str(dname, str);
670 		verbose(VERB_ALGO, "rpz: qname trigger, %s skipping unsupported action: %s",
671 			str, rpz_action_to_string(a));
672 		free(dname);
673 		return;
674 	}
675 
676 	lock_rw_wrlock(&lz->lock);
677 	/* exact match */
678 	z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
679 	if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) {
680 		char* rrstr = sldns_wire2str_rr(rr, rr_len);
681 		if(rrstr == NULL) {
682 			log_err("malloc error while inserting rpz nsdname trigger");
683 			free(dname);
684 			lock_rw_unlock(&lz->lock);
685 			return;
686 		}
687 		if(rrstr[0])
688 			rrstr[strlen(rrstr)-1]=0; /* remove newline */
689 		verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr);
690 		free(rrstr);
691 		free(dname);
692 		lock_rw_unlock(&lz->lock);
693 		return;
694 	}
695 	if(z == NULL) {
696 		tp = rpz_action_to_localzone_type(a);
697 		z = local_zones_add_zone(lz, dname, dnamelen,
698 					 dnamelabs, rrclass, tp);
699 		if(z == NULL) {
700 			log_warn("rpz: create failed");
701 			lock_rw_unlock(&lz->lock);
702 			/* dname will be free'd in failed local_zone_create() */
703 			return;
704 		}
705 		newzone = 1;
706 	}
707 	if(a == RPZ_LOCAL_DATA_ACTION) {
708 		char* rrstr = sldns_wire2str_rr(rr, rr_len);
709 		if(rrstr == NULL) {
710 			log_err("malloc error while inserting rpz nsdname trigger");
711 			free(dname);
712 			lock_rw_unlock(&lz->lock);
713 			return;
714 		}
715 		lock_rw_wrlock(&z->lock);
716 		local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype,
717 				    rrclass, ttl, rdata, rdata_len, rrstr);
718 		lock_rw_unlock(&z->lock);
719 		free(rrstr);
720 	}
721 	if(!newzone) {
722 		free(dname);
723 	}
724 	lock_rw_unlock(&lz->lock);
725 }
726 
727 static void
rpz_log_dname(char const * msg,uint8_t * dname,size_t dname_len)728 rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
729 {
730 	char buf[LDNS_MAX_DOMAINLEN+1];
731 	(void)dname_len;
732 	dname_str(dname, buf);
733 	verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf);
734 }
735 
736 static void
rpz_insert_qname_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)737 rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
738 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
739 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
740 {
741 	if(a == RPZ_INVALID_ACTION) {
742 		verbose(VERB_ALGO, "rpz: skipping invalid action");
743 		free(dname);
744 		return;
745 	}
746 
747 	rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype,
748 				       rrclass, ttl, rdata, rdata_len, rr, rr_len);
749 }
750 
751 static int
rpz_strip_nsdname_suffix(uint8_t * dname,size_t maxdnamelen,uint8_t ** stripdname,size_t * stripdnamelen)752 rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen,
753 	uint8_t** stripdname, size_t* stripdnamelen)
754 {
755 	uint8_t* tldstart = get_tld_label(dname, maxdnamelen);
756 	uint8_t swap;
757 	if(tldstart == NULL) {
758 		if(dname == NULL) {
759 			*stripdname = NULL;
760 			*stripdnamelen = 0;
761 			return 0;
762 		}
763 		*stripdname = memdup(dname, maxdnamelen);
764 		if(!*stripdname) {
765 			*stripdnamelen = 0;
766 			log_err("malloc failure for rpz strip suffix");
767 			return 0;
768 		}
769 		*stripdnamelen = maxdnamelen;
770 		return 1;
771 	}
772 	/* shorten the domain name briefly,
773 	 * then we allocate a new name with the correct length */
774 	swap = *tldstart;
775 	*tldstart = 0;
776 	(void)dname_count_size_labels(dname, stripdnamelen);
777 	*stripdname = memdup(dname, *stripdnamelen);
778 	*tldstart = swap;
779 	if(!*stripdname) {
780 		*stripdnamelen = 0;
781 		log_err("malloc failure for rpz strip suffix");
782 		return 0;
783 	}
784 	return 1;
785 }
786 
787 static void
rpz_insert_nsdname_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)788 rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
789 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
790 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
791 {
792 	uint8_t* dname_stripped = NULL;
793 	size_t dnamelen_stripped = 0;
794 
795 	rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped,
796 		&dnamelen_stripped);
797 	if(a == RPZ_INVALID_ACTION) {
798 		verbose(VERB_ALGO, "rpz: skipping invalid action");
799 		free(dname_stripped);
800 		return;
801 	}
802 
803 	/* dname_stripped is consumed or freed by the insert routine */
804 	rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped,
805 		dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len,
806 		rr, rr_len);
807 }
808 
809 static int
rpz_insert_ipaddr_based_trigger(struct respip_set * set,struct sockaddr_storage * addr,socklen_t addrlen,int net,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)810 rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr,
811 	socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
812 	uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
813 	uint8_t* rr, size_t rr_len)
814 {
815 	struct resp_addr* node;
816 	char* rrstr;
817 	enum respip_action respa = rpz_action_to_respip_action(a);
818 
819 	lock_rw_wrlock(&set->lock);
820 	rrstr = sldns_wire2str_rr(rr, rr_len);
821 	if(rrstr == NULL) {
822 		log_err("malloc error while inserting rpz ipaddr based trigger");
823 		lock_rw_unlock(&set->lock);
824 		return 0;
825 	}
826 
827 	node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr);
828 	if(node == NULL) {
829 		lock_rw_unlock(&set->lock);
830 		free(rrstr);
831 		return 0;
832 	}
833 
834 	lock_rw_wrlock(&node->lock);
835 	lock_rw_unlock(&set->lock);
836 
837 	node->action = respa;
838 
839 	if(a == RPZ_LOCAL_DATA_ACTION) {
840 		respip_enter_rr(set->region, node, rrtype,
841 				rrclass, ttl, rdata, rdata_len, rrstr, "");
842 	}
843 
844 	lock_rw_unlock(&node->lock);
845 	free(rrstr);
846 	return 1;
847 }
848 
849 static inline struct clientip_synthesized_rr*
rpz_clientip_ensure_entry(struct clientip_synthesized_rrset * set,struct sockaddr_storage * addr,socklen_t addrlen,int net)850 rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set,
851 	struct sockaddr_storage* addr, socklen_t addrlen, int net)
852 {
853 	int insert_ok;
854 	struct clientip_synthesized_rr* node =
855 		(struct clientip_synthesized_rr*)addr_tree_find(&set->entries,
856 								addr, addrlen, net);
857 
858 	if(node != NULL) { return node; }
859 
860 	/* node does not yet exist => allocate one */
861 	node = regional_alloc_zero(set->region, sizeof(*node));
862 	if(node == NULL) {
863 		log_err("out of memory");
864 		return NULL;
865 	}
866 
867 	lock_rw_init(&node->lock);
868 	node->action = RPZ_INVALID_ACTION;
869 	insert_ok = addr_tree_insert(&set->entries, &node->node,
870 				     addr, addrlen, net);
871 	if (!insert_ok) {
872 		log_warn("rpz: unexpected: unable to insert clientip address node");
873 		/* we can not free the just allocated node.
874 		 * theoretically a memleak */
875 		return NULL;
876 	}
877 
878 	return node;
879 }
880 
881 static void
rpz_report_rrset_error(const char * msg,uint8_t * rr,size_t rr_len)882 rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
883 	char* rrstr = sldns_wire2str_rr(rr, rr_len);
884 	if(rrstr == NULL) {
885 		log_err("malloc error while inserting rpz clientip based record");
886 		return;
887 	}
888 	log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr);
889 	free(rrstr);
890 }
891 
892 /* from localzone.c; difference is we don't have a dname */
893 static struct local_rrset*
rpz_clientip_new_rrset(struct regional * region,struct clientip_synthesized_rr * raddr,uint16_t rrtype,uint16_t rrclass)894 rpz_clientip_new_rrset(struct regional* region,
895 	struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass)
896 {
897 	struct packed_rrset_data* pd;
898 	struct local_rrset* rrset = (struct local_rrset*)
899 		regional_alloc_zero(region, sizeof(*rrset));
900 	if(rrset == NULL) {
901 		log_err("out of memory");
902 		return NULL;
903 	}
904 	rrset->next = raddr->data;
905 	raddr->data = rrset;
906 	rrset->rrset = (struct ub_packed_rrset_key*)
907 		regional_alloc_zero(region, sizeof(*rrset->rrset));
908 	if(rrset->rrset == NULL) {
909 		log_err("out of memory");
910 		return NULL;
911 	}
912 	rrset->rrset->entry.key = rrset->rrset;
913 	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
914 	if(pd == NULL) {
915 		log_err("out of memory");
916 		return NULL;
917 	}
918 	pd->trust = rrset_trust_prim_noglue;
919 	pd->security = sec_status_insecure;
920 	rrset->rrset->entry.data = pd;
921 	rrset->rrset->rk.type = htons(rrtype);
922 	rrset->rrset->rk.rrset_class = htons(rrclass);
923 	rrset->rrset->rk.dname = regional_alloc_zero(region, 1);
924 	if(rrset->rrset->rk.dname == NULL) {
925 		log_err("out of memory");
926 		return NULL;
927 	}
928 	rrset->rrset->rk.dname_len = 1;
929 	return rrset;
930 }
931 
932 static int
rpz_clientip_enter_rr(struct regional * region,struct clientip_synthesized_rr * raddr,uint16_t rrtype,uint16_t rrclass,time_t ttl,uint8_t * rdata,size_t rdata_len)933 rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* raddr,
934 	uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
935 	size_t rdata_len)
936 {
937 	struct local_rrset* rrset;
938 	if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data != NULL) {
939 		log_err("CNAME response-ip data can not co-exist with other "
940 			"client-ip data");
941 		return 0;
942 	}
943 
944 	rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass);
945 	if(raddr->data == NULL) {
946 		return 0;
947 	}
948 
949 	return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "");
950 }
951 
952 static int
rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset * set,struct sockaddr_storage * addr,socklen_t addrlen,int net,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)953 rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr,
954 	socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
955 	uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
956 	uint8_t* rr, size_t rr_len)
957 {
958 	struct clientip_synthesized_rr* node;
959 
960 	lock_rw_wrlock(&set->lock);
961 
962 	node = rpz_clientip_ensure_entry(set, addr, addrlen, net);
963 	if(node == NULL) {
964 		lock_rw_unlock(&set->lock);
965 		rpz_report_rrset_error("client ip address", rr, rr_len);
966 		return 0;
967 	}
968 
969 	lock_rw_wrlock(&node->lock);
970 	lock_rw_unlock(&set->lock);
971 
972 	node->action = a;
973 	if(a == RPZ_LOCAL_DATA_ACTION) {
974 		if(!rpz_clientip_enter_rr(set->region, node, rrtype,
975 			rrclass, ttl, rdata, rdata_len)) {
976 			verbose(VERB_ALGO, "rpz: unable to insert clientip rr");
977 			lock_rw_unlock(&node->lock);
978 			return 0;
979 		}
980 
981 	}
982 
983 	lock_rw_unlock(&node->lock);
984 
985 	return 1;
986 }
987 
988 static int
rpz_insert_clientip_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)989 rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
990 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
991 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
992 {
993 	struct sockaddr_storage addr;
994 	socklen_t addrlen;
995 	int net, af;
996 
997 	if(a == RPZ_INVALID_ACTION) {
998 		return 0;
999 	}
1000 
1001 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
1002 		verbose(VERB_ALGO, "rpz: unable to parse client ip");
1003 		return 0;
1004 	}
1005 
1006 	return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net,
1007 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1008 }
1009 
1010 static int
rpz_insert_nsip_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)1011 rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1012 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
1013 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
1014 {
1015 	struct sockaddr_storage addr;
1016 	socklen_t addrlen;
1017 	int net, af;
1018 
1019 	if(a == RPZ_INVALID_ACTION) {
1020 		return 0;
1021 	}
1022 
1023 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
1024 		verbose(VERB_ALGO, "rpz: unable to parse ns ip");
1025 		return 0;
1026 	}
1027 
1028 	return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net,
1029 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1030 }
1031 
1032 /** Insert RR into RPZ's respip_set */
1033 static int
rpz_insert_response_ip_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rrtype,uint16_t rrclass,uint32_t ttl,uint8_t * rdata,size_t rdata_len,uint8_t * rr,size_t rr_len)1034 rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1035 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
1036 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
1037 {
1038 	struct sockaddr_storage addr;
1039 	socklen_t addrlen;
1040 	int net, af;
1041 
1042 	if(a == RPZ_INVALID_ACTION) {
1043 		return 0;
1044 	}
1045 
1046 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
1047 		verbose(VERB_ALGO, "rpz: unable to parse response ip");
1048 		return 0;
1049 	}
1050 
1051 	if(a == RPZ_INVALID_ACTION ||
1052 		rpz_action_to_respip_action(a) == respip_invalid) {
1053 		char str[255+1];
1054 		dname_str(dname, str);
1055 		verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s",
1056 			str, rpz_action_to_string(a));
1057 		return 0;
1058 	}
1059 
1060 	return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net,
1061 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1062 }
1063 
1064 int
rpz_insert_rr(struct rpz * r,uint8_t * azname,size_t aznamelen,uint8_t * dname,size_t dnamelen,uint16_t rr_type,uint16_t rr_class,uint32_t rr_ttl,uint8_t * rdatawl,size_t rdatalen,uint8_t * rr,size_t rr_len)1065 rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
1066 	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
1067 	uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
1068 {
1069 	size_t policydnamelen;
1070 	/* name is free'd in local_zone delete */
1071 	enum rpz_trigger t;
1072 	enum rpz_action a;
1073 	uint8_t* policydname;
1074 
1075 	if(rpz_type_ignored(rr_type)) {
1076 		/* this rpz action is not valid, eg. this is the SOA or NS RR */
1077 		return 1;
1078 	}
1079 	if(!dname_subdomain_c(dname, azname)) {
1080 		char* dname_str = sldns_wire2str_dname(dname, dnamelen);
1081 		char* azname_str = sldns_wire2str_dname(azname, aznamelen);
1082 		if(dname_str && azname_str) {
1083 			log_err("rpz: name of record (%s) to insert into RPZ is not a "
1084 				"subdomain of the configured name of the RPZ zone (%s)",
1085 				dname_str, azname_str);
1086 		} else {
1087 			log_err("rpz: name of record to insert into RPZ is not a "
1088 				"subdomain of the configured name of the RPZ zone");
1089 		}
1090 		free(dname_str);
1091 		free(azname_str);
1092 		return 0;
1093 	}
1094 
1095 	log_assert(dnamelen >= aznamelen);
1096 	if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) {
1097 		log_err("malloc error while inserting RPZ RR");
1098 		return 0;
1099 	}
1100 
1101 	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
1102 	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
1103 		policydname, (dnamelen-aznamelen)+1))) {
1104 		free(policydname);
1105 		return 0;
1106 	}
1107 	t = rpz_dname_to_trigger(policydname, policydnamelen);
1108 	if(t == RPZ_INVALID_TRIGGER) {
1109 		free(policydname);
1110 		verbose(VERB_ALGO, "rpz: skipping invalid trigger");
1111 		return 1;
1112 	}
1113 	if(t == RPZ_QNAME_TRIGGER) {
1114 		/* policydname will be consumed, no free */
1115 		rpz_insert_qname_trigger(r, policydname, policydnamelen,
1116 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1117 			rr_len);
1118 	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
1119 		rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
1120 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1121 			rr_len);
1122 		free(policydname);
1123 	} else if(t == RPZ_CLIENT_IP_TRIGGER) {
1124 		rpz_insert_clientip_trigger(r, policydname, policydnamelen,
1125 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1126 			rr_len);
1127 		free(policydname);
1128 	} else if(t == RPZ_NSIP_TRIGGER) {
1129 		rpz_insert_nsip_trigger(r, policydname, policydnamelen,
1130 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1131 			rr_len);
1132 		free(policydname);
1133 	} else if(t == RPZ_NSDNAME_TRIGGER) {
1134 		rpz_insert_nsdname_trigger(r, policydname, policydnamelen,
1135 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1136 			rr_len);
1137 		free(policydname);
1138 	} else {
1139 		free(policydname);
1140 		verbose(VERB_ALGO, "rpz: skipping unsupported trigger: %s",
1141 			rpz_trigger_to_string(t));
1142 	}
1143 	return 1;
1144 }
1145 
1146 /**
1147  * Find RPZ local-zone by qname.
1148  * @param zones: local-zone tree
1149  * @param qname: qname
1150  * @param qname_len: length of qname
1151  * @param qclass: qclass
1152  * @param only_exact: if 1 only exact (non wildcard) matches are returned
1153  * @param wr: get write lock for local-zone if 1, read lock if 0
1154  * @param zones_keep_lock: if set do not release the r->local_zones lock, this
1155  * 	  makes the caller of this function responsible for releasing the lock.
1156  * @return: NULL or local-zone holding rd or wr lock
1157  */
1158 static struct local_zone*
rpz_find_zone(struct local_zones * zones,uint8_t * qname,size_t qname_len,uint16_t qclass,int only_exact,int wr,int zones_keep_lock)1159 rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint16_t qclass,
1160 	int only_exact, int wr, int zones_keep_lock)
1161 {
1162 	uint8_t* ce;
1163 	size_t ce_len;
1164 	int ce_labs;
1165 	uint8_t wc[LDNS_MAX_DOMAINLEN+1];
1166 	int exact;
1167 	struct local_zone* z = NULL;
1168 
1169 	if(wr) {
1170 		lock_rw_wrlock(&zones->lock);
1171 	} else {
1172 		lock_rw_rdlock(&zones->lock);
1173 	}
1174 	z = local_zones_find_le(zones, qname, qname_len,
1175 		dname_count_labels(qname),
1176 		LDNS_RR_CLASS_IN, &exact);
1177 	if(!z || (only_exact && !exact)) {
1178 		if(!zones_keep_lock) {
1179 			lock_rw_unlock(&zones->lock);
1180 		}
1181 		return NULL;
1182 	}
1183 	if(wr) {
1184 		lock_rw_wrlock(&z->lock);
1185 	} else {
1186 		lock_rw_rdlock(&z->lock);
1187 	}
1188 	if(!zones_keep_lock) {
1189 		lock_rw_unlock(&zones->lock);
1190 	}
1191 
1192 	if(exact)
1193 		return z;
1194 
1195 	/* No exact match found, lookup wildcard. closest encloser must
1196 	 * be the shared parent between the qname and the best local
1197 	 * zone match, append '*' to that and do another lookup. */
1198 
1199 	ce = dname_get_shared_topdomain(z->name, qname);
1200 	if(!ce /* should not happen */) {
1201 		lock_rw_unlock(&z->lock);
1202 		if(zones_keep_lock) {
1203 			lock_rw_unlock(&zones->lock);
1204 		}
1205 		return NULL;
1206 	}
1207 	ce_labs = dname_count_size_labels(ce, &ce_len);
1208 	if(ce_len+2 > sizeof(wc)) {
1209 		lock_rw_unlock(&z->lock);
1210 		if(zones_keep_lock) {
1211 			lock_rw_unlock(&zones->lock);
1212 		}
1213 		return NULL;
1214 	}
1215 	wc[0] = 1; /* length of wildcard label */
1216 	wc[1] = (uint8_t)'*'; /* wildcard label */
1217 	memmove(wc+2, ce, ce_len);
1218 	lock_rw_unlock(&z->lock);
1219 
1220 	if(!zones_keep_lock) {
1221 		if(wr) {
1222 			lock_rw_wrlock(&zones->lock);
1223 		} else {
1224 			lock_rw_rdlock(&zones->lock);
1225 		}
1226 	}
1227 	z = local_zones_find_le(zones, wc,
1228 		ce_len+2, ce_labs+1, qclass, &exact);
1229 	if(!z || !exact) {
1230 		lock_rw_unlock(&zones->lock);
1231 		return NULL;
1232 	}
1233 	if(wr) {
1234 		lock_rw_wrlock(&z->lock);
1235 	} else {
1236 		lock_rw_rdlock(&z->lock);
1237 	}
1238 	if(!zones_keep_lock) {
1239 		lock_rw_unlock(&zones->lock);
1240 	}
1241 	return z;
1242 }
1243 
1244 /** Find entry for RR type in the list of rrsets for the clientip. */
1245 static struct local_rrset*
rpz_find_synthesized_rrset(uint16_t qtype,struct clientip_synthesized_rr * data,int alias_ok)1246 rpz_find_synthesized_rrset(uint16_t qtype,
1247 	struct clientip_synthesized_rr* data, int alias_ok)
1248 {
1249 	struct local_rrset* cursor = data->data, *cname = NULL;
1250 	while( cursor != NULL) {
1251 		struct packed_rrset_key* packed_rrset = &cursor->rrset->rk;
1252 		if(htons(qtype) == packed_rrset->type) {
1253 			return cursor;
1254 		}
1255 		if(ntohs(packed_rrset->type) == LDNS_RR_TYPE_CNAME && alias_ok)
1256 			cname = cursor;
1257 		cursor = cursor->next;
1258 	}
1259 	if(alias_ok)
1260 		return cname;
1261 	return NULL;
1262 }
1263 
1264 /**
1265  * Remove RR from RPZ's local-data
1266  * @param z: local-zone for RPZ, holding write lock
1267  * @param policydname: dname of RR to remove
1268  * @param policydnamelen: length of policydname
1269  * @param rr_type: RR type of RR to remove
1270  * @param rdata: rdata of RR to remove
1271  * @param rdatalen: length of rdata
1272  * @return: 1 if zone must be removed after RR deletion
1273  */
1274 static int
rpz_data_delete_rr(struct local_zone * z,uint8_t * policydname,size_t policydnamelen,uint16_t rr_type,uint8_t * rdata,size_t rdatalen)1275 rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname,
1276 	size_t policydnamelen, uint16_t rr_type, uint8_t* rdata,
1277 	size_t rdatalen)
1278 {
1279 	struct local_data* ld;
1280 	struct packed_rrset_data* d;
1281 	size_t index;
1282 	ld = local_zone_find_data(z, policydname, policydnamelen,
1283 		dname_count_labels(policydname));
1284 	if(ld) {
1285 		struct local_rrset* prev=NULL, *p=ld->rrsets;
1286 		while(p && ntohs(p->rrset->rk.type) != rr_type) {
1287 			prev = p;
1288 			p = p->next;
1289 		}
1290 		if(!p)
1291 			return 0;
1292 		d = (struct packed_rrset_data*)p->rrset->entry.data;
1293 		if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
1294 			if(d->count == 1) {
1295 				/* no memory recycling for zone deletions ... */
1296 				if(prev) prev->next = p->next;
1297 				else ld->rrsets = p->next;
1298 			}
1299 			if(d->count > 1) {
1300 				if(!local_rrset_remove_rr(d, index))
1301 					return 0;
1302 			}
1303 		}
1304 	}
1305 	if(ld && ld->rrsets)
1306 		return 0;
1307 	return 1;
1308 }
1309 
1310 /**
1311  * Remove RR from RPZ's respip set
1312  * @param raddr: respip node
1313  * @param rr_type: RR type of RR to remove
1314  * @param rdata: rdata of RR to remove
1315  * @param rdatalen: length of rdata
1316  * @return: 1 if zone must be removed after RR deletion
1317  */
1318 static int
rpz_rrset_delete_rr(struct resp_addr * raddr,uint16_t rr_type,uint8_t * rdata,size_t rdatalen)1319 rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata,
1320 	size_t rdatalen)
1321 {
1322 	size_t index;
1323 	struct packed_rrset_data* d;
1324 	if(!raddr->data)
1325 		return 1;
1326 	d = raddr->data->entry.data;
1327 	if(ntohs(raddr->data->rk.type) != rr_type) {
1328 		return 0;
1329 	}
1330 	if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
1331 		if(d->count == 1) {
1332 			/* regional alloc'd */
1333 			raddr->data->entry.data = NULL;
1334 			raddr->data = NULL;
1335 			return 1;
1336 		}
1337 		if(d->count > 1) {
1338 			if(!local_rrset_remove_rr(d, index))
1339 				return 0;
1340 		}
1341 	}
1342 	return 0;
1343 
1344 }
1345 
1346 /** Remove RR from rpz localzones structure */
1347 static void
rpz_remove_local_zones_trigger(struct local_zones * zones,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rr_type,uint16_t rr_class,uint8_t * rdatawl,size_t rdatalen)1348 rpz_remove_local_zones_trigger(struct local_zones* zones, uint8_t* dname,
1349 	size_t dnamelen, enum rpz_action a, uint16_t rr_type,
1350 	uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
1351 {
1352 	struct local_zone* z;
1353 	int delete_zone = 1;
1354 	z = rpz_find_zone(zones, dname, dnamelen, rr_class,
1355 		1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/);
1356 	if(!z) {
1357 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1358 			"RPZ domain not found");
1359 		return;
1360 	}
1361 	if(a == RPZ_LOCAL_DATA_ACTION)
1362 		delete_zone = rpz_data_delete_rr(z, dname,
1363 			dnamelen, rr_type, rdatawl, rdatalen);
1364 	else if(a != localzone_type_to_rpz_action(z->type)) {
1365 		lock_rw_unlock(&z->lock);
1366 		lock_rw_unlock(&zones->lock);
1367 		return;
1368 	}
1369 	lock_rw_unlock(&z->lock);
1370 	if(delete_zone) {
1371 		local_zones_del_zone(zones, z);
1372 	}
1373 	lock_rw_unlock(&zones->lock);
1374 }
1375 
1376 /** Remove RR from RPZ's local-zone */
1377 static void
rpz_remove_qname_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rr_type,uint16_t rr_class,uint8_t * rdatawl,size_t rdatalen)1378 rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1379 	enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
1380 	uint8_t* rdatawl, size_t rdatalen)
1381 {
1382 	rpz_remove_local_zones_trigger(r->local_zones, dname, dnamelen,
1383 		a, rr_type, rr_class, rdatawl, rdatalen);
1384 }
1385 
1386 static void
rpz_remove_response_ip_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rr_type,uint8_t * rdatawl,size_t rdatalen)1387 rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1388 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1389 {
1390 	struct resp_addr* node;
1391 	struct sockaddr_storage addr;
1392 	socklen_t addrlen;
1393 	int net, af;
1394 	int delete_respip = 1;
1395 
1396 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1397 		return;
1398 
1399 	lock_rw_wrlock(&r->respip_set->lock);
1400 	if(!(node = (struct resp_addr*)addr_tree_find(
1401 		&r->respip_set->ip_tree, &addr, addrlen, net))) {
1402 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1403 			"RPZ domain not found");
1404 		lock_rw_unlock(&r->respip_set->lock);
1405 		return;
1406 	}
1407 
1408 	lock_rw_wrlock(&node->lock);
1409 	if(a == RPZ_LOCAL_DATA_ACTION) {
1410 		/* remove RR, signal whether RR can be removed */
1411 		delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl,
1412 			rdatalen);
1413 	}
1414 	lock_rw_unlock(&node->lock);
1415 	if(delete_respip)
1416 		respip_sockaddr_delete(r->respip_set, node);
1417 	lock_rw_unlock(&r->respip_set->lock);
1418 }
1419 
1420 /** find and remove type from list of local_rrset entries*/
1421 static void
del_local_rrset_from_list(struct local_rrset ** list_head,uint16_t dtype)1422 del_local_rrset_from_list(struct local_rrset** list_head, uint16_t dtype)
1423 {
1424 	struct local_rrset* prev=NULL, *p=*list_head;
1425 	while(p && ntohs(p->rrset->rk.type) != dtype) {
1426 		prev = p;
1427 		p = p->next;
1428 	}
1429 	if(!p)
1430 		return; /* rrset type not found */
1431 	/* unlink it */
1432 	if(prev) prev->next = p->next;
1433 	else *list_head = p->next;
1434 	/* no memory recycling for zone deletions ... */
1435 }
1436 
1437 /** Delete client-ip trigger RR from its RRset and perhaps also the rrset
1438  * from the linked list. Returns if the local data is empty and the node can
1439  * be deleted too, or not. */
rpz_remove_clientip_rr(struct clientip_synthesized_rr * node,uint16_t rr_type,uint8_t * rdatawl,size_t rdatalen)1440 static int rpz_remove_clientip_rr(struct clientip_synthesized_rr* node,
1441 	uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1442 {
1443 	struct local_rrset* rrset;
1444 	struct packed_rrset_data* d;
1445 	size_t index;
1446 	rrset = rpz_find_synthesized_rrset(rr_type, node, 0);
1447 	if(rrset == NULL)
1448 		return 0; /* type not found, ignore */
1449 	d = (struct packed_rrset_data*)rrset->rrset->entry.data;
1450 	if(!packed_rrset_find_rr(d, rdatawl, rdatalen, &index))
1451 		return 0; /* RR not found, ignore */
1452 	if(d->count == 1) {
1453 		/* regional alloc'd */
1454 		/* delete the type entry from the list */
1455 		del_local_rrset_from_list(&node->data, rr_type);
1456 		/* if the list is empty, the node can be removed too */
1457 		if(node->data == NULL)
1458 			return 1;
1459 	} else if (d->count > 1) {
1460 		if(!local_rrset_remove_rr(d, index))
1461 			return 0;
1462 	}
1463 	return 0;
1464 }
1465 
1466 /** remove trigger RR from clientip_syntheized set tree. */
1467 static void
rpz_clientip_remove_trigger_rr(struct clientip_synthesized_rrset * set,struct sockaddr_storage * addr,socklen_t addrlen,int net,enum rpz_action a,uint16_t rr_type,uint8_t * rdatawl,size_t rdatalen)1468 rpz_clientip_remove_trigger_rr(struct clientip_synthesized_rrset* set,
1469 	struct sockaddr_storage* addr, socklen_t addrlen, int net,
1470 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1471 {
1472 	struct clientip_synthesized_rr* node;
1473 	int delete_node = 1;
1474 
1475 	lock_rw_wrlock(&set->lock);
1476 	node = (struct clientip_synthesized_rr*)addr_tree_find(&set->entries,
1477 		addr, addrlen, net);
1478 	if(node == NULL) {
1479 		/* netblock not found */
1480 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1481 			"RPZ address, netblock not found");
1482 		lock_rw_unlock(&set->lock);
1483 		return;
1484 	}
1485 	lock_rw_wrlock(&node->lock);
1486 	if(a == RPZ_LOCAL_DATA_ACTION) {
1487 		/* remove RR, signal whether entry can be removed */
1488 		delete_node = rpz_remove_clientip_rr(node, rr_type, rdatawl,
1489 			rdatalen);
1490 	} else if(a != node->action) {
1491 		/* ignore the RR with different action specification */
1492 		delete_node = 0;
1493 	}
1494 	if(delete_node) {
1495 		rbtree_delete(&set->entries, node->node.node.key);
1496 	}
1497 	lock_rw_unlock(&set->lock);
1498 	lock_rw_unlock(&node->lock);
1499 	if(delete_node) {
1500 		lock_rw_destroy(&node->lock);
1501 	}
1502 }
1503 
1504 /** Remove clientip trigger RR from RPZ. */
1505 static void
rpz_remove_clientip_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rr_type,uint8_t * rdatawl,size_t rdatalen)1506 rpz_remove_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1507 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1508 {
1509 	struct sockaddr_storage addr;
1510 	socklen_t addrlen;
1511 	int net, af;
1512 	if(a == RPZ_INVALID_ACTION)
1513 		return;
1514 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1515 		return;
1516 	rpz_clientip_remove_trigger_rr(r->client_set, &addr, addrlen, net,
1517 		a, rr_type, rdatawl, rdatalen);
1518 }
1519 
1520 /** Remove nsip trigger RR from RPZ. */
1521 static void
rpz_remove_nsip_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rr_type,uint8_t * rdatawl,size_t rdatalen)1522 rpz_remove_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1523 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1524 {
1525 	struct sockaddr_storage addr;
1526 	socklen_t addrlen;
1527 	int net, af;
1528 	if(a == RPZ_INVALID_ACTION)
1529 		return;
1530 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1531 		return;
1532 	rpz_clientip_remove_trigger_rr(r->ns_set, &addr, addrlen, net,
1533 		a, rr_type, rdatawl, rdatalen);
1534 }
1535 
1536 /** Remove nsdname trigger RR from RPZ. */
1537 static void
rpz_remove_nsdname_trigger(struct rpz * r,uint8_t * dname,size_t dnamelen,enum rpz_action a,uint16_t rr_type,uint16_t rr_class,uint8_t * rdatawl,size_t rdatalen)1538 rpz_remove_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1539 	enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
1540 	uint8_t* rdatawl, size_t rdatalen)
1541 {
1542 	uint8_t* dname_stripped = NULL;
1543 	size_t dnamelen_stripped = 0;
1544 	if(a == RPZ_INVALID_ACTION)
1545 		return;
1546 	if(!rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped,
1547 		&dnamelen_stripped))
1548 		return;
1549 	rpz_remove_local_zones_trigger(r->nsdname_zones, dname_stripped,
1550 		dnamelen_stripped, a, rr_type, rr_class, rdatawl, rdatalen);
1551 	free(dname_stripped);
1552 }
1553 
1554 void
rpz_remove_rr(struct rpz * r,uint8_t * azname,size_t aznamelen,uint8_t * dname,size_t dnamelen,uint16_t rr_type,uint16_t rr_class,uint8_t * rdatawl,size_t rdatalen)1555 rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
1556 	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
1557 	size_t rdatalen)
1558 {
1559 	size_t policydnamelen;
1560 	enum rpz_trigger t;
1561 	enum rpz_action a;
1562 	uint8_t* policydname;
1563 
1564 	if(rpz_type_ignored(rr_type)) {
1565 		/* this rpz action is not valid, eg. this is the SOA or NS RR */
1566 		return;
1567 	}
1568 	if(!dname_subdomain_c(dname, azname)) {
1569 		/* not subdomain of the RPZ zone. */
1570 		return;
1571 	}
1572 
1573 	if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1)))
1574 		return;
1575 
1576 	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
1577 	if(a == RPZ_INVALID_ACTION) {
1578 		free(policydname);
1579 		return;
1580 	}
1581 	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
1582 		policydname, LDNS_MAX_DOMAINLEN + 1))) {
1583 		free(policydname);
1584 		return;
1585 	}
1586 	t = rpz_dname_to_trigger(policydname, policydnamelen);
1587 	if(t == RPZ_INVALID_TRIGGER) {
1588 		/* skipping invalid trigger */
1589 		free(policydname);
1590 		return;
1591 	}
1592 	if(t == RPZ_QNAME_TRIGGER) {
1593 		rpz_remove_qname_trigger(r, policydname, policydnamelen, a,
1594 			rr_type, rr_class, rdatawl, rdatalen);
1595 	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
1596 		rpz_remove_response_ip_trigger(r, policydname, policydnamelen,
1597 			a, rr_type, rdatawl, rdatalen);
1598 	} else if(t == RPZ_CLIENT_IP_TRIGGER) {
1599 		rpz_remove_clientip_trigger(r, policydname, policydnamelen, a,
1600 			rr_type, rdatawl, rdatalen);
1601 	} else if(t == RPZ_NSIP_TRIGGER) {
1602 		rpz_remove_nsip_trigger(r, policydname, policydnamelen, a,
1603 			rr_type, rdatawl, rdatalen);
1604 	} else if(t == RPZ_NSDNAME_TRIGGER) {
1605 		rpz_remove_nsdname_trigger(r, policydname, policydnamelen, a,
1606 			rr_type, rr_class, rdatawl, rdatalen);
1607 	}
1608 	/* else it was an unsupported trigger, also skipped. */
1609 	free(policydname);
1610 }
1611 
1612 /** print log information for an applied RPZ policy. Based on local-zone's
1613  * lz_inform_print().
1614  * The repinfo contains the reply address. If it is NULL, the module
1615  * state is used to report the first IP address (if any).
1616  * The dname is used, for the applied rpz, if NULL, addrnode is used.
1617  */
1618 static void
log_rpz_apply(char * trigger,uint8_t * dname,struct addr_tree_node * addrnode,enum rpz_action a,struct query_info * qinfo,struct comm_reply * repinfo,struct module_qstate * ms,char * log_name)1619 log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
1620 	enum rpz_action a, struct query_info* qinfo,
1621 	struct comm_reply* repinfo, struct module_qstate* ms, char* log_name)
1622 {
1623 	char ip[128], txt[512], portstr[32];
1624 	char dnamestr[LDNS_MAX_DOMAINLEN+1];
1625 	uint16_t port = 0;
1626 	if(dname) {
1627 		dname_str(dname, dnamestr);
1628 	} else if(addrnode) {
1629 		char addrbuf[128];
1630 		addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf));
1631 		snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net);
1632 	} else {
1633 		dnamestr[0]=0;
1634 	}
1635 	if(repinfo) {
1636 		addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip));
1637 		port = ntohs(((struct sockaddr_in*)&repinfo->client_addr)->sin_port);
1638 	} else if(ms && ms->mesh_info && ms->mesh_info->reply_list) {
1639 		addr_to_str(&ms->mesh_info->reply_list->query_reply.client_addr,
1640 			ms->mesh_info->reply_list->query_reply.client_addrlen,
1641 			ip, sizeof(ip));
1642 		port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port);
1643 	} else {
1644 		ip[0]=0;
1645 		port = 0;
1646 	}
1647 	snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port);
1648 	snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s",
1649 		(log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""),
1650 		(strcmp(trigger,"qname")==0?"":trigger),
1651 		(strcmp(trigger,"qname")==0?"":" "),
1652 		dnamestr, rpz_action_to_string(a),
1653 		(ip[0]?ip:""), (ip[0]?portstr:""));
1654 	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
1655 }
1656 
1657 static struct clientip_synthesized_rr*
rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset * set,struct sockaddr_storage * addr,socklen_t addrlen,char * triggername)1658 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set,
1659 	struct sockaddr_storage* addr, socklen_t addrlen, char* triggername)
1660 {
1661 	struct clientip_synthesized_rr* raddr = NULL;
1662 	enum rpz_action action = RPZ_INVALID_ACTION;
1663 
1664 	lock_rw_rdlock(&set->lock);
1665 
1666 	raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries,
1667 			addr, addrlen);
1668 	if(raddr != NULL) {
1669 		lock_rw_rdlock(&raddr->lock);
1670 		action = raddr->action;
1671 		if(verbosity >= VERB_ALGO) {
1672 			char ip[256], net[256];
1673 			addr_to_str(addr, addrlen, ip, sizeof(ip));
1674 			addr_to_str(&raddr->node.addr, raddr->node.addrlen,
1675 				net, sizeof(net));
1676 			verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s",
1677 				triggername, net, raddr->node.net, ip, rpz_action_to_string(action));
1678 		}
1679 	}
1680 	lock_rw_unlock(&set->lock);
1681 
1682 	return raddr;
1683 }
1684 
1685 static inline
1686 struct clientip_synthesized_rr*
rpz_resolve_client_action_and_zone(struct auth_zones * az,struct query_info * qinfo,struct comm_reply * repinfo,uint8_t * taglist,size_t taglen,struct ub_server_stats * stats,struct local_zone ** z_out,struct auth_zone ** a_out,struct rpz ** r_out)1687 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo,
1688 	struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
1689 	struct ub_server_stats* stats,
1690 	/* output parameters */
1691 	struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out)
1692 {
1693 	struct clientip_synthesized_rr* node = NULL;
1694 	struct auth_zone* a = NULL;
1695 	struct rpz* r = NULL;
1696 	struct local_zone* z = NULL;
1697 
1698 	lock_rw_rdlock(&az->rpz_lock);
1699 
1700 	for(a = az->rpz_first; a; a = a->rpz_az_next) {
1701 		lock_rw_rdlock(&a->lock);
1702 		r = a->rpz;
1703 		if(r->disabled) {
1704 			lock_rw_unlock(&a->lock);
1705 			continue;
1706 		}
1707 		if(r->taglist && !taglist_intersect(r->taglist,
1708 					r->taglistlen, taglist, taglen)) {
1709 			lock_rw_unlock(&a->lock);
1710 			continue;
1711 		}
1712 		z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len,
1713 			qinfo->qclass, 0, 0, 0);
1714 		node = rpz_ipbased_trigger_lookup(r->client_set,
1715 			&repinfo->client_addr, repinfo->client_addrlen,
1716 			"clientip");
1717 		if((z || node) && r->action_override == RPZ_DISABLED_ACTION) {
1718 			if(r->log)
1719 				log_rpz_apply((node?"clientip":"qname"),
1720 					(z?z->name:NULL),
1721 					(node?&node->node:NULL),
1722 					r->action_override,
1723 					qinfo, repinfo, NULL, r->log_name);
1724 			stats->rpz_action[r->action_override]++;
1725 			if(z != NULL) {
1726 				lock_rw_unlock(&z->lock);
1727 				z = NULL;
1728 			}
1729 			if(node != NULL) {
1730 				lock_rw_unlock(&node->lock);
1731 				node = NULL;
1732 			}
1733 		}
1734 		if(z || node) {
1735 			break;
1736 		}
1737 		/* not found in this auth_zone */
1738 		lock_rw_unlock(&a->lock);
1739 	}
1740 
1741 	lock_rw_unlock(&az->rpz_lock);
1742 
1743 	*r_out = r;
1744 	*a_out = a;
1745 	*z_out = z;
1746 
1747 	return node;
1748 }
1749 
1750 static inline int
rpz_is_udp_query(struct comm_reply * repinfo)1751 rpz_is_udp_query(struct comm_reply* repinfo) {
1752 	return repinfo != NULL
1753 			? (repinfo->c != NULL
1754 				? repinfo->c->type == comm_udp
1755 				: 0)
1756 			: 0;
1757 }
1758 
1759 /** encode answer consisting of 1 rrset */
1760 static int
rpz_local_encode(struct module_env * env,struct query_info * qinfo,struct edns_data * edns,struct comm_reply * repinfo,sldns_buffer * buf,struct regional * temp,struct ub_packed_rrset_key * rrset,int ansec,int rcode,struct ub_packed_rrset_key * soa_rrset)1761 rpz_local_encode(struct module_env* env, struct query_info* qinfo,
1762 	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1763 	struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
1764 	int rcode, struct ub_packed_rrset_key* soa_rrset)
1765 {
1766 	struct reply_info rep;
1767 	uint16_t udpsize;
1768 	struct ub_packed_rrset_key* rrsetlist[3];
1769 
1770 	memset(&rep, 0, sizeof(rep));
1771 	rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
1772 	rep.qdcount = 1;
1773 	rep.rrset_count = ansec;
1774 	rep.rrsets = rrsetlist;
1775 	if(ansec > 0) {
1776 		rep.an_numrrsets = 1;
1777 		rep.rrsets[0] = rrset;
1778 		rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0];
1779 	}
1780 	if(soa_rrset != NULL) {
1781 		rep.ar_numrrsets = 1;
1782 		rep.rrsets[rep.rrset_count] = soa_rrset;
1783 		rep.rrset_count ++;
1784 		if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) {
1785 			rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0];
1786 		}
1787 	}
1788 
1789 	udpsize = edns->udp_size;
1790 	edns->edns_version = EDNS_ADVERTISED_VERSION;
1791 	edns->udp_size = EDNS_ADVERTISED_SIZE;
1792 	edns->ext_rcode = 0;
1793 	edns->bits &= EDNS_DO;
1794 	if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
1795 		repinfo, temp, env->now_tv) ||
1796 	  !reply_info_answer_encode(qinfo, &rep,
1797 		*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
1798 		buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
1799 		error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
1800 			*(uint16_t*)sldns_buffer_begin(buf),
1801 			sldns_buffer_read_u16_at(buf, 2), edns);
1802 	}
1803 
1804 	return 1;
1805 }
1806 
1807 /** allocate SOA record ubrrsetkey in region */
1808 static struct ub_packed_rrset_key*
make_soa_ubrrset(struct auth_zone * auth_zone,struct auth_rrset * soa,struct regional * temp)1809 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa,
1810 	struct regional* temp)
1811 {
1812 	struct ub_packed_rrset_key csoa;
1813 	if(!soa)
1814 		return NULL;
1815 	memset(&csoa, 0, sizeof(csoa));
1816 	csoa.entry.key = &csoa;
1817 	csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN);
1818 	csoa.rk.type = htons(LDNS_RR_TYPE_SOA);
1819 	csoa.rk.flags |= PACKED_RRSET_FIXEDTTL
1820 		| PACKED_RRSET_RPZ;
1821 	csoa.rk.dname = auth_zone->name;
1822 	csoa.rk.dname_len = auth_zone->namelen;
1823 	csoa.entry.hash = rrset_key_hash(&csoa.rk);
1824 	csoa.entry.data = soa->data;
1825 	return respip_copy_rrset(&csoa, temp);
1826 }
1827 
1828 static void
rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr * raddr,struct module_env * env,struct query_info * qinfo,struct edns_data * edns,struct comm_reply * repinfo,sldns_buffer * buf,struct regional * temp,struct auth_zone * auth_zone)1829 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr,
1830 	struct module_env* env, struct query_info* qinfo,
1831 	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1832 	struct regional* temp, struct auth_zone* auth_zone)
1833 {
1834 	struct local_rrset* rrset;
1835 	enum rpz_action action = RPZ_INVALID_ACTION;
1836 	struct ub_packed_rrset_key* rp = NULL;
1837 	struct ub_packed_rrset_key* rsoa = NULL;
1838 	int rcode = LDNS_RCODE_NOERROR|BIT_AA;
1839 	int rrset_count = 1;
1840 
1841 	/* prepare synthesized answer for client */
1842 	action = raddr->action;
1843 	if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) {
1844 		verbose(VERB_ALGO, "rpz: bug: local-data action but no local data");
1845 		return;
1846 	}
1847 
1848 	/* check query type / rr type */
1849 	rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr, 1);
1850 	if(rrset == NULL) {
1851 		verbose(VERB_ALGO, "rpz: unable to find local-data for query");
1852 		rrset_count = 0;
1853 		goto nodata;
1854 	}
1855 
1856 	rp = respip_copy_rrset(rrset->rrset, temp);
1857 	if(!rp) {
1858 		verbose(VERB_ALGO, "rpz: local data action: out of memory");
1859 		return;
1860 	}
1861 
1862 	rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ;
1863 	rp->rk.dname = qinfo->qname;
1864 	rp->rk.dname_len = qinfo->qname_len;
1865 	rp->entry.hash = rrset_key_hash(&rp->rk);
1866 nodata:
1867 	if(auth_zone) {
1868 		struct auth_rrset* soa = NULL;
1869 		soa = auth_zone_get_soa_rrset(auth_zone);
1870 		if(soa) {
1871 			rsoa = make_soa_ubrrset(auth_zone, soa, temp);
1872 			if(!rsoa) {
1873 				verbose(VERB_ALGO, "rpz: local data action soa: out of memory");
1874 				return;
1875 			}
1876 		}
1877 	}
1878 
1879 	rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp,
1880 		rrset_count, rcode, rsoa);
1881 }
1882 
1883 /** Apply the cname override action, during worker request callback.
1884  * false on failure. */
1885 static int
rpz_apply_cname_override_action(struct rpz * r,struct query_info * qinfo,struct regional * temp)1886 rpz_apply_cname_override_action(struct rpz* r,
1887 	struct query_info* qinfo, struct regional* temp)
1888 {
1889 	if(!r)
1890 		return 0;
1891 	qinfo->local_alias = regional_alloc_zero(temp,
1892 		sizeof(struct local_rrset));
1893 	if(qinfo->local_alias == NULL)
1894 		return 0; /* out of memory */
1895 	qinfo->local_alias->rrset = respip_copy_rrset(r->cname_override, temp);
1896 	if(qinfo->local_alias->rrset == NULL) {
1897 		qinfo->local_alias = NULL;
1898 		return 0; /* out of memory */
1899 	}
1900 	qinfo->local_alias->rrset->rk.dname = qinfo->qname;
1901 	qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
1902 	return 1;
1903 }
1904 
1905 /** add additional section SOA record to the reply.
1906  * Since this gets fed into the normal iterator answer creation, it
1907  * gets minimal-responses applied to it, that can remove the additional SOA
1908  * again. */
1909 static int
rpz_add_soa(struct reply_info * rep,struct module_qstate * ms,struct auth_zone * az)1910 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms,
1911 	struct auth_zone* az)
1912 {
1913 	struct auth_rrset* soa = NULL;
1914 	struct ub_packed_rrset_key* rsoa = NULL;
1915 	struct ub_packed_rrset_key** prevrrsets;
1916 	if(!az) return 1;
1917 	soa = auth_zone_get_soa_rrset(az);
1918 	if(!soa) return 1;
1919 	if(!rep) return 0;
1920 	rsoa = make_soa_ubrrset(az, soa, ms->region);
1921 	if(!rsoa) return 0;
1922 	prevrrsets = rep->rrsets;
1923 	rep->rrsets = regional_alloc_zero(ms->region,
1924 		sizeof(*rep->rrsets)*(rep->rrset_count+1));
1925 	if(!rep->rrsets)
1926 		return 0;
1927 	if(prevrrsets && rep->rrset_count > 0)
1928 		memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets));
1929 	rep->rrset_count++;
1930 	rep->ar_numrrsets++;
1931 	rep->rrsets[rep->rrset_count-1] = rsoa;
1932 	return 1;
1933 }
1934 
1935 static inline struct dns_msg*
rpz_dns_msg_new(struct regional * region)1936 rpz_dns_msg_new(struct regional* region)
1937 {
1938 	struct dns_msg* msg =
1939 			(struct dns_msg*)regional_alloc(region,
1940 							sizeof(struct dns_msg));
1941 	if(msg == NULL) { return NULL; }
1942 	memset(msg, 0, sizeof(struct dns_msg));
1943 
1944 	return msg;
1945 }
1946 
1947 static inline struct dns_msg*
rpz_synthesize_nodata(struct rpz * ATTR_UNUSED (r),struct module_qstate * ms,struct query_info * qinfo,struct auth_zone * az)1948 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
1949 	struct query_info* qinfo, struct auth_zone* az)
1950 {
1951 	struct dns_msg* msg = rpz_dns_msg_new(ms->region);
1952 	if(msg == NULL) { return msg; }
1953 	msg->qinfo = *qinfo;
1954 	msg->rep = construct_reply_info_base(ms->region,
1955 					     LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1956 					     1, /* qd */
1957 					     0, /* ttl */
1958 					     0, /* prettl */
1959 					     0, /* expttl */
1960 					     0, /* an */
1961 					     0, /* ns */
1962 					     0, /* ar */
1963 					     0, /* total */
1964 					     sec_status_insecure,
1965 					     LDNS_EDE_NONE);
1966 	if(msg->rep)
1967 		msg->rep->authoritative = 1;
1968 	if(!rpz_add_soa(msg->rep, ms, az))
1969 		return NULL;
1970 	return msg;
1971 }
1972 
1973 static inline struct dns_msg*
rpz_synthesize_nxdomain(struct rpz * r,struct module_qstate * ms,struct query_info * qinfo,struct auth_zone * az)1974 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
1975 	struct query_info* qinfo, struct auth_zone* az)
1976 {
1977 	struct dns_msg* msg = rpz_dns_msg_new(ms->region);
1978 	uint16_t flags;
1979 	if(msg == NULL) { return msg; }
1980 	msg->qinfo = *qinfo;
1981 	flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA;
1982 	if(r->signal_nxdomain_ra)
1983 		flags &= ~BIT_RA;
1984 	msg->rep = construct_reply_info_base(ms->region,
1985 					     flags,
1986 					     1, /* qd */
1987 					     0, /* ttl */
1988 					     0, /* prettl */
1989 					     0, /* expttl */
1990 					     0, /* an */
1991 					     0, /* ns */
1992 					     0, /* ar */
1993 					     0, /* total */
1994 					     sec_status_insecure,
1995 					     LDNS_EDE_NONE);
1996 	if(msg->rep)
1997 		msg->rep->authoritative = 1;
1998 	if(!rpz_add_soa(msg->rep, ms, az))
1999 		return NULL;
2000 	return msg;
2001 }
2002 
2003 static inline struct dns_msg*
rpz_synthesize_localdata_from_rrset(struct rpz * ATTR_UNUSED (r),struct module_qstate * ms,struct query_info * qi,struct local_rrset * rrset,struct auth_zone * az)2004 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
2005 	struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az)
2006 {
2007 	struct dns_msg* msg = NULL;
2008 	struct reply_info* new_reply_info;
2009 	struct ub_packed_rrset_key* rp;
2010 
2011 
2012 	msg = rpz_dns_msg_new(ms->region);
2013 	if(msg == NULL) { return NULL; }
2014 
2015 	msg->qinfo = *qi;
2016         new_reply_info = construct_reply_info_base(ms->region,
2017                                                    LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
2018                                                    1, /* qd */
2019                                                    0, /* ttl */
2020                                                    0, /* prettl */
2021                                                    0, /* expttl */
2022                                                    1, /* an */
2023                                                    0, /* ns */
2024                                                    0, /* ar */
2025                                                    1, /* total */
2026                                                    sec_status_insecure,
2027                                                    LDNS_EDE_NONE);
2028 	if(new_reply_info == NULL) {
2029 		log_err("out of memory");
2030 		return NULL;
2031 	}
2032 	new_reply_info->authoritative = 1;
2033 	rp = respip_copy_rrset(rrset->rrset, ms->region);
2034 	if(rp == NULL) {
2035 		log_err("out of memory");
2036 		return NULL;
2037 	}
2038 	rp->rk.dname = qi->qname;
2039 	rp->rk.dname_len = qi->qname_len;
2040 	/* this rrset is from the rpz data, or synthesized.
2041 	 * It is not actually from the network, so we flag it with this
2042 	 * flags as a fake RRset. If later the cache is used to look up
2043 	 * rrsets, then the fake ones are not returned (if you look without
2044 	 * the flag). For like CNAME lookups from the iterator or A, AAAA
2045 	 * lookups for nameserver targets, it would use the without flag
2046 	 * actual data. So that the actual network data and fake data
2047 	 * are kept track of separately. */
2048 	rp->rk.flags |= PACKED_RRSET_RPZ;
2049 	new_reply_info->rrsets[0] = rp;
2050 	msg->rep = new_reply_info;
2051 	if(!rpz_add_soa(msg->rep, ms, az))
2052 		return NULL;
2053 	return msg;
2054 }
2055 
2056 static inline struct dns_msg*
rpz_synthesize_nsip_localdata(struct rpz * r,struct module_qstate * ms,struct query_info * qi,struct clientip_synthesized_rr * data,struct auth_zone * az)2057 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms,
2058 	struct query_info* qi, struct clientip_synthesized_rr* data,
2059 	struct auth_zone* az)
2060 {
2061 	struct local_rrset* rrset;
2062 
2063 	rrset = rpz_find_synthesized_rrset(qi->qtype, data, 1);
2064 	if(rrset == NULL) {
2065 		verbose(VERB_ALGO, "rpz: nsip: no matching local data found");
2066 		return NULL;
2067 	}
2068 
2069 	return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az);
2070 }
2071 
2072 /* copy'n'paste from localzone.c */
2073 static struct local_rrset*
local_data_find_type(struct local_data * data,uint16_t type,int alias_ok)2074 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok)
2075 {
2076 	struct local_rrset* p, *cname = NULL;
2077 	type = htons(type);
2078 	for(p = data->rrsets; p; p = p->next) {
2079 		if(p->rrset->rk.type == type)
2080 			return p;
2081 		if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME))
2082 			cname = p;
2083 	}
2084 	if(alias_ok)
2085 		return cname;
2086 	return NULL;
2087 }
2088 
2089 /* based on localzone.c:local_data_answer() */
2090 static inline struct dns_msg*
rpz_synthesize_nsdname_localdata(struct rpz * r,struct module_qstate * ms,struct query_info * qi,struct local_zone * z,struct matched_delegation_point const * match,struct auth_zone * az)2091 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms,
2092 	struct query_info* qi, struct local_zone* z,
2093 	struct matched_delegation_point const* match, struct auth_zone* az)
2094 {
2095 	struct local_data key;
2096 	struct local_data* ld;
2097 	struct local_rrset* rrset;
2098 
2099 	if(match->dname == NULL) { return NULL; }
2100 
2101 	key.node.key = &key;
2102 	key.name = match->dname;
2103 	key.namelen = match->dname_len;
2104 	key.namelabs = dname_count_labels(match->dname);
2105 
2106 	rpz_log_dname("nsdname local data", key.name, key.namelen);
2107 
2108 	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
2109 	if(ld == NULL) {
2110 		verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found");
2111 		return NULL;
2112 	}
2113 
2114 	rrset = local_data_find_type(ld, qi->qtype, 1);
2115 	if(rrset == NULL) {
2116 		verbose(VERB_ALGO, "rpz: nsdname: no matching local data found");
2117 		return NULL;
2118 	}
2119 
2120 	return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az);
2121 }
2122 
2123 /* like local_data_answer for qname triggers after a cname */
2124 static struct dns_msg*
rpz_synthesize_qname_localdata_msg(struct rpz * r,struct module_qstate * ms,struct query_info * qinfo,struct local_zone * z,struct auth_zone * az)2125 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
2126 	struct query_info* qinfo, struct local_zone* z, struct auth_zone* az)
2127 {
2128 	struct local_data key;
2129 	struct local_data* ld;
2130 	struct local_rrset* rrset;
2131 	key.node.key = &key;
2132 	key.name = qinfo->qname;
2133 	key.namelen = qinfo->qname_len;
2134 	key.namelabs = dname_count_labels(qinfo->qname);
2135 	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
2136 	if(ld == NULL) {
2137 		verbose(VERB_ALGO, "rpz: qname: name not found");
2138 		return NULL;
2139 	}
2140 	rrset = local_data_find_type(ld, qinfo->qtype, 1);
2141 	if(rrset == NULL) {
2142 		verbose(VERB_ALGO, "rpz: qname: type not found");
2143 		return NULL;
2144 	}
2145 	return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az);
2146 }
2147 
2148 /** Synthesize a CNAME message for RPZ action override */
2149 static struct dns_msg*
rpz_synthesize_cname_override_msg(struct rpz * r,struct module_qstate * ms,struct query_info * qinfo)2150 rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms,
2151 	struct query_info* qinfo)
2152 {
2153 	struct dns_msg* msg = NULL;
2154 	struct reply_info* new_reply_info;
2155 	struct ub_packed_rrset_key* rp;
2156 
2157 	msg = rpz_dns_msg_new(ms->region);
2158 	if(msg == NULL) { return NULL; }
2159 
2160 	msg->qinfo = *qinfo;
2161         new_reply_info = construct_reply_info_base(ms->region,
2162                                                    LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
2163                                                    1, /* qd */
2164                                                    0, /* ttl */
2165                                                    0, /* prettl */
2166                                                    0, /* expttl */
2167                                                    1, /* an */
2168                                                    0, /* ns */
2169                                                    0, /* ar */
2170                                                    1, /* total */
2171                                                    sec_status_insecure,
2172                                                    LDNS_EDE_NONE);
2173 	if(new_reply_info == NULL) {
2174 		log_err("out of memory");
2175 		return NULL;
2176 	}
2177 	new_reply_info->authoritative = 1;
2178 
2179 	rp = respip_copy_rrset(r->cname_override, ms->region);
2180 	if(rp == NULL) {
2181 		log_err("out of memory");
2182 		return NULL;
2183 	}
2184 	rp->rk.dname = qinfo->qname;
2185 	rp->rk.dname_len = qinfo->qname_len;
2186 	/* this rrset is from the rpz data, or synthesized.
2187 	 * It is not actually from the network, so we flag it with this
2188 	 * flags as a fake RRset. If later the cache is used to look up
2189 	 * rrsets, then the fake ones are not returned (if you look without
2190 	 * the flag). For like CNAME lookups from the iterator or A, AAAA
2191 	 * lookups for nameserver targets, it would use the without flag
2192 	 * actual data. So that the actual network data and fake data
2193 	 * are kept track of separately. */
2194 	rp->rk.flags |= PACKED_RRSET_RPZ;
2195 	new_reply_info->rrsets[0] = rp;
2196 
2197 	msg->rep = new_reply_info;
2198 	return msg;
2199 }
2200 
2201 static int
rpz_synthesize_qname_localdata(struct module_env * env,struct rpz * r,struct local_zone * z,enum localzone_type lzt,struct query_info * qinfo,struct edns_data * edns,sldns_buffer * buf,struct regional * temp,struct comm_reply * repinfo,struct ub_server_stats * stats)2202 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
2203 	struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo,
2204 	struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
2205 	struct comm_reply* repinfo, struct ub_server_stats* stats)
2206 {
2207 	struct local_data* ld = NULL;
2208 	int ret = 0;
2209 	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
2210 		if(!rpz_apply_cname_override_action(r, qinfo, temp))
2211 			return 0;
2212 		if(r->log) {
2213 			log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION,
2214 				      qinfo, repinfo, NULL, r->log_name);
2215 		}
2216 		stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
2217 		return 0;
2218 	}
2219 
2220 	if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo,
2221 		edns, repinfo, buf, temp, dname_count_labels(qinfo->qname),
2222 		&ld, lzt, -1, NULL, 0, NULL, 0)) {
2223 		if(r->log) {
2224 			log_rpz_apply("qname", z->name, NULL,
2225 				localzone_type_to_rpz_action(lzt), qinfo,
2226 				repinfo, NULL, r->log_name);
2227 		}
2228 		stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
2229 		return !qinfo->local_alias;
2230 	}
2231 
2232 	ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
2233 		0 /* no local data used */, lzt);
2234 	if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
2235 		== LDNS_RCODE_NXDOMAIN)
2236 		LDNS_RA_CLR(sldns_buffer_begin(buf));
2237 	if(r->log) {
2238 		log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt),
2239 			      qinfo, repinfo, NULL, r->log_name);
2240 	}
2241 	stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
2242 	return ret;
2243 }
2244 
2245 static struct clientip_synthesized_rr*
rpz_delegation_point_ipbased_trigger_lookup(struct rpz * rpz,struct iter_qstate * is)2246 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is)
2247 {
2248 	struct delegpt_addr* cursor;
2249 	struct clientip_synthesized_rr* action = NULL;
2250 	if(is->dp == NULL) { return NULL; }
2251 	for(cursor = is->dp->target_list;
2252 	    cursor != NULL;
2253 	    cursor = cursor->next_target) {
2254 		if(cursor->bogus) { continue; }
2255 		action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr,
2256 						    cursor->addrlen, "nsip");
2257 		if(action != NULL) { return action; }
2258 	}
2259 	return NULL;
2260 }
2261 
2262 static struct dns_msg*
rpz_apply_nsip_trigger(struct module_qstate * ms,struct query_info * qchase,struct rpz * r,struct clientip_synthesized_rr * raddr,struct auth_zone * az)2263 rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
2264 	struct rpz* r, struct clientip_synthesized_rr* raddr,
2265 	struct auth_zone* az)
2266 {
2267 	enum rpz_action action = raddr->action;
2268 	struct dns_msg* ret = NULL;
2269 
2270 	if(r->action_override != RPZ_NO_OVERRIDE_ACTION) {
2271 		verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)",
2272 			rpz_action_to_string(r->action_override), rpz_action_to_string(action));
2273 		action = r->action_override;
2274 	}
2275 
2276 	if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) {
2277 		verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data");
2278 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2279 		goto done;
2280 	}
2281 
2282 	switch(action) {
2283 	case RPZ_NXDOMAIN_ACTION:
2284 		ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
2285 		break;
2286 	case RPZ_NODATA_ACTION:
2287 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2288 		break;
2289 	case RPZ_TCP_ONLY_ACTION:
2290 		/* basically a passthru here but the tcp-only will be
2291 		 * honored before the query gets sent. */
2292 		ms->tcp_required = 1;
2293 		ret = NULL;
2294 		break;
2295 	case RPZ_DROP_ACTION:
2296 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2297 		ms->is_drop = 1;
2298 		break;
2299 	case RPZ_LOCAL_DATA_ACTION:
2300 		ret = rpz_synthesize_nsip_localdata(r, ms, qchase, raddr, az);
2301 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
2302 		break;
2303 	case RPZ_PASSTHRU_ACTION:
2304 		ret = NULL;
2305 		ms->rpz_passthru = 1;
2306 		break;
2307 	case RPZ_CNAME_OVERRIDE_ACTION:
2308 		ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
2309 		break;
2310 	default:
2311 		verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
2312 			rpz_action_to_string(action));
2313 		ret = NULL;
2314 	}
2315 
2316 done:
2317 	if(r->log)
2318 		log_rpz_apply("nsip", NULL, &raddr->node,
2319 			action, &ms->qinfo, NULL, ms, r->log_name);
2320 	if(ms->env->worker)
2321 		ms->env->worker->stats.rpz_action[action]++;
2322 	lock_rw_unlock(&raddr->lock);
2323 	return ret;
2324 }
2325 
2326 static struct dns_msg*
rpz_apply_nsdname_trigger(struct module_qstate * ms,struct query_info * qchase,struct rpz * r,struct local_zone * z,struct matched_delegation_point const * match,struct auth_zone * az)2327 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
2328 	struct rpz* r, struct local_zone* z,
2329 	struct matched_delegation_point const* match, struct auth_zone* az)
2330 {
2331 	struct dns_msg* ret = NULL;
2332 	enum rpz_action action = localzone_type_to_rpz_action(z->type);
2333 
2334 	if(r->action_override != RPZ_NO_OVERRIDE_ACTION) {
2335 		verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)",
2336 			rpz_action_to_string(r->action_override), rpz_action_to_string(action));
2337 		action = r->action_override;
2338 	}
2339 
2340 	switch(action) {
2341 	case RPZ_NXDOMAIN_ACTION:
2342 		ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
2343 		break;
2344 	case RPZ_NODATA_ACTION:
2345 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2346 		break;
2347 	case RPZ_TCP_ONLY_ACTION:
2348 		/* basically a passthru here but the tcp-only will be
2349 		 * honored before the query gets sent. */
2350 		ms->tcp_required = 1;
2351 		ret = NULL;
2352 		break;
2353 	case RPZ_DROP_ACTION:
2354 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2355 		ms->is_drop = 1;
2356 		break;
2357 	case RPZ_LOCAL_DATA_ACTION:
2358 		ret = rpz_synthesize_nsdname_localdata(r, ms, qchase, z, match, az);
2359 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
2360 		break;
2361 	case RPZ_PASSTHRU_ACTION:
2362 		ret = NULL;
2363 		ms->rpz_passthru = 1;
2364 		break;
2365 	case RPZ_CNAME_OVERRIDE_ACTION:
2366 		ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
2367 		break;
2368 	default:
2369 		verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'",
2370 			rpz_action_to_string(action));
2371 		ret = NULL;
2372 	}
2373 
2374 	if(r->log)
2375 		log_rpz_apply("nsdname", match->dname, NULL,
2376 			action, &ms->qinfo, NULL, ms, r->log_name);
2377 	if(ms->env->worker)
2378 		ms->env->worker->stats.rpz_action[action]++;
2379 	lock_rw_unlock(&z->lock);
2380 	return ret;
2381 }
2382 
2383 static struct local_zone*
rpz_delegation_point_zone_lookup(struct delegpt * dp,struct local_zones * zones,uint16_t qclass,struct matched_delegation_point * match)2384 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones,
2385 	uint16_t qclass,
2386 	/* output parameter */
2387 	struct matched_delegation_point* match)
2388 {
2389 	struct delegpt_ns* nameserver;
2390 	struct local_zone* z = NULL;
2391 
2392 	/* the rpz specs match the nameserver names (NS records), not the
2393 	 * name of the delegation point itself, to the nsdname triggers */
2394 	for(nameserver = dp->nslist;
2395 	    nameserver != NULL;
2396 	    nameserver = nameserver->next) {
2397 		z = rpz_find_zone(zones, nameserver->name, nameserver->namelen,
2398 				  qclass, 0, 0, 0);
2399 		if(z != NULL) {
2400 			match->dname = nameserver->name;
2401 			match->dname_len = nameserver->namelen;
2402 			if(verbosity >= VERB_ALGO) {
2403 				char nm[255+1], zn[255+1];
2404 				dname_str(match->dname, nm);
2405 				dname_str(z->name, zn);
2406 				if(strcmp(nm, zn) != 0)
2407 					verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s",
2408 						zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type)));
2409 				else
2410 					verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s",
2411 						nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type)));
2412 			}
2413 			break;
2414 		}
2415 	}
2416 
2417 	return z;
2418 }
2419 
2420 struct dns_msg*
rpz_callback_from_iterator_module(struct module_qstate * ms,struct iter_qstate * is)2421 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is)
2422 {
2423 	struct auth_zones* az;
2424 	struct auth_zone* a;
2425 	struct clientip_synthesized_rr* raddr = NULL;
2426 	struct rpz* r = NULL;
2427 	struct local_zone* z = NULL;
2428 	struct matched_delegation_point match = {0};
2429 
2430 	if(ms->rpz_passthru) {
2431 		verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
2432 		return NULL;
2433 	}
2434 
2435 	if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
2436 
2437 	az = ms->env->auth_zones;
2438 
2439 	verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL);
2440 
2441 	lock_rw_rdlock(&az->rpz_lock);
2442 
2443 	/* precedence of RPZ works, loosely, like this:
2444 	 * CNAMEs in order of the CNAME chain. rpzs in the order they are
2445 	 * configured. In an RPZ: first client-IP addr, then QNAME, then
2446 	 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest
2447 	 * one from a set. */
2448 	/* we use the precedence rules for the topics and triggers that
2449 	 * are pertinent at this stage of the resolve processing */
2450 	for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) {
2451 		lock_rw_rdlock(&a->lock);
2452 		r = a->rpz;
2453 		if(r->disabled) {
2454 			lock_rw_unlock(&a->lock);
2455 			continue;
2456 		}
2457 
2458 		/* the nsdname has precedence over the nsip triggers */
2459 		z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
2460 						     is->qchase.qclass, &match);
2461 		if(z != NULL) {
2462 			lock_rw_unlock(&a->lock);
2463 			break;
2464 		}
2465 
2466 		raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is);
2467 		if(raddr != NULL) {
2468 			lock_rw_unlock(&a->lock);
2469 			break;
2470 		}
2471 		lock_rw_unlock(&a->lock);
2472 	}
2473 
2474 	lock_rw_unlock(&az->rpz_lock);
2475 
2476 	if(raddr == NULL && z == NULL)
2477 		return NULL;
2478 
2479 	if(raddr != NULL) {
2480 		if(z) {
2481 			lock_rw_unlock(&z->lock);
2482 		}
2483 		return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a);
2484 	}
2485 	return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
2486 }
2487 
rpz_callback_from_iterator_cname(struct module_qstate * ms,struct iter_qstate * is)2488 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
2489 	struct iter_qstate* is)
2490 {
2491 	struct auth_zones* az;
2492 	struct auth_zone* a = NULL;
2493 	struct rpz* r = NULL;
2494 	struct local_zone* z = NULL;
2495 	enum localzone_type lzt;
2496 	struct dns_msg* ret = NULL;
2497 
2498 	if(ms->rpz_passthru) {
2499 		verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
2500 		return NULL;
2501 	}
2502 
2503 	if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
2504 	az = ms->env->auth_zones;
2505 
2506 	lock_rw_rdlock(&az->rpz_lock);
2507 
2508 	for(a = az->rpz_first; a; a = a->rpz_az_next) {
2509 		lock_rw_rdlock(&a->lock);
2510 		r = a->rpz;
2511 		if(r->disabled) {
2512 			lock_rw_unlock(&a->lock);
2513 			continue;
2514 		}
2515 		z = rpz_find_zone(r->local_zones, is->qchase.qname,
2516 			is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
2517 		if(z && r->action_override == RPZ_DISABLED_ACTION) {
2518 			if(r->log)
2519 				log_rpz_apply("qname", z->name, NULL,
2520 					r->action_override,
2521 					&ms->qinfo, NULL, ms, r->log_name);
2522 			if(ms->env->worker)
2523 				ms->env->worker->stats.rpz_action[r->action_override]++;
2524 			lock_rw_unlock(&z->lock);
2525 			z = NULL;
2526 		}
2527 		if(z) {
2528 			break;
2529 		}
2530 		/* not found in this auth_zone */
2531 		lock_rw_unlock(&a->lock);
2532 	}
2533 	lock_rw_unlock(&az->rpz_lock);
2534 
2535 	if(z == NULL)
2536 		return NULL;
2537 	if(r->action_override == RPZ_NO_OVERRIDE_ACTION) {
2538 		lzt = z->type;
2539 	} else {
2540 		lzt = rpz_action_to_localzone_type(r->action_override);
2541 	}
2542 
2543 	if(verbosity >= VERB_ALGO) {
2544 		char nm[255+1], zn[255+1];
2545 		dname_str(is->qchase.qname, nm);
2546 		dname_str(z->name, zn);
2547 		if(strcmp(zn, nm) != 0)
2548 			verbose(VERB_ALGO, "rpz: qname trigger %s on %s, with action=%s",
2549 				zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2550 		else
2551 			verbose(VERB_ALGO, "rpz: qname trigger %s, with action=%s",
2552 				nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2553 	}
2554 	switch(localzone_type_to_rpz_action(lzt)) {
2555 	case RPZ_NXDOMAIN_ACTION:
2556 		ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a);
2557 		break;
2558 	case RPZ_NODATA_ACTION:
2559 		ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
2560 		break;
2561 	case RPZ_TCP_ONLY_ACTION:
2562 		/* basically a passthru here but the tcp-only will be
2563 		 * honored before the query gets sent. */
2564 		ms->tcp_required = 1;
2565 		ret = NULL;
2566 		break;
2567 	case RPZ_DROP_ACTION:
2568 		ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
2569 		ms->is_drop = 1;
2570 		break;
2571 	case RPZ_LOCAL_DATA_ACTION:
2572 		ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a);
2573 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); }
2574 		break;
2575 	case RPZ_PASSTHRU_ACTION:
2576 		ret = NULL;
2577 		ms->rpz_passthru = 1;
2578 		break;
2579 	default:
2580 		verbose(VERB_ALGO, "rpz: qname trigger: bug: unhandled or invalid action: '%s'",
2581 			rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2582 		ret = NULL;
2583 	}
2584 	if(r->log)
2585 		log_rpz_apply("qname", (z?z->name:NULL), NULL,
2586 			localzone_type_to_rpz_action(lzt),
2587 			&is->qchase, NULL, ms, r->log_name);
2588 	lock_rw_unlock(&z->lock);
2589 	lock_rw_unlock(&a->lock);
2590 	return ret;
2591 }
2592 
2593 static int
rpz_apply_maybe_clientip_trigger(struct auth_zones * az,struct module_env * env,struct query_info * qinfo,struct edns_data * edns,struct comm_reply * repinfo,uint8_t * taglist,size_t taglen,struct ub_server_stats * stats,sldns_buffer * buf,struct regional * temp,struct local_zone ** z_out,struct auth_zone ** a_out,struct rpz ** r_out,int * passthru)2594 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
2595 	struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo,
2596 	uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
2597 	sldns_buffer* buf, struct regional* temp,
2598 	/* output parameters */
2599 	struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out,
2600 	int* passthru)
2601 {
2602 	int ret = 0;
2603 	enum rpz_action client_action;
2604 	struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone(
2605 		az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out);
2606 
2607 	client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action);
2608 	if(node != NULL && *r_out &&
2609 		(*r_out)->action_override != RPZ_NO_OVERRIDE_ACTION) {
2610 		client_action = (*r_out)->action_override;
2611 	}
2612 	if(client_action == RPZ_PASSTHRU_ACTION) {
2613 		if(*r_out && (*r_out)->log)
2614 			log_rpz_apply(
2615 				(node?"clientip":"qname"),
2616 				((*z_out)?(*z_out)->name:NULL),
2617 				(node?&node->node:NULL),
2618 				client_action, qinfo, repinfo, NULL,
2619 				(*r_out)->log_name);
2620 		*passthru = 1;
2621 		ret = 0;
2622 		goto done;
2623 	}
2624 	if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION &&
2625 			      client_action != RPZ_PASSTHRU_ACTION)) {
2626 		if(client_action == RPZ_PASSTHRU_ACTION
2627 			|| client_action == RPZ_INVALID_ACTION
2628 			|| (client_action == RPZ_TCP_ONLY_ACTION
2629 				&& !rpz_is_udp_query(repinfo))) {
2630 			ret = 0;
2631 			goto done;
2632 		}
2633 		stats->rpz_action[client_action]++;
2634 		if(client_action == RPZ_LOCAL_DATA_ACTION) {
2635 			rpz_apply_clientip_localdata_action(node, env, qinfo,
2636 				edns, repinfo, buf, temp, *a_out);
2637 			ret = 1;
2638 		} else if(client_action == RPZ_CNAME_OVERRIDE_ACTION) {
2639 			if(!rpz_apply_cname_override_action(*r_out, qinfo,
2640 				temp)) {
2641 				ret = 0;
2642 				goto done;
2643 			}
2644 			ret = 0;
2645 		} else {
2646 			local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns,
2647 				repinfo, buf, temp, 0 /* no local data used */,
2648 				rpz_action_to_localzone_type(client_action));
2649 			if(*r_out && (*r_out)->signal_nxdomain_ra &&
2650 				LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
2651 				== LDNS_RCODE_NXDOMAIN)
2652 				LDNS_RA_CLR(sldns_buffer_begin(buf));
2653 			ret = 1;
2654 		}
2655 		if(*r_out && (*r_out)->log)
2656 			log_rpz_apply(
2657 				(node?"clientip":"qname"),
2658 				((*z_out)?(*z_out)->name:NULL),
2659 				(node?&node->node:NULL),
2660 				client_action, qinfo, repinfo, NULL,
2661 				(*r_out)->log_name);
2662 		goto done;
2663 	}
2664 	ret = -1;
2665 done:
2666 	if(node != NULL) {
2667 		lock_rw_unlock(&node->lock);
2668 	}
2669 	return ret;
2670 }
2671 
2672 int
rpz_callback_from_worker_request(struct auth_zones * az,struct module_env * env,struct query_info * qinfo,struct edns_data * edns,sldns_buffer * buf,struct regional * temp,struct comm_reply * repinfo,uint8_t * taglist,size_t taglen,struct ub_server_stats * stats,int * passthru)2673 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
2674 	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
2675 	struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist,
2676 	size_t taglen, struct ub_server_stats* stats, int* passthru)
2677 {
2678 	struct rpz* r = NULL;
2679 	struct auth_zone* a = NULL;
2680 	struct local_zone* z = NULL;
2681 	int ret;
2682 	enum localzone_type lzt;
2683 
2684 	int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo,
2685 		edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r,
2686 		passthru);
2687 	if(clientip_trigger >= 0) {
2688 		if(a) {
2689 			lock_rw_unlock(&a->lock);
2690 		}
2691 		if(z) {
2692 			lock_rw_unlock(&z->lock);
2693 		}
2694 		return clientip_trigger;
2695 	}
2696 
2697 	if(z == NULL) {
2698 		if(a) {
2699 			lock_rw_unlock(&a->lock);
2700 		}
2701 		return 0;
2702 	}
2703 
2704 	log_assert(r);
2705 
2706 	if(r->action_override == RPZ_NO_OVERRIDE_ACTION) {
2707 		lzt = z->type;
2708 	} else {
2709 		lzt = rpz_action_to_localzone_type(r->action_override);
2710 	}
2711 	if(r->action_override == RPZ_PASSTHRU_ACTION ||
2712 		lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) {
2713 		*passthru = 1;
2714 	}
2715 
2716 	if(verbosity >= VERB_ALGO) {
2717 		char nm[255+1], zn[255+1];
2718 		dname_str(qinfo->qname, nm);
2719 		dname_str(z->name, zn);
2720 		if(strcmp(zn, nm) != 0)
2721 			verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s",
2722 				zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2723 		else
2724 			verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s",
2725 				nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2726 	}
2727 
2728 	ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp,
2729 					     repinfo, stats);
2730 
2731 	lock_rw_unlock(&z->lock);
2732 	lock_rw_unlock(&a->lock);
2733 
2734 	return ret;
2735 }
2736 
rpz_enable(struct rpz * r)2737 void rpz_enable(struct rpz* r)
2738 {
2739     if(!r)
2740         return;
2741     r->disabled = 0;
2742 }
2743 
rpz_disable(struct rpz * r)2744 void rpz_disable(struct rpz* r)
2745 {
2746     if(!r)
2747         return;
2748     r->disabled = 1;
2749 }
2750