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_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
227 blocks:
228 /* may be empty */
229 | blocks block ;
230
231 block:
232 server
233 | dnstap
234 | remote_control
235 | key
236 | tls_auth
237 | pattern
238 | zone
239 | verify ;
240
241 server:
242 VAR_SERVER server_block ;
243
244 server_block:
245 server_block server_option | ;
246
247 server_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
530 socket_options:
531 | socket_options socket_option ;
532
533 socket_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
567 cpus:
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
602 service_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
615 dnstap:
616 VAR_DNSTAP dnstap_block ;
617
618 dnstap_block:
619 dnstap_block dnstap_option | ;
620
621 dnstap_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
652 remote_control:
653 VAR_REMOTE_CONTROL remote_control_block ;
654
655 remote_control_block:
656 remote_control_block remote_control_option | ;
657
658 remote_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
689 tls_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
711 tls_auth_block:
712 tls_auth_block tls_auth_option | ;
713
714 tls_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
744 key:
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
769 key_block:
770 key_block key_option | ;
771
772 key_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
810 zone:
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
835 zone_block:
836 zone_block zone_option | ;
837
838 zone_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
854 pattern:
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
871 pattern_block:
872 pattern_block pattern_option | ;
873
874 pattern_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
884 pattern_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
1040 verify:
1041 VAR_VERIFY verify_block ;
1042
1043 verify_block:
1044 verify_block verify_option | ;
1045
1046 verify_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
1077 command:
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
1097 arguments:
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
1116 ip_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
1126 number:
1127 STRING
1128 {
1129 if(!parse_number($1, &$$)) {
1130 yyerror("expected a number");
1131 YYABORT; /* trigger a parser error */
1132 }
1133 } ;
1134
1135 boolean:
1136 STRING
1137 {
1138 if(!parse_boolean($1, &$$)) {
1139 yyerror("expected yes or no");
1140 YYABORT; /* trigger a parser error */
1141 }
1142 } ;
1143
1144 tlsauth_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
1151 static void
1152 append_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
1166 static void
add_to_last_acl(struct acl_options ** list,char * tls_auth_name)1167 add_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
1177 static int
parse_boolean(const char * str,int * bln)1178 parse_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
1191 static int
parse_expire_expr(const char * str,long long * num,uint8_t * expr)1192 parse_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
1206 static int
parse_number(const char * str,long long * num)1207 parse_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
1223 static int
parse_range(const char * str,long long * low,long long * high)1224 parse_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