1 /* 2 * options.c -- options functions. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 #include "config.h" 10 #include <string.h> 11 #include <stdio.h> 12 #include <errno.h> 13 #include "options.h" 14 #include "query.h" 15 #include "tsig.h" 16 #include "difffile.h" 17 #include "rrl.h" 18 19 #include "configyyrename.h" 20 #include "configparser.h" 21 config_parser_state_t* cfg_parser = 0; 22 extern FILE* c_in, *c_out; 23 int c_parse(void); 24 int c_lex(void); 25 int c_wrap(void); 26 void c_error(const char *message); 27 28 static int 29 rbtree_strcmp(const void* p1, const void* p2) 30 { 31 return strcmp((const char*)p1, (const char*)p2); 32 } 33 34 nsd_options_t* 35 nsd_options_create(region_type* region) 36 { 37 nsd_options_t* opt; 38 opt = (nsd_options_t*)region_alloc(region, sizeof(nsd_options_t)); 39 opt->region = region; 40 opt->zone_options = rbtree_create(region, 41 (int (*)(const void *, const void *)) dname_compare); 42 opt->configfile = NULL; 43 opt->patterns = rbtree_create(region, rbtree_strcmp); 44 opt->keys = rbtree_create(region, rbtree_strcmp); 45 opt->ip_addresses = NULL; 46 opt->ip_transparent = 0; 47 opt->debug_mode = 0; 48 opt->verbosity = 0; 49 opt->hide_version = 0; 50 opt->do_ip4 = 1; 51 opt->do_ip6 = 1; 52 opt->database = DBFILE; 53 opt->identity = 0; 54 opt->nsid = 0; 55 opt->logfile = 0; 56 opt->log_time_ascii = 1; 57 opt->round_robin = 0; /* also packet.h::round_robin */ 58 opt->server_count = 1; 59 opt->tcp_count = 100; 60 opt->tcp_query_count = 0; 61 opt->tcp_timeout = TCP_TIMEOUT; 62 opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN; 63 opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN; 64 opt->pidfile = PIDFILE; 65 opt->port = UDP_PORT; 66 /* deprecated? opt->port = TCP_PORT; */ 67 opt->statistics = 0; 68 opt->chroot = 0; 69 opt->username = USER; 70 opt->zonesdir = ZONESDIR; 71 opt->xfrdfile = XFRDFILE; 72 opt->xfrdir = XFRDIR; 73 opt->zonelistfile = ZONELISTFILE; 74 #ifdef RATELIMIT 75 opt->rrl_size = RRL_BUCKETS; 76 opt->rrl_ratelimit = RRL_LIMIT/2; 77 opt->rrl_slip = RRL_SLIP; 78 opt->rrl_ipv4_prefix_length = RRL_IPV4_PREFIX_LENGTH; 79 opt->rrl_ipv6_prefix_length = RRL_IPV6_PREFIX_LENGTH; 80 opt->rrl_whitelist_ratelimit = RRL_WLIST_LIMIT/2; 81 #endif 82 opt->zonefiles_check = 1; 83 if(opt->database == NULL || opt->database[0] == 0) 84 opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL; 85 else opt->zonefiles_write = 0; 86 opt->xfrd_reload_timeout = 1; 87 opt->control_enable = 0; 88 opt->control_interface = NULL; 89 opt->control_port = NSD_CONTROL_PORT; 90 opt->server_key_file = CONFIGDIR"/nsd_server.key"; 91 opt->server_cert_file = CONFIGDIR"/nsd_server.pem"; 92 opt->control_key_file = CONFIGDIR"/nsd_control.key"; 93 opt->control_cert_file = CONFIGDIR"/nsd_control.pem"; 94 return opt; 95 } 96 97 int 98 nsd_options_insert_zone(nsd_options_t* opt, zone_options_t* zone) 99 { 100 /* create dname for lookup */ 101 const dname_type* dname = dname_parse(opt->region, zone->name); 102 if(!dname) 103 return 0; 104 zone->node.key = dname; 105 if(!rbtree_insert(opt->zone_options, (rbnode_t*)zone)) 106 return 0; 107 return 1; 108 } 109 110 int 111 nsd_options_insert_pattern(nsd_options_t* opt, pattern_options_t* pat) 112 { 113 if(!pat->pname) 114 return 0; 115 pat->node.key = pat->pname; 116 if(!rbtree_insert(opt->patterns, (rbnode_t*)pat)) 117 return 0; 118 return 1; 119 } 120 121 int 122 parse_options_file(nsd_options_t* opt, const char* file, 123 void (*err)(void*,const char*), void* err_arg) 124 { 125 FILE *in = 0; 126 pattern_options_t* pat; 127 acl_options_t* acl; 128 129 if(!cfg_parser) { 130 cfg_parser = (config_parser_state_t*)region_alloc( 131 opt->region, sizeof(config_parser_state_t)); 132 cfg_parser->chroot = 0; 133 } 134 cfg_parser->err = err; 135 cfg_parser->err_arg = err_arg; 136 cfg_parser->filename = (char*)file; 137 cfg_parser->line = 1; 138 cfg_parser->errors = 0; 139 cfg_parser->server_settings_seen = 0; 140 cfg_parser->opt = opt; 141 cfg_parser->current_pattern = 0; 142 cfg_parser->current_zone = 0; 143 cfg_parser->current_key = 0; 144 cfg_parser->current_ip_address_option = opt->ip_addresses; 145 while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next) 146 cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next; 147 cfg_parser->current_allow_notify = 0; 148 cfg_parser->current_request_xfr = 0; 149 cfg_parser->current_notify = 0; 150 cfg_parser->current_provide_xfr = 0; 151 152 in = fopen(cfg_parser->filename, "r"); 153 if(!in) { 154 if(err) { 155 char m[MAXSYSLOGMSGLEN]; 156 snprintf(m, sizeof(m), "Could not open %s: %s\n", 157 file, strerror(errno)); 158 err(err_arg, m); 159 } else { 160 fprintf(stderr, "Could not open %s: %s\n", 161 file, strerror(errno)); 162 } 163 return 0; 164 } 165 c_in = in; 166 c_parse(); 167 fclose(in); 168 169 opt->configfile = region_strdup(opt->region, file); 170 if(cfg_parser->current_pattern) { 171 if(!cfg_parser->current_pattern->pname) 172 c_error("last pattern has no name"); 173 else { 174 if(!nsd_options_insert_pattern(cfg_parser->opt, 175 cfg_parser->current_pattern)) 176 c_error("duplicate pattern"); 177 } 178 } 179 if(cfg_parser->current_zone) { 180 if(!cfg_parser->current_zone->name) 181 c_error("last zone has no name"); 182 else { 183 if(!nsd_options_insert_zone(opt, 184 cfg_parser->current_zone)) 185 c_error("duplicate zone"); 186 } 187 if(!cfg_parser->current_zone->pattern) 188 c_error("last zone has no pattern"); 189 } 190 if(cfg_parser->current_key) 191 { 192 if(!cfg_parser->current_key->name) 193 c_error("last key has no name"); 194 if(!cfg_parser->current_key->algorithm) 195 c_error("last key has no algorithm"); 196 if(!cfg_parser->current_key->secret) 197 c_error("last key has no secret blob"); 198 key_options_insert(opt, cfg_parser->current_key); 199 } 200 RBTREE_FOR(pat, pattern_options_t*, opt->patterns) 201 { 202 /* lookup keys for acls */ 203 for(acl=pat->allow_notify; acl; acl=acl->next) 204 { 205 if(acl->nokey || acl->blocked) 206 continue; 207 acl->key_options = key_options_find(opt, acl->key_name); 208 if(!acl->key_options) 209 c_error_msg("key %s in pattern %s could not be found", 210 acl->key_name, pat->pname); 211 } 212 for(acl=pat->notify; acl; acl=acl->next) 213 { 214 if(acl->nokey || acl->blocked) 215 continue; 216 acl->key_options = key_options_find(opt, acl->key_name); 217 if(!acl->key_options) 218 c_error_msg("key %s in pattern %s could not be found", 219 acl->key_name, pat->pname); 220 } 221 for(acl=pat->request_xfr; acl; acl=acl->next) 222 { 223 if(acl->nokey || acl->blocked) 224 continue; 225 acl->key_options = key_options_find(opt, acl->key_name); 226 if(!acl->key_options) 227 c_error_msg("key %s in pattern %s could not be found", 228 acl->key_name, pat->pname); 229 } 230 for(acl=pat->provide_xfr; acl; acl=acl->next) 231 { 232 if(acl->nokey || acl->blocked) 233 continue; 234 acl->key_options = key_options_find(opt, acl->key_name); 235 if(!acl->key_options) 236 c_error_msg("key %s in pattern %s could not be found", 237 acl->key_name, pat->pname); 238 } 239 } 240 241 if(cfg_parser->errors > 0) 242 { 243 if(err) { 244 char m[MAXSYSLOGMSGLEN]; 245 snprintf(m, sizeof(m), "read %s failed: %d errors in " 246 "configuration file\n", file, 247 cfg_parser->errors); 248 err(err_arg, m); 249 } else { 250 fprintf(stderr, "read %s failed: %d errors in " 251 "configuration file\n", file, 252 cfg_parser->errors); 253 } 254 return 0; 255 } 256 return 1; 257 } 258 259 #define ZONELIST_HEADER "# NSD zone list\n# name pattern\n" 260 static int 261 comp_zonebucket(const void* a, const void* b) 262 { 263 return *(const int*)b - *(const int*)a; 264 } 265 266 /* insert free entry into zonelist free buckets */ 267 static void 268 zone_list_free_insert(nsd_options_t* opt, int linesize, off_t off) 269 { 270 struct zonelist_free* e; 271 struct zonelist_bucket* b = (struct zonelist_bucket*)rbtree_search( 272 opt->zonefree, &linesize); 273 if(!b) { 274 b = region_alloc_zero(opt->region, sizeof(*b)); 275 b->linesize = linesize; 276 b->node = *RBTREE_NULL; 277 b->node.key = &b->linesize; 278 rbtree_insert(opt->zonefree, &b->node); 279 } 280 e = (struct zonelist_free*)region_alloc_zero(opt->region, sizeof(*e)); 281 e->next = b->list; 282 b->list = e; 283 e->off = off; 284 opt->zonefree_number++; 285 } 286 287 zone_options_t* 288 zone_list_zone_insert(nsd_options_t* opt, const char* nm, const char* patnm, 289 int linesize, off_t off) 290 { 291 pattern_options_t* pat = pattern_options_find(opt, patnm); 292 zone_options_t* zone; 293 if(!pat) { 294 log_msg(LOG_ERR, "pattern does not exist for zone %s " 295 "pattern %s", nm, patnm); 296 return NULL; 297 } 298 zone = zone_options_create(opt->region); 299 zone->part_of_config = 0; 300 zone->name = region_strdup(opt->region, nm); 301 zone->linesize = linesize; 302 zone->off = off; 303 zone->pattern = pat; 304 if(!nsd_options_insert_zone(opt, zone)) { 305 log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' " 306 "pattern %s", nm, patnm); 307 region_recycle(opt->region, (void*)zone->name, strlen(nm)+1); 308 region_recycle(opt->region, zone, sizeof(*zone)); 309 return NULL; 310 } 311 return zone; 312 } 313 314 int 315 parse_zone_list_file(nsd_options_t* opt) 316 { 317 /* zonelist looks like this: 318 # name pattern 319 add example.com master 320 del example.net slave 321 add foo.bar.nl slave 322 add rutabaga.uk config 323 */ 324 char buf[1024]; 325 326 /* create empty data structures */ 327 opt->zonefree = rbtree_create(opt->region, comp_zonebucket); 328 opt->zonelist = NULL; 329 opt->zonefree_number = 0; 330 opt->zonelist_off = 0; 331 332 /* try to open the zonelist file, an empty or nonexist file is OK */ 333 opt->zonelist = fopen(opt->zonelistfile, "r+"); 334 if(!opt->zonelist) { 335 if(errno == ENOENT) 336 return 1; /* file does not exist, it is created later */ 337 log_msg(LOG_ERR, "could not open zone list %s: %s", opt->zonelistfile, 338 strerror(errno)); 339 return 0; 340 } 341 /* read header */ 342 buf[strlen(ZONELIST_HEADER)] = 0; 343 if(fread(buf, 1, strlen(ZONELIST_HEADER), opt->zonelist) != 344 strlen(ZONELIST_HEADER) || strncmp(buf, ZONELIST_HEADER, 345 strlen(ZONELIST_HEADER)) != 0) { 346 log_msg(LOG_ERR, "zone list %s contains bad header\n", opt->zonelistfile); 347 fclose(opt->zonelist); 348 opt->zonelist = NULL; 349 return 0; 350 } 351 352 /* read entries in file */ 353 while(fgets(buf, sizeof(buf), opt->zonelist)) { 354 /* skip comments and empty lines */ 355 if(buf[0] == 0 || buf[0] == '\n' || buf[0] == '#') 356 continue; 357 if(strncmp(buf, "add ", 4) == 0) { 358 int linesize = strlen(buf); 359 /* parse the 'add' line */ 360 /* pick last space on the line, so that the domain 361 * name can have a space in it (but not the pattern)*/ 362 char* space = strrchr(buf+4, ' '); 363 char* nm, *patnm; 364 if(!space) { 365 /* parse error */ 366 log_msg(LOG_ERR, "parse error in %s: '%s'", 367 opt->zonelistfile, buf); 368 continue; 369 } 370 nm = buf+4; 371 *space = 0; 372 patnm = space+1; 373 if(linesize && buf[linesize-1] == '\n') 374 buf[linesize-1] = 0; 375 376 /* store offset and line size for zone entry */ 377 /* and create zone entry in zonetree */ 378 (void)zone_list_zone_insert(opt, nm, patnm, linesize, 379 ftello(opt->zonelist)-linesize); 380 } else if(strncmp(buf, "del ", 4) == 0) { 381 /* store offset and line size for deleted entry */ 382 int linesize = strlen(buf); 383 zone_list_free_insert(opt, linesize, 384 ftello(opt->zonelist)-linesize); 385 } else { 386 log_msg(LOG_WARNING, "bad data in %s, '%s'", opt->zonelistfile, 387 buf); 388 } 389 } 390 /* store EOF offset */ 391 opt->zonelist_off = ftello(opt->zonelist); 392 return 1; 393 } 394 395 void 396 zone_options_delete(nsd_options_t* opt, zone_options_t* zone) 397 { 398 rbtree_delete(opt->zone_options, zone->node.key); 399 region_recycle(opt->region, (void*)zone->node.key, dname_total_size( 400 (dname_type*)zone->node.key)); 401 region_recycle(opt->region, zone, sizeof(*zone)); 402 } 403 404 /* add a new zone to the zonelist */ 405 zone_options_t* 406 zone_list_add(nsd_options_t* opt, const char* zname, const char* pname) 407 { 408 int r; 409 struct zonelist_free* e; 410 struct zonelist_bucket* b; 411 int linesize = 6 + strlen(zname) + strlen(pname); 412 /* create zone entry */ 413 zone_options_t* zone = zone_list_zone_insert(opt, zname, pname, 414 linesize, 0); 415 if(!zone) 416 return NULL; 417 418 /* use free entry or append to file or create new file */ 419 if(!opt->zonelist || opt->zonelist_off == 0) { 420 /* create new file */ 421 if(opt->zonelist) fclose(opt->zonelist); 422 opt->zonelist = fopen(opt->zonelistfile, "w+"); 423 if(!opt->zonelist) { 424 log_msg(LOG_ERR, "could not create zone list %s: %s", 425 opt->zonelistfile, strerror(errno)); 426 log_msg(LOG_ERR, "zone %s could not be added", zname); 427 zone_options_delete(opt, zone); 428 return NULL; 429 } 430 r = fprintf(opt->zonelist, ZONELIST_HEADER); 431 if(r != strlen(ZONELIST_HEADER)) { 432 if(r == -1) 433 log_msg(LOG_ERR, "could not write to %s: %s", 434 opt->zonelistfile, strerror(errno)); 435 else log_msg(LOG_ERR, "partial write to %s: disk full", 436 opt->zonelistfile); 437 log_msg(LOG_ERR, "zone %s could not be added", zname); 438 zone_options_delete(opt, zone); 439 return NULL; 440 } 441 zone->off = ftello(opt->zonelist); 442 if(zone->off == -1) 443 log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno)); 444 r = fprintf(opt->zonelist, "add %s %s\n", zname, pname); 445 if(r != zone->linesize) { 446 if(r == -1) 447 log_msg(LOG_ERR, "could not write to %s: %s", 448 opt->zonelistfile, strerror(errno)); 449 else log_msg(LOG_ERR, "partial write to %s: disk full", 450 opt->zonelistfile); 451 log_msg(LOG_ERR, "zone %s could not be added", zname); 452 zone_options_delete(opt, zone); 453 return NULL; 454 } 455 opt->zonelist_off = ftello(opt->zonelist); 456 if(opt->zonelist_off == -1) 457 log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno)); 458 if(fflush(opt->zonelist) != 0) { 459 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 460 } 461 return zone; 462 } 463 b = (struct zonelist_bucket*)rbtree_search(opt->zonefree, 464 &zone->linesize); 465 if(!b || b->list == NULL) { 466 /* no empty place, append to file */ 467 zone->off = opt->zonelist_off; 468 if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) { 469 log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno)); 470 log_msg(LOG_ERR, "zone %s could not be added", zname); 471 zone_options_delete(opt, zone); 472 return NULL; 473 } 474 r = fprintf(opt->zonelist, "add %s %s\n", zname, pname); 475 if(r != zone->linesize) { 476 if(r == -1) 477 log_msg(LOG_ERR, "could not write to %s: %s", 478 opt->zonelistfile, strerror(errno)); 479 else log_msg(LOG_ERR, "partial write to %s: disk full", 480 opt->zonelistfile); 481 log_msg(LOG_ERR, "zone %s could not be added", zname); 482 zone_options_delete(opt, zone); 483 return NULL; 484 } 485 opt->zonelist_off += linesize; 486 if(fflush(opt->zonelist) != 0) { 487 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 488 } 489 return zone; 490 } 491 /* reuse empty spot */ 492 e = b->list; 493 zone->off = e->off; 494 if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) { 495 log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno)); 496 log_msg(LOG_ERR, "zone %s could not be added", zname); 497 zone_options_delete(opt, zone); 498 return NULL; 499 } 500 r = fprintf(opt->zonelist, "add %s %s\n", zname, pname); 501 if(r != zone->linesize) { 502 if(r == -1) 503 log_msg(LOG_ERR, "could not write to %s: %s", 504 opt->zonelistfile, strerror(errno)); 505 else log_msg(LOG_ERR, "partial write to %s: disk full", 506 opt->zonelistfile); 507 log_msg(LOG_ERR, "zone %s could not be added", zname); 508 zone_options_delete(opt, zone); 509 return NULL; 510 } 511 if(fflush(opt->zonelist) != 0) { 512 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 513 } 514 515 /* snip off and recycle element */ 516 b->list = e->next; 517 region_recycle(opt->region, e, sizeof(*e)); 518 if(b->list == NULL) { 519 rbtree_delete(opt->zonefree, &b->linesize); 520 region_recycle(opt->region, b, sizeof(*b)); 521 } 522 opt->zonefree_number--; 523 return zone; 524 } 525 526 /* remove a zone on the zonelist */ 527 void 528 zone_list_del(nsd_options_t* opt, zone_options_t* zone) 529 { 530 /* put its space onto the free entry */ 531 if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) { 532 log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno)); 533 return; 534 } 535 fprintf(opt->zonelist, "del"); 536 zone_list_free_insert(opt, zone->linesize, zone->off); 537 538 /* remove zone_options_t */ 539 zone_options_delete(opt, zone); 540 541 /* see if we need to compact: it is going to halve the zonelist */ 542 if(opt->zonefree_number > opt->zone_options->count) { 543 zone_list_compact(opt); 544 } else { 545 if(fflush(opt->zonelist) != 0) { 546 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 547 } 548 } 549 } 550 /* postorder delete of zonelist free space tree */ 551 static void 552 delbucket(region_type* region, struct zonelist_bucket* b) 553 { 554 struct zonelist_free* e, *f; 555 if(!b || (rbnode_t*)b==RBTREE_NULL) 556 return; 557 delbucket(region, (struct zonelist_bucket*)b->node.left); 558 delbucket(region, (struct zonelist_bucket*)b->node.right); 559 e = b->list; 560 while(e) { 561 f = e->next; 562 region_recycle(region, e, sizeof(*e)); 563 e = f; 564 } 565 region_recycle(region, b, sizeof(*b)); 566 } 567 568 /* compact zonelist file */ 569 void 570 zone_list_compact(nsd_options_t* opt) 571 { 572 char outname[1024]; 573 FILE* out; 574 zone_options_t* zone; 575 off_t off; 576 int r; 577 snprintf(outname, sizeof(outname), "%s~", opt->zonelistfile); 578 /* useful, when : count-of-free > count-of-used */ 579 /* write zonelist to zonelist~ */ 580 out = fopen(outname, "w+"); 581 if(!out) { 582 log_msg(LOG_ERR, "could not open %s: %s", outname, strerror(errno)); 583 return; 584 } 585 r = fprintf(out, ZONELIST_HEADER); 586 if(r == -1) { 587 log_msg(LOG_ERR, "write %s failed: %s", outname, 588 strerror(errno)); 589 fclose(out); 590 return; 591 } else if(r != strlen(ZONELIST_HEADER)) { 592 log_msg(LOG_ERR, "write %s was partial: disk full", 593 outname); 594 fclose(out); 595 return; 596 } 597 off = ftello(out); 598 if(off == -1) { 599 log_msg(LOG_ERR, "ftello(%s): %s", outname, strerror(errno)); 600 fclose(out); 601 return; 602 } 603 RBTREE_FOR(zone, zone_options_t*, opt->zone_options) { 604 if(zone->part_of_config) 605 continue; 606 r = fprintf(out, "add %s %s\n", zone->name, 607 zone->pattern->pname); 608 if(r < 0) { 609 log_msg(LOG_ERR, "write %s failed: %s", outname, 610 strerror(errno)); 611 fclose(out); 612 return; 613 } else if(r != zone->linesize) { 614 log_msg(LOG_ERR, "write %s was partial: disk full", 615 outname); 616 fclose(out); 617 return; 618 } 619 } 620 if(fflush(out) != 0) { 621 log_msg(LOG_ERR, "fflush %s: %s", outname, strerror(errno)); 622 } 623 624 /* rename zonelist~ onto zonelist */ 625 if(rename(outname, opt->zonelistfile) == -1) { 626 log_msg(LOG_ERR, "rename(%s to %s) failed: %s", 627 outname, opt->zonelistfile, strerror(errno)); 628 fclose(out); 629 return; 630 } 631 fclose(opt->zonelist); 632 /* set offsets */ 633 RBTREE_FOR(zone, zone_options_t*, opt->zone_options) { 634 if(zone->part_of_config) 635 continue; 636 zone->off = off; 637 off += zone->linesize; 638 } 639 /* empty the free tree */ 640 delbucket(opt->region, (struct zonelist_bucket*)opt->zonefree->root); 641 opt->zonefree->root = RBTREE_NULL; 642 opt->zonefree->count = 0; 643 opt->zonefree_number = 0; 644 /* finish */ 645 opt->zonelist = out; 646 opt->zonelist_off = off; 647 } 648 649 /* close zonelist file */ 650 void 651 zone_list_close(nsd_options_t* opt) 652 { 653 fclose(opt->zonelist); 654 opt->zonelist = NULL; 655 } 656 657 658 void 659 c_error_va_list(const char* fmt, va_list args) 660 { 661 cfg_parser->errors++; 662 if(cfg_parser->err) { 663 char m[MAXSYSLOGMSGLEN]; 664 snprintf(m, sizeof(m), "%s:%d: error: ", cfg_parser->filename, 665 cfg_parser->line); 666 (*cfg_parser->err)(cfg_parser->err_arg, m); 667 vsnprintf(m, sizeof(m), fmt, args); 668 (*cfg_parser->err)(cfg_parser->err_arg, m); 669 (*cfg_parser->err)(cfg_parser->err_arg, "\n"); 670 return; 671 } 672 fprintf(stderr, "%s:%d: error: ", cfg_parser->filename, 673 cfg_parser->line); 674 vfprintf(stderr, fmt, args); 675 fprintf(stderr, "\n"); 676 } 677 678 void 679 c_error_msg(const char* fmt, ...) 680 { 681 va_list args; 682 va_start(args, fmt); 683 c_error_va_list(fmt, args); 684 va_end(args); 685 } 686 687 void 688 c_error(const char* str) 689 { 690 c_error_msg("%s", str); 691 } 692 693 int 694 c_wrap() 695 { 696 return 1; 697 } 698 699 zone_options_t* 700 zone_options_create(region_type* region) 701 { 702 zone_options_t* zone; 703 zone = (zone_options_t*)region_alloc(region, sizeof(zone_options_t)); 704 zone->node = *RBTREE_NULL; 705 zone->name = 0; 706 zone->pattern = 0; 707 zone->part_of_config = 0; 708 return zone; 709 } 710 711 /* true is booleans are the same truth value */ 712 #define booleq(x,y) ( ((x) && (y)) || (!(x) && !(y)) ) 713 714 int 715 acl_equal(acl_options_t* p, acl_options_t* q) 716 { 717 if(!booleq(p->use_axfr_only, q->use_axfr_only)) return 0; 718 if(!booleq(p->allow_udp, q->allow_udp)) return 0; 719 if(strcmp(p->ip_address_spec, q->ip_address_spec)!=0) return 0; 720 /* the ip6, port, addr, mask, type: are derived from the ip_address_spec */ 721 if(!booleq(p->nokey, q->nokey)) return 0; 722 if(!booleq(p->blocked, q->blocked)) return 0; 723 if(p->key_name && q->key_name) { 724 if(strcmp(p->key_name, q->key_name)!=0) return 0; 725 } else if(p->key_name && !q->key_name) return 0; 726 else if(!p->key_name && q->key_name) return 0; 727 /* key_options is derived from key_name */ 728 return 1; 729 } 730 731 int 732 acl_list_equal(acl_options_t* p, acl_options_t* q) 733 { 734 /* must be same and in same order */ 735 while(p && q) { 736 if(!acl_equal(p, q)) 737 return 0; 738 p = p->next; 739 q = q->next; 740 } 741 if(!p && !q) return 1; 742 /* different lengths */ 743 return 0; 744 } 745 746 pattern_options_t* 747 pattern_options_create(region_type* region) 748 { 749 pattern_options_t* p; 750 p = (pattern_options_t*)region_alloc(region, sizeof(pattern_options_t)); 751 p->node = *RBTREE_NULL; 752 p->pname = 0; 753 p->zonefile = 0; 754 p->allow_notify = 0; 755 p->request_xfr = 0; 756 p->notify = 0; 757 p->provide_xfr = 0; 758 p->outgoing_interface = 0; 759 p->notify_retry = 5; 760 p->notify_retry_is_default = 1; 761 p->allow_axfr_fallback = 1; 762 p->allow_axfr_fallback_is_default = 1; 763 p->implicit = 0; 764 p->xfrd_flags = 0; 765 #ifdef RATELIMIT 766 p->rrl_whitelist = 0; 767 #endif 768 return p; 769 } 770 771 static void 772 acl_delete(region_type* region, acl_options_t* acl) 773 { 774 if(acl->ip_address_spec) 775 region_recycle(region, (void*)acl->ip_address_spec, 776 strlen(acl->ip_address_spec)+1); 777 if(acl->key_name) 778 region_recycle(region, (void*)acl->key_name, 779 strlen(acl->key_name)+1); 780 /* key_options is a convenience pointer, not owned by the acl */ 781 region_recycle(region, acl, sizeof(*acl)); 782 } 783 784 static void 785 acl_list_delete(region_type* region, acl_options_t* list) 786 { 787 acl_options_t* n; 788 while(list) { 789 n = list->next; 790 acl_delete(region, list); 791 list = n; 792 } 793 } 794 795 void 796 pattern_options_remove(nsd_options_t* opt, const char* name) 797 { 798 pattern_options_t* p = (pattern_options_t*)rbtree_delete( 799 opt->patterns, name); 800 /* delete p and its contents */ 801 if (!p) 802 return; 803 if(p->pname) 804 region_recycle(opt->region, (void*)p->pname, 805 strlen(p->pname)+1); 806 if(p->zonefile) 807 region_recycle(opt->region, (void*)p->zonefile, 808 strlen(p->zonefile)+1); 809 acl_list_delete(opt->region, p->allow_notify); 810 acl_list_delete(opt->region, p->request_xfr); 811 acl_list_delete(opt->region, p->notify); 812 acl_list_delete(opt->region, p->provide_xfr); 813 acl_list_delete(opt->region, p->outgoing_interface); 814 815 region_recycle(opt->region, p, sizeof(pattern_options_t)); 816 } 817 818 static acl_options_t* 819 copy_acl(region_type* region, acl_options_t* a) 820 { 821 acl_options_t* b; 822 if(!a) return NULL; 823 b = (acl_options_t*)region_alloc(region, sizeof(*b)); 824 /* copy the whole lot */ 825 *b = *a; 826 /* fix the pointers */ 827 if(a->ip_address_spec) 828 b->ip_address_spec = region_strdup(region, a->ip_address_spec); 829 if(a->key_name) 830 b->key_name = region_strdup(region, a->key_name); 831 b->next = NULL; 832 b->key_options = NULL; 833 return b; 834 } 835 836 static acl_options_t* 837 copy_acl_list(nsd_options_t* opt, acl_options_t* a) 838 { 839 acl_options_t* b, *blast = NULL, *blist = NULL; 840 while(a) { 841 b = copy_acl(opt->region, a); 842 /* fixup key_options */ 843 if(b->key_name) 844 b->key_options = key_options_find(opt, b->key_name); 845 else b->key_options = NULL; 846 847 /* link as last into list */ 848 b->next = NULL; 849 if(!blist) blist = b; 850 else blast->next = b; 851 blast = b; 852 853 a = a->next; 854 } 855 return blist; 856 } 857 858 static void 859 copy_changed_acl(nsd_options_t* opt, acl_options_t** orig, 860 acl_options_t* anew) 861 { 862 if(!acl_list_equal(*orig, anew)) { 863 acl_list_delete(opt->region, *orig); 864 *orig = copy_acl_list(opt, anew); 865 } 866 } 867 868 static void 869 copy_pat_fixed(region_type* region, pattern_options_t* orig, 870 pattern_options_t* p) 871 { 872 orig->allow_axfr_fallback = p->allow_axfr_fallback; 873 orig->allow_axfr_fallback_is_default = 874 p->allow_axfr_fallback_is_default; 875 orig->notify_retry = p->notify_retry; 876 orig->notify_retry_is_default = p->notify_retry_is_default; 877 orig->implicit = p->implicit; 878 if(p->zonefile) 879 orig->zonefile = region_strdup(region, p->zonefile); 880 else orig->zonefile = NULL; 881 #ifdef RATELIMIT 882 orig->rrl_whitelist = p->rrl_whitelist; 883 #endif 884 } 885 886 void 887 pattern_options_add_modify(nsd_options_t* opt, pattern_options_t* p) 888 { 889 pattern_options_t* orig = pattern_options_find(opt, p->pname); 890 if(!orig) { 891 /* needs to be copied to opt region */ 892 orig = pattern_options_create(opt->region); 893 orig->pname = region_strdup(opt->region, p->pname); 894 copy_pat_fixed(opt->region, orig, p); 895 orig->allow_notify = copy_acl_list(opt, p->allow_notify); 896 orig->request_xfr = copy_acl_list(opt, p->request_xfr); 897 orig->notify = copy_acl_list(opt, p->notify); 898 orig->provide_xfr = copy_acl_list(opt, p->provide_xfr); 899 orig->outgoing_interface = copy_acl_list(opt, 900 p->outgoing_interface); 901 nsd_options_insert_pattern(opt, orig); 902 } else { 903 /* modify in place so pointers stay valid (and copy 904 into region). Do not touch unchanged acls. */ 905 if(orig->zonefile) 906 region_recycle(opt->region, (char*)orig->zonefile, 907 strlen(orig->zonefile)+1); 908 copy_pat_fixed(opt->region, orig, p); 909 copy_changed_acl(opt, &orig->allow_notify, p->allow_notify); 910 copy_changed_acl(opt, &orig->request_xfr, p->request_xfr); 911 copy_changed_acl(opt, &orig->notify, p->notify); 912 copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr); 913 copy_changed_acl(opt, &orig->outgoing_interface, 914 p->outgoing_interface); 915 } 916 } 917 918 pattern_options_t* 919 pattern_options_find(nsd_options_t* opt, const char* name) 920 { 921 return (pattern_options_t*)rbtree_search(opt->patterns, name); 922 } 923 924 int 925 pattern_options_equal(pattern_options_t* p, pattern_options_t* q) 926 { 927 if(strcmp(p->pname, q->pname) != 0) return 0; 928 if(!p->zonefile && q->zonefile) return 0; 929 else if(p->zonefile && !q->zonefile) return 0; 930 else if(p->zonefile && q->zonefile) { 931 if(strcmp(p->zonefile, q->zonefile) != 0) return 0; 932 } 933 if(!booleq(p->allow_axfr_fallback, q->allow_axfr_fallback)) return 0; 934 if(!booleq(p->allow_axfr_fallback_is_default, 935 q->allow_axfr_fallback_is_default)) return 0; 936 if(p->notify_retry != q->notify_retry) return 0; 937 if(!booleq(p->notify_retry_is_default, 938 q->notify_retry_is_default)) return 0; 939 if(!booleq(p->implicit, q->implicit)) return 0; 940 if(!acl_list_equal(p->allow_notify, q->allow_notify)) return 0; 941 if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0; 942 if(!acl_list_equal(p->notify, q->notify)) return 0; 943 if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0; 944 if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface)) 945 return 0; 946 #ifdef RATELIMIT 947 if(p->rrl_whitelist != q->rrl_whitelist) return 0; 948 #endif 949 return 1; 950 } 951 952 static void 953 marshal_u8(struct buffer* b, uint8_t v) 954 { 955 buffer_reserve(b, 1); 956 buffer_write_u8(b, v); 957 } 958 959 static uint8_t 960 unmarshal_u8(struct buffer* b) 961 { 962 return buffer_read_u8(b); 963 } 964 965 #ifdef RATELIMIT 966 static void 967 marshal_u16(struct buffer* b, uint16_t v) 968 { 969 buffer_reserve(b, 2); 970 buffer_write_u16(b, v); 971 } 972 #endif 973 974 #ifdef RATELIMIT 975 static uint16_t 976 unmarshal_u16(struct buffer* b) 977 { 978 return buffer_read_u16(b); 979 } 980 #endif 981 982 static void 983 marshal_str(struct buffer* b, const char* s) 984 { 985 if(!s) marshal_u8(b, 0); 986 else { 987 size_t len = strlen(s); 988 marshal_u8(b, 1); 989 buffer_reserve(b, len+1); 990 buffer_write(b, s, len+1); 991 } 992 } 993 994 static char* 995 unmarshal_str(region_type* r, struct buffer* b) 996 { 997 uint8_t nonnull = unmarshal_u8(b); 998 if(nonnull) { 999 char* result = region_strdup(r, (char*)buffer_current(b)); 1000 size_t len = strlen((char*)buffer_current(b)); 1001 buffer_skip(b, len+1); 1002 return result; 1003 } else return NULL; 1004 } 1005 1006 static void 1007 marshal_acl(struct buffer* b, acl_options_t* acl) 1008 { 1009 buffer_reserve(b, sizeof(*acl)); 1010 buffer_write(b, acl, sizeof(*acl)); 1011 marshal_str(b, acl->ip_address_spec); 1012 marshal_str(b, acl->key_name); 1013 } 1014 1015 static acl_options_t* 1016 unmarshal_acl(region_type* r, struct buffer* b) 1017 { 1018 acl_options_t* acl = (acl_options_t*)region_alloc(r, sizeof(*acl)); 1019 buffer_read(b, acl, sizeof(*acl)); 1020 acl->next = NULL; 1021 acl->key_options = NULL; 1022 acl->ip_address_spec = unmarshal_str(r, b); 1023 acl->key_name = unmarshal_str(r, b); 1024 return acl; 1025 } 1026 1027 static void 1028 marshal_acl_list(struct buffer* b, acl_options_t* list) 1029 { 1030 while(list) { 1031 marshal_u8(b, 1); /* is there a next one marker */ 1032 marshal_acl(b, list); 1033 list = list->next; 1034 } 1035 marshal_u8(b, 0); /* end of list marker */ 1036 } 1037 1038 static acl_options_t* 1039 unmarshal_acl_list(region_type* r, struct buffer* b) 1040 { 1041 acl_options_t* a, *last=NULL, *list=NULL; 1042 while(unmarshal_u8(b)) { 1043 a = unmarshal_acl(r, b); 1044 /* link in */ 1045 a->next = NULL; 1046 if(!list) list = a; 1047 else last->next = a; 1048 last = a; 1049 } 1050 return list; 1051 } 1052 1053 void 1054 pattern_options_marshal(struct buffer* b, pattern_options_t* p) 1055 { 1056 marshal_str(b, p->pname); 1057 marshal_str(b, p->zonefile); 1058 #ifdef RATELIMIT 1059 marshal_u16(b, p->rrl_whitelist); 1060 #endif 1061 marshal_u8(b, p->allow_axfr_fallback); 1062 marshal_u8(b, p->allow_axfr_fallback_is_default); 1063 marshal_u8(b, p->notify_retry); 1064 marshal_u8(b, p->notify_retry_is_default); 1065 marshal_u8(b, p->implicit); 1066 marshal_acl_list(b, p->allow_notify); 1067 marshal_acl_list(b, p->request_xfr); 1068 marshal_acl_list(b, p->notify); 1069 marshal_acl_list(b, p->provide_xfr); 1070 marshal_acl_list(b, p->outgoing_interface); 1071 } 1072 1073 pattern_options_t* 1074 pattern_options_unmarshal(region_type* r, struct buffer* b) 1075 { 1076 pattern_options_t* p = pattern_options_create(r); 1077 p->pname = unmarshal_str(r, b); 1078 p->zonefile = unmarshal_str(r, b); 1079 #ifdef RATELIMIT 1080 p->rrl_whitelist = unmarshal_u16(b); 1081 #endif 1082 p->allow_axfr_fallback = unmarshal_u8(b); 1083 p->allow_axfr_fallback_is_default = unmarshal_u8(b); 1084 p->notify_retry = unmarshal_u8(b); 1085 p->notify_retry_is_default = unmarshal_u8(b); 1086 p->implicit = unmarshal_u8(b); 1087 p->allow_notify = unmarshal_acl_list(r, b); 1088 p->request_xfr = unmarshal_acl_list(r, b); 1089 p->notify = unmarshal_acl_list(r, b); 1090 p->provide_xfr = unmarshal_acl_list(r, b); 1091 p->outgoing_interface = unmarshal_acl_list(r, b); 1092 return p; 1093 } 1094 1095 key_options_t* 1096 key_options_create(region_type* region) 1097 { 1098 key_options_t* key; 1099 key = (key_options_t*)region_alloc_zero(region, sizeof(key_options_t)); 1100 return key; 1101 } 1102 1103 void 1104 key_options_insert(nsd_options_t* opt, key_options_t* key) 1105 { 1106 if(!key->name) return; 1107 key->node.key = key->name; 1108 (void)rbtree_insert(opt->keys, &key->node); 1109 } 1110 1111 key_options_t* 1112 key_options_find(nsd_options_t* opt, const char* name) 1113 { 1114 return (key_options_t*)rbtree_search(opt->keys, name); 1115 } 1116 1117 /** remove tsig_key contents */ 1118 void 1119 key_options_desetup(region_type* region, key_options_t* key) 1120 { 1121 /* keep tsig_key pointer so that existing references keep valid */ 1122 if(!key->tsig_key) 1123 return; 1124 /* name stays the same */ 1125 if(key->tsig_key->data) { 1126 /* wipe secret! */ 1127 memset(key->tsig_key->data, 0xdd, key->tsig_key->size); 1128 region_recycle(region, key->tsig_key->data, 1129 key->tsig_key->size); 1130 key->tsig_key->data = NULL; 1131 key->tsig_key->size = 0; 1132 } 1133 } 1134 1135 /** add tsig_key contents */ 1136 void 1137 key_options_setup(region_type* region, key_options_t* key) 1138 { 1139 uint8_t data[16384]; /* 16KB */ 1140 int size; 1141 if(!key->tsig_key) { 1142 /* create it */ 1143 key->tsig_key = (tsig_key_type *) region_alloc(region, 1144 sizeof(tsig_key_type)); 1145 /* create name */ 1146 key->tsig_key->name = dname_parse(region, key->name); 1147 if(!key->tsig_key->name) { 1148 log_msg(LOG_ERR, "Failed to parse tsig key name %s", 1149 key->name); 1150 /* key and base64 were checked during syntax parse */ 1151 exit(1); 1152 } 1153 key->tsig_key->size = 0; 1154 key->tsig_key->data = NULL; 1155 } 1156 size = b64_pton(key->secret, data, sizeof(data)); 1157 if(size == -1) { 1158 log_msg(LOG_ERR, "Failed to parse tsig key data %s", 1159 key->name); 1160 /* key and base64 were checked during syntax parse */ 1161 exit(1); 1162 } 1163 key->tsig_key->size = size; 1164 key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size); 1165 } 1166 1167 void 1168 key_options_remove(nsd_options_t* opt, const char* name) 1169 { 1170 key_options_t* k = key_options_find(opt, name); 1171 if(!k) return; 1172 (void)rbtree_delete(opt->keys, name); 1173 if(k->name) 1174 region_recycle(opt->region, k->name, strlen(k->name)+1); 1175 if(k->algorithm) 1176 region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1); 1177 if(k->secret) { 1178 memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */ 1179 region_recycle(opt->region, k->secret, strlen(k->secret)+1); 1180 } 1181 if(k->tsig_key) { 1182 tsig_del_key(k->tsig_key); 1183 if(k->tsig_key->name) 1184 region_recycle(opt->region, (void*)k->tsig_key->name, 1185 dname_total_size(k->tsig_key->name)); 1186 key_options_desetup(opt->region, k); 1187 region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type)); 1188 } 1189 region_recycle(opt->region, k, sizeof(key_options_t)); 1190 } 1191 1192 int 1193 key_options_equal(key_options_t* p, key_options_t* q) 1194 { 1195 return strcmp(p->name, q->name)==0 && strcmp(p->algorithm, 1196 q->algorithm)==0 && strcmp(p->secret, q->secret)==0; 1197 } 1198 1199 void 1200 key_options_add_modify(nsd_options_t* opt, key_options_t* key) 1201 { 1202 key_options_t* orig = key_options_find(opt, key->name); 1203 if(!orig) { 1204 /* needs to be copied to opt region */ 1205 orig = key_options_create(opt->region); 1206 orig->name = region_strdup(opt->region, key->name); 1207 orig->algorithm = region_strdup(opt->region, key->algorithm); 1208 orig->secret = region_strdup(opt->region, key->secret); 1209 key_options_setup(opt->region, orig); 1210 tsig_add_key(orig->tsig_key); 1211 key_options_insert(opt, orig); 1212 } else { 1213 /* modify entries in existing key, and copy to opt region */ 1214 key_options_desetup(opt->region, orig); 1215 region_recycle(opt->region, orig->algorithm, 1216 strlen(orig->algorithm)+1); 1217 orig->algorithm = region_strdup(opt->region, key->algorithm); 1218 region_recycle(opt->region, orig->secret, 1219 strlen(orig->secret)+1); 1220 orig->secret = region_strdup(opt->region, key->secret); 1221 key_options_setup(opt->region, orig); 1222 } 1223 } 1224 1225 int 1226 acl_check_incoming(acl_options_t* acl, struct query* q, 1227 acl_options_t** reason) 1228 { 1229 /* check each acl element. 1230 if 1 blocked element matches - return -1. 1231 if any element matches - return number. 1232 else return -1. */ 1233 int found_match = -1; 1234 int number = 0; 1235 acl_options_t* match = 0; 1236 1237 if(reason) 1238 *reason = NULL; 1239 1240 while(acl) 1241 { 1242 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s", 1243 acl->ip_address_spec, acl->nokey?"NOKEY": 1244 (acl->blocked?"BLOCKED":acl->key_name))); 1245 if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) { 1246 if(!match) 1247 { 1248 match = acl; /* remember first match */ 1249 found_match=number; 1250 } 1251 if(acl->blocked) { 1252 if(reason) 1253 *reason = acl; 1254 return -1; 1255 } 1256 } 1257 number++; 1258 acl = acl->next; 1259 } 1260 1261 if(reason) 1262 *reason = match; 1263 return found_match; 1264 } 1265 1266 #ifdef INET6 1267 int 1268 acl_addr_matches_ipv6host(acl_options_t* acl, struct sockaddr_storage* addr_storage, unsigned int port) 1269 { 1270 struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage; 1271 if(acl->port != 0 && acl->port != port) 1272 return 0; 1273 switch(acl->rangetype) { 1274 case acl_range_mask: 1275 case acl_range_subnet: 1276 if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, 1277 (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) 1278 return 0; 1279 break; 1280 case acl_range_minmax: 1281 if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, 1282 (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) 1283 return 0; 1284 break; 1285 case acl_range_single: 1286 default: 1287 if(memcmp(&addr->sin6_addr, &acl->addr.addr6, 1288 sizeof(struct in6_addr)) != 0) 1289 return 0; 1290 break; 1291 } 1292 return 1; 1293 } 1294 #endif 1295 1296 int 1297 acl_addr_matches_ipv4host(acl_options_t* acl, struct sockaddr_in* addr, unsigned int port) 1298 { 1299 if(acl->port != 0 && acl->port != port) 1300 return 0; 1301 switch(acl->rangetype) { 1302 case acl_range_mask: 1303 case acl_range_subnet: 1304 if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, 1305 (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) 1306 return 0; 1307 break; 1308 case acl_range_minmax: 1309 if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, 1310 (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) 1311 return 0; 1312 break; 1313 case acl_range_single: 1314 default: 1315 if(memcmp(&addr->sin_addr, &acl->addr.addr, 1316 sizeof(struct in_addr)) != 0) 1317 return 0; 1318 break; 1319 } 1320 return 1; 1321 } 1322 1323 int 1324 acl_addr_matches_host(acl_options_t* acl, acl_options_t* host) 1325 { 1326 if(acl->is_ipv6) 1327 { 1328 #ifdef INET6 1329 struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr; 1330 if(!host->is_ipv6) return 0; 1331 return acl_addr_matches_ipv6host(acl, addr, host->port); 1332 #else 1333 return 0; /* no inet6, no match */ 1334 #endif 1335 } 1336 else 1337 { 1338 struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr; 1339 if(host->is_ipv6) return 0; 1340 return acl_addr_matches_ipv4host(acl, addr, host->port); 1341 } 1342 /* ENOTREACH */ 1343 return 0; 1344 } 1345 1346 int 1347 acl_addr_matches(acl_options_t* acl, struct query* q) 1348 { 1349 if(acl->is_ipv6) 1350 { 1351 #ifdef INET6 1352 struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr; 1353 if(addr->ss_family != AF_INET6) 1354 return 0; 1355 return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port)); 1356 #else 1357 return 0; /* no inet6, no match */ 1358 #endif 1359 } 1360 else 1361 { 1362 struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr; 1363 if(addr->sin_family != AF_INET) 1364 return 0; 1365 return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port)); 1366 } 1367 /* ENOTREACH */ 1368 return 0; 1369 } 1370 1371 int 1372 acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz) 1373 { 1374 size_t i; 1375 #ifndef NDEBUG 1376 assert(sz % 4 == 0); 1377 #endif 1378 sz /= 4; 1379 for(i=0; i<sz; ++i) 1380 { 1381 if(((*a++)&*mask) != ((*b++)&*mask)) 1382 return 0; 1383 ++mask; 1384 } 1385 return 1; 1386 } 1387 1388 int 1389 acl_addr_match_range(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz) 1390 { 1391 size_t i; 1392 uint8_t checkmin = 1, checkmax = 1; 1393 #ifndef NDEBUG 1394 assert(sz % 4 == 0); 1395 #endif 1396 /* check treats x as one huge number */ 1397 sz /= 4; 1398 for(i=0; i<sz; ++i) 1399 { 1400 /* if outside bounds, we are done */ 1401 if(checkmin) 1402 if(minval[i] > x[i]) 1403 return 0; 1404 if(checkmax) 1405 if(maxval[i] < x[i]) 1406 return 0; 1407 /* if x is equal to a bound, that bound needs further checks */ 1408 if(checkmin && minval[i]!=x[i]) 1409 checkmin = 0; 1410 if(checkmax && maxval[i]!=x[i]) 1411 checkmax = 0; 1412 if(!checkmin && !checkmax) 1413 return 1; /* will always match */ 1414 } 1415 return 1; 1416 } 1417 1418 int 1419 acl_key_matches(acl_options_t* acl, struct query* q) 1420 { 1421 if(acl->blocked) 1422 return 1; 1423 if(acl->nokey) { 1424 if(q->tsig.status == TSIG_NOT_PRESENT) 1425 return 1; 1426 return 0; 1427 } 1428 /* check name of tsig key */ 1429 if(q->tsig.status != TSIG_OK) { 1430 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG")); 1431 return 0; /* query has no TSIG */ 1432 } 1433 if(q->tsig.error_code != TSIG_ERROR_NOERROR) { 1434 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error")); 1435 return 0; /* some tsig error */ 1436 } 1437 if(!acl->key_options->tsig_key) { 1438 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config")); 1439 return 0; /* key not properly configged */ 1440 } 1441 if(dname_compare(q->tsig.key_name, 1442 acl->key_options->tsig_key->name) != 0) { 1443 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name")); 1444 return 0; /* wrong key name */ 1445 } 1446 if(tsig_strlowercmp(q->tsig.algorithm->short_name, 1447 acl->key_options->algorithm) != 0) { 1448 DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm")); 1449 return 0; /* no such algo */ 1450 } 1451 return 1; 1452 } 1453 1454 int 1455 acl_same_host(acl_options_t* a, acl_options_t* b) 1456 { 1457 if(a->is_ipv6 && !b->is_ipv6) 1458 return 0; 1459 if(!a->is_ipv6 && b->is_ipv6) 1460 return 0; 1461 if(a->port != b->port) 1462 return 0; 1463 if(a->rangetype != b->rangetype) 1464 return 0; 1465 if(!a->is_ipv6) { 1466 if(memcmp(&a->addr.addr, &b->addr.addr, 1467 sizeof(struct in_addr)) != 0) 1468 return 0; 1469 if(a->rangetype != acl_range_single && 1470 memcmp(&a->range_mask.addr, &b->range_mask.addr, 1471 sizeof(struct in_addr)) != 0) 1472 return 0; 1473 } else { 1474 #ifdef INET6 1475 if(memcmp(&a->addr.addr6, &b->addr.addr6, 1476 sizeof(struct in6_addr)) != 0) 1477 return 0; 1478 if(a->rangetype != acl_range_single && 1479 memcmp(&a->range_mask.addr6, &b->range_mask.addr6, 1480 sizeof(struct in6_addr)) != 0) 1481 return 0; 1482 #else 1483 return 0; 1484 #endif 1485 } 1486 return 1; 1487 } 1488 1489 #if defined(HAVE_SSL) 1490 void 1491 key_options_tsig_add(nsd_options_t* opt) 1492 { 1493 key_options_t* optkey; 1494 RBTREE_FOR(optkey, key_options_t*, opt->keys) { 1495 key_options_setup(opt->region, optkey); 1496 tsig_add_key(optkey->tsig_key); 1497 } 1498 } 1499 #endif 1500 1501 int 1502 zone_is_slave(zone_options_t* opt) 1503 { 1504 return opt && opt->pattern && opt->pattern->request_xfr != 0; 1505 } 1506 1507 /* get a character in string (or replacement char if not long enough) */ 1508 static const char* 1509 get_char(const char* str, size_t i) 1510 { 1511 static char res[2]; 1512 if(i >= strlen(str)) 1513 return "."; 1514 res[0] = str[i]; 1515 res[1] = 0; 1516 return res; 1517 } 1518 /* get end label of the zone name (or .) */ 1519 static const char* 1520 get_end_label(zone_options_t* zone, int i) 1521 { 1522 const dname_type* d = (const dname_type*)zone->node.key; 1523 if(i >= d->label_count) { 1524 return "."; 1525 } 1526 return wirelabel2str(dname_label(d, i)); 1527 } 1528 /* replace occurrences of one with two */ 1529 void 1530 replace_str(char* str, size_t len, const char* one, const char* two) 1531 { 1532 char* pos; 1533 char* at = str; 1534 while( (pos=strstr(at, one)) ) { 1535 if(strlen(str)+strlen(two)-strlen(one) >= len) 1536 return; /* no more space to replace */ 1537 /* stuff before pos is fine */ 1538 /* move the stuff after pos to make space for two, add 1539 * one to length of remainder to also copy the 0 byte end */ 1540 memmove(pos+strlen(two), pos+strlen(one), 1541 strlen(pos+strlen(one))+1); 1542 /* copy in two */ 1543 memmove(pos, two, strlen(two)); 1544 /* at is end of the newly inserted two (avoids recursion if 1545 * two contains one) */ 1546 at = pos+strlen(two); 1547 } 1548 } 1549 1550 const char* 1551 config_make_zonefile(zone_options_t* zone, struct nsd* nsd) 1552 { 1553 static char f[1024]; 1554 /* if not a template, return as-is */ 1555 if(!strchr(zone->pattern->zonefile, '%')) { 1556 if (nsd->chrootdir && nsd->chrootdir[0] && 1557 zone->pattern->zonefile && 1558 zone->pattern->zonefile[0] == '/' && 1559 strncmp(zone->pattern->zonefile, nsd->chrootdir, 1560 strlen(nsd->chrootdir)) == 0) 1561 /* -1 because chrootdir ends in trailing slash */ 1562 return zone->pattern->zonefile + strlen(nsd->chrootdir) - 1; 1563 return zone->pattern->zonefile; 1564 } 1565 strlcpy(f, zone->pattern->zonefile, sizeof(f)); 1566 if(strstr(f, "%1")) 1567 replace_str(f, sizeof(f), "%1", get_char(zone->name, 0)); 1568 if(strstr(f, "%2")) 1569 replace_str(f, sizeof(f), "%2", get_char(zone->name, 1)); 1570 if(strstr(f, "%3")) 1571 replace_str(f, sizeof(f), "%3", get_char(zone->name, 2)); 1572 if(strstr(f, "%z")) 1573 replace_str(f, sizeof(f), "%z", get_end_label(zone, 1)); 1574 if(strstr(f, "%y")) 1575 replace_str(f, sizeof(f), "%y", get_end_label(zone, 2)); 1576 if(strstr(f, "%x")) 1577 replace_str(f, sizeof(f), "%x", get_end_label(zone, 3)); 1578 if(strstr(f, "%s")) 1579 replace_str(f, sizeof(f), "%s", zone->name); 1580 if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' && 1581 strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0) 1582 /* -1 because chrootdir ends in trailing slash */ 1583 return f + strlen(nsd->chrootdir) - 1; 1584 return f; 1585 } 1586 1587 zone_options_t* 1588 zone_options_find(nsd_options_t* opt, const struct dname* apex) 1589 { 1590 return (zone_options_t*) rbtree_search(opt->zone_options, apex); 1591 } 1592 1593 acl_options_t* 1594 acl_find_num(acl_options_t* acl, int num) 1595 { 1596 int count = num; 1597 if(num < 0) 1598 return 0; 1599 while(acl && count > 0) { 1600 acl = acl->next; 1601 count--; 1602 } 1603 if(count == 0) 1604 return acl; 1605 return 0; 1606 } 1607 1608 /* true if ipv6 address, false if ipv4 */ 1609 int 1610 parse_acl_is_ipv6(const char* p) 1611 { 1612 /* see if addr is ipv6 or ipv4 -- by : and . */ 1613 while(*p) { 1614 if(*p == '.') return 0; 1615 if(*p == ':') return 1; 1616 ++p; 1617 } 1618 return 0; 1619 } 1620 1621 /* returns range type. mask is the 2nd part of the range */ 1622 int 1623 parse_acl_range_type(char* ip, char** mask) 1624 { 1625 char *p; 1626 if((p=strchr(ip, '&'))!=0) { 1627 *p = 0; 1628 *mask = p+1; 1629 return acl_range_mask; 1630 } 1631 if((p=strchr(ip, '/'))!=0) { 1632 *p = 0; 1633 *mask = p+1; 1634 return acl_range_subnet; 1635 } 1636 if((p=strchr(ip, '-'))!=0) { 1637 *p = 0; 1638 *mask = p+1; 1639 return acl_range_minmax; 1640 } 1641 *mask = 0; 1642 return acl_range_single; 1643 } 1644 1645 /* parses subnet mask, fills 0 mask as well */ 1646 void 1647 parse_acl_range_subnet(char* p, void* addr, int maxbits) 1648 { 1649 int subnet_bits = atoi(p); 1650 uint8_t* addr_bytes = (uint8_t*)addr; 1651 if(subnet_bits == 0 && strcmp(p, "0")!=0) { 1652 c_error_msg("bad subnet range '%s'", p); 1653 return; 1654 } 1655 if(subnet_bits < 0 || subnet_bits > maxbits) { 1656 c_error_msg("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits); 1657 return; 1658 } 1659 /* fill addr with n bits of 1s (struct has been zeroed) */ 1660 while(subnet_bits >= 8) { 1661 *addr_bytes++ = 0xff; 1662 subnet_bits -= 8; 1663 } 1664 if(subnet_bits > 0) { 1665 uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; 1666 *addr_bytes = shifts[subnet_bits]; 1667 } 1668 } 1669 1670 acl_options_t* 1671 parse_acl_info(region_type* region, char* ip, const char* key) 1672 { 1673 char* p; 1674 acl_options_t* acl = (acl_options_t*)region_alloc(region, sizeof(acl_options_t)); 1675 acl->next = 0; 1676 /* ip */ 1677 acl->ip_address_spec = region_strdup(region, ip); 1678 acl->use_axfr_only = 0; 1679 acl->allow_udp = 0; 1680 acl->ixfr_disabled = 0; 1681 acl->bad_xfr_count = 0; 1682 acl->key_options = 0; 1683 acl->is_ipv6 = 0; 1684 acl->port = 0; 1685 memset(&acl->addr, 0, sizeof(union acl_addr_storage)); 1686 memset(&acl->range_mask, 0, sizeof(union acl_addr_storage)); 1687 if((p=strrchr(ip, '@'))!=0) { 1688 if(atoi(p+1) == 0) c_error("expected port number after '@'"); 1689 else acl->port = atoi(p+1); 1690 *p=0; 1691 } 1692 acl->rangetype = parse_acl_range_type(ip, &p); 1693 if(parse_acl_is_ipv6(ip)) { 1694 acl->is_ipv6 = 1; 1695 #ifdef INET6 1696 if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1) 1697 c_error_msg("Bad ip6 address '%s'", ip); 1698 if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) 1699 if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1) 1700 c_error_msg("Bad ip6 address mask '%s'", p); 1701 if(acl->rangetype==acl_range_subnet) 1702 parse_acl_range_subnet(p, &acl->range_mask.addr6, 128); 1703 #else 1704 c_error_msg("encountered IPv6 address '%s'.", ip); 1705 #endif /* INET6 */ 1706 } else { 1707 acl->is_ipv6 = 0; 1708 if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1) 1709 c_error_msg("Bad ip4 address '%s'", ip); 1710 if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) 1711 if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1) 1712 c_error_msg("Bad ip4 address mask '%s'", p); 1713 if(acl->rangetype==acl_range_subnet) 1714 parse_acl_range_subnet(p, &acl->range_mask.addr, 32); 1715 } 1716 1717 /* key */ 1718 if(strcmp(key, "NOKEY")==0) { 1719 acl->nokey = 1; 1720 acl->blocked = 0; 1721 acl->key_name = 0; 1722 } else if(strcmp(key, "BLOCKED")==0) { 1723 acl->nokey = 0; 1724 acl->blocked = 1; 1725 acl->key_name = 0; 1726 } else { 1727 acl->nokey = 0; 1728 acl->blocked = 0; 1729 acl->key_name = region_strdup(region, key); 1730 } 1731 return acl; 1732 } 1733 1734 /* copy acl list at end of parser start, update current */ 1735 static 1736 void append_acl(acl_options_t** start, acl_options_t** cur, 1737 acl_options_t* list) 1738 { 1739 while(list) { 1740 acl_options_t* acl = copy_acl(cfg_parser->opt->region, list); 1741 acl->next = NULL; 1742 if(*cur) 1743 (*cur)->next = acl; 1744 else *start = acl; 1745 *cur = acl; 1746 list = list->next; 1747 } 1748 } 1749 1750 void 1751 config_apply_pattern(const char* name) 1752 { 1753 /* find the pattern */ 1754 pattern_options_t* pat = pattern_options_find(cfg_parser->opt, name); 1755 pattern_options_t* a = cfg_parser->current_pattern; 1756 if(!pat) { 1757 c_error_msg("could not find pattern %s", name); 1758 return; 1759 } 1760 1761 /* apply settings */ 1762 if(pat->zonefile) 1763 a->zonefile = region_strdup(cfg_parser->opt->region, 1764 pat->zonefile); 1765 if(!pat->allow_axfr_fallback_is_default) { 1766 a->allow_axfr_fallback = pat->allow_axfr_fallback; 1767 a->allow_axfr_fallback_is_default = 0; 1768 } 1769 if(!pat->notify_retry_is_default) { 1770 a->notify_retry = pat->notify_retry; 1771 a->notify_retry_is_default = 0; 1772 } 1773 #ifdef RATELIMIT 1774 a->rrl_whitelist |= pat->rrl_whitelist; 1775 #endif 1776 /* append acl items */ 1777 append_acl(&a->allow_notify, &cfg_parser->current_allow_notify, 1778 pat->allow_notify); 1779 append_acl(&a->request_xfr, &cfg_parser->current_request_xfr, 1780 pat->request_xfr); 1781 append_acl(&a->notify, &cfg_parser->current_notify, pat->notify); 1782 append_acl(&a->provide_xfr, &cfg_parser->current_provide_xfr, 1783 pat->provide_xfr); 1784 append_acl(&a->outgoing_interface, &cfg_parser-> 1785 current_outgoing_interface, pat->outgoing_interface); 1786 } 1787 1788 void 1789 nsd_options_destroy(nsd_options_t* opt) 1790 { 1791 region_destroy(opt->region); 1792 } 1793