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 24int yylex(void); 25 26#ifdef __cplusplus 27extern "C" 28#endif 29 30/* these need to be global, otherwise they cannot be used inside yacc */ 31extern config_parser_state_type *cfg_parser; 32 33static void append_acl(struct acl_options **list, struct acl_options *acl); 34static void add_to_last_acl(struct acl_options **list, char *ac); 35static int parse_boolean(const char *str, int *bln); 36static int parse_expire_expr(const char *str, long long *num, uint8_t *expr); 37static int parse_number(const char *str, long long *num); 38static int parse_range(const char *str, long long *low, long long *high); 39 40struct 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_PROXY_PROTOCOL_PORT 129%token VAR_CPU_AFFINITY 130%token VAR_XFRD_CPU_AFFINITY 131%token <llng> VAR_SERVER_CPU_AFFINITY 132%token VAR_DROP_UPDATES 133%token VAR_XFRD_TCP_MAX 134%token VAR_XFRD_TCP_PIPELINE 135 136/* dnstap */ 137%token VAR_DNSTAP 138%token VAR_DNSTAP_ENABLE 139%token VAR_DNSTAP_SOCKET_PATH 140%token VAR_DNSTAP_IP 141%token VAR_DNSTAP_TLS 142%token VAR_DNSTAP_TLS_SERVER_NAME 143%token VAR_DNSTAP_TLS_CERT_BUNDLE 144%token VAR_DNSTAP_TLS_CLIENT_KEY_FILE 145%token VAR_DNSTAP_TLS_CLIENT_CERT_FILE 146%token VAR_DNSTAP_SEND_IDENTITY 147%token VAR_DNSTAP_SEND_VERSION 148%token VAR_DNSTAP_IDENTITY 149%token VAR_DNSTAP_VERSION 150%token VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES 151%token VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES 152 153/* remote-control */ 154%token VAR_REMOTE_CONTROL 155%token VAR_CONTROL_ENABLE 156%token VAR_CONTROL_INTERFACE 157%token VAR_CONTROL_PORT 158%token VAR_SERVER_KEY_FILE 159%token VAR_SERVER_CERT_FILE 160%token VAR_CONTROL_KEY_FILE 161%token VAR_CONTROL_CERT_FILE 162 163/* key */ 164%token VAR_KEY 165%token VAR_ALGORITHM 166%token VAR_SECRET 167 168/* xot auth */ 169%token VAR_TLS_AUTH 170%token VAR_TLS_AUTH_DOMAIN_NAME 171%token VAR_TLS_AUTH_CLIENT_CERT 172%token VAR_TLS_AUTH_CLIENT_KEY 173%token VAR_TLS_AUTH_CLIENT_KEY_PW 174 175/* pattern */ 176%token VAR_PATTERN 177%token VAR_NAME 178%token VAR_ZONEFILE 179%token VAR_NOTIFY 180%token VAR_PROVIDE_XFR 181%token VAR_ALLOW_QUERY 182%token VAR_AXFR 183%token VAR_UDP 184%token VAR_NOTIFY_RETRY 185%token VAR_ALLOW_NOTIFY 186%token VAR_REQUEST_XFR 187%token VAR_ALLOW_AXFR_FALLBACK 188%token VAR_OUTGOING_INTERFACE 189%token VAR_ANSWER_COOKIE 190%token VAR_COOKIE_SECRET 191%token VAR_COOKIE_SECRET_FILE 192%token VAR_MAX_REFRESH_TIME 193%token VAR_MIN_REFRESH_TIME 194%token VAR_MAX_RETRY_TIME 195%token VAR_MIN_RETRY_TIME 196%token VAR_MIN_EXPIRE_TIME 197%token VAR_MULTI_MASTER_CHECK 198%token VAR_SIZE_LIMIT_XFR 199%token VAR_ZONESTATS 200%token VAR_INCLUDE_PATTERN 201%token VAR_STORE_IXFR 202%token VAR_IXFR_SIZE 203%token VAR_IXFR_NUMBER 204%token VAR_CREATE_IXFR 205 206/* zone */ 207%token VAR_ZONE 208%token VAR_RRL_WHITELIST 209 210/* socket options */ 211%token VAR_SERVERS 212%token VAR_BINDTODEVICE 213%token VAR_SETFIB 214 215/* verify */ 216%token VAR_VERIFY 217%token VAR_ENABLE 218%token VAR_VERIFY_ZONE 219%token VAR_VERIFY_ZONES 220%token VAR_VERIFIER 221%token VAR_VERIFIER_COUNT 222%token VAR_VERIFIER_FEED_ZONE 223%token VAR_VERIFIER_TIMEOUT 224 225%% 226 227blocks: 228 /* may be empty */ 229 | blocks block ; 230 231block: 232 server 233 | dnstap 234 | remote_control 235 | key 236 | tls_auth 237 | pattern 238 | zone 239 | verify ; 240 241server: 242 VAR_SERVER server_block ; 243 244server_block: 245 server_block server_option | ; 246 247server_option: 248 VAR_IP_ADDRESS ip_address 249 { 250 struct ip_address_option *ip = cfg_parser->opt->ip_addresses; 251 252 if(ip == NULL) { 253 cfg_parser->opt->ip_addresses = $2; 254 } else { 255 while(ip->next) { ip = ip->next; } 256 ip->next = $2; 257 } 258 259 cfg_parser->ip = $2; 260 } 261 socket_options 262 { 263 cfg_parser->ip = NULL; 264 } 265 | VAR_SERVER_COUNT number 266 { 267 if ($2 > 0) { 268 cfg_parser->opt->server_count = (int)$2; 269 } else { 270 yyerror("expected a number greater than zero"); 271 } 272 } 273 | VAR_IP_TRANSPARENT boolean 274 { cfg_parser->opt->ip_transparent = $2; } 275 | VAR_IP_FREEBIND boolean 276 { cfg_parser->opt->ip_freebind = $2; } 277 | VAR_SEND_BUFFER_SIZE number 278 { cfg_parser->opt->send_buffer_size = (int)$2; } 279 | VAR_RECEIVE_BUFFER_SIZE number 280 { cfg_parser->opt->receive_buffer_size = (int)$2; } 281 | VAR_DEBUG_MODE boolean 282 { cfg_parser->opt->debug_mode = $2; } 283 | VAR_USE_SYSTEMD boolean 284 { /* ignored, obsolete */ } 285 | VAR_HIDE_VERSION boolean 286 { cfg_parser->opt->hide_version = $2; } 287 | VAR_HIDE_IDENTITY boolean 288 { cfg_parser->opt->hide_identity = $2; } 289 | VAR_DROP_UPDATES boolean 290 { cfg_parser->opt->drop_updates = $2; } 291 | VAR_IP4_ONLY boolean 292 { if($2) { cfg_parser->opt->do_ip4 = 1; cfg_parser->opt->do_ip6 = 0; } } 293 | VAR_IP6_ONLY boolean 294 { if($2) { cfg_parser->opt->do_ip4 = 0; cfg_parser->opt->do_ip6 = 1; } } 295 | VAR_DO_IP4 boolean 296 { cfg_parser->opt->do_ip4 = $2; } 297 | VAR_DO_IP6 boolean 298 { cfg_parser->opt->do_ip6 = $2; } 299 | VAR_DATABASE STRING 300 { /* ignored, obsolete */ } 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, obsolete */ } 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_PROXY_PROTOCOL_PORT number 479 { 480 struct proxy_protocol_port_list* elem = region_alloc_zero( 481 cfg_parser->opt->region, sizeof(*elem)); 482 elem->port = $2; 483 elem->next = cfg_parser->opt->proxy_protocol_port; 484 cfg_parser->opt->proxy_protocol_port = elem; 485 } 486 | VAR_ANSWER_COOKIE boolean 487 { cfg_parser->opt->answer_cookie = $2; } 488 | VAR_COOKIE_SECRET STRING 489 { cfg_parser->opt->cookie_secret = region_strdup(cfg_parser->opt->region, $2); } 490 | VAR_COOKIE_SECRET_FILE STRING 491 { cfg_parser->opt->cookie_secret_file = region_strdup(cfg_parser->opt->region, $2); } 492 | VAR_XFRD_TCP_MAX number 493 { cfg_parser->opt->xfrd_tcp_max = (int)$2; } 494 | VAR_XFRD_TCP_PIPELINE number 495 { cfg_parser->opt->xfrd_tcp_pipeline = (int)$2; } 496 | VAR_CPU_AFFINITY cpus 497 { 498 cfg_parser->opt->cpu_affinity = $2; 499 } 500 | service_cpu_affinity number 501 { 502 if($2 < 0) { 503 yyerror("expected a non-negative number"); 504 YYABORT; 505 } else { 506 struct cpu_map_option *opt, *tail; 507 508 opt = cfg_parser->opt->service_cpu_affinity; 509 while(opt && opt->service != $1) { opt = opt->next; } 510 511 if(opt) { 512 opt->cpu = $2; 513 } else { 514 opt = region_alloc_zero(cfg_parser->opt->region, sizeof(*opt)); 515 opt->service = (int)$1; 516 opt->cpu = (int)$2; 517 518 tail = cfg_parser->opt->service_cpu_affinity; 519 if(tail) { 520 while(tail->next) { tail = tail->next; } 521 tail->next = opt; 522 } else { 523 cfg_parser->opt->service_cpu_affinity = opt; 524 } 525 } 526 } 527 } 528 ; 529 530socket_options: 531 | socket_options socket_option ; 532 533socket_option: 534 VAR_SERVERS STRING 535 { 536 char *tok, *ptr, *str; 537 struct range_option *servers = NULL; 538 long long first, last; 539 540 /* user may specify "0 1", "0" "1", 0 1 or a combination thereof */ 541 for(str = $2; (tok = strtok_r(str, " \t", &ptr)); str = NULL) { 542 struct range_option *opt = 543 region_alloc(cfg_parser->opt->region, sizeof(*opt)); 544 first = last = 0; 545 if(!parse_range(tok, &first, &last)) { 546 yyerror("invalid server range '%s'", tok); 547 YYABORT; 548 } 549 assert(first >= 0); 550 assert(last >= 0); 551 opt->next = NULL; 552 opt->first = (int)first; 553 opt->last = (int)last; 554 if(servers) { 555 servers = servers->next = opt; 556 } else { 557 servers = cfg_parser->ip->servers = opt; 558 } 559 } 560 } 561 | VAR_BINDTODEVICE boolean 562 { cfg_parser->ip->dev = $2; } 563 | VAR_SETFIB number 564 { cfg_parser->ip->fib = $2; } 565 ; 566 567cpus: 568 { $$ = NULL; } 569 | cpus STRING 570 { 571 char *tok, *ptr, *str; 572 struct cpu_option *tail; 573 long long cpu; 574 575 str = $2; 576 $$ = tail = $1; 577 if(tail) { 578 while(tail->next) { tail = tail->next; } 579 } 580 581 /* Users may specify "0 1", "0" "1", 0 1 or a combination thereof. */ 582 for(str = $2; (tok = strtok_r(str, " \t", &ptr)); str = NULL) { 583 struct cpu_option *opt = 584 region_alloc_zero(cfg_parser->opt->region, sizeof(*opt)); 585 cpu = 0; 586 if(!parse_number(tok, &cpu) || cpu < 0) { 587 yyerror("expected a positive number"); 588 YYABORT; 589 } 590 assert(cpu >=0); 591 opt->cpu = (int)cpu; 592 if(tail) { 593 tail->next = opt; 594 tail = opt; 595 } else { 596 $$ = tail = opt; 597 } 598 } 599 } 600 ; 601 602service_cpu_affinity: 603 VAR_XFRD_CPU_AFFINITY 604 { $$ = -1; } 605 | VAR_SERVER_CPU_AFFINITY 606 { 607 if($1 <= 0) { 608 yyerror("invalid server identifier"); 609 YYABORT; 610 } 611 $$ = $1; 612 } 613 ; 614 615dnstap: 616 VAR_DNSTAP dnstap_block ; 617 618dnstap_block: 619 dnstap_block dnstap_option | ; 620 621dnstap_option: 622 VAR_DNSTAP_ENABLE boolean 623 { cfg_parser->opt->dnstap_enable = $2; } 624 | VAR_DNSTAP_SOCKET_PATH STRING 625 { cfg_parser->opt->dnstap_socket_path = region_strdup(cfg_parser->opt->region, $2); } 626 | VAR_DNSTAP_IP STRING 627 { cfg_parser->opt->dnstap_ip = region_strdup(cfg_parser->opt->region, $2); } 628 | VAR_DNSTAP_TLS boolean 629 { cfg_parser->opt->dnstap_tls = $2; } 630 | VAR_DNSTAP_TLS_SERVER_NAME STRING 631 { cfg_parser->opt->dnstap_tls_server_name = region_strdup(cfg_parser->opt->region, $2); } 632 | VAR_DNSTAP_TLS_CERT_BUNDLE STRING 633 { cfg_parser->opt->dnstap_tls_cert_bundle = region_strdup(cfg_parser->opt->region, $2); } 634 | VAR_DNSTAP_TLS_CLIENT_KEY_FILE STRING 635 { cfg_parser->opt->dnstap_tls_client_key_file = region_strdup(cfg_parser->opt->region, $2); } 636 | VAR_DNSTAP_TLS_CLIENT_CERT_FILE STRING 637 { cfg_parser->opt->dnstap_tls_client_cert_file = region_strdup(cfg_parser->opt->region, $2); } 638 | VAR_DNSTAP_SEND_IDENTITY boolean 639 { cfg_parser->opt->dnstap_send_identity = $2; } 640 | VAR_DNSTAP_SEND_VERSION boolean 641 { cfg_parser->opt->dnstap_send_version = $2; } 642 | VAR_DNSTAP_IDENTITY STRING 643 { cfg_parser->opt->dnstap_identity = region_strdup(cfg_parser->opt->region, $2); } 644 | VAR_DNSTAP_VERSION STRING 645 { cfg_parser->opt->dnstap_version = region_strdup(cfg_parser->opt->region, $2); } 646 | VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES boolean 647 { cfg_parser->opt->dnstap_log_auth_query_messages = $2; } 648 | VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES boolean 649 { cfg_parser->opt->dnstap_log_auth_response_messages = $2; } 650 ; 651 652remote_control: 653 VAR_REMOTE_CONTROL remote_control_block ; 654 655remote_control_block: 656 remote_control_block remote_control_option | ; 657 658remote_control_option: 659 VAR_CONTROL_ENABLE boolean 660 { cfg_parser->opt->control_enable = $2; } 661 | VAR_CONTROL_INTERFACE ip_address 662 { 663 struct ip_address_option *ip = cfg_parser->opt->control_interface; 664 if(ip == NULL) { 665 cfg_parser->opt->control_interface = $2; 666 } else { 667 while(ip->next != NULL) { ip = ip->next; } 668 ip->next = $2; 669 } 670 } 671 | VAR_CONTROL_PORT number 672 { 673 if($2 == 0) { 674 yyerror("control port number expected"); 675 } else { 676 cfg_parser->opt->control_port = (int)$2; 677 } 678 } 679 | VAR_SERVER_KEY_FILE STRING 680 { cfg_parser->opt->server_key_file = region_strdup(cfg_parser->opt->region, $2); } 681 | VAR_SERVER_CERT_FILE STRING 682 { cfg_parser->opt->server_cert_file = region_strdup(cfg_parser->opt->region, $2); } 683 | VAR_CONTROL_KEY_FILE STRING 684 { cfg_parser->opt->control_key_file = region_strdup(cfg_parser->opt->region, $2); } 685 | VAR_CONTROL_CERT_FILE STRING 686 { cfg_parser->opt->control_cert_file = region_strdup(cfg_parser->opt->region, $2); } 687 ; 688 689tls_auth: 690 VAR_TLS_AUTH 691 { 692 tls_auth_options_type *tls_auth = tls_auth_options_create(cfg_parser->opt->region); 693 assert(cfg_parser->tls_auth == NULL); 694 cfg_parser->tls_auth = tls_auth; 695 } 696 tls_auth_block 697 { 698 struct tls_auth_options *tls_auth = cfg_parser->tls_auth; 699 if(tls_auth->name == NULL) { 700 yyerror("tls-auth has no name"); 701 } else if(tls_auth->auth_domain_name == NULL) { 702 yyerror("tls-auth %s has no auth-domain-name", tls_auth->name); 703 } else if(tls_auth_options_find(cfg_parser->opt, tls_auth->name)) { 704 yyerror("duplicate tls-auth %s", tls_auth->name); 705 } else { 706 tls_auth_options_insert(cfg_parser->opt, tls_auth); 707 cfg_parser->tls_auth = NULL; 708 } 709 } ; 710 711tls_auth_block: 712 tls_auth_block tls_auth_option | ; 713 714tls_auth_option: 715 VAR_NAME STRING 716 { 717 dname_type *dname; 718 dname = (dname_type *)dname_parse(cfg_parser->opt->region, $2); 719 cfg_parser->tls_auth->name = region_strdup(cfg_parser->opt->region, $2); 720 if(dname == NULL) { 721 yyerror("bad tls-auth name %s", $2); 722 } else { 723 region_recycle(cfg_parser->opt->region, dname, dname_total_size(dname)); 724 } 725 } 726 | VAR_TLS_AUTH_DOMAIN_NAME STRING 727 { 728 cfg_parser->tls_auth->auth_domain_name = region_strdup(cfg_parser->opt->region, $2); 729 } 730 | VAR_TLS_AUTH_CLIENT_CERT STRING 731 { 732 cfg_parser->tls_auth->client_cert = region_strdup(cfg_parser->opt->region, $2); 733 } 734 | VAR_TLS_AUTH_CLIENT_KEY STRING 735 { 736 cfg_parser->tls_auth->client_key = region_strdup(cfg_parser->opt->region, $2); 737 } 738 | VAR_TLS_AUTH_CLIENT_KEY_PW STRING 739 { 740 cfg_parser->tls_auth->client_key_pw = region_strdup(cfg_parser->opt->region, $2); 741 } 742 ; 743 744key: 745 VAR_KEY 746 { 747 key_options_type *key = key_options_create(cfg_parser->opt->region); 748 key->algorithm = region_strdup(cfg_parser->opt->region, "sha256"); 749 assert(cfg_parser->key == NULL); 750 cfg_parser->key = key; 751 } 752 key_block 753 { 754 struct key_options *key = cfg_parser->key; 755 if(key->name == NULL) { 756 yyerror("tsig key has no name"); 757 } else if(key->algorithm == NULL) { 758 yyerror("tsig key %s has no algorithm", key->name); 759 } else if(key->secret == NULL) { 760 yyerror("tsig key %s has no secret blob", key->name); 761 } else if(key_options_find(cfg_parser->opt, key->name)) { 762 yyerror("duplicate tsig key %s", key->name); 763 } else { 764 key_options_insert(cfg_parser->opt, key); 765 cfg_parser->key = NULL; 766 } 767 } ; 768 769key_block: 770 key_block key_option | ; 771 772key_option: 773 VAR_NAME STRING 774 { 775 dname_type *dname; 776 777 dname = (dname_type *)dname_parse(cfg_parser->opt->region, $2); 778 cfg_parser->key->name = region_strdup(cfg_parser->opt->region, $2); 779 if(dname == NULL) { 780 yyerror("bad tsig key name %s", $2); 781 } else { 782 region_recycle(cfg_parser->opt->region, dname, dname_total_size(dname)); 783 } 784 } 785 | VAR_ALGORITHM STRING 786 { 787 if(tsig_get_algorithm_by_name($2) == NULL) { 788 yyerror("bad tsig key algorithm %s", $2); 789 } else { 790 cfg_parser->key->algorithm = region_strdup(cfg_parser->opt->region, $2); 791 } 792 } 793 | VAR_SECRET STRING 794 { 795 uint8_t data[16384]; 796 int size; 797 798 cfg_parser->key->secret = region_strdup(cfg_parser->opt->region, $2); 799 size = b64_pton($2, data, sizeof(data)); 800 if(size == -1) { 801 yyerror("cannot base64 decode tsig secret %s", 802 cfg_parser->key->name? 803 cfg_parser->key->name:""); 804 } else if(size != 0) { 805 memset(data, 0xdd, size); /* wipe secret */ 806 } 807 } ; 808 809 810zone: 811 VAR_ZONE 812 { 813 assert(cfg_parser->pattern == NULL); 814 assert(cfg_parser->zone == NULL); 815 cfg_parser->zone = zone_options_create(cfg_parser->opt->region); 816 cfg_parser->zone->part_of_config = 1; 817 cfg_parser->zone->pattern = cfg_parser->pattern = 818 pattern_options_create(cfg_parser->opt->region); 819 cfg_parser->zone->pattern->implicit = 1; 820 } 821 zone_block 822 { 823 assert(cfg_parser->zone != NULL); 824 if(cfg_parser->zone->name == NULL) { 825 yyerror("zone has no name"); 826 } else if(!nsd_options_insert_zone(cfg_parser->opt, cfg_parser->zone)) { 827 yyerror("duplicate zone %s", cfg_parser->zone->name); 828 } else if(!nsd_options_insert_pattern(cfg_parser->opt, cfg_parser->zone->pattern)) { 829 yyerror("duplicate pattern %s", cfg_parser->zone->pattern->pname); 830 } 831 cfg_parser->pattern = NULL; 832 cfg_parser->zone = NULL; 833 } ; 834 835zone_block: 836 zone_block zone_option | ; 837 838zone_option: 839 VAR_NAME STRING 840 { 841 const char *marker = PATTERN_IMPLICIT_MARKER; 842 char *pname = region_alloc(cfg_parser->opt->region, strlen($2) + strlen(marker) + 1); 843 memmove(pname, marker, strlen(marker)); 844 memmove(pname + strlen(marker), $2, strlen($2) + 1); 845 cfg_parser->zone->pattern->pname = pname; 846 cfg_parser->zone->name = region_strdup(cfg_parser->opt->region, $2); 847 if(pattern_options_find(cfg_parser->opt, pname)) { 848 yyerror("zone %s cannot be created because implicit pattern %s " 849 "already exists", $2, pname); 850 } 851 } 852 | pattern_or_zone_option ; 853 854pattern: 855 VAR_PATTERN 856 { 857 assert(cfg_parser->pattern == NULL); 858 cfg_parser->pattern = pattern_options_create(cfg_parser->opt->region); 859 } 860 pattern_block 861 { 862 pattern_options_type *pattern = cfg_parser->pattern; 863 if(pattern->pname == NULL) { 864 yyerror("pattern has no name"); 865 } else if(!nsd_options_insert_pattern(cfg_parser->opt, pattern)) { 866 yyerror("duplicate pattern %s", pattern->pname); 867 } 868 cfg_parser->pattern = NULL; 869 } ; 870 871pattern_block: 872 pattern_block pattern_option | ; 873 874pattern_option: 875 VAR_NAME STRING 876 { 877 if(strchr($2, ' ')) { 878 yyerror("space is not allowed in pattern name: '%s'", $2); 879 } 880 cfg_parser->pattern->pname = region_strdup(cfg_parser->opt->region, $2); 881 } 882 | pattern_or_zone_option ; 883 884pattern_or_zone_option: 885 VAR_RRL_WHITELIST STRING 886 { 887#ifdef RATELIMIT 888 cfg_parser->pattern->rrl_whitelist |= rrlstr2type($2); 889#endif 890 } 891 | VAR_ZONEFILE STRING 892 { cfg_parser->pattern->zonefile = region_strdup(cfg_parser->opt->region, $2); } 893 | VAR_ZONESTATS STRING 894 { cfg_parser->pattern->zonestats = region_strdup(cfg_parser->opt->region, $2); } 895 | VAR_SIZE_LIMIT_XFR number 896 { 897 if($2 > 0) { 898 cfg_parser->pattern->size_limit_xfr = (int)$2; 899 } else { 900 yyerror("expected a number greater than zero"); 901 } 902 } 903 | VAR_MULTI_MASTER_CHECK boolean 904 { cfg_parser->pattern->multi_master_check = (int)$2; } 905 | VAR_INCLUDE_PATTERN STRING 906 { config_apply_pattern(cfg_parser->pattern, $2); } 907 | VAR_REQUEST_XFR STRING STRING 908 { 909 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 910 if(acl->blocked) 911 yyerror("blocked address used for request-xfr"); 912 if(acl->rangetype != acl_range_single) 913 yyerror("address range used for request-xfr"); 914 append_acl(&cfg_parser->pattern->request_xfr, acl); 915 } 916 tlsauth_option 917 { } 918 | VAR_REQUEST_XFR VAR_AXFR STRING STRING 919 { 920 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $3, $4); 921 acl->use_axfr_only = 1; 922 if(acl->blocked) 923 yyerror("blocked address used for request-xfr"); 924 if(acl->rangetype != acl_range_single) 925 yyerror("address range used for request-xfr"); 926 append_acl(&cfg_parser->pattern->request_xfr, acl); 927 } 928 tlsauth_option 929 { } 930 | VAR_REQUEST_XFR VAR_UDP STRING STRING 931 { 932 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $3, $4); 933 acl->allow_udp = 1; 934 if(acl->blocked) 935 yyerror("blocked address used for request-xfr"); 936 if(acl->rangetype != acl_range_single) 937 yyerror("address range used for request-xfr"); 938 append_acl(&cfg_parser->pattern->request_xfr, acl); 939 } 940 | VAR_ALLOW_NOTIFY STRING STRING 941 { 942 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 943 append_acl(&cfg_parser->pattern->allow_notify, acl); 944 } 945 | VAR_NOTIFY STRING STRING 946 { 947 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 948 if(acl->blocked) 949 yyerror("blocked address used for notify"); 950 if(acl->rangetype != acl_range_single) 951 yyerror("address range used for notify"); 952 append_acl(&cfg_parser->pattern->notify, acl); 953 } 954 | VAR_PROVIDE_XFR STRING STRING 955 { 956 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 957 append_acl(&cfg_parser->pattern->provide_xfr, acl); 958 } 959 | VAR_ALLOW_QUERY STRING STRING 960 { 961 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); 962 append_acl(&cfg_parser->pattern->allow_query, acl); 963 } 964 | VAR_OUTGOING_INTERFACE STRING 965 { 966 acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, "NOKEY"); 967 append_acl(&cfg_parser->pattern->outgoing_interface, acl); 968 } 969 | VAR_ALLOW_AXFR_FALLBACK boolean 970 { 971 cfg_parser->pattern->allow_axfr_fallback = $2; 972 cfg_parser->pattern->allow_axfr_fallback_is_default = 0; 973 } 974 | VAR_NOTIFY_RETRY number 975 { 976 cfg_parser->pattern->notify_retry = $2; 977 cfg_parser->pattern->notify_retry_is_default = 0; 978 } 979 | VAR_MAX_REFRESH_TIME number 980 { 981 cfg_parser->pattern->max_refresh_time = $2; 982 cfg_parser->pattern->max_refresh_time_is_default = 0; 983 } 984 | VAR_MIN_REFRESH_TIME number 985 { 986 cfg_parser->pattern->min_refresh_time = $2; 987 cfg_parser->pattern->min_refresh_time_is_default = 0; 988 } 989 | VAR_MAX_RETRY_TIME number 990 { 991 cfg_parser->pattern->max_retry_time = $2; 992 cfg_parser->pattern->max_retry_time_is_default = 0; 993 } 994 | VAR_MIN_RETRY_TIME number 995 { 996 cfg_parser->pattern->min_retry_time = $2; 997 cfg_parser->pattern->min_retry_time_is_default = 0; 998 } 999 | VAR_MIN_EXPIRE_TIME STRING 1000 { 1001 long long num; 1002 uint8_t expr; 1003 1004 if (!parse_expire_expr($2, &num, &expr)) { 1005 yyerror("expected an expire time in seconds or \"refresh+retry+1\""); 1006 YYABORT; /* trigger a parser error */ 1007 } 1008 cfg_parser->pattern->min_expire_time = num; 1009 cfg_parser->pattern->min_expire_time_expr = expr; 1010 } 1011 | VAR_STORE_IXFR boolean 1012 { 1013 cfg_parser->pattern->store_ixfr = $2; 1014 cfg_parser->pattern->store_ixfr_is_default = 0; 1015 } 1016 | VAR_IXFR_SIZE number 1017 { 1018 cfg_parser->pattern->ixfr_size = $2; 1019 cfg_parser->pattern->ixfr_size_is_default = 0; 1020 } 1021 | VAR_IXFR_NUMBER number 1022 { 1023 cfg_parser->pattern->ixfr_number = $2; 1024 cfg_parser->pattern->ixfr_number_is_default = 0; 1025 } 1026 | VAR_CREATE_IXFR boolean 1027 { 1028 cfg_parser->pattern->create_ixfr = $2; 1029 cfg_parser->pattern->create_ixfr_is_default = 0; 1030 } 1031 | VAR_VERIFY_ZONE boolean 1032 { cfg_parser->pattern->verify_zone = $2; } 1033 | VAR_VERIFIER command 1034 { cfg_parser->pattern->verifier = $2; } 1035 | VAR_VERIFIER_FEED_ZONE boolean 1036 { cfg_parser->pattern->verifier_feed_zone = $2; } 1037 | VAR_VERIFIER_TIMEOUT number 1038 { cfg_parser->pattern->verifier_timeout = $2; } ; 1039 1040verify: 1041 VAR_VERIFY verify_block ; 1042 1043verify_block: 1044 verify_block verify_option | ; 1045 1046verify_option: 1047 VAR_ENABLE boolean 1048 { cfg_parser->opt->verify_enable = $2; } 1049 | VAR_IP_ADDRESS ip_address 1050 { 1051 struct ip_address_option *ip = cfg_parser->opt->verify_ip_addresses; 1052 if(!ip) { 1053 cfg_parser->opt->verify_ip_addresses = $2; 1054 } else { 1055 while(ip->next) { ip = ip->next; } 1056 ip->next = $2; 1057 } 1058 } 1059 | VAR_PORT number 1060 { 1061 /* port number, stored as a string */ 1062 char buf[16]; 1063 (void)snprintf(buf, sizeof(buf), "%lld", $2); 1064 cfg_parser->opt->verify_port = region_strdup(cfg_parser->opt->region, buf); 1065 } 1066 | VAR_VERIFY_ZONES boolean 1067 { cfg_parser->opt->verify_zones = $2; } 1068 | VAR_VERIFIER command 1069 { cfg_parser->opt->verifier = $2; } 1070 | VAR_VERIFIER_COUNT number 1071 { cfg_parser->opt->verifier_count = (int)$2; } 1072 | VAR_VERIFIER_TIMEOUT number 1073 { cfg_parser->opt->verifier_timeout = (int)$2; } 1074 | VAR_VERIFIER_FEED_ZONE boolean 1075 { cfg_parser->opt->verifier_feed_zone = $2; } ; 1076 1077command: 1078 STRING arguments 1079 { 1080 char **argv; 1081 size_t argc = 1; 1082 for(struct component *i = $2; i; i = i->next) { 1083 argc++; 1084 } 1085 argv = region_alloc_zero( 1086 cfg_parser->opt->region, (argc + 1) * sizeof(char *)); 1087 argc = 0; 1088 argv[argc++] = $1; 1089 for(struct component *j, *i = $2; i; i = j) { 1090 j = i->next; 1091 argv[argc++] = i->str; 1092 region_recycle(cfg_parser->opt->region, i, sizeof(*i)); 1093 } 1094 $$ = argv; 1095 } ; 1096 1097arguments: 1098 { $$ = NULL; } 1099 | arguments STRING 1100 { 1101 struct component *comp = region_alloc_zero( 1102 cfg_parser->opt->region, sizeof(*comp)); 1103 comp->str = region_strdup(cfg_parser->opt->region, $2); 1104 if($1) { 1105 struct component *tail = $1; 1106 while(tail->next) { 1107 tail = tail->next; 1108 } 1109 tail->next = comp; 1110 $$ = $1; 1111 } else { 1112 $$ = comp; 1113 } 1114 } ; 1115 1116ip_address: 1117 STRING 1118 { 1119 struct ip_address_option *ip = region_alloc_zero( 1120 cfg_parser->opt->region, sizeof(*ip)); 1121 ip->address = region_strdup(cfg_parser->opt->region, $1); 1122 ip->fib = -1; 1123 $$ = ip; 1124 } ; 1125 1126number: 1127 STRING 1128 { 1129 if(!parse_number($1, &$$)) { 1130 yyerror("expected a number"); 1131 YYABORT; /* trigger a parser error */ 1132 } 1133 } ; 1134 1135boolean: 1136 STRING 1137 { 1138 if(!parse_boolean($1, &$$)) { 1139 yyerror("expected yes or no"); 1140 YYABORT; /* trigger a parser error */ 1141 } 1142 } ; 1143 1144tlsauth_option: 1145 | STRING 1146 { char *tls_auth_name = region_strdup(cfg_parser->opt->region, $1); 1147 add_to_last_acl(&cfg_parser->pattern->request_xfr, tls_auth_name);} ; 1148 1149%% 1150 1151static void 1152append_acl(struct acl_options **list, struct acl_options *acl) 1153{ 1154 assert(list != NULL); 1155 1156 if(*list == NULL) { 1157 *list = acl; 1158 } else { 1159 struct acl_options *tail = *list; 1160 while(tail->next != NULL) 1161 tail = tail->next; 1162 tail->next = acl; 1163 } 1164} 1165 1166static void 1167add_to_last_acl(struct acl_options **list, char *tls_auth_name) 1168{ 1169 struct acl_options *tail = *list; 1170 assert(list != NULL); 1171 assert(*list != NULL); 1172 while(tail->next != NULL) 1173 tail = tail->next; 1174 tail->tls_auth_name = tls_auth_name; 1175} 1176 1177static int 1178parse_boolean(const char *str, int *bln) 1179{ 1180 if(strcmp(str, "yes") == 0) { 1181 *bln = 1; 1182 } else if(strcmp(str, "no") == 0) { 1183 *bln = 0; 1184 } else { 1185 return 0; 1186 } 1187 1188 return 1; 1189} 1190 1191static int 1192parse_expire_expr(const char *str, long long *num, uint8_t *expr) 1193{ 1194 if(parse_number(str, num)) { 1195 *expr = EXPIRE_TIME_HAS_VALUE; 1196 return 1; 1197 } 1198 if(strcmp(str, REFRESHPLUSRETRYPLUS1_STR) == 0) { 1199 *num = 0; 1200 *expr = REFRESHPLUSRETRYPLUS1; 1201 return 1; 1202 } 1203 return 0; 1204} 1205 1206static int 1207parse_number(const char *str, long long *num) 1208{ 1209 /* ensure string consists entirely of digits */ 1210 size_t pos = 0; 1211 while(str[pos] >= '0' && str[pos] <= '9') { 1212 pos++; 1213 } 1214 1215 if(pos != 0 && str[pos] == '\0') { 1216 *num = strtoll(str, NULL, 10); 1217 return 1; 1218 } 1219 1220 return 0; 1221} 1222 1223static int 1224parse_range(const char *str, long long *low, long long *high) 1225{ 1226 const char *ptr = str; 1227 long long num[2]; 1228 1229 /* require range to begin with a number */ 1230 if(*ptr < '0' || *ptr > '9') { 1231 return 0; 1232 } 1233 1234 num[0] = strtoll(ptr, (char **)&ptr, 10); 1235 1236 /* require number to be followed by nothing at all or a dash */ 1237 if(*ptr == '\0') { 1238 *low = num[0]; 1239 *high = num[0]; 1240 return 1; 1241 } else if(*ptr != '-') { 1242 return 0; 1243 } 1244 1245 ++ptr; 1246 /* require dash to be followed by a number */ 1247 if(*ptr < '0' || *ptr > '9') { 1248 return 0; 1249 } 1250 1251 num[1] = strtoll(ptr, (char **)&ptr, 10); 1252 1253 /* require number to be followed by nothing at all */ 1254 if(*ptr == '\0') { 1255 if(num[0] < num[1]) { 1256 *low = num[0]; 1257 *high = num[1]; 1258 } else { 1259 *low = num[1]; 1260 *high = num[0]; 1261 } 1262 return 1; 1263 } 1264 1265 return 0; 1266} 1267