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