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