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