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