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* 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 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* 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* 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 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 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 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 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 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 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 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* 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 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 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 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 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 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* 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 struct rpz* 482 rpz_create(struct config_auth* p) 483 { 484 struct rpz* r = calloc(1, sizeof(*r)); 485 if(!r) 486 goto err; 487 488 r->region = regional_create_custom(sizeof(struct regional)); 489 if(!r->region) { 490 goto err; 491 } 492 493 if(!(r->local_zones = local_zones_create())){ 494 goto err; 495 } 496 497 r->nsdname_zones = local_zones_create(); 498 if(r->local_zones == NULL){ 499 goto err; 500 } 501 502 if(!(r->respip_set = respip_set_create())) { 503 goto err; 504 } 505 506 r->client_set = rpz_clientip_synthesized_set_create(); 507 if(r->client_set == NULL) { 508 goto err; 509 } 510 511 r->ns_set = rpz_clientip_synthesized_set_create(); 512 if(r->ns_set == NULL) { 513 goto err; 514 } 515 516 r->taglistlen = p->rpz_taglistlen; 517 r->taglist = memdup(p->rpz_taglist, r->taglistlen); 518 if(p->rpz_action_override) { 519 r->action_override = rpz_config_to_action(p->rpz_action_override); 520 } 521 else 522 r->action_override = RPZ_NO_OVERRIDE_ACTION; 523 524 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 525 uint8_t nm[LDNS_MAX_DOMAINLEN+1]; 526 size_t nmlen = sizeof(nm); 527 528 if(!p->rpz_cname) { 529 log_err("rpz: override with cname action found, but no " 530 "rpz-cname-override configured"); 531 goto err; 532 } 533 534 if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) { 535 log_err("rpz: cannot parse cname override: %s", 536 p->rpz_cname); 537 goto err; 538 } 539 r->cname_override = new_cname_override(r->region, nm, nmlen); 540 if(!r->cname_override) { 541 goto err; 542 } 543 } 544 r->log = p->rpz_log; 545 r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra; 546 if(p->rpz_log_name) { 547 if(!(r->log_name = strdup(p->rpz_log_name))) { 548 log_err("malloc failure on RPZ log_name strdup"); 549 goto err; 550 } 551 } 552 return r; 553 err: 554 if(r) { 555 if(r->local_zones) 556 local_zones_delete(r->local_zones); 557 if(r->nsdname_zones) 558 local_zones_delete(r->nsdname_zones); 559 if(r->respip_set) 560 respip_set_delete(r->respip_set); 561 if(r->client_set != NULL) 562 rpz_clientip_synthesized_set_delete(r->client_set); 563 if(r->ns_set != NULL) 564 rpz_clientip_synthesized_set_delete(r->ns_set); 565 if(r->taglist) 566 free(r->taglist); 567 if(r->region) 568 regional_destroy(r->region); 569 free(r); 570 } 571 return NULL; 572 } 573 574 /** 575 * Remove RPZ zone name from dname 576 * Copy dname to newdname, without the originlen number of trailing bytes 577 */ 578 static size_t 579 strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen, 580 uint8_t* newdname, size_t maxnewdnamelen) 581 { 582 size_t newdnamelen; 583 if(dnamelen < originlen) 584 return 0; 585 newdnamelen = dnamelen - originlen; 586 if(newdnamelen+1 > maxnewdnamelen) 587 return 0; 588 memmove(newdname, dname, newdnamelen); 589 newdname[newdnamelen] = 0; 590 return newdnamelen + 1; /* + 1 for root label */ 591 } 592 593 static void 594 rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, 595 size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass, 596 uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 597 { 598 struct local_zone* z; 599 enum localzone_type tp = local_zone_always_transparent; 600 int dnamelabs = dname_count_labels(dname); 601 int newzone = 0; 602 603 if(a == RPZ_INVALID_ACTION) { 604 char str[255+1]; 605 if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS || 606 rrtype == LDNS_RR_TYPE_DNAME || 607 rrtype == LDNS_RR_TYPE_DNSKEY || 608 rrtype == LDNS_RR_TYPE_RRSIG || 609 rrtype == LDNS_RR_TYPE_NSEC || 610 rrtype == LDNS_RR_TYPE_NSEC3PARAM || 611 rrtype == LDNS_RR_TYPE_NSEC3 || 612 rrtype == LDNS_RR_TYPE_DS) { 613 free(dname); 614 return; /* no need to log these types as unsupported */ 615 } 616 dname_str(dname, str); 617 verbose(VERB_ALGO, "rpz: qname trigger, %s skipping unsupported action: %s", 618 str, rpz_action_to_string(a)); 619 free(dname); 620 return; 621 } 622 623 lock_rw_wrlock(&lz->lock); 624 /* exact match */ 625 z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN); 626 if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) { 627 char* rrstr = sldns_wire2str_rr(rr, rr_len); 628 if(rrstr == NULL) { 629 log_err("malloc error while inserting rpz nsdname trigger"); 630 free(dname); 631 lock_rw_unlock(&lz->lock); 632 return; 633 } 634 if(rrstr[0]) 635 rrstr[strlen(rrstr)-1]=0; /* remove newline */ 636 verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr); 637 free(rrstr); 638 free(dname); 639 lock_rw_unlock(&lz->lock); 640 return; 641 } 642 if(z == NULL) { 643 tp = rpz_action_to_localzone_type(a); 644 z = local_zones_add_zone(lz, dname, dnamelen, 645 dnamelabs, rrclass, tp); 646 if(z == NULL) { 647 log_warn("rpz: create failed"); 648 lock_rw_unlock(&lz->lock); 649 /* dname will be free'd in failed local_zone_create() */ 650 return; 651 } 652 newzone = 1; 653 } 654 if(a == RPZ_LOCAL_DATA_ACTION) { 655 char* rrstr = sldns_wire2str_rr(rr, rr_len); 656 if(rrstr == NULL) { 657 log_err("malloc error while inserting rpz nsdname trigger"); 658 free(dname); 659 lock_rw_unlock(&lz->lock); 660 return; 661 } 662 lock_rw_wrlock(&z->lock); 663 local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype, 664 rrclass, ttl, rdata, rdata_len, rrstr); 665 lock_rw_unlock(&z->lock); 666 free(rrstr); 667 } 668 if(!newzone) { 669 free(dname); 670 } 671 lock_rw_unlock(&lz->lock); 672 } 673 674 static void 675 rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len) 676 { 677 char buf[LDNS_MAX_DOMAINLEN+1]; 678 (void)dname_len; 679 dname_str(dname, buf); 680 verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf); 681 } 682 683 static void 684 rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 685 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 686 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 687 { 688 if(a == RPZ_INVALID_ACTION) { 689 verbose(VERB_ALGO, "rpz: skipping invalid action"); 690 free(dname); 691 return; 692 } 693 694 rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype, 695 rrclass, ttl, rdata, rdata_len, rr, rr_len); 696 } 697 698 static int 699 rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen, 700 uint8_t** stripdname, size_t* stripdnamelen) 701 { 702 uint8_t* tldstart = get_tld_label(dname, maxdnamelen); 703 uint8_t swap; 704 if(tldstart == NULL) { 705 if(dname == NULL) { 706 *stripdname = NULL; 707 *stripdnamelen = 0; 708 return 0; 709 } 710 *stripdname = memdup(dname, maxdnamelen); 711 if(!*stripdname) { 712 *stripdnamelen = 0; 713 log_err("malloc failure for rpz strip suffix"); 714 return 0; 715 } 716 *stripdnamelen = maxdnamelen; 717 return 1; 718 } 719 /* shorten the domain name briefly, 720 * then we allocate a new name with the correct length */ 721 swap = *tldstart; 722 *tldstart = 0; 723 (void)dname_count_size_labels(dname, stripdnamelen); 724 *stripdname = memdup(dname, *stripdnamelen); 725 *tldstart = swap; 726 if(!*stripdname) { 727 *stripdnamelen = 0; 728 log_err("malloc failure for rpz strip suffix"); 729 return 0; 730 } 731 return 1; 732 } 733 734 static void 735 rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 736 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 737 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 738 { 739 uint8_t* dname_stripped = NULL; 740 size_t dnamelen_stripped = 0; 741 742 rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, 743 &dnamelen_stripped); 744 if(a == RPZ_INVALID_ACTION) { 745 verbose(VERB_ALGO, "rpz: skipping invalid action"); 746 free(dname_stripped); 747 return; 748 } 749 750 /* dname_stripped is consumed or freed by the insert routine */ 751 rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped, 752 dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len, 753 rr, rr_len); 754 } 755 756 static int 757 rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr, 758 socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype, 759 uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 760 uint8_t* rr, size_t rr_len) 761 { 762 struct resp_addr* node; 763 char* rrstr; 764 enum respip_action respa = rpz_action_to_respip_action(a); 765 766 lock_rw_wrlock(&set->lock); 767 rrstr = sldns_wire2str_rr(rr, rr_len); 768 if(rrstr == NULL) { 769 log_err("malloc error while inserting rpz ipaddr based trigger"); 770 lock_rw_unlock(&set->lock); 771 return 0; 772 } 773 774 node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr); 775 if(node == NULL) { 776 lock_rw_unlock(&set->lock); 777 free(rrstr); 778 return 0; 779 } 780 781 lock_rw_wrlock(&node->lock); 782 lock_rw_unlock(&set->lock); 783 784 node->action = respa; 785 786 if(a == RPZ_LOCAL_DATA_ACTION) { 787 respip_enter_rr(set->region, node, rrtype, 788 rrclass, ttl, rdata, rdata_len, rrstr, ""); 789 } 790 791 lock_rw_unlock(&node->lock); 792 free(rrstr); 793 return 1; 794 } 795 796 static inline struct clientip_synthesized_rr* 797 rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set, 798 struct sockaddr_storage* addr, socklen_t addrlen, int net) 799 { 800 int insert_ok; 801 struct clientip_synthesized_rr* node = 802 (struct clientip_synthesized_rr*)addr_tree_find(&set->entries, 803 addr, addrlen, net); 804 805 if(node != NULL) { return node; } 806 807 /* node does not yet exist => allocate one */ 808 node = regional_alloc_zero(set->region, sizeof(*node)); 809 if(node == NULL) { 810 log_err("out of memory"); 811 return NULL; 812 } 813 814 lock_rw_init(&node->lock); 815 node->action = RPZ_INVALID_ACTION; 816 insert_ok = addr_tree_insert(&set->entries, &node->node, 817 addr, addrlen, net); 818 if (!insert_ok) { 819 log_warn("rpz: unexpected: unable to insert clientip address node"); 820 /* we can not free the just allocated node. 821 * theoretically a memleak */ 822 return NULL; 823 } 824 825 return node; 826 } 827 828 static void 829 rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) { 830 char* rrstr = sldns_wire2str_rr(rr, rr_len); 831 if(rrstr == NULL) { 832 log_err("malloc error while inserting rpz clientip based record"); 833 return; 834 } 835 log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr); 836 free(rrstr); 837 } 838 839 /* from localzone.c; difference is we don't have a dname */ 840 static struct local_rrset* 841 rpz_clientip_new_rrset(struct regional* region, 842 struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass) 843 { 844 struct packed_rrset_data* pd; 845 struct local_rrset* rrset = (struct local_rrset*) 846 regional_alloc_zero(region, sizeof(*rrset)); 847 if(rrset == NULL) { 848 log_err("out of memory"); 849 return NULL; 850 } 851 rrset->next = raddr->data; 852 raddr->data = rrset; 853 rrset->rrset = (struct ub_packed_rrset_key*) 854 regional_alloc_zero(region, sizeof(*rrset->rrset)); 855 if(rrset->rrset == NULL) { 856 log_err("out of memory"); 857 return NULL; 858 } 859 rrset->rrset->entry.key = rrset->rrset; 860 pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd)); 861 if(pd == NULL) { 862 log_err("out of memory"); 863 return NULL; 864 } 865 pd->trust = rrset_trust_prim_noglue; 866 pd->security = sec_status_insecure; 867 rrset->rrset->entry.data = pd; 868 rrset->rrset->rk.type = htons(rrtype); 869 rrset->rrset->rk.rrset_class = htons(rrclass); 870 rrset->rrset->rk.dname = regional_alloc_zero(region, 1); 871 if(rrset->rrset->rk.dname == NULL) { 872 log_err("out of memory"); 873 return NULL; 874 } 875 rrset->rrset->rk.dname_len = 1; 876 return rrset; 877 } 878 879 static int 880 rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* raddr, 881 uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata, 882 size_t rdata_len) 883 { 884 struct local_rrset* rrset; 885 if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data != NULL) { 886 log_err("CNAME response-ip data can not co-exist with other " 887 "client-ip data"); 888 return 0; 889 } 890 891 rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass); 892 if(raddr->data == NULL) { 893 return 0; 894 } 895 896 return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, ""); 897 } 898 899 static int 900 rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr, 901 socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype, 902 uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 903 uint8_t* rr, size_t rr_len) 904 { 905 struct clientip_synthesized_rr* node; 906 907 lock_rw_wrlock(&set->lock); 908 909 node = rpz_clientip_ensure_entry(set, addr, addrlen, net); 910 if(node == NULL) { 911 lock_rw_unlock(&set->lock); 912 rpz_report_rrset_error("client ip address", rr, rr_len); 913 return 0; 914 } 915 916 lock_rw_wrlock(&node->lock); 917 lock_rw_unlock(&set->lock); 918 919 node->action = a; 920 if(a == RPZ_LOCAL_DATA_ACTION) { 921 if(!rpz_clientip_enter_rr(set->region, node, rrtype, 922 rrclass, ttl, rdata, rdata_len)) { 923 verbose(VERB_ALGO, "rpz: unable to insert clientip rr"); 924 lock_rw_unlock(&node->lock); 925 return 0; 926 } 927 928 } 929 930 lock_rw_unlock(&node->lock); 931 932 return 1; 933 } 934 935 static int 936 rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 937 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 938 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 939 { 940 struct sockaddr_storage addr; 941 socklen_t addrlen; 942 int net, af; 943 944 if(a == RPZ_INVALID_ACTION) { 945 return 0; 946 } 947 948 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 949 verbose(VERB_ALGO, "rpz: unable to parse client ip"); 950 return 0; 951 } 952 953 return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net, 954 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 955 } 956 957 static int 958 rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 959 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 960 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 961 { 962 struct sockaddr_storage addr; 963 socklen_t addrlen; 964 int net, af; 965 966 if(a == RPZ_INVALID_ACTION) { 967 return 0; 968 } 969 970 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 971 verbose(VERB_ALGO, "rpz: unable to parse ns ip"); 972 return 0; 973 } 974 975 return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net, 976 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 977 } 978 979 /** Insert RR into RPZ's respip_set */ 980 static int 981 rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 982 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 983 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 984 { 985 struct sockaddr_storage addr; 986 socklen_t addrlen; 987 int net, af; 988 989 if(a == RPZ_INVALID_ACTION) { 990 return 0; 991 } 992 993 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 994 verbose(VERB_ALGO, "rpz: unable to parse response ip"); 995 return 0; 996 } 997 998 if(a == RPZ_INVALID_ACTION || 999 rpz_action_to_respip_action(a) == respip_invalid) { 1000 char str[255+1]; 1001 dname_str(dname, str); 1002 verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s", 1003 str, rpz_action_to_string(a)); 1004 return 0; 1005 } 1006 1007 return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net, 1008 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 1009 } 1010 1011 int 1012 rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname, 1013 size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl, 1014 uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len) 1015 { 1016 size_t policydnamelen; 1017 /* name is free'd in local_zone delete */ 1018 enum rpz_trigger t; 1019 enum rpz_action a; 1020 uint8_t* policydname; 1021 1022 if(rpz_type_ignored(rr_type)) { 1023 /* this rpz action is not valid, eg. this is the SOA or NS RR */ 1024 return 1; 1025 } 1026 if(!dname_subdomain_c(dname, azname)) { 1027 char* dname_str = sldns_wire2str_dname(dname, dnamelen); 1028 char* azname_str = sldns_wire2str_dname(azname, aznamelen); 1029 if(dname_str && azname_str) { 1030 log_err("rpz: name of record (%s) to insert into RPZ is not a " 1031 "subdomain of the configured name of the RPZ zone (%s)", 1032 dname_str, azname_str); 1033 } else { 1034 log_err("rpz: name of record to insert into RPZ is not a " 1035 "subdomain of the configured name of the RPZ zone"); 1036 } 1037 free(dname_str); 1038 free(azname_str); 1039 return 0; 1040 } 1041 1042 log_assert(dnamelen >= aznamelen); 1043 if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) { 1044 log_err("malloc error while inserting RPZ RR"); 1045 return 0; 1046 } 1047 1048 a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); 1049 if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, 1050 policydname, (dnamelen-aznamelen)+1))) { 1051 free(policydname); 1052 return 0; 1053 } 1054 t = rpz_dname_to_trigger(policydname, policydnamelen); 1055 if(t == RPZ_INVALID_TRIGGER) { 1056 free(policydname); 1057 verbose(VERB_ALGO, "rpz: skipping invalid trigger"); 1058 return 1; 1059 } 1060 if(t == RPZ_QNAME_TRIGGER) { 1061 /* policydname will be consumed, no free */ 1062 rpz_insert_qname_trigger(r, policydname, policydnamelen, 1063 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1064 rr_len); 1065 } else if(t == RPZ_RESPONSE_IP_TRIGGER) { 1066 rpz_insert_response_ip_trigger(r, policydname, policydnamelen, 1067 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1068 rr_len); 1069 free(policydname); 1070 } else if(t == RPZ_CLIENT_IP_TRIGGER) { 1071 rpz_insert_clientip_trigger(r, policydname, policydnamelen, 1072 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1073 rr_len); 1074 free(policydname); 1075 } else if(t == RPZ_NSIP_TRIGGER) { 1076 rpz_insert_nsip_trigger(r, policydname, policydnamelen, 1077 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1078 rr_len); 1079 free(policydname); 1080 } else if(t == RPZ_NSDNAME_TRIGGER) { 1081 rpz_insert_nsdname_trigger(r, policydname, policydnamelen, 1082 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1083 rr_len); 1084 free(policydname); 1085 } else { 1086 free(policydname); 1087 verbose(VERB_ALGO, "rpz: skipping unsupported trigger: %s", 1088 rpz_trigger_to_string(t)); 1089 } 1090 return 1; 1091 } 1092 1093 /** 1094 * Find RPZ local-zone by qname. 1095 * @param zones: local-zone tree 1096 * @param qname: qname 1097 * @param qname_len: length of qname 1098 * @param qclass: qclass 1099 * @param only_exact: if 1 only exact (non wildcard) matches are returned 1100 * @param wr: get write lock for local-zone if 1, read lock if 0 1101 * @param zones_keep_lock: if set do not release the r->local_zones lock, this 1102 * makes the caller of this function responsible for releasing the lock. 1103 * @return: NULL or local-zone holding rd or wr lock 1104 */ 1105 static struct local_zone* 1106 rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint16_t qclass, 1107 int only_exact, int wr, int zones_keep_lock) 1108 { 1109 uint8_t* ce; 1110 size_t ce_len; 1111 int ce_labs; 1112 uint8_t wc[LDNS_MAX_DOMAINLEN+1]; 1113 int exact; 1114 struct local_zone* z = NULL; 1115 1116 if(wr) { 1117 lock_rw_wrlock(&zones->lock); 1118 } else { 1119 lock_rw_rdlock(&zones->lock); 1120 } 1121 z = local_zones_find_le(zones, qname, qname_len, 1122 dname_count_labels(qname), 1123 LDNS_RR_CLASS_IN, &exact); 1124 if(!z || (only_exact && !exact)) { 1125 if(!zones_keep_lock) { 1126 lock_rw_unlock(&zones->lock); 1127 } 1128 return NULL; 1129 } 1130 if(wr) { 1131 lock_rw_wrlock(&z->lock); 1132 } else { 1133 lock_rw_rdlock(&z->lock); 1134 } 1135 if(!zones_keep_lock) { 1136 lock_rw_unlock(&zones->lock); 1137 } 1138 1139 if(exact) 1140 return z; 1141 1142 /* No exact match found, lookup wildcard. closest encloser must 1143 * be the shared parent between the qname and the best local 1144 * zone match, append '*' to that and do another lookup. */ 1145 1146 ce = dname_get_shared_topdomain(z->name, qname); 1147 if(!ce /* should not happen */) { 1148 lock_rw_unlock(&z->lock); 1149 if(zones_keep_lock) { 1150 lock_rw_unlock(&zones->lock); 1151 } 1152 return NULL; 1153 } 1154 ce_labs = dname_count_size_labels(ce, &ce_len); 1155 if(ce_len+2 > sizeof(wc)) { 1156 lock_rw_unlock(&z->lock); 1157 if(zones_keep_lock) { 1158 lock_rw_unlock(&zones->lock); 1159 } 1160 return NULL; 1161 } 1162 wc[0] = 1; /* length of wildcard label */ 1163 wc[1] = (uint8_t)'*'; /* wildcard label */ 1164 memmove(wc+2, ce, ce_len); 1165 lock_rw_unlock(&z->lock); 1166 1167 if(!zones_keep_lock) { 1168 if(wr) { 1169 lock_rw_wrlock(&zones->lock); 1170 } else { 1171 lock_rw_rdlock(&zones->lock); 1172 } 1173 } 1174 z = local_zones_find_le(zones, wc, 1175 ce_len+2, ce_labs+1, qclass, &exact); 1176 if(!z || !exact) { 1177 lock_rw_unlock(&zones->lock); 1178 return NULL; 1179 } 1180 if(wr) { 1181 lock_rw_wrlock(&z->lock); 1182 } else { 1183 lock_rw_rdlock(&z->lock); 1184 } 1185 if(!zones_keep_lock) { 1186 lock_rw_unlock(&zones->lock); 1187 } 1188 return z; 1189 } 1190 1191 /** Find entry for RR type in the list of rrsets for the clientip. */ 1192 static struct local_rrset* 1193 rpz_find_synthesized_rrset(uint16_t qtype, 1194 struct clientip_synthesized_rr* data) 1195 { 1196 struct local_rrset* cursor = data->data; 1197 while( cursor != NULL) { 1198 struct packed_rrset_key* packed_rrset = &cursor->rrset->rk; 1199 if(htons(qtype) == packed_rrset->type) { 1200 return cursor; 1201 } 1202 cursor = cursor->next; 1203 } 1204 return NULL; 1205 } 1206 1207 /** 1208 * Remove RR from RPZ's local-data 1209 * @param z: local-zone for RPZ, holding write lock 1210 * @param policydname: dname of RR to remove 1211 * @param policydnamelen: length of policydname 1212 * @param rr_type: RR type of RR to remove 1213 * @param rdata: rdata of RR to remove 1214 * @param rdatalen: length of rdata 1215 * @return: 1 if zone must be removed after RR deletion 1216 */ 1217 static int 1218 rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname, 1219 size_t policydnamelen, uint16_t rr_type, uint8_t* rdata, 1220 size_t rdatalen) 1221 { 1222 struct local_data* ld; 1223 struct packed_rrset_data* d; 1224 size_t index; 1225 ld = local_zone_find_data(z, policydname, policydnamelen, 1226 dname_count_labels(policydname)); 1227 if(ld) { 1228 struct local_rrset* prev=NULL, *p=ld->rrsets; 1229 while(p && ntohs(p->rrset->rk.type) != rr_type) { 1230 prev = p; 1231 p = p->next; 1232 } 1233 if(!p) 1234 return 0; 1235 d = (struct packed_rrset_data*)p->rrset->entry.data; 1236 if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) { 1237 if(d->count == 1) { 1238 /* no memory recycling for zone deletions ... */ 1239 if(prev) prev->next = p->next; 1240 else ld->rrsets = p->next; 1241 } 1242 if(d->count > 1) { 1243 if(!local_rrset_remove_rr(d, index)) 1244 return 0; 1245 } 1246 } 1247 } 1248 if(ld && ld->rrsets) 1249 return 0; 1250 return 1; 1251 } 1252 1253 /** 1254 * Remove RR from RPZ's respip set 1255 * @param raddr: respip node 1256 * @param rr_type: RR type of RR to remove 1257 * @param rdata: rdata of RR to remove 1258 * @param rdatalen: length of rdata 1259 * @return: 1 if zone must be removed after RR deletion 1260 */ 1261 static int 1262 rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata, 1263 size_t rdatalen) 1264 { 1265 size_t index; 1266 struct packed_rrset_data* d; 1267 if(!raddr->data) 1268 return 1; 1269 d = raddr->data->entry.data; 1270 if(ntohs(raddr->data->rk.type) != rr_type) { 1271 return 0; 1272 } 1273 if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) { 1274 if(d->count == 1) { 1275 /* regional alloc'd */ 1276 raddr->data->entry.data = NULL; 1277 raddr->data = NULL; 1278 return 1; 1279 } 1280 if(d->count > 1) { 1281 if(!local_rrset_remove_rr(d, index)) 1282 return 0; 1283 } 1284 } 1285 return 0; 1286 1287 } 1288 1289 /** Remove RR from rpz localzones structure */ 1290 static void 1291 rpz_remove_local_zones_trigger(struct local_zones* zones, uint8_t* dname, 1292 size_t dnamelen, enum rpz_action a, uint16_t rr_type, 1293 uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen) 1294 { 1295 struct local_zone* z; 1296 int delete_zone = 1; 1297 z = rpz_find_zone(zones, dname, dnamelen, rr_class, 1298 1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/); 1299 if(!z) { 1300 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1301 "RPZ domain not found"); 1302 return; 1303 } 1304 if(a == RPZ_LOCAL_DATA_ACTION) 1305 delete_zone = rpz_data_delete_rr(z, dname, 1306 dnamelen, rr_type, rdatawl, rdatalen); 1307 else if(a != localzone_type_to_rpz_action(z->type)) { 1308 lock_rw_unlock(&z->lock); 1309 lock_rw_unlock(&zones->lock); 1310 return; 1311 } 1312 lock_rw_unlock(&z->lock); 1313 if(delete_zone) { 1314 local_zones_del_zone(zones, z); 1315 } 1316 lock_rw_unlock(&zones->lock); 1317 } 1318 1319 /** Remove RR from RPZ's local-zone */ 1320 static void 1321 rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1322 enum rpz_action a, uint16_t rr_type, uint16_t rr_class, 1323 uint8_t* rdatawl, size_t rdatalen) 1324 { 1325 rpz_remove_local_zones_trigger(r->local_zones, dname, dnamelen, 1326 a, rr_type, rr_class, rdatawl, rdatalen); 1327 } 1328 1329 static void 1330 rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1331 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1332 { 1333 struct resp_addr* node; 1334 struct sockaddr_storage addr; 1335 socklen_t addrlen; 1336 int net, af; 1337 int delete_respip = 1; 1338 1339 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1340 return; 1341 1342 lock_rw_wrlock(&r->respip_set->lock); 1343 if(!(node = (struct resp_addr*)addr_tree_find( 1344 &r->respip_set->ip_tree, &addr, addrlen, net))) { 1345 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1346 "RPZ domain not found"); 1347 lock_rw_unlock(&r->respip_set->lock); 1348 return; 1349 } 1350 1351 lock_rw_wrlock(&node->lock); 1352 if(a == RPZ_LOCAL_DATA_ACTION) { 1353 /* remove RR, signal whether RR can be removed */ 1354 delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl, 1355 rdatalen); 1356 } 1357 lock_rw_unlock(&node->lock); 1358 if(delete_respip) 1359 respip_sockaddr_delete(r->respip_set, node); 1360 lock_rw_unlock(&r->respip_set->lock); 1361 } 1362 1363 /** find and remove type from list of local_rrset entries*/ 1364 static void 1365 del_local_rrset_from_list(struct local_rrset** list_head, uint16_t dtype) 1366 { 1367 struct local_rrset* prev=NULL, *p=*list_head; 1368 while(p && ntohs(p->rrset->rk.type) != dtype) { 1369 prev = p; 1370 p = p->next; 1371 } 1372 if(!p) 1373 return; /* rrset type not found */ 1374 /* unlink it */ 1375 if(prev) prev->next = p->next; 1376 else *list_head = p->next; 1377 /* no memory recycling for zone deletions ... */ 1378 } 1379 1380 /** Delete client-ip trigger RR from its RRset and perhaps also the rrset 1381 * from the linked list. Returns if the local data is empty and the node can 1382 * be deleted too, or not. */ 1383 static int rpz_remove_clientip_rr(struct clientip_synthesized_rr* node, 1384 uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1385 { 1386 struct local_rrset* rrset; 1387 struct packed_rrset_data* d; 1388 size_t index; 1389 rrset = rpz_find_synthesized_rrset(rr_type, node); 1390 if(rrset == NULL) 1391 return 0; /* type not found, ignore */ 1392 d = (struct packed_rrset_data*)rrset->rrset->entry.data; 1393 if(!packed_rrset_find_rr(d, rdatawl, rdatalen, &index)) 1394 return 0; /* RR not found, ignore */ 1395 if(d->count == 1) { 1396 /* regional alloc'd */ 1397 /* delete the type entry from the list */ 1398 del_local_rrset_from_list(&node->data, rr_type); 1399 /* if the list is empty, the node can be removed too */ 1400 if(node->data == NULL) 1401 return 1; 1402 } else if (d->count > 1) { 1403 if(!local_rrset_remove_rr(d, index)) 1404 return 0; 1405 } 1406 return 0; 1407 } 1408 1409 /** remove trigger RR from clientip_syntheized set tree. */ 1410 static void 1411 rpz_clientip_remove_trigger_rr(struct clientip_synthesized_rrset* set, 1412 struct sockaddr_storage* addr, socklen_t addrlen, int net, 1413 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1414 { 1415 struct clientip_synthesized_rr* node; 1416 int delete_node = 1; 1417 1418 lock_rw_wrlock(&set->lock); 1419 node = (struct clientip_synthesized_rr*)addr_tree_find(&set->entries, 1420 addr, addrlen, net); 1421 if(node == NULL) { 1422 /* netblock not found */ 1423 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1424 "RPZ address, netblock not found"); 1425 lock_rw_unlock(&set->lock); 1426 return; 1427 } 1428 lock_rw_wrlock(&node->lock); 1429 if(a == RPZ_LOCAL_DATA_ACTION) { 1430 /* remove RR, signal whether entry can be removed */ 1431 delete_node = rpz_remove_clientip_rr(node, rr_type, rdatawl, 1432 rdatalen); 1433 } else if(a != node->action) { 1434 /* ignore the RR with different action specification */ 1435 delete_node = 0; 1436 } 1437 if(delete_node) { 1438 rbtree_delete(&set->entries, node->node.node.key); 1439 } 1440 lock_rw_unlock(&set->lock); 1441 lock_rw_unlock(&node->lock); 1442 if(delete_node) { 1443 lock_rw_destroy(&node->lock); 1444 } 1445 } 1446 1447 /** Remove clientip trigger RR from RPZ. */ 1448 static void 1449 rpz_remove_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1450 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1451 { 1452 struct sockaddr_storage addr; 1453 socklen_t addrlen; 1454 int net, af; 1455 if(a == RPZ_INVALID_ACTION) 1456 return; 1457 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1458 return; 1459 rpz_clientip_remove_trigger_rr(r->client_set, &addr, addrlen, net, 1460 a, rr_type, rdatawl, rdatalen); 1461 } 1462 1463 /** Remove nsip trigger RR from RPZ. */ 1464 static void 1465 rpz_remove_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1466 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1467 { 1468 struct sockaddr_storage addr; 1469 socklen_t addrlen; 1470 int net, af; 1471 if(a == RPZ_INVALID_ACTION) 1472 return; 1473 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1474 return; 1475 rpz_clientip_remove_trigger_rr(r->ns_set, &addr, addrlen, net, 1476 a, rr_type, rdatawl, rdatalen); 1477 } 1478 1479 /** Remove nsdname trigger RR from RPZ. */ 1480 static void 1481 rpz_remove_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1482 enum rpz_action a, uint16_t rr_type, uint16_t rr_class, 1483 uint8_t* rdatawl, size_t rdatalen) 1484 { 1485 uint8_t* dname_stripped = NULL; 1486 size_t dnamelen_stripped = 0; 1487 if(a == RPZ_INVALID_ACTION) 1488 return; 1489 if(!rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, 1490 &dnamelen_stripped)) 1491 return; 1492 rpz_remove_local_zones_trigger(r->nsdname_zones, dname_stripped, 1493 dnamelen_stripped, a, rr_type, rr_class, rdatawl, rdatalen); 1494 free(dname_stripped); 1495 } 1496 1497 void 1498 rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname, 1499 size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, 1500 size_t rdatalen) 1501 { 1502 size_t policydnamelen; 1503 enum rpz_trigger t; 1504 enum rpz_action a; 1505 uint8_t* policydname; 1506 1507 if(rpz_type_ignored(rr_type)) { 1508 /* this rpz action is not valid, eg. this is the SOA or NS RR */ 1509 return; 1510 } 1511 if(!dname_subdomain_c(dname, azname)) { 1512 /* not subdomain of the RPZ zone. */ 1513 return; 1514 } 1515 1516 if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1))) 1517 return; 1518 1519 a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); 1520 if(a == RPZ_INVALID_ACTION) { 1521 free(policydname); 1522 return; 1523 } 1524 if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, 1525 policydname, LDNS_MAX_DOMAINLEN + 1))) { 1526 free(policydname); 1527 return; 1528 } 1529 t = rpz_dname_to_trigger(policydname, policydnamelen); 1530 if(t == RPZ_INVALID_TRIGGER) { 1531 /* skipping invalid trigger */ 1532 free(policydname); 1533 return; 1534 } 1535 if(t == RPZ_QNAME_TRIGGER) { 1536 rpz_remove_qname_trigger(r, policydname, policydnamelen, a, 1537 rr_type, rr_class, rdatawl, rdatalen); 1538 } else if(t == RPZ_RESPONSE_IP_TRIGGER) { 1539 rpz_remove_response_ip_trigger(r, policydname, policydnamelen, 1540 a, rr_type, rdatawl, rdatalen); 1541 } else if(t == RPZ_CLIENT_IP_TRIGGER) { 1542 rpz_remove_clientip_trigger(r, policydname, policydnamelen, a, 1543 rr_type, rdatawl, rdatalen); 1544 } else if(t == RPZ_NSIP_TRIGGER) { 1545 rpz_remove_nsip_trigger(r, policydname, policydnamelen, a, 1546 rr_type, rdatawl, rdatalen); 1547 } else if(t == RPZ_NSDNAME_TRIGGER) { 1548 rpz_remove_nsdname_trigger(r, policydname, policydnamelen, a, 1549 rr_type, rr_class, rdatawl, rdatalen); 1550 } 1551 /* else it was an unsupported trigger, also skipped. */ 1552 free(policydname); 1553 } 1554 1555 /** print log information for an applied RPZ policy. Based on local-zone's 1556 * lz_inform_print(). 1557 * The repinfo contains the reply address. If it is NULL, the module 1558 * state is used to report the first IP address (if any). 1559 * The dname is used, for the applied rpz, if NULL, addrnode is used. 1560 */ 1561 static void 1562 log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode, 1563 enum rpz_action a, struct query_info* qinfo, 1564 struct comm_reply* repinfo, struct module_qstate* ms, char* log_name) 1565 { 1566 char ip[128], txt[512], portstr[32]; 1567 char dnamestr[LDNS_MAX_DOMAINLEN+1]; 1568 uint16_t port = 0; 1569 if(dname) { 1570 dname_str(dname, dnamestr); 1571 } else if(addrnode) { 1572 char addrbuf[128]; 1573 addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf)); 1574 snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net); 1575 } else { 1576 dnamestr[0]=0; 1577 } 1578 if(repinfo) { 1579 addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip)); 1580 port = ntohs(((struct sockaddr_in*)&repinfo->client_addr)->sin_port); 1581 } else if(ms && ms->mesh_info && ms->mesh_info->reply_list) { 1582 addr_to_str(&ms->mesh_info->reply_list->query_reply.client_addr, 1583 ms->mesh_info->reply_list->query_reply.client_addrlen, 1584 ip, sizeof(ip)); 1585 port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port); 1586 } else { 1587 ip[0]=0; 1588 port = 0; 1589 } 1590 snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port); 1591 snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s", 1592 (log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""), 1593 (strcmp(trigger,"qname")==0?"":trigger), 1594 (strcmp(trigger,"qname")==0?"":" "), 1595 dnamestr, rpz_action_to_string(a), 1596 (ip[0]?ip:""), (ip[0]?portstr:"")); 1597 log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1598 } 1599 1600 static struct clientip_synthesized_rr* 1601 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set, 1602 struct sockaddr_storage* addr, socklen_t addrlen, char* triggername) 1603 { 1604 struct clientip_synthesized_rr* raddr = NULL; 1605 enum rpz_action action = RPZ_INVALID_ACTION; 1606 1607 lock_rw_rdlock(&set->lock); 1608 1609 raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries, 1610 addr, addrlen); 1611 if(raddr != NULL) { 1612 lock_rw_rdlock(&raddr->lock); 1613 action = raddr->action; 1614 if(verbosity >= VERB_ALGO) { 1615 char ip[256], net[256]; 1616 addr_to_str(addr, addrlen, ip, sizeof(ip)); 1617 addr_to_str(&raddr->node.addr, raddr->node.addrlen, 1618 net, sizeof(net)); 1619 verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s", 1620 triggername, net, raddr->node.net, ip, rpz_action_to_string(action)); 1621 } 1622 } 1623 lock_rw_unlock(&set->lock); 1624 1625 return raddr; 1626 } 1627 1628 static inline 1629 struct clientip_synthesized_rr* 1630 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo, 1631 struct comm_reply* repinfo, uint8_t* taglist, size_t taglen, 1632 struct ub_server_stats* stats, 1633 /* output parameters */ 1634 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out) 1635 { 1636 struct clientip_synthesized_rr* node = NULL; 1637 struct auth_zone* a = NULL; 1638 struct rpz* r = NULL; 1639 struct local_zone* z = NULL; 1640 1641 lock_rw_rdlock(&az->rpz_lock); 1642 1643 for(a = az->rpz_first; a; a = a->rpz_az_next) { 1644 lock_rw_rdlock(&a->lock); 1645 r = a->rpz; 1646 if(r->disabled) { 1647 lock_rw_unlock(&a->lock); 1648 continue; 1649 } 1650 if(r->taglist && !taglist_intersect(r->taglist, 1651 r->taglistlen, taglist, taglen)) { 1652 lock_rw_unlock(&a->lock); 1653 continue; 1654 } 1655 z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len, 1656 qinfo->qclass, 0, 0, 0); 1657 node = rpz_ipbased_trigger_lookup(r->client_set, 1658 &repinfo->client_addr, repinfo->client_addrlen, 1659 "clientip"); 1660 if((z || node) && r->action_override == RPZ_DISABLED_ACTION) { 1661 if(r->log) 1662 log_rpz_apply((node?"clientip":"qname"), 1663 (z?z->name:NULL), 1664 (node?&node->node:NULL), 1665 r->action_override, 1666 qinfo, repinfo, NULL, r->log_name); 1667 stats->rpz_action[r->action_override]++; 1668 if(z != NULL) { 1669 lock_rw_unlock(&z->lock); 1670 z = NULL; 1671 } 1672 if(node != NULL) { 1673 lock_rw_unlock(&node->lock); 1674 node = NULL; 1675 } 1676 } 1677 if(z || node) { 1678 break; 1679 } 1680 /* not found in this auth_zone */ 1681 lock_rw_unlock(&a->lock); 1682 } 1683 1684 lock_rw_unlock(&az->rpz_lock); 1685 1686 *r_out = r; 1687 *a_out = a; 1688 *z_out = z; 1689 1690 return node; 1691 } 1692 1693 static inline int 1694 rpz_is_udp_query(struct comm_reply* repinfo) { 1695 return repinfo != NULL 1696 ? (repinfo->c != NULL 1697 ? repinfo->c->type == comm_udp 1698 : 0) 1699 : 0; 1700 } 1701 1702 /** encode answer consisting of 1 rrset */ 1703 static int 1704 rpz_local_encode(struct module_env* env, struct query_info* qinfo, 1705 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1706 struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, 1707 int rcode, struct ub_packed_rrset_key* soa_rrset) 1708 { 1709 struct reply_info rep; 1710 uint16_t udpsize; 1711 struct ub_packed_rrset_key* rrsetlist[3]; 1712 1713 memset(&rep, 0, sizeof(rep)); 1714 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1715 rep.qdcount = 1; 1716 rep.rrset_count = ansec; 1717 rep.rrsets = rrsetlist; 1718 if(ansec > 0) { 1719 rep.an_numrrsets = 1; 1720 rep.rrsets[0] = rrset; 1721 rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0]; 1722 } 1723 if(soa_rrset != NULL) { 1724 rep.ar_numrrsets = 1; 1725 rep.rrsets[rep.rrset_count] = soa_rrset; 1726 rep.rrset_count ++; 1727 if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) { 1728 rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]; 1729 } 1730 } 1731 1732 udpsize = edns->udp_size; 1733 edns->edns_version = EDNS_ADVERTISED_VERSION; 1734 edns->udp_size = EDNS_ADVERTISED_SIZE; 1735 edns->ext_rcode = 0; 1736 edns->bits &= EDNS_DO; 1737 if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, 1738 repinfo, temp, env->now_tv) || 1739 !reply_info_answer_encode(qinfo, &rep, 1740 *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), 1741 buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) { 1742 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1743 *(uint16_t*)sldns_buffer_begin(buf), 1744 sldns_buffer_read_u16_at(buf, 2), edns); 1745 } 1746 1747 return 1; 1748 } 1749 1750 /** allocate SOA record ubrrsetkey in region */ 1751 static struct ub_packed_rrset_key* 1752 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa, 1753 struct regional* temp) 1754 { 1755 struct ub_packed_rrset_key csoa; 1756 if(!soa) 1757 return NULL; 1758 memset(&csoa, 0, sizeof(csoa)); 1759 csoa.entry.key = &csoa; 1760 csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN); 1761 csoa.rk.type = htons(LDNS_RR_TYPE_SOA); 1762 csoa.rk.flags |= PACKED_RRSET_FIXEDTTL 1763 | PACKED_RRSET_RPZ; 1764 csoa.rk.dname = auth_zone->name; 1765 csoa.rk.dname_len = auth_zone->namelen; 1766 csoa.entry.hash = rrset_key_hash(&csoa.rk); 1767 csoa.entry.data = soa->data; 1768 return respip_copy_rrset(&csoa, temp); 1769 } 1770 1771 static void 1772 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr, 1773 struct module_env* env, struct query_info* qinfo, 1774 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1775 struct regional* temp, struct auth_zone* auth_zone) 1776 { 1777 struct local_rrset* rrset; 1778 enum rpz_action action = RPZ_INVALID_ACTION; 1779 struct ub_packed_rrset_key* rp = NULL; 1780 struct ub_packed_rrset_key* rsoa = NULL; 1781 int rcode = LDNS_RCODE_NOERROR|BIT_AA; 1782 int rrset_count = 1; 1783 1784 /* prepare synthesized answer for client */ 1785 action = raddr->action; 1786 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) { 1787 verbose(VERB_ALGO, "rpz: bug: local-data action but no local data"); 1788 return; 1789 } 1790 1791 /* check query type / rr type */ 1792 rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr); 1793 if(rrset == NULL) { 1794 verbose(VERB_ALGO, "rpz: unable to find local-data for query"); 1795 rrset_count = 0; 1796 goto nodata; 1797 } 1798 1799 rp = respip_copy_rrset(rrset->rrset, temp); 1800 if(!rp) { 1801 verbose(VERB_ALGO, "rpz: local data action: out of memory"); 1802 return; 1803 } 1804 1805 rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ; 1806 rp->rk.dname = qinfo->qname; 1807 rp->rk.dname_len = qinfo->qname_len; 1808 rp->entry.hash = rrset_key_hash(&rp->rk); 1809 nodata: 1810 if(auth_zone) { 1811 struct auth_rrset* soa = NULL; 1812 soa = auth_zone_get_soa_rrset(auth_zone); 1813 if(soa) { 1814 rsoa = make_soa_ubrrset(auth_zone, soa, temp); 1815 if(!rsoa) { 1816 verbose(VERB_ALGO, "rpz: local data action soa: out of memory"); 1817 return; 1818 } 1819 } 1820 } 1821 1822 rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp, 1823 rrset_count, rcode, rsoa); 1824 } 1825 1826 /** add additional section SOA record to the reply. 1827 * Since this gets fed into the normal iterator answer creation, it 1828 * gets minimal-responses applied to it, that can remove the additional SOA 1829 * again. */ 1830 static int 1831 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms, 1832 struct auth_zone* az) 1833 { 1834 struct auth_rrset* soa = NULL; 1835 struct ub_packed_rrset_key* rsoa = NULL; 1836 struct ub_packed_rrset_key** prevrrsets; 1837 if(!az) return 1; 1838 soa = auth_zone_get_soa_rrset(az); 1839 if(!soa) return 1; 1840 if(!rep) return 0; 1841 rsoa = make_soa_ubrrset(az, soa, ms->region); 1842 if(!rsoa) return 0; 1843 prevrrsets = rep->rrsets; 1844 rep->rrsets = regional_alloc_zero(ms->region, 1845 sizeof(*rep->rrsets)*(rep->rrset_count+1)); 1846 if(!rep->rrsets) 1847 return 0; 1848 if(prevrrsets && rep->rrset_count > 0) 1849 memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets)); 1850 rep->rrset_count++; 1851 rep->ar_numrrsets++; 1852 rep->rrsets[rep->rrset_count-1] = rsoa; 1853 return 1; 1854 } 1855 1856 static inline struct dns_msg* 1857 rpz_dns_msg_new(struct regional* region) 1858 { 1859 struct dns_msg* msg = 1860 (struct dns_msg*)regional_alloc(region, 1861 sizeof(struct dns_msg)); 1862 if(msg == NULL) { return NULL; } 1863 memset(msg, 0, sizeof(struct dns_msg)); 1864 1865 return msg; 1866 } 1867 1868 static inline struct dns_msg* 1869 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1870 struct query_info* qinfo, struct auth_zone* az) 1871 { 1872 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1873 if(msg == NULL) { return msg; } 1874 msg->qinfo = *qinfo; 1875 msg->rep = construct_reply_info_base(ms->region, 1876 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1877 1, /* qd */ 1878 0, /* ttl */ 1879 0, /* prettl */ 1880 0, /* expttl */ 1881 0, /* an */ 1882 0, /* ns */ 1883 0, /* ar */ 1884 0, /* total */ 1885 sec_status_insecure, 1886 LDNS_EDE_NONE); 1887 if(msg->rep) 1888 msg->rep->authoritative = 1; 1889 if(!rpz_add_soa(msg->rep, ms, az)) 1890 return NULL; 1891 return msg; 1892 } 1893 1894 static inline struct dns_msg* 1895 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms, 1896 struct query_info* qinfo, struct auth_zone* az) 1897 { 1898 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1899 uint16_t flags; 1900 if(msg == NULL) { return msg; } 1901 msg->qinfo = *qinfo; 1902 flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA; 1903 if(r->signal_nxdomain_ra) 1904 flags &= ~BIT_RA; 1905 msg->rep = construct_reply_info_base(ms->region, 1906 flags, 1907 1, /* qd */ 1908 0, /* ttl */ 1909 0, /* prettl */ 1910 0, /* expttl */ 1911 0, /* an */ 1912 0, /* ns */ 1913 0, /* ar */ 1914 0, /* total */ 1915 sec_status_insecure, 1916 LDNS_EDE_NONE); 1917 if(msg->rep) 1918 msg->rep->authoritative = 1; 1919 if(!rpz_add_soa(msg->rep, ms, az)) 1920 return NULL; 1921 return msg; 1922 } 1923 1924 static inline struct dns_msg* 1925 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1926 struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az) 1927 { 1928 struct dns_msg* msg = NULL; 1929 struct reply_info* new_reply_info; 1930 struct ub_packed_rrset_key* rp; 1931 1932 1933 msg = rpz_dns_msg_new(ms->region); 1934 if(msg == NULL) { return NULL; } 1935 1936 new_reply_info = construct_reply_info_base(ms->region, 1937 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1938 1, /* qd */ 1939 0, /* ttl */ 1940 0, /* prettl */ 1941 0, /* expttl */ 1942 1, /* an */ 1943 0, /* ns */ 1944 0, /* ar */ 1945 1, /* total */ 1946 sec_status_insecure, 1947 LDNS_EDE_NONE); 1948 if(new_reply_info == NULL) { 1949 log_err("out of memory"); 1950 return NULL; 1951 } 1952 new_reply_info->authoritative = 1; 1953 rp = respip_copy_rrset(rrset->rrset, ms->region); 1954 if(rp == NULL) { 1955 log_err("out of memory"); 1956 return NULL; 1957 } 1958 rp->rk.dname = qi->qname; 1959 rp->rk.dname_len = qi->qname_len; 1960 /* this rrset is from the rpz data, or synthesized. 1961 * It is not actually from the network, so we flag it with this 1962 * flags as a fake RRset. If later the cache is used to look up 1963 * rrsets, then the fake ones are not returned (if you look without 1964 * the flag). For like CNAME lookups from the iterator or A, AAAA 1965 * lookups for nameserver targets, it would use the without flag 1966 * actual data. So that the actual network data and fake data 1967 * are kept track of separately. */ 1968 rp->rk.flags |= PACKED_RRSET_RPZ; 1969 new_reply_info->rrsets[0] = rp; 1970 msg->rep = new_reply_info; 1971 if(!rpz_add_soa(msg->rep, ms, az)) 1972 return NULL; 1973 return msg; 1974 } 1975 1976 static inline struct dns_msg* 1977 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms, 1978 struct clientip_synthesized_rr* data, struct auth_zone* az) 1979 { 1980 struct query_info* qi = &ms->qinfo; 1981 struct local_rrset* rrset; 1982 1983 rrset = rpz_find_synthesized_rrset(qi->qtype, data); 1984 if(rrset == NULL) { 1985 verbose(VERB_ALGO, "rpz: nsip: no matching local data found"); 1986 return NULL; 1987 } 1988 1989 return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az); 1990 } 1991 1992 /* copy'n'paste from localzone.c */ 1993 static struct local_rrset* 1994 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok) 1995 { 1996 struct local_rrset* p; 1997 type = htons(type); 1998 for(p = data->rrsets; p; p = p->next) { 1999 if(p->rrset->rk.type == type) 2000 return p; 2001 if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) 2002 return p; 2003 } 2004 return NULL; 2005 } 2006 2007 /* based on localzone.c:local_data_answer() */ 2008 static inline struct dns_msg* 2009 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms, 2010 struct local_zone* z, struct matched_delegation_point const* match, 2011 struct auth_zone* az) 2012 { 2013 struct local_data key; 2014 struct local_data* ld; 2015 struct local_rrset* rrset; 2016 2017 if(match->dname == NULL) { return NULL; } 2018 2019 key.node.key = &key; 2020 key.name = match->dname; 2021 key.namelen = match->dname_len; 2022 key.namelabs = dname_count_labels(match->dname); 2023 2024 rpz_log_dname("nsdname local data", key.name, key.namelen); 2025 2026 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 2027 if(ld == NULL) { 2028 verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found"); 2029 return NULL; 2030 } 2031 2032 rrset = local_data_find_type(ld, ms->qinfo.qtype, 1); 2033 if(rrset == NULL) { 2034 verbose(VERB_ALGO, "rpz: nsdname: no matching local data found"); 2035 return NULL; 2036 } 2037 2038 return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az); 2039 } 2040 2041 /* like local_data_answer for qname triggers after a cname */ 2042 static struct dns_msg* 2043 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms, 2044 struct query_info* qinfo, struct local_zone* z, struct auth_zone* az) 2045 { 2046 struct local_data key; 2047 struct local_data* ld; 2048 struct local_rrset* rrset; 2049 key.node.key = &key; 2050 key.name = qinfo->qname; 2051 key.namelen = qinfo->qname_len; 2052 key.namelabs = dname_count_labels(qinfo->qname); 2053 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 2054 if(ld == NULL) { 2055 verbose(VERB_ALGO, "rpz: qname after cname: name not found"); 2056 return NULL; 2057 } 2058 rrset = local_data_find_type(ld, qinfo->qtype, 1); 2059 if(rrset == NULL) { 2060 verbose(VERB_ALGO, "rpz: qname after cname: type not found"); 2061 return NULL; 2062 } 2063 return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az); 2064 } 2065 2066 static int 2067 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r, 2068 struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo, 2069 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 2070 struct comm_reply* repinfo, struct ub_server_stats* stats) 2071 { 2072 struct local_data* ld = NULL; 2073 int ret = 0; 2074 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 2075 qinfo->local_alias = regional_alloc_zero(temp, sizeof(struct local_rrset)); 2076 if(qinfo->local_alias == NULL) { 2077 return 0; /* out of memory */ 2078 } 2079 qinfo->local_alias->rrset = regional_alloc_init(temp, r->cname_override, 2080 sizeof(*r->cname_override)); 2081 if(qinfo->local_alias->rrset == NULL) { 2082 return 0; /* out of memory */ 2083 } 2084 qinfo->local_alias->rrset->rk.dname = qinfo->qname; 2085 qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; 2086 if(r->log) { 2087 log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION, 2088 qinfo, repinfo, NULL, r->log_name); 2089 } 2090 stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; 2091 return 0; 2092 } 2093 2094 if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo, 2095 edns, repinfo, buf, temp, dname_count_labels(qinfo->qname), 2096 &ld, lzt, -1, NULL, 0, NULL, 0)) { 2097 if(r->log) { 2098 log_rpz_apply("qname", z->name, NULL, 2099 localzone_type_to_rpz_action(lzt), qinfo, 2100 repinfo, NULL, r->log_name); 2101 } 2102 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 2103 return !qinfo->local_alias; 2104 } 2105 2106 ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, 2107 0 /* no local data used */, lzt); 2108 if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2109 == LDNS_RCODE_NXDOMAIN) 2110 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2111 if(r->log) { 2112 log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt), 2113 qinfo, repinfo, NULL, r->log_name); 2114 } 2115 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 2116 return ret; 2117 } 2118 2119 static struct clientip_synthesized_rr* 2120 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is) 2121 { 2122 struct delegpt_addr* cursor; 2123 struct clientip_synthesized_rr* action = NULL; 2124 if(is->dp == NULL) { return NULL; } 2125 for(cursor = is->dp->target_list; 2126 cursor != NULL; 2127 cursor = cursor->next_target) { 2128 if(cursor->bogus) { continue; } 2129 action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr, 2130 cursor->addrlen, "nsip"); 2131 if(action != NULL) { return action; } 2132 } 2133 return NULL; 2134 } 2135 2136 static struct dns_msg* 2137 rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r, 2138 struct clientip_synthesized_rr* raddr, struct auth_zone* az) 2139 { 2140 enum rpz_action action = raddr->action; 2141 struct dns_msg* ret = NULL; 2142 2143 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2144 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2145 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2146 action = r->action_override; 2147 } 2148 2149 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) { 2150 verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data"); 2151 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2152 goto done; 2153 } 2154 2155 switch(action) { 2156 case RPZ_NXDOMAIN_ACTION: 2157 ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az); 2158 break; 2159 case RPZ_NODATA_ACTION: 2160 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2161 break; 2162 case RPZ_TCP_ONLY_ACTION: 2163 /* basically a passthru here but the tcp-only will be 2164 * honored before the query gets sent. */ 2165 ms->tcp_required = 1; 2166 ret = NULL; 2167 break; 2168 case RPZ_DROP_ACTION: 2169 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2170 ms->is_drop = 1; 2171 break; 2172 case RPZ_LOCAL_DATA_ACTION: 2173 ret = rpz_synthesize_nsip_localdata(r, ms, raddr, az); 2174 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); } 2175 break; 2176 case RPZ_PASSTHRU_ACTION: 2177 ret = NULL; 2178 ms->rpz_passthru = 1; 2179 break; 2180 default: 2181 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2182 rpz_action_to_string(action)); 2183 ret = NULL; 2184 } 2185 2186 done: 2187 if(r->log) 2188 log_rpz_apply("nsip", NULL, &raddr->node, 2189 action, &ms->qinfo, NULL, ms, r->log_name); 2190 if(ms->env->worker) 2191 ms->env->worker->stats.rpz_action[action]++; 2192 lock_rw_unlock(&raddr->lock); 2193 return ret; 2194 } 2195 2196 static struct dns_msg* 2197 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r, 2198 struct local_zone* z, struct matched_delegation_point const* match, 2199 struct auth_zone* az) 2200 { 2201 struct dns_msg* ret = NULL; 2202 enum rpz_action action = localzone_type_to_rpz_action(z->type); 2203 2204 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2205 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2206 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2207 action = r->action_override; 2208 } 2209 2210 switch(action) { 2211 case RPZ_NXDOMAIN_ACTION: 2212 ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az); 2213 break; 2214 case RPZ_NODATA_ACTION: 2215 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2216 break; 2217 case RPZ_TCP_ONLY_ACTION: 2218 /* basically a passthru here but the tcp-only will be 2219 * honored before the query gets sent. */ 2220 ms->tcp_required = 1; 2221 ret = NULL; 2222 break; 2223 case RPZ_DROP_ACTION: 2224 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2225 ms->is_drop = 1; 2226 break; 2227 case RPZ_LOCAL_DATA_ACTION: 2228 ret = rpz_synthesize_nsdname_localdata(r, ms, z, match, az); 2229 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); } 2230 break; 2231 case RPZ_PASSTHRU_ACTION: 2232 ret = NULL; 2233 ms->rpz_passthru = 1; 2234 break; 2235 default: 2236 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2237 rpz_action_to_string(action)); 2238 ret = NULL; 2239 } 2240 2241 if(r->log) 2242 log_rpz_apply("nsdname", match->dname, NULL, 2243 action, &ms->qinfo, NULL, ms, r->log_name); 2244 if(ms->env->worker) 2245 ms->env->worker->stats.rpz_action[action]++; 2246 lock_rw_unlock(&z->lock); 2247 return ret; 2248 } 2249 2250 static struct local_zone* 2251 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, 2252 uint16_t qclass, 2253 /* output parameter */ 2254 struct matched_delegation_point* match) 2255 { 2256 struct delegpt_ns* nameserver; 2257 struct local_zone* z = NULL; 2258 2259 /* the rpz specs match the nameserver names (NS records), not the 2260 * name of the delegation point itself, to the nsdname triggers */ 2261 for(nameserver = dp->nslist; 2262 nameserver != NULL; 2263 nameserver = nameserver->next) { 2264 z = rpz_find_zone(zones, nameserver->name, nameserver->namelen, 2265 qclass, 0, 0, 0); 2266 if(z != NULL) { 2267 match->dname = nameserver->name; 2268 match->dname_len = nameserver->namelen; 2269 if(verbosity >= VERB_ALGO) { 2270 char nm[255+1], zn[255+1]; 2271 dname_str(match->dname, nm); 2272 dname_str(z->name, zn); 2273 if(strcmp(nm, zn) != 0) 2274 verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s", 2275 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2276 else 2277 verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s", 2278 nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2279 } 2280 break; 2281 } 2282 } 2283 2284 return z; 2285 } 2286 2287 struct dns_msg* 2288 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is) 2289 { 2290 struct auth_zones* az; 2291 struct auth_zone* a; 2292 struct clientip_synthesized_rr* raddr = NULL; 2293 struct rpz* r = NULL; 2294 struct local_zone* z = NULL; 2295 struct matched_delegation_point match = {0}; 2296 2297 if(ms->rpz_passthru) { 2298 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2299 return NULL; 2300 } 2301 2302 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2303 2304 az = ms->env->auth_zones; 2305 2306 verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL); 2307 2308 lock_rw_rdlock(&az->rpz_lock); 2309 2310 /* precedence of RPZ works, loosely, like this: 2311 * CNAMEs in order of the CNAME chain. rpzs in the order they are 2312 * configured. In an RPZ: first client-IP addr, then QNAME, then 2313 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest 2314 * one from a set. */ 2315 /* we use the precedence rules for the topics and triggers that 2316 * are pertinent at this stage of the resolve processing */ 2317 for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) { 2318 lock_rw_rdlock(&a->lock); 2319 r = a->rpz; 2320 if(r->disabled) { 2321 lock_rw_unlock(&a->lock); 2322 continue; 2323 } 2324 2325 /* the nsdname has precedence over the nsip triggers */ 2326 z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones, 2327 ms->qinfo.qclass, &match); 2328 if(z != NULL) { 2329 lock_rw_unlock(&a->lock); 2330 break; 2331 } 2332 2333 raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is); 2334 if(raddr != NULL) { 2335 lock_rw_unlock(&a->lock); 2336 break; 2337 } 2338 lock_rw_unlock(&a->lock); 2339 } 2340 2341 lock_rw_unlock(&az->rpz_lock); 2342 2343 if(raddr == NULL && z == NULL) 2344 return NULL; 2345 2346 if(raddr != NULL) { 2347 if(z) { 2348 lock_rw_unlock(&z->lock); 2349 } 2350 return rpz_apply_nsip_trigger(ms, r, raddr, a); 2351 } 2352 return rpz_apply_nsdname_trigger(ms, r, z, &match, a); 2353 } 2354 2355 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, 2356 struct iter_qstate* is) 2357 { 2358 struct auth_zones* az; 2359 struct auth_zone* a = NULL; 2360 struct rpz* r = NULL; 2361 struct local_zone* z = NULL; 2362 enum localzone_type lzt; 2363 struct dns_msg* ret = NULL; 2364 2365 if(ms->rpz_passthru) { 2366 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2367 return NULL; 2368 } 2369 2370 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2371 az = ms->env->auth_zones; 2372 2373 lock_rw_rdlock(&az->rpz_lock); 2374 2375 for(a = az->rpz_first; a; a = a->rpz_az_next) { 2376 lock_rw_rdlock(&a->lock); 2377 r = a->rpz; 2378 if(r->disabled) { 2379 lock_rw_unlock(&a->lock); 2380 continue; 2381 } 2382 z = rpz_find_zone(r->local_zones, is->qchase.qname, 2383 is->qchase.qname_len, is->qchase.qclass, 0, 0, 0); 2384 if(z && r->action_override == RPZ_DISABLED_ACTION) { 2385 if(r->log) 2386 log_rpz_apply("qname", z->name, NULL, 2387 r->action_override, 2388 &ms->qinfo, NULL, ms, r->log_name); 2389 if(ms->env->worker) 2390 ms->env->worker->stats.rpz_action[r->action_override]++; 2391 lock_rw_unlock(&z->lock); 2392 z = NULL; 2393 } 2394 if(z) { 2395 break; 2396 } 2397 /* not found in this auth_zone */ 2398 lock_rw_unlock(&a->lock); 2399 } 2400 lock_rw_unlock(&az->rpz_lock); 2401 2402 if(z == NULL) 2403 return NULL; 2404 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2405 lzt = z->type; 2406 } else { 2407 lzt = rpz_action_to_localzone_type(r->action_override); 2408 } 2409 2410 if(verbosity >= VERB_ALGO) { 2411 char nm[255+1], zn[255+1]; 2412 dname_str(is->qchase.qname, nm); 2413 dname_str(z->name, zn); 2414 if(strcmp(zn, nm) != 0) 2415 verbose(VERB_ALGO, "rpz: qname trigger after cname %s on %s, with action=%s", 2416 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2417 else 2418 verbose(VERB_ALGO, "rpz: qname trigger after cname %s, with action=%s", 2419 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2420 } 2421 switch(localzone_type_to_rpz_action(lzt)) { 2422 case RPZ_NXDOMAIN_ACTION: 2423 ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a); 2424 break; 2425 case RPZ_NODATA_ACTION: 2426 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2427 break; 2428 case RPZ_TCP_ONLY_ACTION: 2429 /* basically a passthru here but the tcp-only will be 2430 * honored before the query gets sent. */ 2431 ms->tcp_required = 1; 2432 ret = NULL; 2433 break; 2434 case RPZ_DROP_ACTION: 2435 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2436 ms->is_drop = 1; 2437 break; 2438 case RPZ_LOCAL_DATA_ACTION: 2439 ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a); 2440 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); } 2441 break; 2442 case RPZ_PASSTHRU_ACTION: 2443 ret = NULL; 2444 ms->rpz_passthru = 1; 2445 break; 2446 default: 2447 verbose(VERB_ALGO, "rpz: qname trigger after cname: bug: unhandled or invalid action: '%s'", 2448 rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2449 ret = NULL; 2450 } 2451 if(r->log) 2452 log_rpz_apply("qname", (z?z->name:NULL), NULL, 2453 localzone_type_to_rpz_action(lzt), 2454 &is->qchase, NULL, ms, r->log_name); 2455 lock_rw_unlock(&z->lock); 2456 lock_rw_unlock(&a->lock); 2457 return ret; 2458 } 2459 2460 static int 2461 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env, 2462 struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo, 2463 uint8_t* taglist, size_t taglen, struct ub_server_stats* stats, 2464 sldns_buffer* buf, struct regional* temp, 2465 /* output parameters */ 2466 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out, 2467 int* passthru) 2468 { 2469 int ret = 0; 2470 enum rpz_action client_action; 2471 struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone( 2472 az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out); 2473 2474 client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action); 2475 if(client_action == RPZ_PASSTHRU_ACTION) { 2476 *passthru = 1; 2477 } 2478 if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION && 2479 client_action != RPZ_PASSTHRU_ACTION)) { 2480 if(client_action == RPZ_PASSTHRU_ACTION 2481 || client_action == RPZ_INVALID_ACTION 2482 || (client_action == RPZ_TCP_ONLY_ACTION 2483 && !rpz_is_udp_query(repinfo))) { 2484 ret = 0; 2485 goto done; 2486 } 2487 stats->rpz_action[client_action]++; 2488 if(client_action == RPZ_LOCAL_DATA_ACTION) { 2489 rpz_apply_clientip_localdata_action(node, env, qinfo, 2490 edns, repinfo, buf, temp, *a_out); 2491 } else { 2492 if(*r_out && (*r_out)->log) 2493 log_rpz_apply( 2494 (node?"clientip":"qname"), 2495 ((*z_out)?(*z_out)->name:NULL), 2496 (node?&node->node:NULL), 2497 client_action, qinfo, repinfo, NULL, 2498 (*r_out)->log_name); 2499 local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns, 2500 repinfo, buf, temp, 0 /* no local data used */, 2501 rpz_action_to_localzone_type(client_action)); 2502 if(*r_out && (*r_out)->signal_nxdomain_ra && 2503 LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2504 == LDNS_RCODE_NXDOMAIN) 2505 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2506 } 2507 ret = 1; 2508 goto done; 2509 } 2510 ret = -1; 2511 done: 2512 if(node != NULL) { 2513 lock_rw_unlock(&node->lock); 2514 } 2515 return ret; 2516 } 2517 2518 int 2519 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, 2520 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 2521 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 2522 size_t taglen, struct ub_server_stats* stats, int* passthru) 2523 { 2524 struct rpz* r = NULL; 2525 struct auth_zone* a = NULL; 2526 struct local_zone* z = NULL; 2527 int ret; 2528 enum localzone_type lzt; 2529 2530 int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo, 2531 edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r, 2532 passthru); 2533 if(clientip_trigger >= 0) { 2534 if(a) { 2535 lock_rw_unlock(&a->lock); 2536 } 2537 if(z) { 2538 lock_rw_unlock(&z->lock); 2539 } 2540 return clientip_trigger; 2541 } 2542 2543 if(z == NULL) { 2544 if(a) { 2545 lock_rw_unlock(&a->lock); 2546 } 2547 return 0; 2548 } 2549 2550 log_assert(r); 2551 2552 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2553 lzt = z->type; 2554 } else { 2555 lzt = rpz_action_to_localzone_type(r->action_override); 2556 } 2557 if(r->action_override == RPZ_PASSTHRU_ACTION || 2558 lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) { 2559 *passthru = 1; 2560 } 2561 2562 if(verbosity >= VERB_ALGO) { 2563 char nm[255+1], zn[255+1]; 2564 dname_str(qinfo->qname, nm); 2565 dname_str(z->name, zn); 2566 if(strcmp(zn, nm) != 0) 2567 verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s", 2568 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2569 else 2570 verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s", 2571 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2572 } 2573 2574 ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp, 2575 repinfo, stats); 2576 2577 lock_rw_unlock(&z->lock); 2578 lock_rw_unlock(&a->lock); 2579 2580 return ret; 2581 } 2582 2583 void rpz_enable(struct rpz* r) 2584 { 2585 if(!r) 2586 return; 2587 r->disabled = 0; 2588 } 2589 2590 void rpz_disable(struct rpz* r) 2591 { 2592 if(!r) 2593 return; 2594 r->disabled = 1; 2595 } 2596