xref: /netbsd/external/bsd/nsd/dist/options.c (revision cb958623)
1 /*
2  * options.c -- options functions.
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 #include "config.h"
10 #include <string.h>
11 #include <stdio.h>
12 #include <sys/stat.h>
13 #include <errno.h>
14 #ifdef HAVE_IFADDRS_H
15 #include <ifaddrs.h>
16 #endif
17 #include "options.h"
18 #include "query.h"
19 #include "tsig.h"
20 #include "ixfr.h"
21 #include "difffile.h"
22 #include "rrl.h"
23 #include "bitset.h"
24 
25 #include "configparser.h"
26 config_parser_state_type* cfg_parser = 0;
27 extern FILE* c_in, *c_out;
28 int c_parse(void);
29 int c_lex(void);
30 int c_wrap(void);
31 int c_lex_destroy(void);
32 extern char* c_text;
33 
34 static int
rbtree_strcmp(const void * p1,const void * p2)35 rbtree_strcmp(const void* p1, const void* p2)
36 {
37 	if(p1 == NULL && p2 == NULL) return 0;
38 	if(p1 == NULL) return -1;
39 	if(p2 == NULL) return 1;
40 	return strcmp((const char*)p1, (const char*)p2);
41 }
42 
43 struct nsd_options*
nsd_options_create(region_type * region)44 nsd_options_create(region_type* region)
45 {
46 	struct nsd_options* opt;
47 	opt = (struct nsd_options*)region_alloc(region, sizeof(
48 		struct nsd_options));
49 	opt->region = region;
50 	opt->zone_options = rbtree_create(region,
51 		(int (*)(const void *, const void *)) dname_compare);
52 	opt->configfile = NULL;
53 	opt->zonestatnames = rbtree_create(opt->region, rbtree_strcmp);
54 	opt->patterns = rbtree_create(region, rbtree_strcmp);
55 	opt->keys = rbtree_create(region, rbtree_strcmp);
56 	opt->tls_auths = rbtree_create(region, rbtree_strcmp);
57 	opt->ip_addresses = NULL;
58 	opt->ip_transparent = 0;
59 	opt->ip_freebind = 0;
60 	opt->send_buffer_size = 0;
61 	opt->receive_buffer_size = 0;
62 	opt->debug_mode = 0;
63 	opt->verbosity = 0;
64 	opt->hide_version = 0;
65 	opt->hide_identity = 0;
66 	opt->drop_updates = 0;
67 	opt->do_ip4 = 1;
68 	opt->do_ip6 = 1;
69 	opt->database = DBFILE;
70 	opt->identity = 0;
71 	opt->version = 0;
72 	opt->nsid = 0;
73 	opt->logfile = 0;
74 	opt->log_only_syslog = 0;
75 	opt->log_time_ascii = 1;
76 	opt->round_robin = 0; /* also packet.h::round_robin */
77 	opt->minimal_responses = 0; /* also packet.h::minimal_responses */
78 	opt->confine_to_zone = 0;
79 	opt->refuse_any = 0;
80 	opt->server_count = 1;
81 	opt->cpu_affinity = NULL;
82 	opt->service_cpu_affinity = NULL;
83 	opt->tcp_count = 100;
84 	opt->tcp_reject_overflow = 0;
85 	opt->tcp_query_count = 0;
86 	opt->tcp_timeout = TCP_TIMEOUT;
87 	opt->tcp_mss = 0;
88 	opt->outgoing_tcp_mss = 0;
89 	opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN;
90 	opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN;
91 	opt->pidfile = PIDFILE;
92 	opt->port = UDP_PORT;
93 /* deprecated?	opt->port = TCP_PORT; */
94 	opt->reuseport = 0;
95 	opt->xfrd_tcp_max = 128;
96 	opt->xfrd_tcp_pipeline = 128;
97 	opt->statistics = 0;
98 	opt->chroot = 0;
99 	opt->username = USER;
100 	opt->zonesdir = ZONESDIR;
101 	opt->xfrdfile = XFRDFILE;
102 	opt->xfrdir = XFRDIR;
103 	opt->zonelistfile = ZONELISTFILE;
104 #ifdef RATELIMIT
105 	opt->rrl_size = RRL_BUCKETS;
106 	opt->rrl_slip = RRL_SLIP;
107 	opt->rrl_ipv4_prefix_length = RRL_IPV4_PREFIX_LENGTH;
108 	opt->rrl_ipv6_prefix_length = RRL_IPV6_PREFIX_LENGTH;
109 #  ifdef RATELIMIT_DEFAULT_OFF
110 	opt->rrl_ratelimit = 0;
111 	opt->rrl_whitelist_ratelimit = 0;
112 #  else
113 	opt->rrl_ratelimit = RRL_LIMIT/2;
114 	opt->rrl_whitelist_ratelimit = RRL_WLIST_LIMIT/2;
115 #  endif
116 #endif
117 #ifdef USE_DNSTAP
118 	opt->dnstap_enable = 0;
119 	opt->dnstap_socket_path = DNSTAP_SOCKET_PATH;
120 	opt->dnstap_send_identity = 0;
121 	opt->dnstap_send_version = 0;
122 	opt->dnstap_identity = NULL;
123 	opt->dnstap_version = NULL;
124 	opt->dnstap_log_auth_query_messages = 0;
125 	opt->dnstap_log_auth_response_messages = 0;
126 #endif
127 	opt->zonefiles_check = 1;
128 	if(opt->database == NULL || opt->database[0] == 0)
129 		opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL;
130 	else	opt->zonefiles_write = 0;
131 	opt->xfrd_reload_timeout = 1;
132 	opt->tls_service_key = NULL;
133 	opt->tls_service_ocsp = NULL;
134 	opt->tls_service_pem = NULL;
135 	opt->tls_port = TLS_PORT;
136 	opt->tls_cert_bundle = NULL;
137 	opt->answer_cookie = 0;
138 	opt->cookie_secret = NULL;
139 	opt->cookie_secret_file = CONFIGDIR"/nsd_cookiesecrets.txt";
140 	opt->control_enable = 0;
141 	opt->control_interface = NULL;
142 	opt->control_port = NSD_CONTROL_PORT;
143 	opt->server_key_file = CONFIGDIR"/nsd_server.key";
144 	opt->server_cert_file = CONFIGDIR"/nsd_server.pem";
145 	opt->control_key_file = CONFIGDIR"/nsd_control.key";
146 	opt->control_cert_file = CONFIGDIR"/nsd_control.pem";
147 
148 	opt->verify_enable = 0;
149 	opt->verify_ip_addresses = NULL;
150 	opt->verify_port = VERIFY_PORT;
151 	opt->verify_zones = 1;
152 	opt->verifier = NULL;
153 	opt->verifier_count = 1;
154 	opt->verifier_feed_zone = 1;
155 	opt->verifier_timeout = 0;
156 
157 	return opt;
158 }
159 
160 int
nsd_options_insert_zone(struct nsd_options * opt,struct zone_options * zone)161 nsd_options_insert_zone(struct nsd_options* opt, struct zone_options* zone)
162 {
163 	/* create dname for lookup */
164 	const dname_type* dname = dname_parse(opt->region, zone->name);
165 	if(!dname)
166 		return 0;
167 	zone->node.key = dname;
168 	if(!rbtree_insert(opt->zone_options, (rbnode_type*)zone))
169 		return 0;
170 	return 1;
171 }
172 
173 int
nsd_options_insert_pattern(struct nsd_options * opt,struct pattern_options * pat)174 nsd_options_insert_pattern(struct nsd_options* opt,
175 	struct pattern_options* pat)
176 {
177 	if(!pat->pname)
178 		return 0;
179 	pat->node.key = pat->pname;
180 	if(!rbtree_insert(opt->patterns, (rbnode_type*)pat))
181 		return 0;
182 	return 1;
183 }
184 
185 void
warn_if_directory(const char * filetype,FILE * f,const char * fname)186 warn_if_directory(const char* filetype, FILE* f, const char* fname)
187 {
188 	if(fileno(f) != -1) {
189 		struct stat st;
190 		memset(&st, 0, sizeof(st));
191 		if(fstat(fileno(f), &st) != -1) {
192 			if(S_ISDIR(st.st_mode)) {
193 				log_msg(LOG_WARNING, "trying to read %s but it is a directory: %s", filetype, fname);
194 			}
195 		}
196 	}
197 }
198 
199 int
parse_options_file(struct nsd_options * opt,const char * file,void (* err)(void *,const char *),void * err_arg)200 parse_options_file(struct nsd_options* opt, const char* file,
201 	void (*err)(void*,const char*), void* err_arg)
202 {
203 	FILE *in = 0;
204 	struct pattern_options* pat;
205 	struct acl_options* acl;
206 
207 	if(!cfg_parser) {
208 		cfg_parser = (config_parser_state_type*)region_alloc(
209 			opt->region, sizeof(config_parser_state_type));
210 		cfg_parser->chroot = 0;
211 	}
212 	cfg_parser->err = err;
213 	cfg_parser->err_arg = err_arg;
214 	cfg_parser->filename = (char*)file;
215 	cfg_parser->line = 1;
216 	cfg_parser->errors = 0;
217 	cfg_parser->opt = opt;
218 	cfg_parser->pattern = NULL;
219 	cfg_parser->zone = NULL;
220 	cfg_parser->key = NULL;
221 	cfg_parser->tls_auth = NULL;
222 
223 	in = fopen(cfg_parser->filename, "r");
224 	if(!in) {
225 		if(err) {
226 			char m[MAXSYSLOGMSGLEN];
227 			snprintf(m, sizeof(m), "Could not open %s: %s\n",
228 				file, strerror(errno));
229 			err(err_arg, m);
230 		} else {
231 			fprintf(stderr, "Could not open %s: %s\n",
232 				file, strerror(errno));
233 		}
234 		return 0;
235 	}
236 	warn_if_directory("configfile", in, file);
237 	c_in = in;
238 	c_parse();
239 	fclose(in);
240 
241 	opt->configfile = region_strdup(opt->region, file);
242 
243 	RBTREE_FOR(pat, struct pattern_options*, opt->patterns)
244 	{
245 		/* lookup keys for acls */
246 		for(acl=pat->allow_notify; acl; acl=acl->next)
247 		{
248 			if(acl->nokey || acl->blocked)
249 				continue;
250 			acl->key_options = key_options_find(opt, acl->key_name);
251 			if(!acl->key_options)
252 				c_error("key %s in pattern %s could not be found",
253 					acl->key_name, pat->pname);
254 		}
255 		for(acl=pat->notify; acl; acl=acl->next)
256 		{
257 			if(acl->nokey || acl->blocked)
258 				continue;
259 			acl->key_options = key_options_find(opt, acl->key_name);
260 			if(!acl->key_options)
261 				c_error("key %s in pattern %s could not be found",
262 					acl->key_name, pat->pname);
263 		}
264 		for(acl=pat->request_xfr; acl; acl=acl->next)
265 		{
266 			/* Find tls_auth */
267 			if (!acl->tls_auth_name)
268 				; /* pass */
269 			else if (!(acl->tls_auth_options =
270 			                tls_auth_options_find(opt, acl->tls_auth_name)))
271 				c_error("tls_auth %s in pattern %s could not be found",
272 						acl->tls_auth_name, pat->pname);
273 			/* Find key */
274 			if(acl->nokey || acl->blocked)
275 				continue;
276 			acl->key_options = key_options_find(opt, acl->key_name);
277 			if(!acl->key_options)
278 				c_error("key %s in pattern %s could not be found",
279 					acl->key_name, pat->pname);
280 		}
281 		for(acl=pat->provide_xfr; acl; acl=acl->next)
282 		{
283 			if(acl->nokey || acl->blocked)
284 				continue;
285 			acl->key_options = key_options_find(opt, acl->key_name);
286 			if(!acl->key_options)
287 				c_error("key %s in pattern %s could not be found",
288 					acl->key_name, pat->pname);
289 		}
290 		for(acl=pat->allow_query; acl; acl=acl->next)
291 		{
292 			if(acl->nokey || acl->blocked)
293 				continue;
294 			acl->key_options = key_options_find(opt, acl->key_name);
295 			if(!acl->key_options)
296 				c_error("key %s in pattern %s could not be found",
297 					acl->key_name, pat->pname);
298 		}
299 	}
300 
301 	if(cfg_parser->errors > 0)
302 	{
303 		if(err) {
304 			char m[MAXSYSLOGMSGLEN];
305 			snprintf(m, sizeof(m), "read %s failed: %d errors in "
306 				"configuration file\n", file,
307 				cfg_parser->errors);
308 			err(err_arg, m);
309 		} else {
310 			fprintf(stderr, "read %s failed: %d errors in "
311 				"configuration file\n", file,
312 				cfg_parser->errors);
313 		}
314 		return 0;
315 	}
316 	return 1;
317 }
318 
options_zonestatnames_create(struct nsd_options * opt)319 void options_zonestatnames_create(struct nsd_options* opt)
320 {
321 	struct zone_options* zopt;
322 	/* allocate "" as zonestat 0, for zones without a zonestat */
323 	if(!rbtree_search(opt->zonestatnames, "")) {
324 		struct zonestatname* n;
325 		n = (struct zonestatname*)region_alloc_zero(opt->region,
326 			sizeof(*n));
327 		n->node.key = region_strdup(opt->region, "");
328 		if(!n->node.key) {
329 			log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
330 			exit(1);
331 		}
332 		n->id = (unsigned)(opt->zonestatnames->count);
333 		rbtree_insert(opt->zonestatnames, (rbnode_type*)n);
334 	}
335 	RBTREE_FOR(zopt, struct zone_options*, opt->zone_options) {
336 		/* insert into tree, so that when read in later id exists */
337 		(void)getzonestatid(opt, zopt);
338 	}
339 }
340 
341 #define ZONELIST_HEADER "# NSD zone list\n# name pattern\n"
342 static int
comp_zonebucket(const void * a,const void * b)343 comp_zonebucket(const void* a, const void* b)
344 {
345 	/* the line size is much smaller than max-int, and positive,
346 	 * so the subtraction works */
347 	return *(const int*)b - *(const int*)a;
348 }
349 
350 /* insert free entry into zonelist free buckets */
351 static void
zone_list_free_insert(struct nsd_options * opt,int linesize,off_t off)352 zone_list_free_insert(struct nsd_options* opt, int linesize, off_t off)
353 {
354 	struct zonelist_free* e;
355 	struct zonelist_bucket* b = (struct zonelist_bucket*)rbtree_search(
356 		opt->zonefree, &linesize);
357 	if(!b) {
358 		b = region_alloc_zero(opt->region, sizeof(*b));
359 		b->linesize = linesize;
360 		b->node = *RBTREE_NULL;
361 		b->node.key = &b->linesize;
362 		rbtree_insert(opt->zonefree, &b->node);
363 	}
364 	e = (struct zonelist_free*)region_alloc_zero(opt->region, sizeof(*e));
365 	e->next = b->list;
366 	b->list = e;
367 	e->off = off;
368 	opt->zonefree_number++;
369 }
370 
371 struct zone_options*
zone_list_zone_insert(struct nsd_options * opt,const char * nm,const char * patnm,int linesize,off_t off)372 zone_list_zone_insert(struct nsd_options* opt, const char* nm,
373 	const char* patnm, int linesize, off_t off)
374 {
375 	struct pattern_options* pat = pattern_options_find(opt, patnm);
376 	struct zone_options* zone;
377 	if(!pat) {
378 		log_msg(LOG_ERR, "pattern does not exist for zone %s "
379 			"pattern %s", nm, patnm);
380 		return NULL;
381 	}
382 	zone = zone_options_create(opt->region);
383 	zone->part_of_config = 0;
384 	zone->name = region_strdup(opt->region, nm);
385 	zone->linesize = linesize;
386 	zone->off = off;
387 	zone->pattern = pat;
388 	if(!nsd_options_insert_zone(opt, zone)) {
389 		log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' "
390 			"pattern %s", nm, patnm);
391 		region_recycle(opt->region, (void*)zone->name, strlen(nm)+1);
392 		region_recycle(opt->region, zone, sizeof(*zone));
393 		return NULL;
394 	}
395 	return zone;
396 }
397 
398 int
parse_zone_list_file(struct nsd_options * opt)399 parse_zone_list_file(struct nsd_options* opt)
400 {
401 	/* zonelist looks like this:
402 	# name pattern
403 	add example.com master
404 	del example.net slave
405 	add foo.bar.nl slave
406 	add rutabaga.uk config
407 	*/
408 	char hdr[64];
409 	char buf[1024];
410 
411 	/* create empty data structures */
412 	opt->zonefree = rbtree_create(opt->region, comp_zonebucket);
413 	opt->zonelist = NULL;
414 	opt->zonefree_number = 0;
415 	opt->zonelist_off = 0;
416 
417 	/* try to open the zonelist file, an empty or nonexist file is OK */
418 	opt->zonelist = fopen(opt->zonelistfile, "r+");
419 	if(!opt->zonelist) {
420 		if(errno == ENOENT)
421 			return 1; /* file does not exist, it is created later */
422 		log_msg(LOG_ERR, "could not open zone list %s: %s", opt->zonelistfile,
423 			strerror(errno));
424 		return 0;
425 	}
426 	/* read header */
427 	hdr[strlen(ZONELIST_HEADER)] = 0;
428 	if(fread(hdr, 1, strlen(ZONELIST_HEADER), opt->zonelist) !=
429 		strlen(ZONELIST_HEADER) || strncmp(hdr, ZONELIST_HEADER,
430 		strlen(ZONELIST_HEADER)) != 0) {
431 		log_msg(LOG_ERR, "zone list %s contains bad header\n", opt->zonelistfile);
432 		fclose(opt->zonelist);
433 		opt->zonelist = NULL;
434 		return 0;
435 	}
436 	buf[sizeof(buf)-1]=0;
437 
438 	/* read entries in file */
439 	while(fgets(buf, sizeof(buf), opt->zonelist)) {
440 		/* skip comments and empty lines */
441 		if(buf[0] == 0 || buf[0] == '\n' || buf[0] == '#')
442 			continue;
443 		if(strncmp(buf, "add ", 4) == 0) {
444 			int linesize = strlen(buf);
445 			/* parse the 'add' line */
446 			/* pick last space on the line, so that the domain
447 			 * name can have a space in it (but not the pattern)*/
448 			char* space = strrchr(buf+4, ' ');
449 			char* nm, *patnm;
450 			if(!space) {
451 				/* parse error */
452 				log_msg(LOG_ERR, "parse error in %s: '%s'",
453 					opt->zonelistfile, buf);
454 				continue;
455 			}
456 			nm = buf+4;
457 			*space = 0;
458 			patnm = space+1;
459 			if(linesize && buf[linesize-1] == '\n')
460 				buf[linesize-1] = 0;
461 
462 			/* store offset and line size for zone entry */
463 			/* and create zone entry in zonetree */
464 			(void)zone_list_zone_insert(opt, nm, patnm, linesize,
465 				ftello(opt->zonelist)-linesize);
466 		} else if(strncmp(buf, "del ", 4) == 0) {
467 			/* store offset and line size for deleted entry */
468 			int linesize = strlen(buf);
469 			zone_list_free_insert(opt, linesize,
470 				ftello(opt->zonelist)-linesize);
471 		} else {
472 			log_msg(LOG_WARNING, "bad data in %s, '%s'", opt->zonelistfile,
473 				buf);
474 		}
475 	}
476 	/* store EOF offset */
477 	opt->zonelist_off = ftello(opt->zonelist);
478 	return 1;
479 }
480 
481 void
zone_options_delete(struct nsd_options * opt,struct zone_options * zone)482 zone_options_delete(struct nsd_options* opt, struct zone_options* zone)
483 {
484 	rbtree_delete(opt->zone_options, zone->node.key);
485 	region_recycle(opt->region, (void*)zone->node.key, dname_total_size(
486 		(dname_type*)zone->node.key));
487 	region_recycle(opt->region, zone, sizeof(*zone));
488 }
489 
490 /* add a new zone to the zonelist */
491 struct zone_options*
zone_list_add(struct nsd_options * opt,const char * zname,const char * pname)492 zone_list_add(struct nsd_options* opt, const char* zname, const char* pname)
493 {
494 	int r;
495 	struct zonelist_free* e;
496 	struct zonelist_bucket* b;
497 	int linesize = 6 + strlen(zname) + strlen(pname);
498 	/* create zone entry */
499 	struct zone_options* zone = zone_list_zone_insert(opt, zname, pname,
500 		linesize, 0);
501 	if(!zone)
502 		return NULL;
503 
504 	/* use free entry or append to file or create new file */
505 	if(!opt->zonelist || opt->zonelist_off == 0) {
506 		/* create new file */
507 		if(opt->zonelist) fclose(opt->zonelist);
508 		opt->zonelist = fopen(opt->zonelistfile, "w+");
509 		if(!opt->zonelist) {
510 			log_msg(LOG_ERR, "could not create zone list %s: %s",
511 				opt->zonelistfile, strerror(errno));
512 			log_msg(LOG_ERR, "zone %s could not be added", zname);
513 			zone_options_delete(opt, zone);
514 			return NULL;
515 		}
516 		r = fprintf(opt->zonelist, ZONELIST_HEADER);
517 		if(r != strlen(ZONELIST_HEADER)) {
518 			if(r == -1)
519 				log_msg(LOG_ERR, "could not write to %s: %s",
520 					opt->zonelistfile, strerror(errno));
521 			else log_msg(LOG_ERR, "partial write to %s: disk full",
522 				opt->zonelistfile);
523 			log_msg(LOG_ERR, "zone %s could not be added", zname);
524 			zone_options_delete(opt, zone);
525 			return NULL;
526 		}
527 		zone->off = ftello(opt->zonelist);
528 		if(zone->off == -1)
529 			log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno));
530 		r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
531 		if(r != zone->linesize) {
532 			if(r == -1)
533 				log_msg(LOG_ERR, "could not write to %s: %s",
534 					opt->zonelistfile, strerror(errno));
535 			else log_msg(LOG_ERR, "partial write to %s: disk full",
536 				opt->zonelistfile);
537 			log_msg(LOG_ERR, "zone %s could not be added", zname);
538 			zone_options_delete(opt, zone);
539 			return NULL;
540 		}
541 		opt->zonelist_off = ftello(opt->zonelist);
542 		if(opt->zonelist_off == -1)
543 			log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno));
544 		if(fflush(opt->zonelist) != 0) {
545 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
546 		}
547 		return zone;
548 	}
549 	b = (struct zonelist_bucket*)rbtree_search(opt->zonefree,
550 		&zone->linesize);
551 	if(!b || b->list == NULL) {
552 		/* no empty place, append to file */
553 		zone->off = opt->zonelist_off;
554 		if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
555 			log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
556 			log_msg(LOG_ERR, "zone %s could not be added", zname);
557 			zone_options_delete(opt, zone);
558 			return NULL;
559 		}
560 		r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
561 		if(r != zone->linesize) {
562 			if(r == -1)
563 				log_msg(LOG_ERR, "could not write to %s: %s",
564 					opt->zonelistfile, strerror(errno));
565 			else log_msg(LOG_ERR, "partial write to %s: disk full",
566 				opt->zonelistfile);
567 			log_msg(LOG_ERR, "zone %s could not be added", zname);
568 			zone_options_delete(opt, zone);
569 			return NULL;
570 		}
571 		opt->zonelist_off += linesize;
572 		if(fflush(opt->zonelist) != 0) {
573 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
574 		}
575 		return zone;
576 	}
577 	/* reuse empty spot */
578 	e = b->list;
579 	zone->off = e->off;
580 	if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
581 		log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
582 		log_msg(LOG_ERR, "zone %s could not be added", zname);
583 		zone_options_delete(opt, zone);
584 		return NULL;
585 	}
586 	r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
587 	if(r != zone->linesize) {
588 		if(r == -1)
589 			log_msg(LOG_ERR, "could not write to %s: %s",
590 				opt->zonelistfile, strerror(errno));
591 		else log_msg(LOG_ERR, "partial write to %s: disk full",
592 			opt->zonelistfile);
593 		log_msg(LOG_ERR, "zone %s could not be added", zname);
594 		zone_options_delete(opt, zone);
595 		return NULL;
596 	}
597 	if(fflush(opt->zonelist) != 0) {
598 		log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
599 	}
600 
601 	/* snip off and recycle element */
602 	b->list = e->next;
603 	region_recycle(opt->region, e, sizeof(*e));
604 	if(b->list == NULL) {
605 		rbtree_delete(opt->zonefree, &b->linesize);
606 		region_recycle(opt->region, b, sizeof(*b));
607 	}
608 	opt->zonefree_number--;
609 	return zone;
610 }
611 
612 /* remove a zone on the zonelist */
613 void
zone_list_del(struct nsd_options * opt,struct zone_options * zone)614 zone_list_del(struct nsd_options* opt, struct zone_options* zone)
615 {
616 	/* put its space onto the free entry */
617 	if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
618 		log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
619 		return;
620 	}
621 	fprintf(opt->zonelist, "del");
622 	zone_list_free_insert(opt, zone->linesize, zone->off);
623 
624 	/* remove zone_options */
625 	zone_options_delete(opt, zone);
626 
627 	/* see if we need to compact: it is going to halve the zonelist */
628 	if(opt->zonefree_number > opt->zone_options->count) {
629 		zone_list_compact(opt);
630 	} else {
631 		if(fflush(opt->zonelist) != 0) {
632 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
633 		}
634 	}
635 }
636 /* postorder delete of zonelist free space tree */
637 static void
delbucket(region_type * region,struct zonelist_bucket * b)638 delbucket(region_type* region, struct zonelist_bucket* b)
639 {
640 	struct zonelist_free* e, *f;
641 	if(!b || (rbnode_type*)b==RBTREE_NULL)
642 		return;
643 	delbucket(region, (struct zonelist_bucket*)b->node.left);
644 	delbucket(region, (struct zonelist_bucket*)b->node.right);
645 	e = b->list;
646 	while(e) {
647 		f = e->next;
648 		region_recycle(region, e, sizeof(*e));
649 		e = f;
650 	}
651 	region_recycle(region, b, sizeof(*b));
652 }
653 
654 /* compact zonelist file */
655 void
zone_list_compact(struct nsd_options * opt)656 zone_list_compact(struct nsd_options* opt)
657 {
658 	char outname[1024];
659 	FILE* out;
660 	struct zone_options* zone;
661 	off_t off;
662 	int r;
663 	snprintf(outname, sizeof(outname), "%s~", opt->zonelistfile);
664 	/* useful, when : count-of-free > count-of-used */
665 	/* write zonelist to zonelist~ */
666 	out = fopen(outname, "w+");
667 	if(!out) {
668 		log_msg(LOG_ERR, "could not open %s: %s", outname, strerror(errno));
669 		return;
670 	}
671 	r = fprintf(out, ZONELIST_HEADER);
672 	if(r == -1) {
673 		log_msg(LOG_ERR, "write %s failed: %s", outname,
674 			strerror(errno));
675 		fclose(out);
676 		return;
677 	} else if(r != strlen(ZONELIST_HEADER)) {
678 		log_msg(LOG_ERR, "write %s was partial: disk full",
679 			outname);
680 		fclose(out);
681 		return;
682 	}
683 	off = ftello(out);
684 	if(off == -1) {
685 		log_msg(LOG_ERR, "ftello(%s): %s", outname, strerror(errno));
686 		fclose(out);
687 		return;
688 	}
689 	RBTREE_FOR(zone, struct zone_options*, opt->zone_options) {
690 		if(zone->part_of_config)
691 			continue;
692 		r = fprintf(out, "add %s %s\n", zone->name,
693 			zone->pattern->pname);
694 		if(r < 0) {
695 			log_msg(LOG_ERR, "write %s failed: %s", outname,
696 				strerror(errno));
697 			fclose(out);
698 			return;
699 		} else if(r != zone->linesize) {
700 			log_msg(LOG_ERR, "write %s was partial: disk full",
701 				outname);
702 			fclose(out);
703 			return;
704 		}
705 	}
706 	if(fflush(out) != 0) {
707 		log_msg(LOG_ERR, "fflush %s: %s", outname, strerror(errno));
708 	}
709 
710 	/* rename zonelist~ onto zonelist */
711 	if(rename(outname, opt->zonelistfile) == -1) {
712 		log_msg(LOG_ERR, "rename(%s to %s) failed: %s",
713 			outname, opt->zonelistfile, strerror(errno));
714 		fclose(out);
715 		return;
716 	}
717 	fclose(opt->zonelist);
718 	/* set offsets */
719 	RBTREE_FOR(zone, struct zone_options*, opt->zone_options) {
720 		if(zone->part_of_config)
721 			continue;
722 		zone->off = off;
723 		off += zone->linesize;
724 	}
725 	/* empty the free tree */
726 	delbucket(opt->region, (struct zonelist_bucket*)opt->zonefree->root);
727 	opt->zonefree->root = RBTREE_NULL;
728 	opt->zonefree->count = 0;
729 	opt->zonefree_number = 0;
730 	/* finish */
731 	opt->zonelist = out;
732 	opt->zonelist_off = off;
733 }
734 
735 /* close zonelist file */
736 void
zone_list_close(struct nsd_options * opt)737 zone_list_close(struct nsd_options* opt)
738 {
739 	if(opt->zonelist) {
740 		fclose(opt->zonelist);
741 		opt->zonelist = NULL;
742 	}
743 }
744 
745 static void
c_error_va_list_pos(int showpos,const char * fmt,va_list args)746 c_error_va_list_pos(int showpos, const char* fmt, va_list args)
747 {
748 	char* at = NULL;
749 	cfg_parser->errors++;
750 	if(showpos && c_text && c_text[0]!=0) {
751 		at = c_text;
752 	}
753 	if(cfg_parser->err) {
754 		char m[MAXSYSLOGMSGLEN];
755 		snprintf(m, sizeof(m), "%s:%d: ", cfg_parser->filename,
756 			cfg_parser->line);
757 		(*cfg_parser->err)(cfg_parser->err_arg, m);
758 		if(at) {
759 			snprintf(m, sizeof(m), "at '%s': ", at);
760 			(*cfg_parser->err)(cfg_parser->err_arg, m);
761 		}
762 		(*cfg_parser->err)(cfg_parser->err_arg, "error: ");
763 		vsnprintf(m, sizeof(m), fmt, args);
764 		(*cfg_parser->err)(cfg_parser->err_arg, m);
765 		(*cfg_parser->err)(cfg_parser->err_arg, "\n");
766 		return;
767 	}
768         fprintf(stderr, "%s:%d: ", cfg_parser->filename, cfg_parser->line);
769 	if(at) fprintf(stderr, "at '%s': ", at);
770 	fprintf(stderr, "error: ");
771 	vfprintf(stderr, fmt, args);
772 	fprintf(stderr, "\n");
773 }
774 
775 void
c_error(const char * fmt,...)776 c_error(const char *fmt, ...)
777 {
778 	va_list ap;
779 	int showpos = 0;
780 
781 	if (strcmp(fmt, "syntax error") == 0 || strcmp(fmt, "parse error") == 0) {
782 		showpos = 1;
783 	}
784 
785 	va_start(ap, fmt);
786 	c_error_va_list_pos(showpos, fmt, ap);
787 	va_end(ap);
788 }
789 
790 int
c_wrap(void)791 c_wrap(void)
792 {
793 	return 1;
794 }
795 
796 struct zone_options*
zone_options_create(region_type * region)797 zone_options_create(region_type* region)
798 {
799 	struct zone_options* zone;
800 	zone = (struct zone_options*)region_alloc(region, sizeof(
801 		struct zone_options));
802 	zone->node = *RBTREE_NULL;
803 	zone->name = 0;
804 	zone->pattern = 0;
805 	zone->part_of_config = 0;
806 	return zone;
807 }
808 
809 /* true is booleans are the same truth value */
810 #define booleq(x,y) ( ((x) && (y)) || (!(x) && !(y)) )
811 
812 /* true is min_expire_time_expr has either an equal known value
813  * or none of these known values but booleanally equal
814  */
815 #define expire_expr_eq(x,y) (  (  (x) == REFRESHPLUSRETRYPLUS1 \
816                                && (y) == REFRESHPLUSRETRYPLUS1 ) \
817                             || (  (x) != REFRESHPLUSRETRYPLUS1 \
818                                && (y) != REFRESHPLUSRETRYPLUS1 \
819                                && booleq((x), (y))))
820 
821 
822 int
acl_equal(struct acl_options * p,struct acl_options * q)823 acl_equal(struct acl_options* p, struct acl_options* q)
824 {
825 	if(!booleq(p->use_axfr_only, q->use_axfr_only)) return 0;
826 	if(!booleq(p->allow_udp, q->allow_udp)) return 0;
827 	if(strcmp(p->ip_address_spec, q->ip_address_spec)!=0) return 0;
828 	/* the ip6, port, addr, mask, type: are derived from the ip_address_spec */
829 	if(!booleq(p->nokey, q->nokey)) return 0;
830 	if(!booleq(p->blocked, q->blocked)) return 0;
831 	if(p->key_name && q->key_name) {
832 		if(strcmp(p->key_name, q->key_name)!=0) return 0;
833 	} else if(p->key_name && !q->key_name) return 0;
834 	else if(!p->key_name && q->key_name) return 0;
835 	/* key_options is derived from key_name */
836 	if(p->tls_auth_name && q->tls_auth_name) {
837 		if(strcmp(p->tls_auth_name, q->tls_auth_name)!=0) return 0;
838 	} else if(p->tls_auth_name && !q->tls_auth_name) return 0;
839 	else if(!p->tls_auth_name && q->tls_auth_name) return 0;
840 	/* tls_auth_options is derived from tls_auth_name */
841 	return 1;
842 }
843 
844 int
acl_list_equal(struct acl_options * p,struct acl_options * q)845 acl_list_equal(struct acl_options* p, struct acl_options* q)
846 {
847 	/* must be same and in same order */
848 	while(p && q) {
849 		if(!acl_equal(p, q))
850 			return 0;
851 		p = p->next;
852 		q = q->next;
853 	}
854 	if(!p && !q) return 1;
855 	/* different lengths */
856 	return 0;
857 }
858 
859 struct pattern_options*
pattern_options_create(region_type * region)860 pattern_options_create(region_type* region)
861 {
862 	struct pattern_options* p;
863 	p = (struct pattern_options*)region_alloc(region, sizeof(
864 		struct pattern_options));
865 	p->node = *RBTREE_NULL;
866 	p->pname = 0;
867 	p->zonefile = 0;
868 	p->zonestats = 0;
869 	p->allow_notify = 0;
870 	p->request_xfr = 0;
871 	p->size_limit_xfr = 0;
872 	p->notify = 0;
873 	p->provide_xfr = 0;
874 	p->allow_query = 0;
875 	p->outgoing_interface = 0;
876 	p->notify_retry = 5;
877 	p->notify_retry_is_default = 1;
878 	p->allow_axfr_fallback = 1;
879 	p->allow_axfr_fallback_is_default = 1;
880 	p->implicit = 0;
881 	p->xfrd_flags = 0;
882 	p->max_refresh_time = 2419200;	/* 4 weeks */
883 	p->max_refresh_time_is_default = 1;
884 	p->min_refresh_time = 0;
885 	p->min_refresh_time_is_default = 1;
886 	p->max_retry_time = 1209600;	/* 2 weeks */
887 	p->max_retry_time_is_default = 1;
888 	p->min_retry_time = 0;
889 	p->min_retry_time_is_default = 1;
890 	p->min_expire_time = 0;
891 	p->min_expire_time_expr = EXPIRE_TIME_IS_DEFAULT;
892 #ifdef RATELIMIT
893 	p->rrl_whitelist = 0;
894 #endif
895 	p->multi_master_check = 0;
896 	p->store_ixfr = 0;
897 	p->store_ixfr_is_default = 1;
898 	p->ixfr_size = IXFR_SIZE_DEFAULT;
899 	p->ixfr_size_is_default = 1;
900 	p->ixfr_number = IXFR_NUMBER_DEFAULT;
901 	p->ixfr_number_is_default = 1;
902 	p->create_ixfr = 0;
903 	p->create_ixfr_is_default = 1;
904 	p->verify_zone = VERIFY_ZONE_INHERIT;
905 	p->verify_zone_is_default = 1;
906 	p->verifier = NULL;
907 	p->verifier_feed_zone = VERIFIER_FEED_ZONE_INHERIT;
908 	p->verifier_feed_zone_is_default = 1;
909 	p->verifier_timeout = VERIFIER_TIMEOUT_INHERIT;
910 	p->verifier_timeout_is_default = 1;
911 
912 	return p;
913 }
914 
915 static void
acl_delete(region_type * region,struct acl_options * acl)916 acl_delete(region_type* region, struct acl_options* acl)
917 {
918 	if(acl->ip_address_spec)
919 		region_recycle(region, (void*)acl->ip_address_spec,
920 			strlen(acl->ip_address_spec)+1);
921 	if(acl->key_name)
922 		region_recycle(region, (void*)acl->key_name,
923 			strlen(acl->key_name)+1);
924 	if(acl->tls_auth_name)
925 		region_recycle(region, (void*)acl->tls_auth_name,
926 			strlen(acl->tls_auth_name)+1);
927 	/* key_options is a convenience pointer, not owned by the acl */
928 	region_recycle(region, acl, sizeof(*acl));
929 }
930 
931 static void
acl_list_delete(region_type * region,struct acl_options * list)932 acl_list_delete(region_type* region, struct acl_options* list)
933 {
934 	struct acl_options* n;
935 	while(list) {
936 		n = list->next;
937 		acl_delete(region, list);
938 		list = n;
939 	}
940 }
941 
942 static void
verifier_delete(region_type * region,char ** v)943 verifier_delete(region_type* region, char **v)
944 {
945 	if(v != NULL) {
946 		size_t vc = 0;
947 		for(vc = 0; v[vc] != NULL; vc++)
948 			region_recycle(region, v[vc], strlen(v[vc]) + 1);
949 		region_recycle(region, v, (vc + 1) * sizeof(char *));
950 	}
951 }
952 
953 void
pattern_options_remove(struct nsd_options * opt,const char * name)954 pattern_options_remove(struct nsd_options* opt, const char* name)
955 {
956 	struct pattern_options* p = (struct pattern_options*)rbtree_delete(
957 		opt->patterns, name);
958 	/* delete p and its contents */
959 	if (!p)
960 		return;
961 	if(p->pname)
962 		region_recycle(opt->region, (void*)p->pname,
963 			strlen(p->pname)+1);
964 	if(p->zonefile)
965 		region_recycle(opt->region, (void*)p->zonefile,
966 			strlen(p->zonefile)+1);
967 	if(p->zonestats)
968 		region_recycle(opt->region, (void*)p->zonestats,
969 			strlen(p->zonestats)+1);
970 	acl_list_delete(opt->region, p->allow_notify);
971 	acl_list_delete(opt->region, p->request_xfr);
972 	acl_list_delete(opt->region, p->notify);
973 	acl_list_delete(opt->region, p->provide_xfr);
974 	acl_list_delete(opt->region, p->allow_query);
975 	acl_list_delete(opt->region, p->outgoing_interface);
976 	verifier_delete(opt->region, p->verifier);
977 
978 	region_recycle(opt->region, p, sizeof(struct pattern_options));
979 }
980 
981 static struct acl_options*
copy_acl(region_type * region,struct acl_options * a)982 copy_acl(region_type* region, struct acl_options* a)
983 {
984 	struct acl_options* b;
985 	if(!a) return NULL;
986 	b = (struct acl_options*)region_alloc(region, sizeof(*b));
987 	/* copy the whole lot */
988 	*b = *a;
989 	/* fix the pointers */
990 	if(a->ip_address_spec)
991 		b->ip_address_spec = region_strdup(region, a->ip_address_spec);
992 	if(a->key_name)
993 		b->key_name = region_strdup(region, a->key_name);
994 	if(a->tls_auth_name)
995 		b->tls_auth_name = region_strdup(region, a->tls_auth_name);
996 	b->next = NULL;
997 	b->key_options = NULL;
998 	b->tls_auth_options = NULL;
999 	return b;
1000 }
1001 
1002 static struct acl_options*
copy_acl_list(struct nsd_options * opt,struct acl_options * a)1003 copy_acl_list(struct nsd_options* opt, struct acl_options* a)
1004 {
1005 	struct acl_options* b, *blast = NULL, *blist = NULL;
1006 	while(a) {
1007 		b = copy_acl(opt->region, a);
1008 		/* fixup key_options */
1009 		if(b->key_name)
1010 			b->key_options = key_options_find(opt, b->key_name);
1011 		else	b->key_options = NULL;
1012 		/* fixup tls_auth_options */
1013 		if(b->tls_auth_name)
1014 			b->tls_auth_options = tls_auth_options_find(opt, b->tls_auth_name);
1015 		else	b->tls_auth_options = NULL;
1016 
1017 		/* link as last into list */
1018 		b->next = NULL;
1019 		if(!blist) blist = b;
1020 		else blast->next = b;
1021 		blast = b;
1022 
1023 		a = a->next;
1024 	}
1025 	return blist;
1026 }
1027 
1028 static void
copy_changed_acl(struct nsd_options * opt,struct acl_options ** orig,struct acl_options * anew)1029 copy_changed_acl(struct nsd_options* opt, struct acl_options** orig,
1030 	struct acl_options* anew)
1031 {
1032 	if(!acl_list_equal(*orig, anew)) {
1033 		acl_list_delete(opt->region, *orig);
1034 		*orig = copy_acl_list(opt, anew);
1035 	}
1036 }
1037 
1038 static void
copy_changed_verifier(struct nsd_options * opt,char *** ov,char ** nv)1039 copy_changed_verifier(struct nsd_options* opt, char ***ov, char **nv)
1040 {
1041 	size_t ovc, nvc;
1042 	assert(ov != NULL);
1043 	ovc = nvc = 0;
1044 	if(nv != NULL) {
1045 		for(; nv[nvc] != NULL; nvc++) ;
1046 	} else {
1047 		verifier_delete(opt->region, *ov);
1048 		*ov = NULL;
1049 		return;
1050 	}
1051 	if(*ov != NULL) {
1052 		for(; (*ov)[ovc] != NULL; ovc++) {
1053 			if(ovc < nvc && strcmp((*ov)[ovc], nv[ovc]) != 0)
1054 				break;
1055 		}
1056 		if(ovc == nvc)
1057 			return;
1058 		verifier_delete(opt->region, *ov);
1059 		*ov = NULL;
1060 	}
1061 	*ov = region_alloc(opt->region, (nvc + 1) * sizeof(*nv));
1062 	for(ovc = 0; nv[ovc] != NULL; ovc++) {
1063 		(*ov)[ovc] = region_strdup(opt->region, nv[ovc]);
1064 	}
1065 	(*ov)[ovc] = NULL;
1066 	assert(ovc == nvc);
1067 }
1068 
1069 static void
copy_pat_fixed(region_type * region,struct pattern_options * orig,struct pattern_options * p)1070 copy_pat_fixed(region_type* region, struct pattern_options* orig,
1071 	struct pattern_options* p)
1072 {
1073 	orig->allow_axfr_fallback = p->allow_axfr_fallback;
1074 	orig->allow_axfr_fallback_is_default =
1075 		p->allow_axfr_fallback_is_default;
1076 	orig->notify_retry = p->notify_retry;
1077 	orig->notify_retry_is_default = p->notify_retry_is_default;
1078 	orig->implicit = p->implicit;
1079 	if(p->zonefile)
1080 		orig->zonefile = region_strdup(region, p->zonefile);
1081 	else orig->zonefile = NULL;
1082 	if(p->zonestats)
1083 		orig->zonestats = region_strdup(region, p->zonestats);
1084 	else orig->zonestats = NULL;
1085 	orig->max_refresh_time = p->max_refresh_time;
1086 	orig->max_refresh_time_is_default = p->max_refresh_time_is_default;
1087 	orig->min_refresh_time = p->min_refresh_time;
1088 	orig->min_refresh_time_is_default = p->min_refresh_time_is_default;
1089 	orig->max_retry_time = p->max_retry_time;
1090 	orig->max_retry_time_is_default = p->max_retry_time_is_default;
1091 	orig->min_retry_time = p->min_retry_time;
1092 	orig->min_retry_time_is_default = p->min_retry_time_is_default;
1093 	orig->min_expire_time = p->min_expire_time;
1094 	orig->min_expire_time_expr = p->min_expire_time_expr;
1095 #ifdef RATELIMIT
1096 	orig->rrl_whitelist = p->rrl_whitelist;
1097 #endif
1098 	orig->multi_master_check = p->multi_master_check;
1099 	orig->store_ixfr = p->store_ixfr;
1100 	orig->store_ixfr_is_default = p->store_ixfr_is_default;
1101 	orig->ixfr_size = p->ixfr_size;
1102 	orig->ixfr_size_is_default = p->ixfr_size_is_default;
1103 	orig->ixfr_number = p->ixfr_number;
1104 	orig->ixfr_number_is_default = p->ixfr_number_is_default;
1105 	orig->create_ixfr = p->create_ixfr;
1106 	orig->create_ixfr_is_default = p->create_ixfr_is_default;
1107 	orig->verify_zone = p->verify_zone;
1108 	orig->verify_zone_is_default = p->verify_zone_is_default;
1109 	orig->verifier_timeout = p->verifier_timeout;
1110 	orig->verifier_timeout_is_default = p->verifier_timeout_is_default;
1111 	orig->verifier_feed_zone = p->verifier_feed_zone;
1112 	orig->verifier_feed_zone_is_default = p->verifier_feed_zone_is_default;
1113 }
1114 
1115 void
pattern_options_add_modify(struct nsd_options * opt,struct pattern_options * p)1116 pattern_options_add_modify(struct nsd_options* opt, struct pattern_options* p)
1117 {
1118 	struct pattern_options* orig = pattern_options_find(opt, p->pname);
1119 	if(!orig) {
1120 		/* needs to be copied to opt region */
1121 		orig = pattern_options_create(opt->region);
1122 		orig->pname = region_strdup(opt->region, p->pname);
1123 		copy_pat_fixed(opt->region, orig, p);
1124 		orig->allow_notify = copy_acl_list(opt, p->allow_notify);
1125 		orig->request_xfr = copy_acl_list(opt, p->request_xfr);
1126 		orig->notify = copy_acl_list(opt, p->notify);
1127 		orig->provide_xfr = copy_acl_list(opt, p->provide_xfr);
1128 		orig->allow_query = copy_acl_list(opt, p->allow_query);
1129 		orig->outgoing_interface = copy_acl_list(opt,
1130 			p->outgoing_interface);
1131 		copy_changed_verifier(opt, &orig->verifier, p->verifier);
1132 		nsd_options_insert_pattern(opt, orig);
1133 	} else {
1134 		/* modify in place so pointers stay valid (and copy
1135 		   into region). Do not touch unchanged acls. */
1136 		if(orig->zonefile)
1137 			region_recycle(opt->region, (char*)orig->zonefile,
1138 				strlen(orig->zonefile)+1);
1139 		if(orig->zonestats)
1140 			region_recycle(opt->region, (char*)orig->zonestats,
1141 				strlen(orig->zonestats)+1);
1142 		copy_pat_fixed(opt->region, orig, p);
1143 		copy_changed_acl(opt, &orig->allow_notify, p->allow_notify);
1144 		copy_changed_acl(opt, &orig->request_xfr, p->request_xfr);
1145 		copy_changed_acl(opt, &orig->notify, p->notify);
1146 		copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr);
1147 		copy_changed_acl(opt, &orig->allow_query, p->allow_query);
1148 		copy_changed_acl(opt, &orig->outgoing_interface,
1149 			p->outgoing_interface);
1150 		copy_changed_verifier(opt, &orig->verifier, p->verifier);
1151 	}
1152 }
1153 
1154 struct pattern_options*
pattern_options_find(struct nsd_options * opt,const char * name)1155 pattern_options_find(struct nsd_options* opt, const char* name)
1156 {
1157 	return (struct pattern_options*)rbtree_search(opt->patterns, name);
1158 }
1159 
1160 static int
pattern_verifiers_equal(const char ** vp,const char ** vq)1161 pattern_verifiers_equal(const char **vp, const char **vq)
1162 {
1163 	size_t vpc, vqc;
1164 	if(vp == NULL)
1165 		return vq == NULL;
1166 	if(vq == NULL)
1167 		return 0;
1168 	for(vpc = 0; vp[vpc] != NULL; vpc++) ;
1169 	for(vqc = 0; vq[vqc] != NULL; vqc++) ;
1170 	if(vpc != vqc)
1171 		return 0;
1172 	for(vpc = 0; vp[vpc] != NULL; vpc++) {
1173 		assert(vq[vpc] != NULL);
1174 		if (strcmp(vp[vpc], vq[vpc]) != 0)
1175 			return 0;
1176 	}
1177 	return 1;
1178 }
1179 
1180 int
pattern_options_equal(struct pattern_options * p,struct pattern_options * q)1181 pattern_options_equal(struct pattern_options* p, struct pattern_options* q)
1182 {
1183 	if(strcmp(p->pname, q->pname) != 0) return 0;
1184 	if(!p->zonefile && q->zonefile) return 0;
1185 	else if(p->zonefile && !q->zonefile) return 0;
1186 	else if(p->zonefile && q->zonefile) {
1187 		if(strcmp(p->zonefile, q->zonefile) != 0) return 0;
1188 	}
1189 	if(!p->zonestats && q->zonestats) return 0;
1190 	else if(p->zonestats && !q->zonestats) return 0;
1191 	else if(p->zonestats && q->zonestats) {
1192 		if(strcmp(p->zonestats, q->zonestats) != 0) return 0;
1193 	}
1194 	if(!booleq(p->allow_axfr_fallback, q->allow_axfr_fallback)) return 0;
1195 	if(!booleq(p->allow_axfr_fallback_is_default,
1196 		q->allow_axfr_fallback_is_default)) return 0;
1197 	if(p->notify_retry != q->notify_retry) return 0;
1198 	if(!booleq(p->notify_retry_is_default,
1199 		q->notify_retry_is_default)) return 0;
1200 	if(!booleq(p->implicit, q->implicit)) return 0;
1201 	if(!acl_list_equal(p->allow_notify, q->allow_notify)) return 0;
1202 	if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0;
1203 	if(!acl_list_equal(p->notify, q->notify)) return 0;
1204 	if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0;
1205 	if(!acl_list_equal(p->allow_query, q->allow_query)) return 0;
1206 	if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface))
1207 		return 0;
1208 	if(p->max_refresh_time != q->max_refresh_time) return 0;
1209 	if(!booleq(p->max_refresh_time_is_default,
1210 		q->max_refresh_time_is_default)) return 0;
1211 	if(p->min_refresh_time != q->min_refresh_time) return 0;
1212 	if(!booleq(p->min_refresh_time_is_default,
1213 		q->min_refresh_time_is_default)) return 0;
1214 	if(p->max_retry_time != q->max_retry_time) return 0;
1215 	if(!booleq(p->max_retry_time_is_default,
1216 		q->max_retry_time_is_default)) return 0;
1217 	if(p->min_retry_time != q->min_retry_time) return 0;
1218 	if(!booleq(p->min_retry_time_is_default,
1219 		q->min_retry_time_is_default)) return 0;
1220 	if(p->min_expire_time != q->min_expire_time) return 0;
1221 	if(!expire_expr_eq(p->min_expire_time_expr,
1222 		q->min_expire_time_expr)) return 0;
1223 #ifdef RATELIMIT
1224 	if(p->rrl_whitelist != q->rrl_whitelist) return 0;
1225 #endif
1226 	if(!booleq(p->multi_master_check,q->multi_master_check)) return 0;
1227 	if(p->size_limit_xfr != q->size_limit_xfr) return 0;
1228 	if(!booleq(p->store_ixfr,q->store_ixfr)) return 0;
1229 	if(!booleq(p->store_ixfr_is_default,q->store_ixfr_is_default)) return 0;
1230 	if(p->ixfr_size != q->ixfr_size) return 0;
1231 	if(!booleq(p->ixfr_size_is_default,q->ixfr_size_is_default)) return 0;
1232 	if(p->ixfr_number != q->ixfr_number) return 0;
1233 	if(!booleq(p->ixfr_number_is_default,q->ixfr_number_is_default)) return 0;
1234 	if(!booleq(p->create_ixfr,q->create_ixfr)) return 0;
1235 	if(!booleq(p->create_ixfr_is_default,q->create_ixfr_is_default)) return 0;
1236 	if(p->verify_zone != q->verify_zone) return 0;
1237 	if(!booleq(p->verify_zone_is_default,
1238 		q->verify_zone_is_default)) return 0;
1239 	if(!pattern_verifiers_equal((const char **)p->verifier,
1240 		(const char **)q->verifier)) return 0;
1241 	if(p->verifier_feed_zone != q->verifier_feed_zone) return 0;
1242 	if(!booleq(p->verifier_feed_zone_is_default,
1243 		q->verifier_feed_zone_is_default)) return 0;
1244 	if(p->verifier_timeout != q->verifier_timeout) return 0;
1245 	if(!booleq(p->verifier_timeout_is_default,
1246 		q->verifier_timeout_is_default)) return 0;
1247 	return 1;
1248 }
1249 
1250 static void
marshal_u8(struct buffer * b,uint8_t v)1251 marshal_u8(struct buffer* b, uint8_t v)
1252 {
1253 	buffer_reserve(b, 1);
1254 	buffer_write_u8(b, v);
1255 }
1256 
1257 static uint8_t
unmarshal_u8(struct buffer * b)1258 unmarshal_u8(struct buffer* b)
1259 {
1260 	return buffer_read_u8(b);
1261 }
1262 
1263 static void
marshal_u64(struct buffer * b,uint64_t v)1264 marshal_u64(struct buffer* b, uint64_t v)
1265 {
1266 	buffer_reserve(b, 8);
1267 	buffer_write_u64(b, v);
1268 }
1269 
1270 static uint64_t
unmarshal_u64(struct buffer * b)1271 unmarshal_u64(struct buffer* b)
1272 {
1273 	return buffer_read_u64(b);
1274 }
1275 
1276 #ifdef RATELIMIT
1277 static void
marshal_u16(struct buffer * b,uint16_t v)1278 marshal_u16(struct buffer* b, uint16_t v)
1279 {
1280 	buffer_reserve(b, 2);
1281 	buffer_write_u16(b, v);
1282 }
1283 #endif
1284 
1285 #ifdef RATELIMIT
1286 static uint16_t
unmarshal_u16(struct buffer * b)1287 unmarshal_u16(struct buffer* b)
1288 {
1289 	return buffer_read_u16(b);
1290 }
1291 #endif
1292 
1293 static void
marshal_u32(struct buffer * b,uint32_t v)1294 marshal_u32(struct buffer* b, uint32_t v)
1295 {
1296 	buffer_reserve(b, 4);
1297 	buffer_write_u32(b, v);
1298 }
1299 
1300 static uint32_t
unmarshal_u32(struct buffer * b)1301 unmarshal_u32(struct buffer* b)
1302 {
1303 	return buffer_read_u32(b);
1304 }
1305 
1306 static void
marshal_str(struct buffer * b,const char * s)1307 marshal_str(struct buffer* b, const char* s)
1308 {
1309 	if(!s) marshal_u8(b, 0);
1310 	else {
1311 		size_t len = strlen(s);
1312 		marshal_u8(b, 1);
1313 		buffer_reserve(b, len+1);
1314 		buffer_write(b, s, len+1);
1315 	}
1316 }
1317 
1318 static char*
unmarshal_str(region_type * r,struct buffer * b)1319 unmarshal_str(region_type* r, struct buffer* b)
1320 {
1321 	uint8_t nonnull = unmarshal_u8(b);
1322 	if(nonnull) {
1323 		char* result = region_strdup(r, (char*)buffer_current(b));
1324 		size_t len = strlen((char*)buffer_current(b));
1325 		buffer_skip(b, len+1);
1326 		return result;
1327 	} else return NULL;
1328 }
1329 
1330 static void
marshal_acl(struct buffer * b,struct acl_options * acl)1331 marshal_acl(struct buffer* b, struct acl_options* acl)
1332 {
1333 	buffer_reserve(b, sizeof(*acl));
1334 	buffer_write(b, acl, sizeof(*acl));
1335 	marshal_str(b, acl->ip_address_spec);
1336 	marshal_str(b, acl->key_name);
1337 	marshal_str(b, acl->tls_auth_name);
1338 }
1339 
1340 static struct acl_options*
unmarshal_acl(region_type * r,struct buffer * b)1341 unmarshal_acl(region_type* r, struct buffer* b)
1342 {
1343 	struct acl_options* acl = (struct acl_options*)region_alloc(r,
1344 		sizeof(*acl));
1345 	buffer_read(b, acl, sizeof(*acl));
1346 	acl->next = NULL;
1347 	acl->key_options = NULL;
1348 	acl->tls_auth_options = NULL;
1349 	acl->ip_address_spec = unmarshal_str(r, b);
1350 	acl->key_name = unmarshal_str(r, b);
1351 	acl->tls_auth_name = unmarshal_str(r, b);
1352 	return acl;
1353 }
1354 
1355 static void
marshal_acl_list(struct buffer * b,struct acl_options * list)1356 marshal_acl_list(struct buffer* b, struct acl_options* list)
1357 {
1358 	while(list) {
1359 		marshal_u8(b, 1); /* is there a next one marker */
1360 		marshal_acl(b, list);
1361 		list = list->next;
1362 	}
1363 	marshal_u8(b, 0); /* end of list marker */
1364 }
1365 
1366 static struct acl_options*
unmarshal_acl_list(region_type * r,struct buffer * b)1367 unmarshal_acl_list(region_type* r, struct buffer* b)
1368 {
1369 	struct acl_options* a, *last=NULL, *list=NULL;
1370 	while(unmarshal_u8(b)) {
1371 		a = unmarshal_acl(r, b);
1372 		/* link in */
1373 		a->next = NULL;
1374 		if(!list) list = a;
1375 		else last->next = a;
1376 		last = a;
1377 	}
1378 	return list;
1379 }
1380 
1381 static void
marshal_strv(struct buffer * b,char ** strv)1382 marshal_strv(struct buffer* b, char **strv)
1383 {
1384 	uint32_t i, n;
1385 
1386 	assert(b != NULL);
1387 
1388 	if (strv == NULL) {
1389 		marshal_u32(b, 0);
1390 		return;
1391 	}
1392 	for(n = 0; strv[n]; n++) {
1393 		/* do nothing */
1394 	}
1395 	marshal_u32(b, n);
1396 	for(i = 0; strv[i] != NULL; i++) {
1397 		marshal_str(b, strv[i]);
1398 	}
1399 	marshal_u8(b, 0);
1400 }
1401 
1402 static char **
unmarshal_strv(region_type * r,struct buffer * b)1403 unmarshal_strv(region_type* r, struct buffer* b)
1404 {
1405 	uint32_t i, n;
1406 	char **strv;
1407 
1408 	assert(r != NULL);
1409 	assert(b != NULL);
1410 
1411 	if ((n = unmarshal_u32(b)) == 0) {
1412 		return NULL;
1413 	}
1414 	strv = region_alloc_zero(r, (n + 1) * sizeof(char *));
1415 	for(i = 0; i <= n; i++) {
1416 		strv[i] = unmarshal_str(r, b);
1417 	}
1418 	assert(i == (n + 1));
1419 	assert(strv[i - 1] == NULL);
1420 
1421 	return strv;
1422 }
1423 
1424 void
pattern_options_marshal(struct buffer * b,struct pattern_options * p)1425 pattern_options_marshal(struct buffer* b, struct pattern_options* p)
1426 {
1427 	marshal_str(b, p->pname);
1428 	marshal_str(b, p->zonefile);
1429 	marshal_str(b, p->zonestats);
1430 #ifdef RATELIMIT
1431 	marshal_u16(b, p->rrl_whitelist);
1432 #endif
1433 	marshal_u8(b, p->allow_axfr_fallback);
1434 	marshal_u8(b, p->allow_axfr_fallback_is_default);
1435 	marshal_u8(b, p->notify_retry);
1436 	marshal_u8(b, p->notify_retry_is_default);
1437 	marshal_u8(b, p->implicit);
1438 	marshal_u64(b, p->size_limit_xfr);
1439 	marshal_acl_list(b, p->allow_notify);
1440 	marshal_acl_list(b, p->request_xfr);
1441 	marshal_acl_list(b, p->notify);
1442 	marshal_acl_list(b, p->provide_xfr);
1443 	marshal_acl_list(b, p->allow_query);
1444 	marshal_acl_list(b, p->outgoing_interface);
1445 	marshal_u32(b, p->max_refresh_time);
1446 	marshal_u8(b, p->max_refresh_time_is_default);
1447 	marshal_u32(b, p->min_refresh_time);
1448 	marshal_u8(b, p->min_refresh_time_is_default);
1449 	marshal_u32(b, p->max_retry_time);
1450 	marshal_u8(b, p->max_retry_time_is_default);
1451 	marshal_u32(b, p->min_retry_time);
1452 	marshal_u8(b, p->min_retry_time_is_default);
1453 	marshal_u32(b, p->min_expire_time);
1454 	marshal_u8(b, p->min_expire_time_expr);
1455 	marshal_u8(b, p->multi_master_check);
1456 	marshal_u8(b, p->store_ixfr);
1457 	marshal_u8(b, p->store_ixfr_is_default);
1458 	marshal_u64(b, p->ixfr_size);
1459 	marshal_u8(b, p->ixfr_size_is_default);
1460 	marshal_u32(b, p->ixfr_number);
1461 	marshal_u8(b, p->ixfr_number_is_default);
1462 	marshal_u8(b, p->create_ixfr);
1463 	marshal_u8(b, p->create_ixfr_is_default);
1464 	marshal_u8(b, p->verify_zone);
1465 	marshal_u8(b, p->verify_zone_is_default);
1466 	marshal_strv(b, p->verifier);
1467 	marshal_u8(b, p->verifier_feed_zone);
1468 	marshal_u8(b, p->verifier_feed_zone_is_default);
1469 	marshal_u32(b, p->verifier_timeout);
1470 	marshal_u8(b, p->verifier_timeout_is_default);
1471 }
1472 
1473 struct pattern_options*
pattern_options_unmarshal(region_type * r,struct buffer * b)1474 pattern_options_unmarshal(region_type* r, struct buffer* b)
1475 {
1476 	struct pattern_options* p = pattern_options_create(r);
1477 	p->pname = unmarshal_str(r, b);
1478 	p->zonefile = unmarshal_str(r, b);
1479 	p->zonestats = unmarshal_str(r, b);
1480 #ifdef RATELIMIT
1481 	p->rrl_whitelist = unmarshal_u16(b);
1482 #endif
1483 	p->allow_axfr_fallback = unmarshal_u8(b);
1484 	p->allow_axfr_fallback_is_default = unmarshal_u8(b);
1485 	p->notify_retry = unmarshal_u8(b);
1486 	p->notify_retry_is_default = unmarshal_u8(b);
1487 	p->implicit = unmarshal_u8(b);
1488 	p->size_limit_xfr = unmarshal_u64(b);
1489 	p->allow_notify = unmarshal_acl_list(r, b);
1490 	p->request_xfr = unmarshal_acl_list(r, b);
1491 	p->notify = unmarshal_acl_list(r, b);
1492 	p->provide_xfr = unmarshal_acl_list(r, b);
1493 	p->allow_query = unmarshal_acl_list(r, b);
1494 	p->outgoing_interface = unmarshal_acl_list(r, b);
1495 	p->max_refresh_time = unmarshal_u32(b);
1496 	p->max_refresh_time_is_default = unmarshal_u8(b);
1497 	p->min_refresh_time = unmarshal_u32(b);
1498 	p->min_refresh_time_is_default = unmarshal_u8(b);
1499 	p->max_retry_time = unmarshal_u32(b);
1500 	p->max_retry_time_is_default = unmarshal_u8(b);
1501 	p->min_retry_time = unmarshal_u32(b);
1502 	p->min_retry_time_is_default = unmarshal_u8(b);
1503 	p->min_expire_time = unmarshal_u32(b);
1504 	p->min_expire_time_expr = unmarshal_u8(b);
1505 	p->multi_master_check = unmarshal_u8(b);
1506 	p->store_ixfr = unmarshal_u8(b);
1507 	p->store_ixfr_is_default = unmarshal_u8(b);
1508 	p->ixfr_size = unmarshal_u64(b);
1509 	p->ixfr_size_is_default = unmarshal_u8(b);
1510 	p->ixfr_number = unmarshal_u32(b);
1511 	p->ixfr_number_is_default = unmarshal_u8(b);
1512 	p->create_ixfr = unmarshal_u8(b);
1513 	p->create_ixfr_is_default = unmarshal_u8(b);
1514 	p->verify_zone = unmarshal_u8(b);
1515 	p->verify_zone_is_default = unmarshal_u8(b);
1516 	p->verifier = unmarshal_strv(r, b);
1517 	p->verifier_feed_zone = unmarshal_u8(b);
1518 	p->verifier_feed_zone_is_default = unmarshal_u8(b);
1519 	p->verifier_timeout = unmarshal_u32(b);
1520 	p->verifier_timeout_is_default = unmarshal_u8(b);
1521 	return p;
1522 }
1523 
1524 struct key_options*
key_options_create(region_type * region)1525 key_options_create(region_type* region)
1526 {
1527 	struct key_options* key;
1528 	key = (struct key_options*)region_alloc_zero(region,
1529 		sizeof(struct key_options));
1530 	return key;
1531 }
1532 
1533 struct tls_auth_options*
tls_auth_options_create(region_type * region)1534 tls_auth_options_create(region_type* region)
1535 {
1536 	struct tls_auth_options* tls_auth_options;
1537 	tls_auth_options = (struct tls_auth_options*)region_alloc_zero(region, sizeof(struct tls_auth_options));
1538 	return tls_auth_options;
1539 }
1540 
1541 void
key_options_insert(struct nsd_options * opt,struct key_options * key)1542 key_options_insert(struct nsd_options* opt, struct key_options* key)
1543 {
1544 	if(!key->name) return;
1545 	key->node.key = key->name;
1546 	(void)rbtree_insert(opt->keys, &key->node);
1547 }
1548 
1549 struct key_options*
key_options_find(struct nsd_options * opt,const char * name)1550 key_options_find(struct nsd_options* opt, const char* name)
1551 {
1552 	return (struct key_options*)rbtree_search(opt->keys, name);
1553 }
1554 
1555 void
tls_auth_options_insert(struct nsd_options * opt,struct tls_auth_options * auth)1556 tls_auth_options_insert(struct nsd_options* opt, struct tls_auth_options* auth)
1557 {
1558 	if(!auth->name) return;
1559 	auth->node.key = auth->name;
1560 	(void)rbtree_insert(opt->tls_auths, &auth->node);
1561 }
1562 
1563 struct tls_auth_options*
tls_auth_options_find(struct nsd_options * opt,const char * name)1564 tls_auth_options_find(struct nsd_options* opt, const char* name)
1565 {
1566 	return (struct tls_auth_options*)rbtree_search(opt->tls_auths, name);
1567 }
1568 
1569 /** remove tsig_key contents */
1570 void
key_options_desetup(region_type * region,struct key_options * key)1571 key_options_desetup(region_type* region, struct key_options* key)
1572 {
1573 	/* keep tsig_key pointer so that existing references keep valid */
1574 	if(!key->tsig_key)
1575 		return;
1576 	/* name stays the same */
1577 	if(key->tsig_key->data) {
1578 		/* wipe secret! */
1579 		memset(key->tsig_key->data, 0xdd, key->tsig_key->size);
1580 		region_recycle(region, key->tsig_key->data,
1581 			key->tsig_key->size);
1582 		key->tsig_key->data = NULL;
1583 		key->tsig_key->size = 0;
1584 	}
1585 }
1586 
1587 /** add tsig_key contents */
1588 void
key_options_setup(region_type * region,struct key_options * key)1589 key_options_setup(region_type* region, struct key_options* key)
1590 {
1591 	uint8_t data[16384]; /* 16KB */
1592 	int size;
1593 	if(!key->tsig_key) {
1594 		/* create it */
1595 		key->tsig_key = (tsig_key_type *) region_alloc(region,
1596 			sizeof(tsig_key_type));
1597 		/* create name */
1598 		key->tsig_key->name = dname_parse(region, key->name);
1599 		if(!key->tsig_key->name) {
1600 			log_msg(LOG_ERR, "Failed to parse tsig key name %s",
1601 				key->name);
1602 			/* key and base64 were checked during syntax parse */
1603 			exit(1);
1604 		}
1605 		key->tsig_key->size = 0;
1606 		key->tsig_key->data = NULL;
1607 	}
1608 	size = b64_pton(key->secret, data, sizeof(data));
1609 	if(size == -1) {
1610 		log_msg(LOG_ERR, "Failed to parse tsig key data %s",
1611 			key->name);
1612 		/* key and base64 were checked during syntax parse */
1613 		exit(1);
1614 	}
1615 	key->tsig_key->size = size;
1616 	key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size);
1617 }
1618 
1619 void
key_options_remove(struct nsd_options * opt,const char * name)1620 key_options_remove(struct nsd_options* opt, const char* name)
1621 {
1622 	struct key_options* k = key_options_find(opt, name);
1623 	if(!k) return;
1624 	(void)rbtree_delete(opt->keys, name);
1625 	if(k->name)
1626 		region_recycle(opt->region, k->name, strlen(k->name)+1);
1627 	if(k->algorithm)
1628 		region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1);
1629 	if(k->secret) {
1630 		memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */
1631 		region_recycle(opt->region, k->secret, strlen(k->secret)+1);
1632 	}
1633 	if(k->tsig_key) {
1634 		tsig_del_key(k->tsig_key);
1635 		if(k->tsig_key->name)
1636 			region_recycle(opt->region, (void*)k->tsig_key->name,
1637 				dname_total_size(k->tsig_key->name));
1638 		key_options_desetup(opt->region, k);
1639 		region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type));
1640 	}
1641 	region_recycle(opt->region, k, sizeof(struct key_options));
1642 }
1643 
1644 int
key_options_equal(struct key_options * p,struct key_options * q)1645 key_options_equal(struct key_options* p, struct key_options* q)
1646 {
1647 	return strcmp(p->name, q->name)==0 && strcmp(p->algorithm,
1648 		q->algorithm)==0 && strcmp(p->secret, q->secret)==0;
1649 }
1650 
1651 void
key_options_add_modify(struct nsd_options * opt,struct key_options * key)1652 key_options_add_modify(struct nsd_options* opt, struct key_options* key)
1653 {
1654 	struct key_options* orig = key_options_find(opt, key->name);
1655 	if(!orig) {
1656 		/* needs to be copied to opt region */
1657 		orig = key_options_create(opt->region);
1658 		orig->name = region_strdup(opt->region, key->name);
1659 		orig->algorithm = region_strdup(opt->region, key->algorithm);
1660 		orig->secret = region_strdup(opt->region, key->secret);
1661 		key_options_setup(opt->region, orig);
1662 		tsig_add_key(orig->tsig_key);
1663 		key_options_insert(opt, orig);
1664 	} else {
1665 		/* modify entries in existing key, and copy to opt region */
1666 		key_options_desetup(opt->region, orig);
1667 		region_recycle(opt->region, orig->algorithm,
1668 			strlen(orig->algorithm)+1);
1669 		orig->algorithm = region_strdup(opt->region, key->algorithm);
1670 		region_recycle(opt->region, orig->secret,
1671 			strlen(orig->secret)+1);
1672 		orig->secret = region_strdup(opt->region, key->secret);
1673 		key_options_setup(opt->region, orig);
1674 	}
1675 }
1676 
1677 int
acl_check_incoming(struct acl_options * acl,struct query * q,struct acl_options ** reason)1678 acl_check_incoming(struct acl_options* acl, struct query* q,
1679 	struct acl_options** reason)
1680 {
1681 	/* check each acl element.
1682 	   if 1 blocked element matches - return -1.
1683 	   if any element matches - return number.
1684 	   else return -1. */
1685 	int found_match = -1;
1686 	int number = 0;
1687 	struct acl_options* match = 0;
1688 
1689 	if(reason)
1690 		*reason = NULL;
1691 
1692 	while(acl)
1693 	{
1694 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s",
1695 			acl->ip_address_spec, acl->nokey?"NOKEY":
1696 			(acl->blocked?"BLOCKED":acl->key_name)));
1697 		if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) {
1698 			if(!match)
1699 			{
1700 				match = acl; /* remember first match */
1701 				found_match=number;
1702 			}
1703 			if(acl->blocked) {
1704 				if(reason)
1705 					*reason = acl;
1706 				return -1;
1707 			}
1708 		}
1709 		number++;
1710 		acl = acl->next;
1711 	}
1712 
1713 	if(reason)
1714 		*reason = match;
1715 	return found_match;
1716 }
1717 
1718 #ifdef INET6
1719 int
acl_addr_matches_ipv6host(struct acl_options * acl,struct sockaddr_storage * addr_storage,unsigned int port)1720 acl_addr_matches_ipv6host(struct acl_options* acl, struct sockaddr_storage* addr_storage, unsigned int port)
1721 {
1722 	struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage;
1723 	if(acl->port != 0 && acl->port != port)
1724 		return 0;
1725 	switch(acl->rangetype) {
1726 	case acl_range_mask:
1727 	case acl_range_subnet:
1728 		if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
1729 			(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
1730 			return 0;
1731 		break;
1732 	case acl_range_minmax:
1733 		if(!acl_addr_match_range_v6((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
1734 			(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
1735 			return 0;
1736 		break;
1737 	case acl_range_single:
1738 	default:
1739 		if(memcmp(&addr->sin6_addr, &acl->addr.addr6,
1740 			sizeof(struct in6_addr)) != 0)
1741 			return 0;
1742 		break;
1743 	}
1744 	return 1;
1745 }
1746 #endif
1747 
1748 int
acl_addr_matches_ipv4host(struct acl_options * acl,struct sockaddr_in * addr,unsigned int port)1749 acl_addr_matches_ipv4host(struct acl_options* acl, struct sockaddr_in* addr, unsigned int port)
1750 {
1751 	if(acl->port != 0 && acl->port != port)
1752 		return 0;
1753 	switch(acl->rangetype) {
1754 	case acl_range_mask:
1755 	case acl_range_subnet:
1756 		if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
1757 			(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
1758 			return 0;
1759 		break;
1760 	case acl_range_minmax:
1761 		if(!acl_addr_match_range_v4((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
1762 			(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
1763 			return 0;
1764 		break;
1765 	case acl_range_single:
1766 	default:
1767 		if(memcmp(&addr->sin_addr, &acl->addr.addr,
1768 			sizeof(struct in_addr)) != 0)
1769 			return 0;
1770 		break;
1771 	}
1772 	return 1;
1773 }
1774 
1775 int
acl_addr_matches_host(struct acl_options * acl,struct acl_options * host)1776 acl_addr_matches_host(struct acl_options* acl, struct acl_options* host)
1777 {
1778 	if(acl->is_ipv6)
1779 	{
1780 #ifdef INET6
1781 		struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr;
1782 		if(!host->is_ipv6) return 0;
1783 		return acl_addr_matches_ipv6host(acl, addr, host->port);
1784 #else
1785 		return 0; /* no inet6, no match */
1786 #endif
1787 	}
1788 	else
1789 	{
1790 		struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr;
1791 		if(host->is_ipv6) return 0;
1792 		return acl_addr_matches_ipv4host(acl, addr, host->port);
1793 	}
1794 	/* ENOTREACH */
1795 	return 0;
1796 }
1797 
1798 int
acl_addr_matches(struct acl_options * acl,struct query * q)1799 acl_addr_matches(struct acl_options* acl, struct query* q)
1800 {
1801 	if(acl->is_ipv6)
1802 	{
1803 #ifdef INET6
1804 		struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr;
1805 		if(addr->ss_family != AF_INET6)
1806 			return 0;
1807 		return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port));
1808 #else
1809 		return 0; /* no inet6, no match */
1810 #endif
1811 	}
1812 	else
1813 	{
1814 		struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr;
1815 		if(addr->sin_family != AF_INET)
1816 			return 0;
1817 		return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port));
1818 	}
1819 	/* ENOTREACH */
1820 	return 0;
1821 }
1822 
1823 int
acl_addr_match_mask(uint32_t * a,uint32_t * b,uint32_t * mask,size_t sz)1824 acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz)
1825 {
1826 	size_t i;
1827 #ifndef NDEBUG
1828 	assert(sz % 4 == 0);
1829 #endif
1830 	sz /= 4;
1831 	for(i=0; i<sz; ++i)
1832 	{
1833 		if(((*a++)&*mask) != ((*b++)&*mask))
1834 			return 0;
1835 		++mask;
1836 	}
1837 	return 1;
1838 }
1839 
1840 int
acl_addr_match_range_v4(uint32_t * minval,uint32_t * x,uint32_t * maxval,size_t sz)1841 acl_addr_match_range_v4(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz)
1842 {
1843 	assert(sz == 4); (void)sz;
1844 	/* check treats x as one huge number */
1845 
1846 	/* if outside bounds, we are done */
1847 	if(*minval > *x)
1848 		return 0;
1849 	if(*maxval < *x)
1850 		return 0;
1851 
1852 	return 1;
1853 }
1854 
1855 #ifdef INET6
1856 int
acl_addr_match_range_v6(uint32_t * minval,uint32_t * x,uint32_t * maxval,size_t sz)1857 acl_addr_match_range_v6(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz)
1858 {
1859 	size_t i;
1860 	uint8_t checkmin = 1, checkmax = 1;
1861 #ifndef NDEBUG
1862 	assert(sz % 4 == 0);
1863 #endif
1864 	/* check treats x as one huge number */
1865 	sz /= 4;
1866 	for(i=0; i<sz; ++i)
1867 	{
1868 		/* if outside bounds, we are done */
1869 		if(checkmin)
1870 			if(minval[i] > x[i])
1871 				return 0;
1872 		if(checkmax)
1873 			if(maxval[i] < x[i])
1874 				return 0;
1875 		/* if x is equal to a bound, that bound needs further checks */
1876 		if(checkmin && minval[i]!=x[i])
1877 			checkmin = 0;
1878 		if(checkmax && maxval[i]!=x[i])
1879 			checkmax = 0;
1880 		if(!checkmin && !checkmax)
1881 			return 1; /* will always match */
1882 	}
1883 	return 1;
1884 }
1885 #endif /* INET6 */
1886 
1887 int
acl_key_matches(struct acl_options * acl,struct query * q)1888 acl_key_matches(struct acl_options* acl, struct query* q)
1889 {
1890 	if(acl->blocked)
1891 		return 1;
1892 	if(acl->nokey) {
1893 		if(q->tsig.status == TSIG_NOT_PRESENT)
1894 			return 1;
1895 		return 0;
1896 	}
1897 	/* check name of tsig key */
1898 	if(q->tsig.status != TSIG_OK) {
1899 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG"));
1900 		return 0; /* query has no TSIG */
1901 	}
1902 	if(q->tsig.error_code != TSIG_ERROR_NOERROR) {
1903 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error"));
1904 		return 0; /* some tsig error */
1905 	}
1906 	if(!acl->key_options->tsig_key) {
1907 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config"));
1908 		return 0; /* key not properly configured */
1909 	}
1910 	if(dname_compare(q->tsig.key_name,
1911 		acl->key_options->tsig_key->name) != 0) {
1912 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name"));
1913 		return 0; /* wrong key name */
1914 	}
1915 	if(tsig_strlowercmp(q->tsig.algorithm->short_name,
1916 		acl->key_options->algorithm) != 0 && (
1917 		strncmp("hmac-", q->tsig.algorithm->short_name, 5) != 0 ||
1918 		tsig_strlowercmp(q->tsig.algorithm->short_name+5,
1919 		acl->key_options->algorithm) != 0) ) {
1920 		DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm"));
1921 		return 0; /* no such algo */
1922 	}
1923 	return 1;
1924 }
1925 
1926 int
acl_same_host(struct acl_options * a,struct acl_options * b)1927 acl_same_host(struct acl_options* a, struct acl_options* b)
1928 {
1929 	if(a->is_ipv6 && !b->is_ipv6)
1930 		return 0;
1931 	if(!a->is_ipv6 && b->is_ipv6)
1932 		return 0;
1933 	if(a->port != b->port)
1934 		return 0;
1935 	if(a->rangetype != b->rangetype)
1936 		return 0;
1937 	if(!a->is_ipv6) {
1938 		if(memcmp(&a->addr.addr, &b->addr.addr,
1939 		   sizeof(struct in_addr)) != 0)
1940 			return 0;
1941 		if(a->rangetype != acl_range_single &&
1942 		   memcmp(&a->range_mask.addr, &b->range_mask.addr,
1943 		   sizeof(struct in_addr)) != 0)
1944 			return 0;
1945 	} else {
1946 #ifdef INET6
1947 		if(memcmp(&a->addr.addr6, &b->addr.addr6,
1948 		   sizeof(struct in6_addr)) != 0)
1949 			return 0;
1950 		if(a->rangetype != acl_range_single &&
1951 		   memcmp(&a->range_mask.addr6, &b->range_mask.addr6,
1952 		   sizeof(struct in6_addr)) != 0)
1953 			return 0;
1954 #else
1955 		return 0;
1956 #endif
1957 	}
1958 	return 1;
1959 }
1960 
1961 #if defined(HAVE_SSL)
1962 void
key_options_tsig_add(struct nsd_options * opt)1963 key_options_tsig_add(struct nsd_options* opt)
1964 {
1965 	struct key_options* optkey;
1966 	RBTREE_FOR(optkey, struct key_options*, opt->keys) {
1967 		key_options_setup(opt->region, optkey);
1968 		tsig_add_key(optkey->tsig_key);
1969 	}
1970 }
1971 #endif
1972 
1973 int
zone_is_slave(struct zone_options * opt)1974 zone_is_slave(struct zone_options* opt)
1975 {
1976 	return opt && opt->pattern && opt->pattern->request_xfr != 0;
1977 }
1978 
1979 /* get a character in string (or replacement char if not long enough) */
1980 static const char*
get_char(const char * str,size_t i)1981 get_char(const char* str, size_t i)
1982 {
1983 	static char res[2];
1984 	if(i >= strlen(str))
1985 		return ".";
1986 	res[0] = str[i];
1987 	res[1] = 0;
1988 	return res;
1989 }
1990 /* get end label of the zone name (or .) */
1991 static const char*
get_end_label(struct zone_options * zone,int i)1992 get_end_label(struct zone_options* zone, int i)
1993 {
1994 	const dname_type* d = (const dname_type*)zone->node.key;
1995 	if(i >= d->label_count) {
1996 		return ".";
1997 	}
1998 	return wirelabel2str(dname_label(d, i));
1999 }
2000 /* replace occurrences of one with two */
2001 void
replace_str(char * str,size_t len,const char * one,const char * two)2002 replace_str(char* str, size_t len, const char* one, const char* two)
2003 {
2004 	char* pos;
2005 	char* at = str;
2006 	while( (pos=strstr(at, one)) ) {
2007 		if(strlen(str)+strlen(two)-strlen(one) >= len)
2008 			return; /* no more space to replace */
2009 		/* stuff before pos is fine */
2010 		/* move the stuff after pos to make space for two, add
2011 		 * one to length of remainder to also copy the 0 byte end */
2012 		memmove(pos+strlen(two), pos+strlen(one),
2013 			strlen(pos+strlen(one))+1);
2014 		/* copy in two */
2015 		memmove(pos, two, strlen(two));
2016 		/* at is end of the newly inserted two (avoids recursion if
2017 		 * two contains one) */
2018 		at = pos+strlen(two);
2019 	}
2020 }
2021 
2022 const char*
config_cook_string(struct zone_options * zone,const char * input)2023 config_cook_string(struct zone_options* zone, const char* input)
2024 {
2025 	static char f[1024];
2026 	/* if not a template, return as-is */
2027 	if(!strchr(input, '%')) {
2028 		return input;
2029 	}
2030 	strlcpy(f, input, sizeof(f));
2031 	if(strstr(f, "%1"))
2032 		replace_str(f, sizeof(f), "%1", get_char(zone->name, 0));
2033 	if(strstr(f, "%2"))
2034 		replace_str(f, sizeof(f), "%2", get_char(zone->name, 1));
2035 	if(strstr(f, "%3"))
2036 		replace_str(f, sizeof(f), "%3", get_char(zone->name, 2));
2037 	if(strstr(f, "%z"))
2038 		replace_str(f, sizeof(f), "%z", get_end_label(zone, 1));
2039 	if(strstr(f, "%y"))
2040 		replace_str(f, sizeof(f), "%y", get_end_label(zone, 2));
2041 	if(strstr(f, "%x"))
2042 		replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
2043 	if(strstr(f, "%s"))
2044 		replace_str(f, sizeof(f), "%s", zone->name);
2045 	return f;
2046 }
2047 
2048 const char*
config_make_zonefile(struct zone_options * zone,struct nsd * nsd)2049 config_make_zonefile(struct zone_options* zone, struct nsd* nsd)
2050 {
2051 	static char f[1024];
2052 	/* if not a template, return as-is */
2053 	if(!strchr(zone->pattern->zonefile, '%')) {
2054 		if (nsd->chrootdir && nsd->chrootdir[0] &&
2055 			zone->pattern->zonefile &&
2056 			zone->pattern->zonefile[0] == '/' &&
2057 			strncmp(zone->pattern->zonefile, nsd->chrootdir,
2058 			strlen(nsd->chrootdir)) == 0)
2059 			/* -1 because chrootdir ends in trailing slash */
2060 			return zone->pattern->zonefile + strlen(nsd->chrootdir) - 1;
2061 		return zone->pattern->zonefile;
2062 	}
2063 	strlcpy(f, zone->pattern->zonefile, sizeof(f));
2064 	if(strstr(f, "%1"))
2065 		replace_str(f, sizeof(f), "%1", get_char(zone->name, 0));
2066 	if(strstr(f, "%2"))
2067 		replace_str(f, sizeof(f), "%2", get_char(zone->name, 1));
2068 	if(strstr(f, "%3"))
2069 		replace_str(f, sizeof(f), "%3", get_char(zone->name, 2));
2070 	if(strstr(f, "%z"))
2071 		replace_str(f, sizeof(f), "%z", get_end_label(zone, 1));
2072 	if(strstr(f, "%y"))
2073 		replace_str(f, sizeof(f), "%y", get_end_label(zone, 2));
2074 	if(strstr(f, "%x"))
2075 		replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
2076 	if(strstr(f, "%s"))
2077 		replace_str(f, sizeof(f), "%s", zone->name);
2078 	if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' &&
2079 		strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0)
2080 		/* -1 because chrootdir ends in trailing slash */
2081 		return f + strlen(nsd->chrootdir) - 1;
2082 	return f;
2083 }
2084 
2085 struct zone_options*
zone_options_find(struct nsd_options * opt,const struct dname * apex)2086 zone_options_find(struct nsd_options* opt, const struct dname* apex)
2087 {
2088 	return (struct zone_options*) rbtree_search(opt->zone_options, apex);
2089 }
2090 
2091 struct acl_options*
acl_find_num(struct acl_options * acl,int num)2092 acl_find_num(struct acl_options* acl, int num)
2093 {
2094 	int count = num;
2095 	if(num < 0)
2096 		return 0;
2097 	while(acl && count > 0) {
2098 		acl = acl->next;
2099 		count--;
2100 	}
2101 	if(count == 0)
2102 		return acl;
2103 	return 0;
2104 }
2105 
2106 /* true if ipv6 address, false if ipv4 */
2107 int
parse_acl_is_ipv6(const char * p)2108 parse_acl_is_ipv6(const char* p)
2109 {
2110 	/* see if addr is ipv6 or ipv4 -- by : and . */
2111 	while(*p) {
2112 		if(*p == '.') return 0;
2113 		if(*p == ':') return 1;
2114 		++p;
2115 	}
2116 	return 0;
2117 }
2118 
2119 /* returns range type. mask is the 2nd part of the range */
2120 int
parse_acl_range_type(char * ip,char ** mask)2121 parse_acl_range_type(char* ip, char** mask)
2122 {
2123 	char *p;
2124 	if((p=strchr(ip, '&'))!=0) {
2125 		*p = 0;
2126 		*mask = p+1;
2127 		return acl_range_mask;
2128 	}
2129 	if((p=strchr(ip, '/'))!=0) {
2130 		*p = 0;
2131 		*mask = p+1;
2132 		return acl_range_subnet;
2133 	}
2134 	if((p=strchr(ip, '-'))!=0) {
2135 		*p = 0;
2136 		*mask = p+1;
2137 		return acl_range_minmax;
2138 	}
2139 	*mask = 0;
2140 	return acl_range_single;
2141 }
2142 
2143 /* parses subnet mask, fills 0 mask as well */
2144 void
parse_acl_range_subnet(char * p,void * addr,int maxbits)2145 parse_acl_range_subnet(char* p, void* addr, int maxbits)
2146 {
2147 	int subnet_bits = atoi(p);
2148 	uint8_t* addr_bytes = (uint8_t*)addr;
2149 	if(subnet_bits == 0 && strcmp(p, "0")!=0) {
2150 		c_error("bad subnet range '%s'", p);
2151 		return;
2152 	}
2153 	if(subnet_bits < 0 || subnet_bits > maxbits) {
2154 		c_error("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits);
2155 		return;
2156 	}
2157 	/* fill addr with n bits of 1s (struct has been zeroed) */
2158 	while(subnet_bits >= 8) {
2159 		*addr_bytes++ = 0xff;
2160 		subnet_bits -= 8;
2161 	}
2162 	if(subnet_bits > 0) {
2163 		uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
2164 		*addr_bytes = shifts[subnet_bits];
2165 	}
2166 }
2167 
2168 struct acl_options*
parse_acl_info(region_type * region,char * ip,const char * key)2169 parse_acl_info(region_type* region, char* ip, const char* key)
2170 {
2171 	char* p;
2172 	struct acl_options* acl = (struct acl_options*)region_alloc(region,
2173 		sizeof(struct acl_options));
2174 	acl->next = 0;
2175 	/* ip */
2176 	acl->ip_address_spec = region_strdup(region, ip);
2177 	acl->use_axfr_only = 0;
2178 	acl->allow_udp = 0;
2179 	acl->ixfr_disabled = 0;
2180 	acl->bad_xfr_count = 0;
2181 	acl->key_options = 0;
2182 	acl->tls_auth_options = 0;
2183 	acl->tls_auth_name = 0;
2184 	acl->is_ipv6 = 0;
2185 	acl->port = 0;
2186 	memset(&acl->addr, 0, sizeof(union acl_addr_storage));
2187 	memset(&acl->range_mask, 0, sizeof(union acl_addr_storage));
2188 	if((p=strrchr(ip, '@'))!=0) {
2189 		if(atoi(p+1) == 0) c_error("expected port number after '@'");
2190 		else acl->port = atoi(p+1);
2191 		*p=0;
2192 	}
2193 	acl->rangetype = parse_acl_range_type(ip, &p);
2194 	if(parse_acl_is_ipv6(ip)) {
2195 		acl->is_ipv6 = 1;
2196 #ifdef INET6
2197 		if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1)
2198 			c_error("Bad ip6 address '%s'", ip);
2199 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
2200 			assert(p);
2201 			if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1)
2202 				c_error("Bad ip6 address mask '%s'", p);
2203 		}
2204 		if(acl->rangetype==acl_range_subnet) {
2205 			assert(p);
2206 			parse_acl_range_subnet(p, &acl->range_mask.addr6, 128);
2207 		}
2208 #else
2209 		c_error("encountered IPv6 address '%s'.", ip);
2210 #endif /* INET6 */
2211 	} else {
2212 		acl->is_ipv6 = 0;
2213 		if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1)
2214 			c_error("Bad ip4 address '%s'", ip);
2215 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
2216 			assert(p);
2217 			if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1)
2218 				c_error("Bad ip4 address mask '%s'", p);
2219 		}
2220 		if(acl->rangetype==acl_range_subnet) {
2221 			assert(p);
2222 			parse_acl_range_subnet(p, &acl->range_mask.addr, 32);
2223 		}
2224 	}
2225 
2226 	/* key */
2227 	if(strcmp(key, "NOKEY")==0) {
2228 		acl->nokey = 1;
2229 		acl->blocked = 0;
2230 		acl->key_name = 0;
2231 	} else if(strcmp(key, "BLOCKED")==0) {
2232 		acl->nokey = 0;
2233 		acl->blocked = 1;
2234 		acl->key_name = 0;
2235 	} else {
2236 		acl->nokey = 0;
2237 		acl->blocked = 0;
2238 		acl->key_name = region_strdup(region, key);
2239 	}
2240 	return acl;
2241 }
2242 
2243 /* copy acl list at end of parser start, update current */
2244 static
copy_and_append_acls(struct acl_options ** start,struct acl_options * list)2245 void copy_and_append_acls(struct acl_options** start, struct acl_options* list)
2246 {
2247 	struct acl_options *tail = NULL;
2248 
2249 	assert(start != NULL);
2250 
2251 	tail = *start;
2252 	if(tail) {
2253 		while(tail->next) {
2254 			tail = tail->next;
2255 		}
2256 	}
2257 
2258 	while(list) {
2259 		struct acl_options* acl = copy_acl(cfg_parser->opt->region,
2260 			list);
2261 		acl->next = NULL;
2262 		if(tail) {
2263 			tail->next = acl;
2264 		} else {
2265 			*start = acl;
2266 		}
2267 		tail = acl;
2268 		list = list->next;
2269 	}
2270 }
2271 
2272 void
config_apply_pattern(struct pattern_options * dest,const char * name)2273 config_apply_pattern(struct pattern_options *dest, const char* name)
2274 {
2275 	/* find the pattern */
2276 	struct pattern_options* pat = pattern_options_find(cfg_parser->opt,
2277 		name);
2278 	if(!pat) {
2279 		c_error("could not find pattern %s", name);
2280 		return;
2281 	}
2282 
2283 	/* apply settings */
2284 	if(pat->zonefile)
2285 		dest->zonefile = region_strdup(cfg_parser->opt->region,
2286 			pat->zonefile);
2287 	if(pat->zonestats)
2288 		dest->zonestats = region_strdup(cfg_parser->opt->region,
2289 			pat->zonestats);
2290 	if(!pat->allow_axfr_fallback_is_default) {
2291 		dest->allow_axfr_fallback = pat->allow_axfr_fallback;
2292 		dest->allow_axfr_fallback_is_default = 0;
2293 	}
2294 	if(!pat->notify_retry_is_default) {
2295 		dest->notify_retry = pat->notify_retry;
2296 		dest->notify_retry_is_default = 0;
2297 	}
2298 	if(!pat->max_refresh_time_is_default) {
2299 		dest->max_refresh_time = pat->max_refresh_time;
2300 		dest->max_refresh_time_is_default = 0;
2301 	}
2302 	if(!pat->min_refresh_time_is_default) {
2303 		dest->min_refresh_time = pat->min_refresh_time;
2304 		dest->min_refresh_time_is_default = 0;
2305 	}
2306 	if(!pat->max_retry_time_is_default) {
2307 		dest->max_retry_time = pat->max_retry_time;
2308 		dest->max_retry_time_is_default = 0;
2309 	}
2310 	if(!pat->min_retry_time_is_default) {
2311 		dest->min_retry_time = pat->min_retry_time;
2312 		dest->min_retry_time_is_default = 0;
2313 	}
2314 	if(!expire_time_is_default(pat->min_expire_time_expr)) {
2315 		dest->min_expire_time = pat->min_expire_time;
2316 		dest->min_expire_time_expr = pat->min_expire_time_expr;
2317 	}
2318 	if(!pat->store_ixfr_is_default) {
2319 		dest->store_ixfr = pat->store_ixfr;
2320 		dest->store_ixfr_is_default = 0;
2321 	}
2322 	if(!pat->ixfr_size_is_default) {
2323 		dest->ixfr_size = pat->ixfr_size;
2324 		dest->ixfr_size_is_default = 0;
2325 	}
2326 	if(!pat->ixfr_number_is_default) {
2327 		dest->ixfr_number = pat->ixfr_number;
2328 		dest->ixfr_number_is_default = 0;
2329 	}
2330 	if(!pat->create_ixfr_is_default) {
2331 		dest->create_ixfr = pat->create_ixfr;
2332 		dest->create_ixfr_is_default = 0;
2333 	}
2334 	dest->size_limit_xfr = pat->size_limit_xfr;
2335 #ifdef RATELIMIT
2336 	dest->rrl_whitelist |= pat->rrl_whitelist;
2337 #endif
2338 	/* append acl items */
2339 	copy_and_append_acls(&dest->allow_notify, pat->allow_notify);
2340 	copy_and_append_acls(&dest->request_xfr, pat->request_xfr);
2341 	copy_and_append_acls(&dest->notify, pat->notify);
2342 	copy_and_append_acls(&dest->provide_xfr, pat->provide_xfr);
2343 	copy_and_append_acls(&dest->allow_query, pat->allow_query);
2344 	copy_and_append_acls(&dest->outgoing_interface, pat->outgoing_interface);
2345 	if(pat->multi_master_check)
2346 		dest->multi_master_check = pat->multi_master_check;
2347 
2348 	if(!pat->verify_zone_is_default) {
2349 		dest->verify_zone = pat->verify_zone;
2350 		dest->verify_zone_is_default = 0;
2351 	}
2352 	if(!pat->verifier_timeout_is_default) {
2353 		dest->verifier_timeout = pat->verifier_timeout;
2354 		dest->verifier_timeout_is_default = 0;
2355 	}
2356 	if(!pat->verifier_feed_zone_is_default) {
2357 		dest->verifier_feed_zone = pat->verifier_feed_zone;
2358 		dest->verifier_feed_zone_is_default = 0;
2359 	}
2360 	if(pat->verifier != NULL) {
2361 		size_t cnt;
2362 		char **vec;
2363 		region_type *region = cfg_parser->opt->region;
2364 
2365 		for(cnt = 0; pat->verifier[cnt] != NULL; cnt++) ;
2366 		vec = region_alloc(region, (cnt + 1) * sizeof(char *));
2367 		for(cnt = 0; pat->verifier[cnt] != NULL; cnt++) {
2368 			vec[cnt] = region_strdup(region, pat->verifier[cnt]);
2369 		}
2370 		vec[cnt] = NULL;
2371 		if(dest->verifier != NULL) {
2372 			size_t size;
2373 			for(cnt = 0; dest->verifier[cnt] != NULL; cnt++) {
2374 				size = strlen(dest->verifier[cnt]) + 1;
2375 				region_recycle(
2376 					region, dest->verifier[cnt], size);
2377 			}
2378 			size = (cnt + 1) * sizeof(char *);
2379 			region_recycle(region, dest->verifier, size);
2380 		}
2381 		dest->verifier = vec;
2382 	}
2383 }
2384 
2385 void
nsd_options_destroy(struct nsd_options * opt)2386 nsd_options_destroy(struct nsd_options* opt)
2387 {
2388 	region_destroy(opt->region);
2389 #ifdef MEMCLEAN /* OS collects memory pages */
2390 	c_lex_destroy();
2391 #endif
2392 }
2393 
getzonestatid(struct nsd_options * opt,struct zone_options * zopt)2394 unsigned getzonestatid(struct nsd_options* opt, struct zone_options* zopt)
2395 {
2396 #ifdef USE_ZONE_STATS
2397 	const char* statname;
2398 	struct zonestatname* n;
2399 	rbnode_type* res;
2400 	/* try to find the instantiated zonestat name */
2401 	if(!zopt->pattern->zonestats || zopt->pattern->zonestats[0]==0)
2402 		return 0; /* no zone stats */
2403 	statname = config_cook_string(zopt, zopt->pattern->zonestats);
2404 	res = rbtree_search(opt->zonestatnames, statname);
2405 	if(res)
2406 		return ((struct zonestatname*)res)->id;
2407 	/* create it */
2408 	n = (struct zonestatname*)region_alloc_zero(opt->region, sizeof(*n));
2409 	n->node.key = region_strdup(opt->region, statname);
2410 	if(!n->node.key) {
2411 		log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
2412 		exit(1);
2413 	}
2414 	n->id = (unsigned)(opt->zonestatnames->count);
2415 	rbtree_insert(opt->zonestatnames, (rbnode_type*)n);
2416 	return n->id;
2417 #else /* USE_ZONE_STATS */
2418 	(void)opt; (void)zopt;
2419 	return 0;
2420 #endif /* USE_ZONE_STATS */
2421 }
2422 
2423 /** check if config turns on IP-address interface with certificates or a
2424  * named pipe without certificates. */
2425 int
options_remote_is_address(struct nsd_options * cfg)2426 options_remote_is_address(struct nsd_options* cfg)
2427 {
2428 	if(!cfg->control_enable) return 0;
2429 	if(!cfg->control_interface) return 1;
2430 	if(!cfg->control_interface->address) return 1;
2431 	if(cfg->control_interface->address[0] == 0) return 1;
2432 	return (cfg->control_interface->address[0] != '/');
2433 }
2434 
2435 #ifdef HAVE_GETIFADDRS
2436 static void
resolve_ifa_name(struct ifaddrs * ifas,const char * search_ifa,char *** ip_addresses,size_t * ip_addresses_size)2437 resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addresses, size_t *ip_addresses_size)
2438 {
2439 	struct ifaddrs *ifa;
2440 	size_t last_ip_addresses_size = *ip_addresses_size;
2441 
2442 	for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
2443 		sa_family_t family;
2444 		const char* atsign;
2445 #ifdef INET6      /* |   address ip    | % |  ifa name  | @ |  port  | nul */
2446 		char addr_buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1 + 16 + 1];
2447 #else
2448 		char addr_buf[INET_ADDRSTRLEN + 1 + 16 + 1];
2449 #endif
2450 
2451 		if((atsign=strrchr(search_ifa, '@')) != NULL) {
2452 			if(strlen(ifa->ifa_name) != (size_t)(atsign-search_ifa)
2453 			   || strncmp(ifa->ifa_name, search_ifa,
2454 			   atsign-search_ifa) != 0)
2455 				continue;
2456 		} else {
2457 			if(strcmp(ifa->ifa_name, search_ifa) != 0)
2458 				continue;
2459 			atsign = "";
2460 		}
2461 
2462 		if(ifa->ifa_addr == NULL)
2463 			continue;
2464 
2465 		family = ifa->ifa_addr->sa_family;
2466 		if(family == AF_INET) {
2467 			char a4[INET_ADDRSTRLEN + 1];
2468 			struct sockaddr_in *in4 = (struct sockaddr_in *)
2469 				ifa->ifa_addr;
2470 			if(!inet_ntop(family, &in4->sin_addr, a4, sizeof(a4)))
2471 				error("inet_ntop");
2472 			snprintf(addr_buf, sizeof(addr_buf), "%s%s",
2473 				a4, atsign);
2474 		}
2475 #ifdef INET6
2476 		else if(family == AF_INET6) {
2477 			struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)
2478 				ifa->ifa_addr;
2479 			char a6[INET6_ADDRSTRLEN + 1];
2480 			char if_index_name[IF_NAMESIZE + 1];
2481 			if_index_name[0] = 0;
2482 			if(!inet_ntop(family, &in6->sin6_addr, a6, sizeof(a6)))
2483 				error("inet_ntop");
2484 			if_indextoname(in6->sin6_scope_id,
2485 				(char *)if_index_name);
2486 			if (strlen(if_index_name) != 0) {
2487 				snprintf(addr_buf, sizeof(addr_buf),
2488 					"%s%%%s%s", a6, if_index_name, atsign);
2489 			} else {
2490 				snprintf(addr_buf, sizeof(addr_buf), "%s%s",
2491 					a6, atsign);
2492 			}
2493 		}
2494 #endif
2495 		else {
2496 			continue;
2497 		}
2498 		VERBOSITY(4, (LOG_INFO, "interface %s has address %s",
2499 			search_ifa, addr_buf));
2500 
2501 		*ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
2502 		(*ip_addresses)[*ip_addresses_size] = xstrdup(addr_buf);
2503 		(*ip_addresses_size)++;
2504 	}
2505 
2506 	if (*ip_addresses_size == last_ip_addresses_size) {
2507 		*ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
2508 		(*ip_addresses)[*ip_addresses_size] = xstrdup(search_ifa);
2509 		(*ip_addresses_size)++;
2510 	}
2511 }
2512 
2513 static void
resolve_interface_names_for_ref(struct ip_address_option ** ip_addresses_ref,struct ifaddrs * addrs,region_type * region)2514 resolve_interface_names_for_ref(struct ip_address_option** ip_addresses_ref,
2515 		struct ifaddrs *addrs, region_type* region)
2516 {
2517 	struct ip_address_option *ip_addr;
2518 	struct ip_address_option *last = NULL;
2519 	struct ip_address_option *first = NULL;
2520 
2521 	/* replace the list of ip_adresses with a new list where the
2522 	 * interface names are replaced with their ip-address strings
2523 	 * from getifaddrs.  An interface can have several addresses. */
2524 	for(ip_addr = *ip_addresses_ref; ip_addr; ip_addr = ip_addr->next) {
2525 		char **ip_addresses = NULL;
2526 		size_t ip_addresses_size = 0, i;
2527 		resolve_ifa_name(addrs, ip_addr->address, &ip_addresses,
2528 			&ip_addresses_size);
2529 
2530 		for (i = 0; i < ip_addresses_size; i++) {
2531 			struct ip_address_option *current;
2532 			/* this copies the range_option, dev, and fib from
2533 			 * the original ip_address option to the new ones
2534 			 * with the addresses spelled out by resolve_ifa_name*/
2535 			current = region_alloc_init(region, ip_addr,
2536 				sizeof(*ip_addr));
2537 			current->address = region_strdup(region,
2538 				ip_addresses[i]);
2539 			current->next = NULL;
2540 			free(ip_addresses[i]);
2541 
2542 			if(first == NULL) {
2543 				first = current;
2544 			} else {
2545 				last->next = current;
2546 			}
2547 			last = current;
2548 		}
2549 		free(ip_addresses);
2550 	}
2551 	*ip_addresses_ref = first;
2552 
2553 }
2554 #endif /* HAVE_GETIFADDRS */
2555 
2556 void
resolve_interface_names(struct nsd_options * options)2557 resolve_interface_names(struct nsd_options* options)
2558 {
2559 #ifdef HAVE_GETIFADDRS
2560 	struct ifaddrs *addrs;
2561 
2562 	if(getifaddrs(&addrs) == -1)
2563 		  error("failed to list interfaces");
2564 
2565 	resolve_interface_names_for_ref(&options->ip_addresses,
2566 			addrs, options->region);
2567 	resolve_interface_names_for_ref(&options->control_interface,
2568 			addrs, options->region);
2569 
2570 	freeifaddrs(addrs);
2571 #else
2572 	(void)options;
2573 #endif /* HAVE_GETIFADDRS */
2574 }
2575