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