1 /* 2 * configparser.y -- yacc grammar for NSD configuration files 3 * 4 * Copyright (c) 2001-2019, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 %{ 11 #include "config.h" 12 13 #include <assert.h> 14 #include <errno.h> 15 #include <stdio.h> 16 #include <string.h> 17 18 #include "options.h" 19 #include "util.h" 20 #include "dname.h" 21 #include "tsig.h" 22 #include "rrl.h" 23 24 int yylex(void); 25 26 #ifdef __cplusplus 27 extern "C" 28 #endif 29 30 /* these need to be global, otherwise they cannot be used inside yacc */ 31 extern config_parser_state_type *cfg_parser; 32 33 static void append_acl(struct acl_options **list, struct acl_options *acl); 34 static void add_to_last_acl(struct acl_options **list, char *ac); 35 static int parse_boolean(const char *str, int *bln); 36 static int parse_expire_expr(const char *str, long long *num, uint8_t *expr); 37 static int parse_number(const char *str, long long *num); 38 static int parse_range(const char *str, long long *low, long long *high); 39 %} 40 41 %union { 42 char *str; 43 long long llng; 44 int bln; 45 struct ip_address_option *ip; 46 struct range_option *range; 47 struct cpu_option *cpu; 48 } 49 50 %token <str> STRING 51 %type <llng> number 52 %type <bln> boolean 53 %type <ip> ip_address 54 %type <llng> service_cpu_affinity 55 %type <cpu> cpus 56 57 /* server */ 58 %token VAR_SERVER 59 %token VAR_SERVER_COUNT 60 %token VAR_IP_ADDRESS 61 %token VAR_IP_TRANSPARENT 62 %token VAR_IP_FREEBIND 63 %token VAR_REUSEPORT 64 %token VAR_SEND_BUFFER_SIZE 65 %token VAR_RECEIVE_BUFFER_SIZE 66 %token VAR_DEBUG_MODE 67 %token VAR_IP4_ONLY 68 %token VAR_IP6_ONLY 69 %token VAR_DO_IP4 70 %token VAR_DO_IP6 71 %token VAR_PORT 72 %token VAR_USE_SYSTEMD 73 %token VAR_VERBOSITY 74 %token VAR_USERNAME 75 %token VAR_CHROOT 76 %token VAR_ZONESDIR 77 %token VAR_ZONELISTFILE 78 %token VAR_DATABASE 79 %token VAR_LOGFILE 80 %token VAR_LOG_ONLY_SYSLOG 81 %token VAR_PIDFILE 82 %token VAR_DIFFFILE 83 %token VAR_XFRDFILE 84 %token VAR_XFRDIR 85 %token VAR_HIDE_VERSION 86 %token VAR_HIDE_IDENTITY 87 %token VAR_VERSION 88 %token VAR_IDENTITY 89 %token VAR_NSID 90 %token VAR_TCP_COUNT 91 %token VAR_TCP_REJECT_OVERFLOW 92 %token VAR_TCP_QUERY_COUNT 93 %token VAR_TCP_TIMEOUT 94 %token VAR_TCP_MSS 95 %token VAR_OUTGOING_TCP_MSS 96 %token VAR_IPV4_EDNS_SIZE 97 %token VAR_IPV6_EDNS_SIZE 98 %token VAR_STATISTICS 99 %token VAR_XFRD_RELOAD_TIMEOUT 100 %token VAR_LOG_TIME_ASCII 101 %token VAR_ROUND_ROBIN 102 %token VAR_MINIMAL_RESPONSES 103 %token VAR_CONFINE_TO_ZONE 104 %token VAR_REFUSE_ANY 105 %token VAR_ZONEFILES_CHECK 106 %token VAR_ZONEFILES_WRITE 107 %token VAR_RRL_SIZE 108 %token VAR_RRL_RATELIMIT 109 %token VAR_RRL_SLIP 110 %token VAR_RRL_IPV4_PREFIX_LENGTH 111 %token VAR_RRL_IPV6_PREFIX_LENGTH 112 %token VAR_RRL_WHITELIST_RATELIMIT 113 %token VAR_TLS_SERVICE_KEY 114 %token VAR_TLS_SERVICE_PEM 115 %token VAR_TLS_SERVICE_OCSP 116 %token VAR_TLS_PORT 117 %token VAR_TLS_CERT_BUNDLE 118 %token VAR_CPU_AFFINITY 119 %token VAR_XFRD_CPU_AFFINITY 120 %token <llng> VAR_SERVER_CPU_AFFINITY 121 %token VAR_DROP_UPDATES 122 123 /* dnstap */ 124 %token VAR_DNSTAP 125 %token VAR_DNSTAP_ENABLE 126 %token VAR_DNSTAP_SOCKET_PATH 127 %token VAR_DNSTAP_SEND_IDENTITY 128 %token VAR_DNSTAP_SEND_VERSION 129 %token VAR_DNSTAP_IDENTITY 130 %token VAR_DNSTAP_VERSION 131 %token VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES 132 %token VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES 133 134 /* remote-control */ 135 %token VAR_REMOTE_CONTROL 136 %token VAR_CONTROL_ENABLE 137 %token VAR_CONTROL_INTERFACE 138 %token VAR_CONTROL_PORT 139 %token VAR_SERVER_KEY_FILE 140 %token VAR_SERVER_CERT_FILE 141 %token VAR_CONTROL_KEY_FILE 142 %token VAR_CONTROL_CERT_FILE 143 144 /* key */ 145 %token VAR_KEY 146 %token VAR_ALGORITHM 147 %token VAR_SECRET 148 149 /* xot auth */ 150 %token VAR_TLS_AUTH 151 %token VAR_TLS_AUTH_DOMAIN_NAME 152 %token VAR_TLS_AUTH_CLIENT_CERT 153 %token VAR_TLS_AUTH_CLIENT_KEY 154 %token VAR_TLS_AUTH_CLIENT_KEY_PW 155 156 /* pattern */ 157 %token VAR_PATTERN 158 %token VAR_NAME 159 %token VAR_ZONEFILE 160 %token VAR_NOTIFY 161 %token VAR_PROVIDE_XFR 162 %token VAR_ALLOW_QUERY 163 %token VAR_AXFR 164 %token VAR_UDP 165 %token VAR_NOTIFY_RETRY 166 %token VAR_ALLOW_NOTIFY 167 %token VAR_REQUEST_XFR 168 %token VAR_ALLOW_AXFR_FALLBACK 169 %token VAR_OUTGOING_INTERFACE 170 %token VAR_ANSWER_COOKIE 171 %token VAR_COOKIE_SECRET 172 %token VAR_COOKIE_SECRET_FILE 173 %token VAR_MAX_REFRESH_TIME 174 %token VAR_MIN_REFRESH_TIME 175 %token VAR_MAX_RETRY_TIME 176 %token VAR_MIN_RETRY_TIME 177 %token VAR_MIN_EXPIRE_TIME 178 %token VAR_MULTI_MASTER_CHECK 179 %token VAR_SIZE_LIMIT_XFR 180 %token VAR_ZONESTATS 181 %token VAR_INCLUDE_PATTERN 182 183 /* zone */ 184 %token VAR_ZONE 185 %token VAR_RRL_WHITELIST 186 187 /* socket options */ 188 %token VAR_SERVERS 189 %token VAR_BINDTODEVICE 190 %token VAR_SETFIB 191 192 %% 193 194 blocks: 195 /* may be empty */ 196 | blocks block ; 197 198 block: 199 server 200 | dnstap 201 | remote_control 202 | key 203 | tls_auth 204 | pattern 205 | zone ; 206 207 server: 208 VAR_SERVER server_block ; 209 210 server_block: 211 server_block server_option | ; 212 213 server_option: 214 VAR_IP_ADDRESS ip_address 215 { 216 struct ip_address_option *ip = cfg_parser->opt->ip_addresses; 217 218 if(ip == NULL) { 219 cfg_parser->opt->ip_addresses = $2; 220 } else { 221 while(ip->next) { ip = ip->next; } 222 ip->next = $2; 223 } 224 225 cfg_parser->ip = $2; 226 } 227 socket_options 228 { 229 cfg_parser->ip = NULL; 230 } 231 | VAR_SERVER_COUNT number 232 { 233 if ($2 > 0) { 234 cfg_parser->opt->server_count = (int)$2; 235 } else { 236 yyerror("expected a number greater than zero"); 237 } 238 } 239 | VAR_IP_TRANSPARENT boolean 240 { cfg_parser->opt->ip_transparent = $2; } 241 | VAR_IP_FREEBIND boolean 242 { cfg_parser->opt->ip_freebind = $2; } 243 | VAR_SEND_BUFFER_SIZE number 244 { cfg_parser->opt->send_buffer_size = (int)$2; } 245 | VAR_RECEIVE_BUFFER_SIZE number 246 { cfg_parser->opt->receive_buffer_size = (int)$2; } 247 | VAR_DEBUG_MODE boolean 248 { cfg_parser->opt->debug_mode = $2; } 249 | VAR_USE_SYSTEMD boolean 250 { /* ignored, deprecated */ } 251 | VAR_HIDE_VERSION boolean 252 { cfg_parser->opt->hide_version = $2; } 253 | VAR_HIDE_IDENTITY boolean 254 { cfg_parser->opt->hide_identity = $2; } 255 | VAR_DROP_UPDATES boolean 256 { cfg_parser->opt->drop_updates = $2; } 257 | VAR_IP4_ONLY boolean 258 { if($2) { cfg_parser->opt->do_ip4 = 1; cfg_parser->opt->do_ip6 = 0; } } 259 | VAR_IP6_ONLY boolean 260 { if($2) { cfg_parser->opt->do_ip4 = 0; cfg_parser->opt->do_ip6 = 1; } } 261 | VAR_DO_IP4 boolean 262 { cfg_parser->opt->do_ip4 = $2; } 263 | VAR_DO_IP6 boolean 264 { cfg_parser->opt->do_ip6 = $2; } 265 | VAR_DATABASE STRING 266 { 267 cfg_parser->opt->database = region_strdup(cfg_parser->opt->region, $2); 268 if(cfg_parser->opt->database[0] == 0 && 269 cfg_parser->opt->zonefiles_write == 0) 270 { 271 cfg_parser->opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL; 272 } 273 } 274 | VAR_IDENTITY STRING 275 { cfg_parser->opt->identity = region_strdup(cfg_parser->opt->region, $2); } 276 | VAR_VERSION STRING 277 { cfg_parser->opt->version = region_strdup(cfg_parser->opt->region, $2); } 278 | VAR_NSID STRING 279 { 280 unsigned char* nsid = 0; 281 size_t nsid_len = strlen($2); 282 283 if (strncasecmp($2, "ascii_", 6) == 0) { 284 nsid_len -= 6; /* discard "ascii_" */ 285 if(nsid_len < 65535) { 286 cfg_parser->opt->nsid = region_alloc(cfg_parser->opt->region, nsid_len*2+1); 287 hex_ntop((uint8_t*)$2+6, nsid_len, (char*)cfg_parser->opt->nsid, nsid_len*2+1); 288 } else { 289 yyerror("NSID too long"); 290 } 291 } else if (nsid_len % 2 != 0) { 292 yyerror("the NSID must be a hex string of an even length."); 293 } else { 294 nsid_len = nsid_len / 2; 295 if(nsid_len < 65535) { 296 nsid = xalloc(nsid_len); 297 if (hex_pton($2, nsid, nsid_len) == -1) { 298 yyerror("hex string cannot be parsed in NSID."); 299 } else { 300 cfg_parser->opt->nsid = region_strdup(cfg_parser->opt->region, $2); 301 } 302 free(nsid); 303 } else { 304 yyerror("NSID too long"); 305 } 306 } 307 } 308 | VAR_LOGFILE STRING 309 { cfg_parser->opt->logfile = region_strdup(cfg_parser->opt->region, $2); } 310 | VAR_LOG_ONLY_SYSLOG boolean 311 { cfg_parser->opt->log_only_syslog = $2; } 312 | VAR_TCP_COUNT number 313 { 314 if ($2 > 0) { 315 cfg_parser->opt->tcp_count = (int)$2; 316 } else { 317 yyerror("expected a number greater than zero"); 318 } 319 } 320 | VAR_TCP_REJECT_OVERFLOW boolean 321 { cfg_parser->opt->tcp_reject_overflow = $2; } 322 | VAR_TCP_QUERY_COUNT number 323 { cfg_parser->opt->tcp_query_count = (int)$2; } 324 | VAR_TCP_TIMEOUT number 325 { cfg_parser->opt->tcp_timeout = (int)$2; } 326 | VAR_TCP_MSS number 327 { cfg_parser->opt->tcp_mss = (int)$2; } 328 | VAR_OUTGOING_TCP_MSS number 329 { cfg_parser->opt->outgoing_tcp_mss = (int)$2; } 330 | VAR_IPV4_EDNS_SIZE number 331 { cfg_parser->opt->ipv4_edns_size = (size_t)$2; } 332 | VAR_IPV6_EDNS_SIZE number 333 { cfg_parser->opt->ipv6_edns_size = (size_t)$2; } 334 | VAR_PIDFILE STRING 335 { cfg_parser->opt->pidfile = region_strdup(cfg_parser->opt->region, $2); } 336 | VAR_PORT number 337 { 338 /* port number, stored as a string */ 339 char buf[16]; 340 (void)snprintf(buf, sizeof(buf), "%lld", $2); 341 cfg_parser->opt->port = region_strdup(cfg_parser->opt->region, buf); 342 } 343 | VAR_REUSEPORT boolean 344 { cfg_parser->opt->reuseport = $2; } 345 | VAR_STATISTICS number 346 { cfg_parser->opt->statistics = (int)$2; } 347 | VAR_CHROOT STRING 348 { cfg_parser->opt->chroot = region_strdup(cfg_parser->opt->region, $2); } 349 | VAR_USERNAME STRING 350 { cfg_parser->opt->username = region_strdup(cfg_parser->opt->region, $2); } 351 | VAR_ZONESDIR STRING 352 { cfg_parser->opt->zonesdir = region_strdup(cfg_parser->opt->region, $2); } 353 | VAR_ZONELISTFILE STRING 354 { cfg_parser->opt->zonelistfile = region_strdup(cfg_parser->opt->region, $2); } 355 | VAR_DIFFFILE STRING 356 { /* ignored, deprecated */ } 357 | VAR_XFRDFILE STRING 358 { cfg_parser->opt->xfrdfile = region_strdup(cfg_parser->opt->region, $2); } 359 | VAR_XFRDIR STRING 360 { cfg_parser->opt->xfrdir = region_strdup(cfg_parser->opt->region, $2); } 361 | VAR_XFRD_RELOAD_TIMEOUT number 362 { cfg_parser->opt->xfrd_reload_timeout = (int)$2; } 363 | VAR_VERBOSITY number 364 { cfg_parser->opt->verbosity = (int)$2; } 365 | VAR_RRL_SIZE number 366 { 367 #ifdef RATELIMIT 368 if ($2 > 0) { 369 cfg_parser->opt->rrl_size = (size_t)$2; 370 } else { 371 yyerror("expected a number greater than zero"); 372 } 373 #endif 374 } 375 | VAR_RRL_RATELIMIT number 376 { 377 #ifdef RATELIMIT 378 cfg_parser->opt->rrl_ratelimit = (size_t)$2; 379 #endif 380 } 381 | VAR_RRL_SLIP number 382 { 383 #ifdef RATELIMIT 384 cfg_parser->opt->rrl_slip = (size_t)$2; 385 #endif 386 } 387 | VAR_RRL_IPV4_PREFIX_LENGTH number 388 { 389 #ifdef RATELIMIT 390 if ($2 > 32) { 391 yyerror("invalid IPv4 prefix length"); 392 } else { 393 cfg_parser->opt->rrl_ipv4_prefix_length = (size_t)$2; 394 } 395 #endif 396 } 397 | VAR_RRL_IPV6_PREFIX_LENGTH number 398 { 399 #ifdef RATELIMIT 400 if ($2 > 64) { 401 yyerror("invalid IPv6 prefix length"); 402 } else { 403 cfg_parser->opt->rrl_ipv6_prefix_length = (size_t)$2; 404 } 405 #endif 406 } 407 | VAR_RRL_WHITELIST_RATELIMIT number 408 { 409 #ifdef RATELIMIT 410 cfg_parser->opt->rrl_whitelist_ratelimit = (size_t)$2; 411 #endif 412 } 413 | VAR_ZONEFILES_CHECK boolean 414 { cfg_parser->opt->zonefiles_check = $2; } 415 | VAR_ZONEFILES_WRITE number 416 { cfg_parser->opt->zonefiles_write = (int)$2; } 417 | VAR_LOG_TIME_ASCII boolean 418 { 419 cfg_parser->opt->log_time_ascii = $2; 420 log_time_asc = cfg_parser->opt->log_time_ascii; 421 } 422 | VAR_ROUND_ROBIN boolean 423 { 424 cfg_parser->opt->round_robin = $2; 425 round_robin = cfg_parser->opt->round_robin; 426 } 427 | VAR_MINIMAL_RESPONSES boolean 428 { 429 cfg_parser->opt->minimal_responses = $2; 430 minimal_responses = cfg_parser->opt->minimal_responses; 431 } 432 | VAR_CONFINE_TO_ZONE boolean 433 { cfg_parser->opt->confine_to_zone = $2; } 434 | VAR_REFUSE_ANY boolean 435 { cfg_parser->opt->refuse_any = $2; } 436 | VAR_TLS_SERVICE_KEY STRING 437 { cfg_parser->opt->tls_service_key = region_strdup(cfg_parser->opt->region, $2); } 438 | VAR_TLS_SERVICE_OCSP STRING 439 { cfg_parser->opt->tls_service_ocsp = region_strdup(cfg_parser->opt->region, $2); } 440 | VAR_TLS_SERVICE_PEM STRING 441 { cfg_parser->opt->tls_service_pem = region_strdup(cfg_parser->opt->region, $2); } 442 | VAR_TLS_PORT number 443 { 444 /* port number, stored as string */ 445 char buf[16]; 446 (void)snprintf(buf, sizeof(buf), "%lld", $2); 447 cfg_parser->opt->tls_port = region_strdup(cfg_parser->opt->region, buf); 448 } 449 | VAR_TLS_CERT_BUNDLE STRING 450 { cfg_parser->opt->tls_cert_bundle = region_strdup(cfg_parser->opt->region, $2); } 451 | VAR_ANSWER_COOKIE boolean 452 { cfg_parser->opt->answer_cookie = $2; } 453 | VAR_COOKIE_SECRET STRING 454 { cfg_parser->opt->cookie_secret = region_strdup(cfg_parser->opt->region, $2); } 455 | VAR_COOKIE_SECRET_FILE STRING 456 { cfg_parser->opt->cookie_secret_file = region_strdup(cfg_parser->opt->region, $2); } 457 | VAR_CPU_AFFINITY cpus 458 { 459 cfg_parser->opt->cpu_affinity = $2; 460 } 461 | service_cpu_affinity number 462 { 463 if($2 < 0) { 464 yyerror("expected a non-negative number"); 465 YYABORT; 466 } else { 467 struct cpu_map_option *opt, *tail; 468 469 opt = cfg_parser->opt->service_cpu_affinity; 470 while(opt && opt->service != $1) { opt = opt->next; } 471 472 if(opt) { 473 opt->cpu = $2; 474 } else { 475 opt = region_alloc_zero(cfg_parser->opt->region, sizeof(*opt)); 476 opt->service = (int)$1; 477 opt->cpu = (int)$2; 478 479 tail = cfg_parser->opt->service_cpu_affinity; 480 if(tail) { 481 while(tail->next) { tail = tail->next; } 482 tail->next = opt; 483 } else { 484 cfg_parser->opt->service_cpu_affinity = opt; 485 } 486 } 487 } 488 } 489 ; 490 491 socket_options: 492 | socket_options socket_option ; 493 494 socket_option: 495 VAR_SERVERS STRING 496 { 497 char *tok, *ptr, *str; 498 struct range_option *servers = NULL; 499 long long first, last; 500 501 /* user may specify "0 1", "0" "1", 0 1 or a combination thereof */ 502 for(str = $2; (tok = strtok_r(str, " \t", &ptr)); str = NULL) { 503 struct range_option *opt = 504 region_alloc(cfg_parser->opt->region, sizeof(*opt)); 505 first = last = 0; 506 if(!parse_range(tok, &first, &last)) { 507 yyerror("invalid server range '%s'", tok); 508 YYABORT; 509 } 510 assert(first >= 0); 511 assert(last >= 0); 512 opt->next = NULL; 513 opt->first = (int)first; 514 opt->last = (int)last; 515 if(servers) { 516 servers = servers->next = opt; 517 } else { 518 servers = cfg_parser->ip->servers = opt; 519 } 520 } 521 } 522 | VAR_BINDTODEVICE boolean 523 { cfg_parser->ip->dev = $2; } 524 | VAR_SETFIB number 525 { cfg_parser->ip->fib = $2; } 526 ; 527 528 cpus: 529 { $$ = NULL; } 530 | cpus STRING 531 { 532 char *tok, *ptr, *str; 533 struct cpu_option *tail; 534 long long cpu; 535 536 str = $2; 537 $$ = tail = $1; 538 if(tail) { 539 while(tail->next) { tail = tail->next; } 540 } 541 542 /* Users may specify "0 1", "0" "1", 0 1 or a combination thereof. */ 543 for(str = $2; (tok = strtok_r(str, " \t", &ptr)); str = NULL) { 544 struct cpu_option *opt = 545 region_alloc(cfg_parser->opt->region, sizeof(*opt)); 546 cpu = 0; 547 if(!parse_number(tok, &cpu) || opt->cpu < 0) { 548 yyerror("expected a positive number"); 549 YYABORT; 550 } 551 assert(cpu >=0); 552 opt->cpu = (int)cpu; 553 if(tail) { 554 tail->next = opt; 555 tail = opt; 556 } else { 557 $$ = tail = opt; 558 } 559 } 560 } 561 ; 562 563 service_cpu_affinity: 564 VAR_XFRD_CPU_AFFINITY 565 { $$ = -1; } 566 | VAR_SERVER_CPU_AFFINITY 567 { 568 if($1 <= 0) { 569 yyerror("invalid server identifier"); 570 YYABORT; 571 } 572 $$ = $1; 573 } 574 ; 575 576 dnstap: 577 VAR_DNSTAP dnstap_block ; 578 579 dnstap_block: 580 dnstap_block dnstap_option | ; 581 582 dnstap_option: 583 VAR_DNSTAP_ENABLE boolean 584 { cfg_parser->opt->dnstap_enable = $2; } 585 | VAR_DNSTAP_SOCKET_PATH STRING 586 { cfg_parser->opt->dnstap_socket_path = region_strdup(cfg_parser->opt->region, $2); } 587 | VAR_DNSTAP_SEND_IDENTITY boolean 588 { cfg_parser->opt->dnstap_send_identity = $2; } 589 | VAR_DNSTAP_SEND_VERSION boolean 590 { cfg_parser->opt->dnstap_send_version = $2; } 591 | VAR_DNSTAP_IDENTITY STRING 592 { cfg_parser->opt->dnstap_identity = region_strdup(cfg_parser->opt->region, $2); } 593 | VAR_DNSTAP_VERSION STRING 594 { cfg_parser->opt->dnstap_version = region_strdup(cfg_parser->opt->region, $2); } 595 | VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES boolean 596 { cfg_parser->opt->dnstap_log_auth_query_messages = $2; } 597 | VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES boolean 598 { cfg_parser->opt->dnstap_log_auth_response_messages = $2; } 599 ; 600 601 remote_control: 602 VAR_REMOTE_CONTROL remote_control_block ; 603 604 remote_control_block: 605 remote_control_block remote_control_option | ; 606 607 remote_control_option: 608 VAR_CONTROL_ENABLE boolean 609 { cfg_parser->opt->control_enable = $2; } 610 | VAR_CONTROL_INTERFACE ip_address 611 { 612 struct ip_address_option *ip = cfg_parser->opt->control_interface; 613 if(ip == NULL) { 614 cfg_parser->opt->control_interface = $2; 615 } else { 616 while(ip->next != NULL) { ip = ip->next; } 617 ip->next = $2; 618 } 619 } 620 | VAR_CONTROL_PORT number 621 { 622 if($2 == 0) { 623 yyerror("control port number expected"); 624 } else { 625 cfg_parser->opt->control_port = (int)$2; 626 } 627 } 628 | VAR_SERVER_KEY_FILE STRING 629 { cfg_parser->opt->server_key_file = region_strdup(cfg_parser->opt->region, $2); } 630 | VAR_SERVER_CERT_FILE STRING 631 { cfg_parser->opt->server_cert_file = region_strdup(cfg_parser->opt->region, $2); } 632 | VAR_CONTROL_KEY_FILE STRING 633 { cfg_parser->opt->control_key_file = region_strdup(cfg_parser->opt->region, $2); } 634 | VAR_CONTROL_CERT_FILE STRING 635 { cfg_parser->opt->control_cert_file = region_strdup(cfg_parser->opt->region, $2); } 636 ; 637 638 tls_auth: 639 VAR_TLS_AUTH 640 { 641 tls_auth_options_type *tls_auth = tls_auth_options_create(cfg_parser->opt->region); 642 assert(cfg_parser->tls_auth == NULL); 643 cfg_parser->tls_auth = tls_auth; 644 } 645 tls_auth_block 646 { 647 struct tls_auth_options *tls_auth = cfg_parser->tls_auth; 648 if(tls_auth->name == NULL) { 649 yyerror("tls-auth has no name"); 650 } else if(tls_auth->auth_domain_name == NULL) { 651 yyerror("tls-auth %s has no auth-domain-name", tls_auth->name); 652 } else if(tls_auth_options_find(cfg_parser->opt, tls_auth->name)) { 653 yyerror("duplicate tls-auth %s", tls_auth->name); 654 } else { 655 tls_auth_options_insert(cfg_parser->opt, tls_auth); 656 cfg_parser->tls_auth = NULL; 657 } 658 } ; 659 660 tls_auth_block: 661 tls_auth_block tls_auth_option | ; 662 663 tls_auth_option: 664 VAR_NAME STRING 665 { 666 dname_type *dname; 667 dname = (dname_type *)dname_parse(cfg_parser->opt->region, $2); 668 cfg_parser->tls_auth->name = region_strdup(cfg_parser->opt->region, $2); 669 if(dname == NULL) { 670 yyerror("bad tls-auth name %s", $2); 671 } else { 672 region_recycle(cfg_parser->opt->region, dname, dname_total_size(dname)); 673 } 674 } 675 | VAR_TLS_AUTH_DOMAIN_NAME STRING 676 { 677 cfg_parser->tls_auth->auth_domain_name = region_strdup(cfg_parser->opt->region, $2); 678 } 679 | VAR_TLS_AUTH_CLIENT_CERT STRING 680 { 681 cfg_parser->tls_auth->client_cert = region_strdup(cfg_parser->opt->region, $2); 682 } 683 | VAR_TLS_AUTH_CLIENT_KEY STRING 684 { 685 cfg_parser->tls_auth->client_key = region_strdup(cfg_parser->opt->region, $2); 686 } 687 | VAR_TLS_AUTH_CLIENT_KEY_PW STRING 688 { 689 cfg_parser->tls_auth->client_key_pw = region_strdup(cfg_parser->opt->region, $2); 690 } 691 ; 692 693 key: 694 VAR_KEY 695 { 696 key_options_type *key = key_options_create(cfg_parser->opt->region); 697 key->algorithm = region_strdup(cfg_parser->opt->region, "sha256"); 698 assert(cfg_parser->key == NULL); 699 cfg_parser->key = key; 700 } 701 key_block 702 { 703 struct key_options *key = cfg_parser->key; 704 if(key->name == NULL) { 705 yyerror("tsig key has no name"); 706 } else if(key->algorithm == NULL) { 707 yyerror("tsig key %s has no algorithm", key->name); 708 } else if(key->secret == NULL) { 709 yyerror("tsig key %s has no secret blob", key->name); 710 } else if(key_options_find(cfg_parser->opt, key->name)) { 711 yyerror("duplicate tsig key %s", key->name); 712 } else { 713 key_options_insert(cfg_parser->opt, key); 714 cfg_parser->key = NULL; 715 } 716 } ; 717 718 key_block: 719 key_block key_option | ; 720 721 key_option: 722 VAR_NAME STRING 723 { 724 dname_type *dname; 725 726 dname = (dname_type *)dname_parse(cfg_parser->opt->region, $2); 727 cfg_parser->key->name = region_strdup(cfg_parser->opt->region, $2); 728 if(dname == NULL) { 729 yyerror("bad tsig key name %s", $2); 730 } else { 731 region_recycle(cfg_parser->opt->region, dname, dname_total_size(dname)); 732 } 733 } 734 | VAR_ALGORITHM STRING 735 { 736 if(tsig_get_algorithm_by_name($2) == NULL) { 737 yyerror("bad tsig key algorithm %s", $2); 738 } else { 739 cfg_parser->key->algorithm = region_strdup(cfg_parser->opt->region, $2); 740 } 741 } 742 | VAR_SECRET STRING 743 { 744 uint8_t data[16384]; 745 int size; 746 747 cfg_parser->key->secret = region_strdup(cfg_parser->opt->region, $2); 748 size = __b64_pton($2, data, sizeof(data)); 749 if(size == -1) { 750 yyerror("cannot base64 decode tsig secret %s", 751 cfg_parser->key->name? 752 cfg_parser->key->name:""); 753 } else if(size != 0) { 754 memset(data, 0xdd, size); /* wipe secret */ 755 } 756 } ; 757 758 759 zone: 760 VAR_ZONE 761 { 762 assert(cfg_parser->pattern == NULL); 763 assert(cfg_parser->zone == NULL); 764 cfg_parser->zone = zone_options_create(cfg_parser->opt->region); 765 cfg_parser->zone->part_of_config = 1; 766 cfg_parser->zone->pattern = cfg_parser->pattern = 767 pattern_options_create(cfg_parser->opt->region); 768 cfg_parser->zone->pattern->implicit = 1; 769 } 770 zone_block 771 { 772 assert(cfg_parser->zone != NULL); 773 if(cfg_parser->zone->name == NULL) { 774 yyerror("zone has no name"); 775 } else if(!nsd_options_insert_zone(cfg_parser->opt, cfg_parser->zone)) { 776 yyerror("duplicate zone %s", cfg_parser->zone->name); 777 } else if(!nsd_options_insert_pattern(cfg_parser->opt, cfg_parser->zone->pattern)) { 778 yyerror("duplicate pattern %s", cfg_parser->zone->pattern->pname); 779 } 780 cfg_parser->pattern = NULL; 781 cfg_parser->zone = NULL; 782 } ; 783 784 zone_block: 785 zone_block zone_option | ; 786 787 zone_option: 788 VAR_NAME STRING 789 { 790 const char *marker = PATTERN_IMPLICIT_MARKER; 791 char *pname = region_alloc(cfg_parser->opt->region, strlen($2) + strlen(marker) + 1); 792 memmove(pname, marker, strlen(marker)); 793 memmove(pname + strlen(marker), $2, strlen($2) + 1); 794 cfg_parser->zone->pattern->pname = pname; 795 cfg_parser->zone->name = region_strdup(cfg_parser->opt->region, $2); 796 if(pattern_options_find(cfg_parser->opt, pname)) { 797 yyerror("zone %s cannot be created because implicit pattern %s " 798 "already exists", $2, pname); 799 } 800 } 801 | pattern_or_zone_option ; 802 803 pattern: 804 VAR_PATTERN 805 { 806 assert(cfg_parser->pattern == NULL); 807 cfg_parser->pattern = pattern_options_create(cfg_parser->opt->region); 808 } 809 pattern_block 810 { 811 pattern_options_type *pattern = cfg_parser->pattern; 812 if(pattern->pname == NULL) { 813 yyerror("pattern has no name"); 814 } else if(!nsd_options_insert_pattern(cfg_parser->opt, pattern)) { 815 yyerror("duplicate pattern %s", pattern->pname); 816 } 817 cfg_parser->pattern = NULL; 818 } ; 819 820 pattern_block: 821 pattern_block pattern_option | ; 822 823 pattern_option: 824 VAR_NAME STRING 825 { 826 if(strchr($2, ' ')) { 827 yyerror("space is not allowed in pattern name: '%s'", $2); 828 } 829 cfg_parser->pattern->pname = region_strdup(cfg_parser->opt->region, $2); 830 } 831 | pattern_or_zone_option ; 832 833 pattern_or_zone_option: 834 VAR_RRL_WHITELIST STRING 835 { 836 #ifdef RATELIMIT 837 cfg_parser->pattern->rrl_whitelist |= rrlstr2type($2); 838 #endif 839 } 840 | VAR_ZONEFILE STRING 841 { cfg_parser->pattern->zonefile = region_strdup(cfg_parser->opt->region, $2); } 842 | VAR_ZONESTATS STRING 843 { cfg_parser->pattern->zonestats = region_strdup(cfg_parser->opt->region, $2); } 844 | VAR_SIZE_LIMIT_XFR number 845 { 846 if($2 > 0) { 847 cfg_parser->pattern->size_limit_xfr = (int)$2; 848 } else { 849 yyerror("expected a number greater than zero"); 850 } 851 } 852 | VAR_MULTI_MASTER_CHECK boolean 853 { cfg_parser->pattern->multi_master_check = (int)$2; } 854 | VAR_INCLUDE_PATTERN STRING 855 { config_apply_pattern(cfg_parser->pattern, $2); } 856 | VAR_REQUEST_XFR STRING STRING 857 { 858 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 859 if(acl->blocked) 860 yyerror("blocked address used for request-xfr"); 861 if(acl->rangetype != acl_range_single) 862 yyerror("address range used for request-xfr"); 863 append_acl(&cfg_parser->pattern->request_xfr, acl); 864 } 865 tlsauth_option 866 { } 867 | VAR_REQUEST_XFR VAR_AXFR STRING STRING 868 { 869 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $3, $4); 870 acl->use_axfr_only = 1; 871 if(acl->blocked) 872 yyerror("blocked address used for request-xfr"); 873 if(acl->rangetype != acl_range_single) 874 yyerror("address range used for request-xfr"); 875 append_acl(&cfg_parser->pattern->request_xfr, acl); 876 } 877 tlsauth_option 878 { } 879 | VAR_REQUEST_XFR VAR_UDP STRING STRING 880 { 881 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $3, $4); 882 acl->allow_udp = 1; 883 if(acl->blocked) 884 yyerror("blocked address used for request-xfr"); 885 if(acl->rangetype != acl_range_single) 886 yyerror("address range used for request-xfr"); 887 append_acl(&cfg_parser->pattern->request_xfr, acl); 888 } 889 | VAR_ALLOW_NOTIFY STRING STRING 890 { 891 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 892 append_acl(&cfg_parser->pattern->allow_notify, acl); 893 } 894 | VAR_NOTIFY STRING STRING 895 { 896 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 897 if(acl->blocked) 898 yyerror("blocked address used for notify"); 899 if(acl->rangetype != acl_range_single) 900 yyerror("address range used for notify"); 901 append_acl(&cfg_parser->pattern->notify, acl); 902 } 903 | VAR_PROVIDE_XFR STRING STRING 904 { 905 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 906 append_acl(&cfg_parser->pattern->provide_xfr, acl); 907 } 908 | VAR_ALLOW_QUERY STRING STRING 909 { 910 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 911 append_acl(&cfg_parser->pattern->allow_query, acl); 912 } 913 | VAR_OUTGOING_INTERFACE STRING 914 { 915 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, "NOKEY"); 916 append_acl(&cfg_parser->pattern->outgoing_interface, acl); 917 } 918 | VAR_ALLOW_AXFR_FALLBACK boolean 919 { 920 cfg_parser->pattern->allow_axfr_fallback = $2; 921 cfg_parser->pattern->allow_axfr_fallback_is_default = 0; 922 } 923 | VAR_NOTIFY_RETRY number 924 { 925 cfg_parser->pattern->notify_retry = $2; 926 cfg_parser->pattern->notify_retry_is_default = 0; 927 } 928 | VAR_MAX_REFRESH_TIME number 929 { 930 cfg_parser->pattern->max_refresh_time = $2; 931 cfg_parser->pattern->max_refresh_time_is_default = 0; 932 } 933 | VAR_MIN_REFRESH_TIME number 934 { 935 cfg_parser->pattern->min_refresh_time = $2; 936 cfg_parser->pattern->min_refresh_time_is_default = 0; 937 } 938 | VAR_MAX_RETRY_TIME number 939 { 940 cfg_parser->pattern->max_retry_time = $2; 941 cfg_parser->pattern->max_retry_time_is_default = 0; 942 } 943 | VAR_MIN_RETRY_TIME number 944 { 945 cfg_parser->pattern->min_retry_time = $2; 946 cfg_parser->pattern->min_retry_time_is_default = 0; 947 } 948 | VAR_MIN_EXPIRE_TIME STRING 949 { 950 long long num; 951 uint8_t expr; 952 953 if (!parse_expire_expr($2, &num, &expr)) { 954 yyerror("expected an expire time in seconds or \"refresh+retry+1\""); 955 YYABORT; /* trigger a parser error */ 956 } 957 cfg_parser->pattern->min_expire_time = num; 958 cfg_parser->pattern->min_expire_time_expr = expr; 959 }; 960 961 ip_address: 962 STRING 963 { 964 struct ip_address_option *ip = region_alloc_zero( 965 cfg_parser->opt->region, sizeof(*ip)); 966 ip->address = region_strdup(cfg_parser->opt->region, $1); 967 ip->fib = -1; 968 $$ = ip; 969 } ; 970 971 number: 972 STRING 973 { 974 if(!parse_number($1, &$$)) { 975 yyerror("expected a number"); 976 YYABORT; /* trigger a parser error */ 977 } 978 } ; 979 980 boolean: 981 STRING 982 { 983 if(!parse_boolean($1, &$$)) { 984 yyerror("expected yes or no"); 985 YYABORT; /* trigger a parser error */ 986 } 987 } ; 988 989 tlsauth_option: 990 | STRING 991 { char *tls_auth_name = region_strdup(cfg_parser->opt->region, $1); 992 add_to_last_acl(&cfg_parser->pattern->request_xfr, tls_auth_name);} ; 993 994 %% 995 996 static void 997 append_acl(struct acl_options **list, struct acl_options *acl) 998 { 999 assert(list != NULL); 1000 1001 if(*list == NULL) { 1002 *list = acl; 1003 } else { 1004 struct acl_options *tail = *list; 1005 while(tail->next != NULL) 1006 tail = tail->next; 1007 tail->next = acl; 1008 } 1009 } 1010 1011 static void 1012 add_to_last_acl(struct acl_options **list, char *tls_auth_name) 1013 { 1014 struct acl_options *tail = *list; 1015 assert(list != NULL); 1016 assert(*list != NULL); 1017 while(tail->next != NULL) 1018 tail = tail->next; 1019 tail->tls_auth_name = tls_auth_name; 1020 } 1021 1022 static int 1023 parse_boolean(const char *str, int *bln) 1024 { 1025 if(strcmp(str, "yes") == 0) { 1026 *bln = 1; 1027 } else if(strcmp(str, "no") == 0) { 1028 *bln = 0; 1029 } else { 1030 return 0; 1031 } 1032 1033 return 1; 1034 } 1035 1036 static int 1037 parse_expire_expr(const char *str, long long *num, uint8_t *expr) 1038 { 1039 if(parse_number(str, num)) { 1040 *expr = EXPIRE_TIME_HAS_VALUE; 1041 return 1; 1042 } 1043 if(strcmp(str, REFRESHPLUSRETRYPLUS1_STR) == 0) { 1044 *num = 0; 1045 *expr = REFRESHPLUSRETRYPLUS1; 1046 return 1; 1047 } 1048 return 0; 1049 } 1050 1051 static int 1052 parse_number(const char *str, long long *num) 1053 { 1054 /* ensure string consists entirely of digits */ 1055 size_t pos = 0; 1056 while(str[pos] >= '0' && str[pos] <= '9') { 1057 pos++; 1058 } 1059 1060 if(pos != 0 && str[pos] == '\0') { 1061 *num = strtoll(str, NULL, 10); 1062 return 1; 1063 } 1064 1065 return 0; 1066 } 1067 1068 static int 1069 parse_range(const char *str, long long *low, long long *high) 1070 { 1071 const char *ptr = str; 1072 long long num[2]; 1073 1074 /* require range to begin with a number */ 1075 if(*ptr < '0' || *ptr > '9') { 1076 return 0; 1077 } 1078 1079 num[0] = strtoll(ptr, (char **)&ptr, 10); 1080 1081 /* require number to be followed by nothing at all or a dash */ 1082 if(*ptr == '\0') { 1083 *low = num[0]; 1084 *high = num[0]; 1085 return 1; 1086 } else if(*ptr != '-') { 1087 return 0; 1088 } 1089 1090 ++ptr; 1091 /* require dash to be followed by a number */ 1092 if(*ptr < '0' || *ptr > '9') { 1093 return 0; 1094 } 1095 1096 num[1] = strtoll(ptr, (char **)&ptr, 10); 1097 1098 /* require number to be followed by nothing at all */ 1099 if(*ptr == '\0') { 1100 if(num[0] < num[1]) { 1101 *low = num[0]; 1102 *high = num[1]; 1103 } else { 1104 *low = num[1]; 1105 *high = num[0]; 1106 } 1107 return 1; 1108 } 1109 1110 return 0; 1111 } 1112