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