xref: /openbsd-src/usr.sbin/nsd/options.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*
2  * options.c -- options functions.
3  *
4  * Copyright (c) 2001-2011, 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 <errno.h>
13 #include "options.h"
14 #include "query.h"
15 #include "tsig.h"
16 #include "difffile.h"
17 
18 #include "configyyrename.h"
19 #include "configparser.h"
20 nsd_options_t* nsd_options = 0;
21 config_parser_state_t* cfg_parser = 0;
22 extern FILE* c_in, *c_out;
23 int c_parse(void);
24 int c_lex(void);
25 int c_wrap(void);
26 void c_error(const char *message);
27 
28 nsd_options_t* nsd_options_create(region_type* region)
29 {
30 	nsd_options_t* opt;
31 	opt = (nsd_options_t*)region_alloc(region, sizeof(nsd_options_t));
32 	opt->region = region;
33 	opt->zone_options = rbtree_create(region,
34 		(int (*)(const void *, const void *)) dname_compare);
35 	opt->keys = NULL;
36 	opt->numkeys = 0;
37 	opt->ip_addresses = NULL;
38 	opt->debug_mode = 0;
39 	opt->verbosity = 0;
40 	opt->hide_version = 0;
41 	opt->ip4_only = 0;
42 	opt->ip6_only = 0;
43 	opt->database = DBFILE;
44 	opt->identity = 0;
45 	opt->nsid = 0;
46 	opt->logfile = 0;
47 	opt->server_count = 1;
48 	opt->tcp_count = 10;
49 	opt->tcp_query_count = 0;
50 	opt->tcp_timeout = TCP_TIMEOUT;
51 	opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN;
52 	opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN;
53 	opt->pidfile = PIDFILE;
54 	opt->port = UDP_PORT;
55 /* deprecated?	opt->port = TCP_PORT; */
56 	opt->statistics = 0;
57 	opt->chroot = 0;
58 	opt->username = USER;
59 	opt->zonesdir = ZONESDIR;
60 	opt->difffile = DIFFFILE;
61 	opt->xfrdfile = XFRDFILE;
62 	opt->xfrd_reload_timeout = 10;
63 	nsd_options = opt;
64 	return opt;
65 }
66 
67 int nsd_options_insert_zone(nsd_options_t* opt, zone_options_t* zone)
68 {
69 	/* create dname for lookup */
70 	const dname_type* dname = dname_parse(opt->region, zone->name);
71 	if(!dname)
72 		return 0;
73 	zone->node.key = dname;
74 	if(!rbtree_insert(opt->zone_options, (rbnode_t*)zone))
75 		return 0;
76 	return 1;
77 }
78 
79 int parse_options_file(nsd_options_t* opt, const char* file)
80 {
81 	FILE *in = 0;
82 	zone_options_t* zone;
83 	acl_options_t* acl;
84 
85 	if(!cfg_parser)
86 		cfg_parser = (config_parser_state_t*)region_alloc(
87 			opt->region, sizeof(config_parser_state_t));
88 	cfg_parser->filename = file;
89 	cfg_parser->line = 1;
90 	cfg_parser->errors = 0;
91 	cfg_parser->opt = opt;
92 	cfg_parser->current_zone = 0;
93 	cfg_parser->current_key = opt->keys;
94 	while(cfg_parser->current_key && cfg_parser->current_key->next)
95 		cfg_parser->current_key = cfg_parser->current_key->next;
96 	cfg_parser->current_ip_address_option = opt->ip_addresses;
97 	while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next)
98 		cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next;
99 	cfg_parser->current_allow_notify = 0;
100 	cfg_parser->current_request_xfr = 0;
101 	cfg_parser->current_notify = 0;
102 	cfg_parser->current_provide_xfr = 0;
103 
104 	in = fopen(cfg_parser->filename, "r");
105 	if(!in) {
106 		fprintf(stderr, "Could not open %s: %s\n", file, strerror(errno));
107 		return 0;
108 	}
109 	c_in = in;
110 	c_parse();
111 	fclose(in);
112 
113 	if(cfg_parser->current_zone) {
114 		if(!cfg_parser->current_zone->name)
115 			c_error("last zone has no name");
116 		else {
117 			if(!nsd_options_insert_zone(opt,
118 				cfg_parser->current_zone))
119 				c_error("duplicate zone");
120 		}
121 		if(!cfg_parser->current_zone->zonefile)
122 			c_error("last zone has no zonefile");
123 	}
124 	if(opt->keys)
125 	{
126 		if(!opt->keys->name)
127 			c_error("last key has no name");
128 		if(!opt->keys->algorithm)
129 			c_error("last key has no algorithm");
130 		if(!opt->keys->secret)
131 			c_error("last key has no secret blob");
132 	}
133 	RBTREE_FOR(zone, zone_options_t*, opt->zone_options)
134 	{
135 		if(!zone->name)
136 			continue;
137 		if(!zone->zonefile)
138 			continue;
139 		/* lookup keys for acls */
140 		for(acl=zone->allow_notify; acl; acl=acl->next)
141 		{
142 			if(acl->nokey || acl->blocked)
143 				continue;
144 			acl->key_options = key_options_find(opt, acl->key_name);
145 			if(!acl->key_options)
146 				c_error_msg("key %s in zone %s could not be found",
147 					acl->key_name, zone->name);
148 		}
149 		for(acl=zone->notify; acl; acl=acl->next)
150 		{
151 			if(acl->nokey || acl->blocked)
152 				continue;
153 			acl->key_options = key_options_find(opt, acl->key_name);
154 			if(!acl->key_options)
155 				c_error_msg("key %s in zone %s could not be found",
156 					acl->key_name, zone->name);
157 		}
158 		for(acl=zone->request_xfr; acl; acl=acl->next)
159 		{
160 			if(acl->nokey || acl->blocked)
161 				continue;
162 			acl->key_options = key_options_find(opt, acl->key_name);
163 			if(!acl->key_options)
164 				c_error_msg("key %s in zone %s could not be found",
165 					acl->key_name, zone->name);
166 		}
167 		for(acl=zone->provide_xfr; acl; acl=acl->next)
168 		{
169 			if(acl->nokey || acl->blocked)
170 				continue;
171 			acl->key_options = key_options_find(opt, acl->key_name);
172 			if(!acl->key_options)
173 				c_error_msg("key %s in zone %s could not be found",
174 					acl->key_name, zone->name);
175 		}
176 	}
177 
178 	if(cfg_parser->errors > 0)
179 	{
180         	fprintf(stderr, "read %s failed: %d errors in configuration file\n",
181 			cfg_parser->filename,
182 			cfg_parser->errors);
183 		return 0;
184 	}
185 	return 1;
186 }
187 
188 void c_error_va_list(const char *fmt, va_list args)
189 {
190 	cfg_parser->errors++;
191         fprintf(stderr, "%s:%d: error: ", cfg_parser->filename,
192 		cfg_parser->line);
193 	vfprintf(stderr, fmt, args);
194 	fprintf(stderr, "\n");
195 }
196 
197 void c_error_msg(const char* fmt, ...)
198 {
199         va_list args;
200         va_start(args, fmt);
201         c_error_va_list(fmt, args);
202         va_end(args);
203 }
204 
205 void c_error(const char *str)
206 {
207 	cfg_parser->errors++;
208         fprintf(stderr, "%s:%d: error: %s\n", cfg_parser->filename,
209 		cfg_parser->line, str);
210 }
211 
212 int c_wrap()
213 {
214         return 1;
215 }
216 
217 zone_options_t* zone_options_create(region_type* region)
218 {
219 	zone_options_t* zone;
220 	zone = (zone_options_t*)region_alloc(region, sizeof(zone_options_t));
221 	zone->node = *RBTREE_NULL;
222 	zone->name = 0;
223 	zone->zonefile = 0;
224 	zone->allow_notify = 0;
225 	zone->request_xfr = 0;
226 	zone->notify = 0;
227 	zone->notify_retry = 5;
228 	zone->provide_xfr = 0;
229 	zone->outgoing_interface = 0;
230 	zone->allow_axfr_fallback = 1;
231 	return zone;
232 }
233 
234 key_options_t* key_options_create(region_type* region)
235 {
236 	key_options_t* key;
237 	key = (key_options_t*)region_alloc(region, sizeof(key_options_t));
238 	key->name = 0;
239 	key->next = 0;
240 	key->algorithm = 0;
241 	key->secret = 0;
242 	key->tsig_key = 0;
243 	return key;
244 }
245 
246 key_options_t* key_options_find(nsd_options_t* opt, const char* name)
247 {
248 	key_options_t* key = opt->keys;
249 	while(key) {
250 		if(strcmp(key->name, name)==0)
251 			return key;
252 		key = key->next;
253 	}
254 	return 0;
255 }
256 
257 int acl_check_incoming(acl_options_t* acl, struct query* q,
258 	acl_options_t** reason)
259 {
260 	/* check each acl element.
261 	   if 1 blocked element matches - return -1.
262 	   if any element matches - return number.
263 	   else return -1. */
264 	int found_match = -1;
265 	int number = 0;
266 	acl_options_t* match = 0;
267 
268 	if(reason)
269 		*reason = NULL;
270 
271 	while(acl)
272 	{
273 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s",
274 			acl->ip_address_spec, acl->nokey?"NOKEY":
275 			(acl->blocked?"BLOCKED":acl->key_name)));
276 		if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) {
277 			if(!match)
278 			{
279 				match = acl; /* remember first match */
280 				found_match=number;
281 			}
282 			if(acl->blocked) {
283 				if(reason)
284 					*reason = acl;
285 				return -1;
286 			}
287 		}
288 		number++;
289 		acl = acl->next;
290 	}
291 
292 	if(reason)
293 		*reason = match;
294 	return found_match;
295 }
296 
297 int acl_addr_matches(acl_options_t* acl, struct query* q)
298 {
299 	if(acl->is_ipv6)
300 	{
301 #ifdef INET6
302 		struct sockaddr_storage* addr_storage = (struct sockaddr_storage*)&q->addr;
303 		struct sockaddr_in6* addr = (struct sockaddr_in6*)&q->addr;
304 		if(addr_storage->ss_family != AF_INET6)
305 			return 0;
306 		if(acl->port != 0 && acl->port != ntohs(addr->sin6_port))
307 			return 0;
308 		switch(acl->rangetype) {
309 		case acl_range_mask:
310 		case acl_range_subnet:
311 			if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
312 				(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
313 				return 0;
314 			break;
315 		case acl_range_minmax:
316 			if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
317 				(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
318 				return 0;
319 			break;
320 		case acl_range_single:
321 		default:
322 			if(memcmp(&addr->sin6_addr, &acl->addr.addr6,
323 				sizeof(struct in6_addr)) != 0)
324 				return 0;
325 			break;
326 		}
327 		return 1;
328 #else
329 		return 0; /* no inet6, no match */
330 #endif
331 	}
332 	else
333 	{
334 		struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr;
335 		if(addr->sin_family != AF_INET)
336 			return 0;
337 		if(acl->port != 0 && acl->port != ntohs(addr->sin_port))
338 			return 0;
339 		switch(acl->rangetype) {
340 		case acl_range_mask:
341 		case acl_range_subnet:
342 			if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
343 				(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
344 				return 0;
345 			break;
346 		case acl_range_minmax:
347 			if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
348 				(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
349 				return 0;
350 			break;
351 		case acl_range_single:
352 		default:
353 			if(memcmp(&addr->sin_addr, &acl->addr.addr,
354 				sizeof(struct in_addr)) != 0)
355 				return 0;
356 			break;
357 		}
358 		return 1;
359 	}
360 	/* ENOTREACH */
361 	return 0;
362 }
363 
364 int acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz)
365 {
366 	size_t i;
367 #ifndef NDEBUG
368 	assert(sz % 4 == 0);
369 #endif
370 	sz /= 4;
371 	for(i=0; i<sz; ++i)
372 	{
373 		if(((*a++)&*mask) != ((*b++)&*mask))
374 			return 0;
375 		++mask;
376 	}
377 	return 1;
378 }
379 
380 int acl_addr_match_range(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz)
381 {
382 	size_t i;
383 	uint8_t checkmin = 1, checkmax = 1;
384 #ifndef NDEBUG
385 	assert(sz % 4 == 0);
386 #endif
387 	/* check treats x as one huge number */
388 	sz /= 4;
389 	for(i=0; i<sz; ++i)
390 	{
391 		/* if outside bounds, we are done */
392 		if(checkmin)
393 			if(minval[i] > x[i])
394 				return 0;
395 		if(checkmax)
396 			if(maxval[i] < x[i])
397 				return 0;
398 		/* if x is equal to a bound, that bound needs further checks */
399 		if(checkmin && minval[i]!=x[i])
400 			checkmin = 0;
401 		if(checkmax && maxval[i]!=x[i])
402 			checkmax = 0;
403 		if(!checkmin && !checkmax)
404 			return 1; /* will always match */
405 	}
406 	return 1;
407 }
408 
409 int acl_key_matches(acl_options_t* acl, struct query* q)
410 {
411 	if(acl->blocked)
412 		return 1;
413 	if(acl->nokey) {
414 		if(q->tsig.status == TSIG_NOT_PRESENT)
415 			return 1;
416 		return 0;
417 	}
418 	/* check name of tsig key */
419 	if(q->tsig.status != TSIG_OK) {
420 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG"));
421 		return 0; /* query has no TSIG */
422 	}
423 	if(q->tsig.error_code != TSIG_ERROR_NOERROR) {
424 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error"));
425 		return 0; /* some tsig error */
426 	}
427 	if(!acl->key_options->tsig_key) {
428 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config"));
429 		return 0; /* key not properly configged */
430 	}
431 	if(dname_compare(q->tsig.key_name,
432 		acl->key_options->tsig_key->name) != 0) {
433 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name"));
434 		return 0; /* wrong key name */
435 	}
436 	if(tsig_strlowercmp(q->tsig.algorithm->short_name,
437 		acl->key_options->algorithm) != 0) {
438 		DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm"));
439 		return 0; /* no such algo */
440 	}
441 	return 1;
442 }
443 
444 int
445 acl_same_host(acl_options_t* a, acl_options_t* b)
446 {
447 	if(a->is_ipv6 && !b->is_ipv6)
448 		return 0;
449 	if(!a->is_ipv6 && b->is_ipv6)
450 		return 0;
451 	if(a->port != b->port)
452 		return 0;
453 	if(a->rangetype != b->rangetype)
454 		return 0;
455 	if(!a->is_ipv6) {
456 		if(memcmp(&a->addr.addr, &b->addr.addr,
457 		   sizeof(struct in_addr)) != 0)
458 			return 0;
459 		if(a->rangetype != acl_range_single &&
460 		   memcmp(&a->range_mask.addr, &b->range_mask.addr,
461 		   sizeof(struct in_addr)) != 0)
462 			return 0;
463 	} else {
464 #ifdef INET6
465 		if(memcmp(&a->addr.addr6, &b->addr.addr6,
466 		   sizeof(struct in6_addr)) != 0)
467 			return 0;
468 		if(a->rangetype != acl_range_single &&
469 		   memcmp(&a->range_mask.addr6, &b->range_mask.addr6,
470 		   sizeof(struct in6_addr)) != 0)
471 			return 0;
472 #else
473 		return 0;
474 #endif
475 	}
476 	return 1;
477 }
478 
479 #if defined(HAVE_SSL)
480 void key_options_tsig_add(nsd_options_t* opt)
481 {
482 	key_options_t* optkey;
483 	uint8_t data[4000];
484 	tsig_key_type* tsigkey;
485 	const dname_type* dname;
486 	int size;
487 
488 	for(optkey = opt->keys; optkey; optkey = optkey->next)
489 	{
490 		dname = dname_parse(opt->region, optkey->name);
491 		if(!dname) {
492 			log_msg(LOG_ERR, "Failed to parse tsig key name %s", optkey->name);
493 			continue;
494 		}
495 		size = b64_pton(optkey->secret, data, sizeof(data));
496 		if(size == -1) {
497 			log_msg(LOG_ERR, "Failed to parse tsig key data %s", optkey->name);
498 			continue;
499 		}
500 		tsigkey = (tsig_key_type *) region_alloc(opt->region, sizeof(tsig_key_type));
501 		tsigkey->name = dname;
502 		tsigkey->size = size;
503 		tsigkey->data = (uint8_t *) region_alloc_init(opt->region, data, tsigkey->size);
504 		tsig_add_key(tsigkey);
505 		optkey->tsig_key = tsigkey;
506 	}
507 }
508 #endif
509 
510 int zone_is_slave(zone_options_t* opt)
511 {
512 	return opt->request_xfr != 0;
513 }
514 
515 zone_options_t* zone_options_find(nsd_options_t* opt, const struct dname* apex)
516 {
517 	return (zone_options_t*) rbtree_search(opt->zone_options, apex);
518 }
519 
520 acl_options_t*
521 acl_find_num(acl_options_t* acl, int num)
522 {
523 	int count = num;
524 	if(num < 0)
525 		return 0;
526 	while(acl && count > 0) {
527 		acl = acl->next;
528 		count--;
529 	}
530 	if(count == 0)
531 		return acl;
532 	return 0;
533 }
534 
535 /* true if ipv6 address, false if ipv4 */
536 int parse_acl_is_ipv6(const char* p)
537 {
538 	/* see if addr is ipv6 or ipv4 -- by : and . */
539 	while(*p) {
540 		if(*p == '.') return 0;
541 		if(*p == ':') return 1;
542 		++p;
543 	}
544 	return 0;
545 }
546 
547 /* returns range type. mask is the 2nd part of the range */
548 int parse_acl_range_type(char* ip, char** mask)
549 {
550 	char *p;
551 	if((p=strchr(ip, '&'))!=0) {
552 		*p = 0;
553 		*mask = p+1;
554 		return acl_range_mask;
555 	}
556 	if((p=strchr(ip, '/'))!=0) {
557 		*p = 0;
558 		*mask = p+1;
559 		return acl_range_subnet;
560 	}
561 	if((p=strchr(ip, '-'))!=0) {
562 		*p = 0;
563 		*mask = p+1;
564 		return acl_range_minmax;
565 	}
566 	*mask = 0;
567 	return acl_range_single;
568 }
569 
570 /* parses subnet mask, fills 0 mask as well */
571 void parse_acl_range_subnet(char* p, void* addr, int maxbits)
572 {
573 	int subnet_bits = atoi(p);
574 	uint8_t* addr_bytes = (uint8_t*)addr;
575 	if(subnet_bits == 0 && strcmp(p, "0")!=0) {
576 		c_error_msg("bad subnet range '%s'", p);
577 		return;
578 	}
579 	if(subnet_bits < 0 || subnet_bits > maxbits) {
580 		c_error_msg("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits);
581 		return;
582 	}
583 	/* fill addr with n bits of 1s (struct has been zeroed) */
584 	while(subnet_bits >= 8) {
585 		*addr_bytes++ = 0xff;
586 		subnet_bits -= 8;
587 	}
588 	if(subnet_bits > 0) {
589 		uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
590 		*addr_bytes = shifts[subnet_bits];
591 	}
592 }
593 
594 acl_options_t* parse_acl_info(region_type* region, char* ip, const char* key)
595 {
596 	char* p;
597 	acl_options_t* acl = (acl_options_t*)region_alloc(region, sizeof(acl_options_t));
598 	acl->next = 0;
599 	/* ip */
600 	acl->ip_address_spec = region_strdup(region, ip);
601 	acl->use_axfr_only = 0;
602 	acl->allow_udp = 0;
603 	acl->ixfr_disabled = 0;
604 	acl->key_options = 0;
605 	acl->is_ipv6 = 0;
606 	acl->port = 0;
607 	memset(&acl->addr, 0, sizeof(union acl_addr_storage));
608 	memset(&acl->range_mask, 0, sizeof(union acl_addr_storage));
609 	if((p=strrchr(ip, '@'))!=0) {
610 		if(atoi(p+1) == 0) c_error("expected port number after '@'");
611 		else acl->port = atoi(p+1);
612 		*p=0;
613 	}
614 	acl->rangetype = parse_acl_range_type(ip, &p);
615 	if(parse_acl_is_ipv6(ip)) {
616 		acl->is_ipv6 = 1;
617 #ifdef INET6
618 		if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1)
619 			c_error_msg("Bad ip6 address '%s'", ip);
620 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax)
621 			if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1)
622 				c_error_msg("Bad ip6 address mask '%s'", p);
623 		if(acl->rangetype==acl_range_subnet)
624 			parse_acl_range_subnet(p, &acl->range_mask.addr6, 128);
625 #else
626 		c_error_msg("encountered IPv6 address '%s'.", ip);
627 #endif /* INET6 */
628 	} else {
629 		acl->is_ipv6 = 0;
630 		if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1)
631 			c_error_msg("Bad ip4 address '%s'", ip);
632 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax)
633 			if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1)
634 				c_error_msg("Bad ip4 address mask '%s'", p);
635 		if(acl->rangetype==acl_range_subnet)
636 			parse_acl_range_subnet(p, &acl->range_mask.addr, 32);
637 	}
638 
639 	/* key */
640 	if(strcmp(key, "NOKEY")==0) {
641 		acl->nokey = 1;
642 		acl->blocked = 0;
643 		acl->key_name = 0;
644 	} else if(strcmp(key, "BLOCKED")==0) {
645 		acl->nokey = 0;
646 		acl->blocked = 1;
647 		acl->key_name = 0;
648 	} else {
649 		acl->nokey = 0;
650 		acl->blocked = 0;
651 		acl->key_name = region_strdup(region, key);
652 	}
653 	return acl;
654 }
655 
656 void nsd_options_destroy(nsd_options_t* opt)
657 {
658 	region_destroy(opt->region);
659 }
660