xref: /openbsd/usr.sbin/nsd/zonec.c (revision 3efee2e1)
1 /*
2  * zonec.c -- zone compiler.
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 #include "config.h"
11 
12 #include <assert.h>
13 #include <fcntl.h>
14 #include <ctype.h>
15 #include <errno.h>
16 #include <limits.h>
17 #include <stdio.h>
18 #include <string.h>
19 #ifdef HAVE_STRINGS_H
20 #include <strings.h>
21 #endif
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #ifdef HAVE_SYS_STAT_H
26 #include <sys/stat.h>
27 #endif
28 
29 #include <netinet/in.h>
30 
31 #ifdef HAVE_NETDB_H
32 #include <netdb.h>
33 #endif
34 
35 #include "zonec.h"
36 
37 #include "dname.h"
38 #include "dns.h"
39 #include "namedb.h"
40 #include "rdata.h"
41 #include "region-allocator.h"
42 #include "util.h"
43 #include "zparser.h"
44 #include "options.h"
45 #include "nsec3.h"
46 
47 #define ILNP_MAXDIGITS 4
48 #define ILNP_NUMGROUPS 4
49 #define SVCB_MAX_COMMA_SEPARATED_VALUES 1000
50 
51 
52 const dname_type *error_dname;
53 domain_type *error_domain;
54 
55 static time_t startzonec = 0;
56 static long int totalrrs = 0;
57 
58 extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
59 extern uint16_t nsec_highest_rcode;
60 
61 
62 /*
63  * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first
64  * element.  Return a pointer to the allocation.
65  */
66 static uint16_t *
alloc_rdata(region_type * region,size_t size)67 alloc_rdata(region_type *region, size_t size)
68 {
69 	uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
70 	*result = size;
71 	return result;
72 }
73 
74 uint16_t *
alloc_rdata_init(region_type * region,const void * data,size_t size)75 alloc_rdata_init(region_type *region, const void *data, size_t size)
76 {
77 	uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
78 	*result = size;
79 	memcpy(result + 1, data, size);
80 	return result;
81 }
82 
83 /*
84  * These are parser function for generic zone file stuff.
85  */
86 uint16_t *
zparser_conv_hex(region_type * region,const char * hex,size_t len)87 zparser_conv_hex(region_type *region, const char *hex, size_t len)
88 {
89 	/* convert a hex value to wireformat */
90 	uint16_t *r = NULL;
91 	uint8_t *t;
92 	int i;
93 
94 	if(len == 1 && hex[0] == '0') {
95 		/* single 0 represents empty buffer */
96 		return alloc_rdata(region, 0);
97 	}
98 	if (len % 2 != 0) {
99 		zc_error_prev_line("number of hex digits must be a multiple of 2");
100 	} else if (len > MAX_RDLENGTH * 2) {
101 		zc_error_prev_line("hex data exceeds maximum rdata length (%d)",
102 				   MAX_RDLENGTH);
103 	} else {
104 		/* the length part */
105 		r = alloc_rdata(region, len/2);
106 		t = (uint8_t *)(r + 1);
107 
108 		/* Now process octet by octet... */
109 		while (*hex) {
110 			*t = 0;
111 			for (i = 16; i >= 1; i -= 15) {
112 				if (isxdigit((unsigned char)*hex)) {
113 					*t += hexdigit_to_int(*hex) * i;
114 				} else {
115 					zc_error_prev_line(
116 						"illegal hex character '%c'",
117 						(int) *hex);
118 					return NULL;
119 				}
120 				++hex;
121 			}
122 			++t;
123 		}
124 	}
125 	return r;
126 }
127 
128 /* convert hex, precede by a 1-byte length */
129 uint16_t *
zparser_conv_hex_length(region_type * region,const char * hex,size_t len)130 zparser_conv_hex_length(region_type *region, const char *hex, size_t len)
131 {
132 	uint16_t *r = NULL;
133 	uint8_t *t;
134 	int i;
135 	if (len % 2 != 0) {
136 		zc_error_prev_line("number of hex digits must be a multiple of 2");
137 	} else if (len > 255 * 2) {
138 		zc_error_prev_line("hex data exceeds 255 bytes");
139 	} else {
140 		uint8_t *l;
141 
142 		/* the length part */
143 		r = alloc_rdata(region, len/2+1);
144 		t = (uint8_t *)(r + 1);
145 
146 		l = t++;
147 		*l = '\0';
148 
149 		/* Now process octet by octet... */
150 		while (*hex) {
151 			*t = 0;
152 			for (i = 16; i >= 1; i -= 15) {
153 				if (isxdigit((unsigned char)*hex)) {
154 					*t += hexdigit_to_int(*hex) * i;
155 				} else {
156 					zc_error_prev_line(
157 						"illegal hex character '%c'",
158 						(int) *hex);
159 					return NULL;
160 				}
161 				++hex;
162 			}
163 			++t;
164 			++*l;
165 		}
166 	}
167 	return r;
168 }
169 
170 uint16_t *
zparser_conv_time(region_type * region,const char * time)171 zparser_conv_time(region_type *region, const char *time)
172 {
173 	/* convert a time YYHM to wireformat */
174 	uint16_t *r = NULL;
175 	struct tm tm;
176 
177 	/* Try to scan the time... */
178 	if (!strptime(time, "%Y%m%d%H%M%S", &tm)) {
179 		zc_error_prev_line("date and time is expected");
180 	} else {
181 		uint32_t l = htonl(mktime_from_utc(&tm));
182 		r = alloc_rdata_init(region, &l, sizeof(l));
183 	}
184 	return r;
185 }
186 
187 uint16_t *
zparser_conv_services(region_type * region,const char * protostr,char * servicestr)188 zparser_conv_services(region_type *region, const char *protostr,
189 		      char *servicestr)
190 {
191 	/*
192 	 * Convert a protocol and a list of service port numbers
193 	 * (separated by spaces) in the rdata to wireformat
194 	 */
195 	uint16_t *r = NULL;
196 	uint8_t *p;
197 	uint8_t bitmap[65536/8];
198 	char sep[] = " ";
199 	char *word;
200 	int max_port = -8;
201 	/* convert a protocol in the rdata to wireformat */
202 	struct protoent *proto;
203 
204 	memset(bitmap, 0, sizeof(bitmap));
205 
206 	proto = getprotobyname(protostr);
207 	if (!proto) {
208 		proto = getprotobynumber(atoi(protostr));
209 	}
210 	if (!proto) {
211 		zc_error_prev_line("unknown protocol '%s'", protostr);
212 		return NULL;
213 	}
214 
215 	for (word = strtok(servicestr, sep); word; word = strtok(NULL, sep)) {
216 		struct servent *service;
217 		int port;
218 
219 		service = getservbyname(word, proto->p_name);
220 		if (service) {
221 			/* Note: ntohs not ntohl!  Strange but true.  */
222 			port = ntohs((uint16_t) service->s_port);
223 		} else {
224 			char *end;
225 			port = strtol(word, &end, 10);
226 			if (*end != '\0') {
227 				zc_error_prev_line("unknown service '%s' for protocol '%s'",
228 						   word, protostr);
229 				continue;
230 			}
231 		}
232 
233 		if (port < 0 || port > 65535) {
234 			zc_error_prev_line("bad port number %d", port);
235 		} else {
236 			set_bit(bitmap, port);
237 			if (port > max_port)
238 				max_port = port;
239 		}
240 	}
241 
242 	r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1);
243 	p = (uint8_t *) (r + 1);
244 	*p = proto->p_proto;
245 	memcpy(p + 1, bitmap, *r-1);
246 
247 	return r;
248 }
249 
250 uint16_t *
zparser_conv_serial(region_type * region,const char * serialstr)251 zparser_conv_serial(region_type *region, const char *serialstr)
252 {
253 	uint16_t *r = NULL;
254 	uint32_t serial;
255 	const char *t;
256 
257 	serial = strtoserial(serialstr, &t);
258 	if (*t != '\0') {
259 		zc_error_prev_line("serial is expected or serial too big");
260 	} else {
261 		serial = htonl(serial);
262 		r = alloc_rdata_init(region, &serial, sizeof(serial));
263 	}
264 	return r;
265 }
266 
267 uint16_t *
zparser_conv_period(region_type * region,const char * periodstr)268 zparser_conv_period(region_type *region, const char *periodstr)
269 {
270 	/* convert a time period (think TTL's) to wireformat) */
271 	uint16_t *r = NULL;
272 	uint32_t period;
273 	const char *end;
274 
275 	/* Allocate required space... */
276 	period = strtottl(periodstr, &end);
277 	if (*end != '\0') {
278 		zc_error_prev_line("time period is expected");
279 	} else {
280 		period = htonl(period);
281 		r = alloc_rdata_init(region, &period, sizeof(period));
282 	}
283 	return r;
284 }
285 
286 uint16_t *
zparser_conv_short(region_type * region,const char * text)287 zparser_conv_short(region_type *region, const char *text)
288 {
289 	uint16_t *r = NULL;
290 	uint16_t value;
291 	char *end;
292 
293 	value = htons((uint16_t) strtol(text, &end, 10));
294 	if (*end != '\0') {
295 		zc_error_prev_line("integer value is expected");
296 	} else {
297 		r = alloc_rdata_init(region, &value, sizeof(value));
298 	}
299 	return r;
300 }
301 
302 uint16_t *
zparser_conv_byte(region_type * region,const char * text)303 zparser_conv_byte(region_type *region, const char *text)
304 {
305 	uint16_t *r = NULL;
306 	uint8_t value;
307 	char *end;
308 
309 	value = (uint8_t) strtol(text, &end, 10);
310 	if (*end != '\0') {
311 		zc_error_prev_line("integer value is expected");
312 	} else {
313 		r = alloc_rdata_init(region, &value, sizeof(value));
314 	}
315 	return r;
316 }
317 
318 uint16_t *
zparser_conv_algorithm(region_type * region,const char * text)319 zparser_conv_algorithm(region_type *region, const char *text)
320 {
321 	const lookup_table_type *alg;
322 	uint8_t id;
323 
324 	alg = lookup_by_name(dns_algorithms, text);
325 	if (alg) {
326 		id = (uint8_t) alg->id;
327 	} else {
328 		char *end;
329 		id = (uint8_t) strtol(text, &end, 10);
330 		if (*end != '\0') {
331 			zc_error_prev_line("algorithm is expected");
332 			return NULL;
333 		}
334 	}
335 
336 	return alloc_rdata_init(region, &id, sizeof(id));
337 }
338 
339 uint16_t *
zparser_conv_certificate_type(region_type * region,const char * text)340 zparser_conv_certificate_type(region_type *region, const char *text)
341 {
342 	/* convert an algorithm string to integer */
343 	const lookup_table_type *type;
344 	uint16_t id;
345 
346 	type = lookup_by_name(dns_certificate_types, text);
347 	if (type) {
348 		id = htons((uint16_t) type->id);
349 	} else {
350 		char *end;
351 		id = htons((uint16_t) strtol(text, &end, 10));
352 		if (*end != '\0') {
353 			zc_error_prev_line("certificate type is expected");
354 			return NULL;
355 		}
356 	}
357 
358 	return alloc_rdata_init(region, &id, sizeof(id));
359 }
360 
361 uint16_t *
zparser_conv_a(region_type * region,const char * text)362 zparser_conv_a(region_type *region, const char *text)
363 {
364 	in_addr_t address;
365 	uint16_t *r = NULL;
366 
367 	if (inet_pton(AF_INET, text, &address) != 1) {
368 		zc_error_prev_line("invalid IPv4 address '%s'", text);
369 	} else {
370 		r = alloc_rdata_init(region, &address, sizeof(address));
371 	}
372 	return r;
373 }
374 
375 uint16_t *
zparser_conv_aaaa(region_type * region,const char * text)376 zparser_conv_aaaa(region_type *region, const char *text)
377 {
378 	uint8_t address[IP6ADDRLEN];
379 	uint16_t *r = NULL;
380 
381 	if (inet_pton(AF_INET6, text, address) != 1) {
382 		zc_error_prev_line("invalid IPv6 address '%s'", text);
383 	} else {
384 		r = alloc_rdata_init(region, address, sizeof(address));
385 	}
386 	return r;
387 }
388 
389 
390 uint16_t *
zparser_conv_ilnp64(region_type * region,const char * text)391 zparser_conv_ilnp64(region_type *region, const char *text)
392 {
393 	uint16_t *r = NULL;
394 	int ngroups, num;
395 	unsigned long hex;
396 	const char *ch;
397 	char digits[ILNP_MAXDIGITS+1];
398 	unsigned int ui[ILNP_NUMGROUPS];
399 	uint16_t a[ILNP_NUMGROUPS];
400 
401 	ngroups = 1; /* Always at least one group */
402 	num = 0;
403 	for (ch = text; *ch != '\0'; ch++) {
404 		if (*ch == ':') {
405 			if (num <= 0) {
406 				zc_error_prev_line("ilnp64: empty group of "
407 					"digits is not allowed");
408 				return NULL;
409 			}
410 			digits[num] = '\0';
411 			hex = (unsigned long) strtol(digits, NULL, 16);
412 			num = 0;
413 			ui[ngroups - 1] = hex;
414 			if (ngroups >= ILNP_NUMGROUPS) {
415 				zc_error_prev_line("ilnp64: more than %d groups "
416 					"of digits", ILNP_NUMGROUPS);
417 				return NULL;
418 			}
419 			ngroups++;
420 		} else {
421 			/* Our grammar is stricter than the one accepted by
422 			 * strtol. */
423 			if (!isxdigit((unsigned char)*ch)) {
424 				zc_error_prev_line("ilnp64: invalid "
425 					"(non-hexadecimal) character %c", *ch);
426 				return NULL;
427 			}
428 			if (num >= ILNP_MAXDIGITS) {
429 				zc_error_prev_line("ilnp64: more than %d digits "
430 					"in a group", ILNP_MAXDIGITS);
431 				return NULL;
432 			}
433 			digits[num++] = *ch;
434 		}
435 	}
436 	if (num <= 0) {
437 		zc_error_prev_line("ilnp64: empty group of digits is not "
438 			"allowed");
439 		return NULL;
440 	}
441 	digits[num] = '\0';
442 	hex = (unsigned long) strtol(digits, NULL, 16);
443 	ui[ngroups - 1] = hex;
444 	if (ngroups < 4) {
445 		zc_error_prev_line("ilnp64: less than %d groups of digits",
446 			ILNP_NUMGROUPS);
447 		return NULL;
448 	}
449 
450 	a[0] = htons(ui[0]);
451 	a[1] = htons(ui[1]);
452 	a[2] = htons(ui[2]);
453 	a[3] = htons(ui[3]);
454 	r = alloc_rdata_init(region, a, sizeof(a));
455 	return r;
456 }
457 
458 static uint16_t *
zparser_conv_eui48(region_type * region,const char * text)459 zparser_conv_eui48(region_type *region, const char *text)
460 {
461 	uint8_t nums[6];
462 	uint16_t *r = NULL;
463 	unsigned int a, b, c, d, e, f;
464 	int l;
465 
466 	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n",
467 		&a, &b, &c, &d, &e, &f, &l) != 6 ||
468 		l != (int)strlen(text)){
469 		zc_error_prev_line("eui48: invalid rr");
470 		return NULL;
471 	}
472 	nums[0] = (uint8_t)a;
473 	nums[1] = (uint8_t)b;
474 	nums[2] = (uint8_t)c;
475 	nums[3] = (uint8_t)d;
476 	nums[4] = (uint8_t)e;
477 	nums[5] = (uint8_t)f;
478 	r = alloc_rdata_init(region, nums, sizeof(nums));
479 	return r;
480 }
481 
482 static uint16_t *
zparser_conv_eui64(region_type * region,const char * text)483 zparser_conv_eui64(region_type *region, const char *text)
484 {
485 	uint8_t nums[8];
486 	uint16_t *r = NULL;
487 	unsigned int a, b, c, d, e, f, g, h;
488 	int l;
489 	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
490 		&a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
491 		l != (int)strlen(text)) {
492 		zc_error_prev_line("eui64: invalid rr");
493 		return NULL;
494 	}
495 	nums[0] = (uint8_t)a;
496 	nums[1] = (uint8_t)b;
497 	nums[2] = (uint8_t)c;
498 	nums[3] = (uint8_t)d;
499 	nums[4] = (uint8_t)e;
500 	nums[5] = (uint8_t)f;
501 	nums[6] = (uint8_t)g;
502 	nums[7] = (uint8_t)h;
503 	r = alloc_rdata_init(region, nums, sizeof(nums));
504 	return r;
505 }
506 
507 uint16_t *
zparser_conv_eui(region_type * region,const char * text,size_t len)508 zparser_conv_eui(region_type *region, const char *text, size_t len)
509 {
510 	uint16_t *r = NULL;
511 	int nnum, num;
512 	const char* ch;
513 
514 	nnum = len/8;
515 	num = 1;
516 	for (ch = text; *ch != '\0'; ch++) {
517 		if (*ch == '-') {
518 			num++;
519 		} else if (!isxdigit((unsigned char)*ch)) {
520 			zc_error_prev_line("eui%u: invalid (non-hexadecimal) "
521 				"character %c", (unsigned) len, *ch);
522 			return NULL;
523 		}
524 	}
525 	if (num != nnum) {
526 		zc_error_prev_line("eui%u: wrong number of hex numbers",
527 			(unsigned) len);
528 		return NULL;
529 	}
530 
531 	switch (len) {
532 		case 48:
533 			r = zparser_conv_eui48(region, text);
534 			break;
535 		case 64:
536 			r = zparser_conv_eui64(region, text);
537 		break;
538 		default:
539 			zc_error_prev_line("eui%u: invalid length",
540 				(unsigned) len);
541 			return NULL;
542 			break;
543 	}
544 	return r;
545 }
546 
547 uint16_t *
zparser_conv_text(region_type * region,const char * text,size_t len)548 zparser_conv_text(region_type *region, const char *text, size_t len)
549 {
550 	uint16_t *r = NULL;
551 	uint8_t *p;
552 
553 	if (len > 255) {
554 		zc_error_prev_line("text string is longer than 255 characters,"
555 				   " try splitting it into multiple parts");
556 		len = 255;
557 	}
558 	r = alloc_rdata(region, len + 1);
559 	p = (uint8_t *) (r + 1);
560 	*p = len;
561 	memcpy(p + 1, text, len);
562 	return r;
563 }
564 
565 /* for CAA Value [RFC 6844] */
566 uint16_t *
zparser_conv_long_text(region_type * region,const char * text,size_t len)567 zparser_conv_long_text(region_type *region, const char *text, size_t len)
568 {
569 	uint16_t *r = NULL;
570 	if (len > MAX_RDLENGTH) {
571 		zc_error_prev_line("text string is longer than max rdlen");
572 		return NULL;
573 	}
574 	r = alloc_rdata_init(region, text, len);
575 	return r;
576 }
577 
578 /* for CAA Tag [RFC 6844] */
579 uint16_t *
zparser_conv_tag(region_type * region,const char * text,size_t len)580 zparser_conv_tag(region_type *region, const char *text, size_t len)
581 {
582 	uint16_t *r = NULL;
583 	uint8_t *p;
584 	const char* ptr;
585 
586 	if (len < 1) {
587 		zc_error_prev_line("invalid tag: zero length");
588 		return NULL;
589 	}
590 	if (len > 15) {
591 		zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)",
592 			text, (unsigned) len);
593 		return NULL;
594 	}
595 	for (ptr = text; *ptr; ptr++) {
596 		if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) {
597 			zc_error_prev_line("invalid tag %s: contains invalid char %c",
598 				text, *ptr);
599 			return NULL;
600 		}
601 	}
602 	r = alloc_rdata(region, len + 1);
603 	p = (uint8_t *) (r + 1);
604 	*p = len;
605 	memmove(p + 1, text, len);
606 	return r;
607 }
608 
609 uint16_t *
zparser_conv_dns_name(region_type * region,const uint8_t * name,size_t len)610 zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len)
611 {
612 	uint16_t* r = NULL;
613 	uint8_t* p = NULL;
614 	r = alloc_rdata(region, len);
615 	p = (uint8_t *) (r + 1);
616 	memcpy(p, name, len);
617 
618 	return r;
619 }
620 
621 uint16_t *
zparser_conv_b32(region_type * region,const char * b32)622 zparser_conv_b32(region_type *region, const char *b32)
623 {
624 	uint8_t buffer[B64BUFSIZE];
625 	uint16_t *r = NULL;
626 	int i;
627 
628 	if(strcmp(b32, "-") == 0) {
629 		return alloc_rdata_init(region, "", 1);
630 	}
631 	i = b32_pton(b32, buffer+1, B64BUFSIZE-1);
632 	if (i == -1 || i > 255) {
633 		zc_error_prev_line("invalid base32 data");
634 	} else {
635 		buffer[0] = i; /* store length byte */
636 		r = alloc_rdata_init(region, buffer, i+1);
637 	}
638 	return r;
639 }
640 
641 uint16_t *
zparser_conv_b64(region_type * region,const char * b64)642 zparser_conv_b64(region_type *region, const char *b64)
643 {
644 	uint8_t buffer[B64BUFSIZE];
645 	uint16_t *r = NULL;
646 	int i;
647 
648 	if(strcmp(b64, "0") == 0) {
649 		/* single 0 represents empty buffer */
650 		return alloc_rdata(region, 0);
651 	}
652 	i = __b64_pton(b64, buffer, B64BUFSIZE);
653 	if (i == -1) {
654 		zc_error_prev_line("invalid base64 data");
655 	} else {
656 		r = alloc_rdata_init(region, buffer, i);
657 	}
658 	return r;
659 }
660 
661 uint16_t *
zparser_conv_rrtype(region_type * region,const char * text)662 zparser_conv_rrtype(region_type *region, const char *text)
663 {
664 	uint16_t *r = NULL;
665 	uint16_t type = rrtype_from_string(text);
666 
667 	if (type == 0) {
668 		zc_error_prev_line("unrecognized RR type '%s'", text);
669 	} else {
670 		type = htons(type);
671 		r = alloc_rdata_init(region, &type, sizeof(type));
672 	}
673 	return r;
674 }
675 
676 uint16_t *
zparser_conv_nxt(region_type * region,uint8_t nxtbits[])677 zparser_conv_nxt(region_type *region, uint8_t nxtbits[])
678 {
679 	/* nxtbits[] consists of 16 bytes with some zero's in it
680 	 * copy every byte with zero to r and write the length in
681 	 * the first byte
682 	 */
683 	uint16_t i;
684 	uint16_t last = 0;
685 
686 	for (i = 0; i < 16; i++) {
687 		if (nxtbits[i] != 0)
688 			last = i + 1;
689 	}
690 
691 	return alloc_rdata_init(region, nxtbits, last);
692 }
693 
694 
695 /* we potentially have 256 windows, each one is numbered. empty ones
696  * should be discarded
697  */
698 uint16_t *
zparser_conv_nsec(region_type * region,uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE])699 zparser_conv_nsec(region_type *region,
700 		  uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE])
701 {
702 	/* nsecbits contains up to 64K of bits which represent the
703 	 * types available for a name. Walk the bits according to
704 	 * nsec++ draft from jakob
705 	 */
706 	uint16_t *r;
707 	uint8_t *ptr;
708 	size_t i,j;
709 	uint16_t window_count = 0;
710 	uint16_t total_size = 0;
711 	uint16_t window_max = 0;
712 
713 	/* The used windows.  */
714 	int used[NSEC_WINDOW_COUNT];
715 	/* The last byte used in each the window.  */
716 	int size[NSEC_WINDOW_COUNT];
717 
718 	window_max = 1 + (nsec_highest_rcode / 256);
719 
720 	/* used[i] is the i-th window included in the nsec
721 	 * size[used[0]] is the size of window 0
722 	 */
723 
724 	/* walk through the 256 windows */
725 	for (i = 0; i < window_max; ++i) {
726 		int empty_window = 1;
727 		/* check each of the 32 bytes */
728 		for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) {
729 			if (nsecbits[i][j] != 0) {
730 				size[i] = j + 1;
731 				empty_window = 0;
732 			}
733 		}
734 		if (!empty_window) {
735 			used[window_count] = i;
736 			window_count++;
737 		}
738 	}
739 
740 	for (i = 0; i < window_count; ++i) {
741 		total_size += sizeof(uint16_t) + size[used[i]];
742 	}
743 
744 	r = alloc_rdata(region, total_size);
745 	ptr = (uint8_t *) (r + 1);
746 
747 	/* now walk used and copy it */
748 	for (i = 0; i < window_count; ++i) {
749 		ptr[0] = used[i];
750 		ptr[1] = size[used[i]];
751 		memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]);
752 		ptr += size[used[i]] + 2;
753 	}
754 
755 	return r;
756 }
757 
758 static uint16_t
svcbparam_lookup_key(const char * key,size_t key_len)759 svcbparam_lookup_key(const char *key, size_t key_len)
760 {
761 	char buf[64];
762 	char *endptr;
763 	unsigned long int key_value;
764 
765 	if (key_len >= 4  && key_len <= 8 && !strncmp(key, "key", 3)) {
766 		memcpy(buf, key + 3, key_len - 3);
767 		buf[key_len - 3] = 0;
768 		key_value = strtoul(buf, &endptr, 10);
769 		if (endptr > buf	/* digits seen */
770 		&& *endptr == 0		/* no non-digit chars after digits */
771 		&&  key_value <= 65535)	/* no overflow */
772 			return key_value;
773 
774 	} else switch (key_len) {
775 	case sizeof("mandatory")-1:
776 		if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
777 			return SVCB_KEY_MANDATORY;
778 		if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
779 			return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
780 		break;
781 
782 	case sizeof("alpn")-1:
783 		if (!strncmp(key, "alpn", sizeof("alpn")-1))
784 			return SVCB_KEY_ALPN;
785 		if (!strncmp(key, "port", sizeof("port")-1))
786 			return SVCB_KEY_PORT;
787 		break;
788 
789 	case sizeof("no-default-alpn")-1:
790 		if (!strncmp( key  , "no-default-alpn"
791 		            , sizeof("no-default-alpn")-1))
792 			return SVCB_KEY_NO_DEFAULT_ALPN;
793 		break;
794 
795 	case sizeof("ipv4hint")-1:
796 		if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
797 			return SVCB_KEY_IPV4HINT;
798 		if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
799 			return SVCB_KEY_IPV6HINT;
800 		break;
801 	case sizeof("dohpath")-1:
802 		if (!strncmp(key, "dohpath", sizeof("dohpath")-1))
803 			return SVCB_KEY_DOHPATH;
804 		break;
805 	case sizeof("ech")-1:
806 		if (!strncmp(key, "ech", sizeof("ech")-1))
807 			return SVCB_KEY_ECH;
808 		break;
809 	default:
810 		break;
811 	}
812 	if (key_len > sizeof(buf) - 1)
813 		zc_error_prev_line("Unknown SvcParamKey");
814 	else {
815 		memcpy(buf, key, key_len);
816 		buf[key_len] = 0;
817 		zc_error_prev_line("Unknown SvcParamKey: %s", buf);
818 	}
819 	/* Although the returned value might be used by the caller,
820 	 * the parser has erred, so the zone will not be loaded.
821 	 */
822 	return -1;
823 }
824 
825 static uint16_t *
zparser_conv_svcbparam_port_value(region_type * region,const char * val)826 zparser_conv_svcbparam_port_value(region_type *region, const char *val)
827 {
828 	unsigned long int port;
829 	char *endptr;
830 	uint16_t *r;
831 
832 	port = strtoul(val, &endptr, 10);
833 	if (endptr > val	/* digits seen */
834 	&& *endptr == 0		/* no non-digit chars after digits */
835 	&&  port <= 65535) {	/* no overflow */
836 
837 		r = alloc_rdata(region, 3 * sizeof(uint16_t));
838 		r[1] = htons(SVCB_KEY_PORT);
839 		r[2] = htons(sizeof(uint16_t));
840 		r[3] = htons(port);
841 		return r;
842 	}
843 	zc_error_prev_line("Could not parse port SvcParamValue: \"%s\"", val);
844 	return NULL;
845 }
846 
847 static uint16_t *
zparser_conv_svcbparam_ipv4hint_value(region_type * region,const char * val)848 zparser_conv_svcbparam_ipv4hint_value(region_type *region, const char *val)
849 {
850 	uint16_t *r;
851 	int count;
852 	char ip_str[INET_ADDRSTRLEN+1];
853 	char *next_ip_str;
854 	uint32_t *ip_wire_dst;
855 	size_t i;
856 
857 	for (i = 0, count = 1; val[i]; i++) {
858 		if (val[i] == ',')
859 			count += 1;
860 		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
861 			zc_error_prev_line("Too many IPV4 addresses in ipv4hint");
862 			return NULL;
863 		}
864 	}
865 
866 	/* count == number of comma's in val + 1, so the actual number of IPv4
867 	 * addresses in val
868 	 */
869 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP4ADDRLEN * count);
870 	r[1] = htons(SVCB_KEY_IPV4HINT);
871 	r[2] = htons(IP4ADDRLEN * count);
872 	ip_wire_dst = (void *)&r[3];
873 
874 	while (count) {
875 		if (!(next_ip_str = strchr(val, ','))) {
876 			if (inet_pton(AF_INET, val, ip_wire_dst) != 1)
877 				break;
878 
879 			assert(count == 1);
880 
881 		} else if (next_ip_str - val >= (int)sizeof(ip_str))
882 			break;
883 
884 		else {
885 			memcpy(ip_str, val, next_ip_str - val);
886 			ip_str[next_ip_str - val] = 0;
887 			if (inet_pton(AF_INET, ip_str, ip_wire_dst) != 1) {
888 				val = ip_str; /* to use in error reporting below */
889 				break;
890 			}
891 
892 			val = next_ip_str + 1;
893 		}
894 		ip_wire_dst++;
895 		count--;
896 	}
897 	if (count)
898 		zc_error_prev_line("Could not parse ipv4hint SvcParamValue: %s", val);
899 
900 	return r;
901 }
902 
903 static uint16_t *
zparser_conv_svcbparam_ipv6hint_value(region_type * region,const char * val)904 zparser_conv_svcbparam_ipv6hint_value(region_type *region, const char *val)
905 {
906 	uint16_t *r;
907 	int i, count;
908 	char ip6_str[INET6_ADDRSTRLEN+1];
909 	char *next_ip6_str;
910 	uint8_t *ipv6_wire_dst;
911 
912 	for (i = 0, count = 1; val[i]; i++) {
913 		if (val[i] == ',')
914 			count += 1;
915 		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
916 			zc_error_prev_line("Too many IPV6 addresses in ipv6hint");
917 			return NULL;
918 		}
919 	}
920 
921 	/* count == number of comma's in val + 1
922 	 * so actually the number of IPv6 addresses in val
923 	 */
924 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP6ADDRLEN * count);
925 	r[1] = htons(SVCB_KEY_IPV6HINT);
926 	r[2] = htons(IP6ADDRLEN * count);
927 	ipv6_wire_dst = (void *)&r[3];
928 
929 	while (count) {
930 		if (!(next_ip6_str = strchr(val, ','))) {
931 			if ((inet_pton(AF_INET6, val, ipv6_wire_dst) != 1))
932 				break;
933 
934 			assert(count == 1);
935 
936 		} else if (next_ip6_str - val >= (int)sizeof(ip6_str))
937 			break;
938 
939 		else {
940 			memcpy(ip6_str, val, next_ip6_str - val);
941 			ip6_str[next_ip6_str - val] = 0;
942 			if (inet_pton(AF_INET6, ip6_str, ipv6_wire_dst) != 1) {
943 				val = ip6_str; /* for error reporting below */
944 				break;
945 			}
946 
947 			val = next_ip6_str + 1; /* skip the comma */
948 		}
949 		ipv6_wire_dst += IP6ADDRLEN;
950 		count--;
951 	}
952 	if (count)
953 		zc_error_prev_line("Could not parse ipv6hint SvcParamValue: %s", val);
954 
955 	return r;
956 }
957 
958 static int
network_uint16_cmp(const void * a,const void * b)959 network_uint16_cmp(const void *a, const void *b)
960 {
961 	return ((int)read_uint16(a)) - ((int)read_uint16(b));
962 }
963 
964 static uint16_t *
zparser_conv_svcbparam_mandatory_value(region_type * region,const char * val,size_t val_len)965 zparser_conv_svcbparam_mandatory_value(region_type *region,
966 		const char *val, size_t val_len)
967 {
968 	uint16_t *r;
969 	size_t i, count;
970 	char* next_key;
971 	uint16_t* key_dst;
972 
973 	for (i = 0, count = 1; val[i]; i++) {
974 		if (val[i] == ',')
975 			count += 1;
976 		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
977 			zc_error_prev_line("Too many keys in mandatory");
978 			return NULL;
979 		}
980 	}
981 
982 	r = alloc_rdata(region, (2 + count) * sizeof(uint16_t));
983 	r[1] = htons(SVCB_KEY_MANDATORY);
984 	r[2] = htons(sizeof(uint16_t) * count);
985 	key_dst = (void *)&r[3];
986 
987 	for(;;) {
988 		if (!(next_key = strchr(val, ','))) {
989 			*key_dst = htons(svcbparam_lookup_key(val, val_len));
990 			break;
991 		} else {
992 			*key_dst = htons(svcbparam_lookup_key(val, next_key - val));
993 		}
994 
995 		val_len -= next_key - val + 1;
996 		val = next_key + 1; /* skip the comma */
997 		key_dst += 1;
998 	}
999 
1000 	/* In draft-ietf-dnsop-svcb-https-04 Section 7:
1001 	 *
1002 	 *     In wire format, the keys are represented by their numeric
1003 	 *     values in network byte order, concatenated in ascending order.
1004 	 */
1005 	qsort((void *)&r[3], count, sizeof(uint16_t), network_uint16_cmp);
1006 
1007 	return r;
1008 }
1009 
1010 static uint16_t *
zparser_conv_svcbparam_ech_value(region_type * region,const char * b64)1011 zparser_conv_svcbparam_ech_value(region_type *region, const char *b64)
1012 {
1013 	uint8_t buffer[B64BUFSIZE];
1014 	uint16_t *r = NULL;
1015 	int wire_len;
1016 
1017 	if(strcmp(b64, "0") == 0) {
1018 		/* single 0 represents empty buffer */
1019 		return alloc_rdata(region, 0);
1020 	}
1021 	wire_len = __b64_pton(b64, buffer, B64BUFSIZE);
1022 	if (wire_len == -1) {
1023 		zc_error_prev_line("invalid base64 data in ech");
1024 	} else {
1025 		r = alloc_rdata(region, 2 * sizeof(uint16_t) + wire_len);
1026 		r[1] = htons(SVCB_KEY_ECH);
1027 		r[2] = htons(wire_len);
1028 		memcpy(&r[3], buffer, wire_len);
1029 	}
1030 
1031 	return r;
1032 }
1033 
parse_alpn_next_unescaped_comma(const char * val)1034 static const char* parse_alpn_next_unescaped_comma(const char *val)
1035 {
1036 	while (*val) {
1037 		/* Only return when the comma is not escaped*/
1038 		if (*val == '\\'){
1039 			++val;
1040 			if (!*val)
1041 				break;
1042 		} else if (*val == ',')
1043 				return val;
1044 
1045 		val++;
1046 	}
1047 	return NULL;
1048 }
1049 
1050 static size_t
parse_alpn_copy_unescaped(uint8_t * dst,const char * src,size_t len)1051 parse_alpn_copy_unescaped(uint8_t *dst, const char *src, size_t len)
1052 {
1053 	uint8_t *orig_dst = dst;
1054 
1055 	while (len) {
1056 		if (*src == '\\') {
1057 			src++;
1058 			len--;
1059 			if (!len)
1060 				break;
1061 		}
1062 		*dst++ = *src++;
1063 		len--;
1064 	}
1065 	return (size_t)(dst - orig_dst);
1066 }
1067 
1068 static uint16_t *
zparser_conv_svcbparam_alpn_value(region_type * region,const char * val,size_t val_len)1069 zparser_conv_svcbparam_alpn_value(region_type *region,
1070 		const char *val, size_t val_len)
1071 {
1072 	uint8_t     unescaped_dst[65536];
1073 	uint8_t    *dst = unescaped_dst;
1074 	const char *next_str;
1075 	size_t      str_len;
1076 	size_t      dst_len;
1077 	uint16_t   *r = NULL;
1078 
1079 	if (val_len > sizeof(unescaped_dst)) {
1080 		zc_error_prev_line("invalid alpn");
1081 		return r;
1082 	}
1083 	while (val_len) {
1084 		size_t dst_len;
1085 
1086 		str_len = (next_str = parse_alpn_next_unescaped_comma(val))
1087 		        ? (size_t)(next_str - val) : val_len;
1088 
1089 		if (str_len > 255) {
1090 			zc_error_prev_line("alpn strings need to be"
1091 					   " smaller than 255 chars");
1092 			return r;
1093 		}
1094 		dst_len = parse_alpn_copy_unescaped(dst + 1, val, str_len);
1095 		*dst++ = dst_len;
1096 		 dst  += dst_len;
1097 
1098 		if (!next_str)
1099 			break;
1100 
1101 		/* skip the comma for the next iteration */
1102 		val_len -= next_str - val + 1;
1103 		val = next_str + 1;
1104 	}
1105 	dst_len = dst - unescaped_dst;
1106 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + dst_len);
1107 	r[1] = htons(SVCB_KEY_ALPN);
1108 	r[2] = htons(dst_len);
1109 	memcpy(&r[3], unescaped_dst, dst_len);
1110 	return r;
1111 }
1112 
1113 static uint16_t *
zparser_conv_svcbparam_key_value(region_type * region,const char * key,size_t key_len,const char * val,size_t val_len)1114 zparser_conv_svcbparam_key_value(region_type *region,
1115     const char *key, size_t key_len, const char *val, size_t val_len)
1116 {
1117 	uint16_t svcparamkey = svcbparam_lookup_key(key, key_len);
1118 	uint16_t *r;
1119 
1120 	switch (svcparamkey) {
1121 	case SVCB_KEY_PORT:
1122 		return zparser_conv_svcbparam_port_value(region, val);
1123 	case SVCB_KEY_IPV4HINT:
1124 		return zparser_conv_svcbparam_ipv4hint_value(region, val);
1125 	case SVCB_KEY_IPV6HINT:
1126 		return zparser_conv_svcbparam_ipv6hint_value(region, val);
1127 	case SVCB_KEY_MANDATORY:
1128 		return zparser_conv_svcbparam_mandatory_value(region, val, val_len);
1129 	case SVCB_KEY_NO_DEFAULT_ALPN:
1130 		if(zone_is_slave(parser->current_zone->opts))
1131 			zc_warning_prev_line("no-default-alpn should not have a value");
1132 		else
1133 			zc_error_prev_line("no-default-alpn should not have a value");
1134 		break;
1135 	case SVCB_KEY_ECH:
1136 		return zparser_conv_svcbparam_ech_value(region, val);
1137 	case SVCB_KEY_ALPN:
1138 		return zparser_conv_svcbparam_alpn_value(region, val, val_len);
1139 	case SVCB_KEY_DOHPATH:
1140 		/* fallthrough */
1141 	default:
1142 		break;
1143 	}
1144 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + val_len);
1145 	r[1] = htons(svcparamkey);
1146 	r[2] = htons(val_len);
1147 	memcpy(r + 3, val, val_len);
1148 	return r;
1149 }
1150 
1151 uint16_t *
zparser_conv_svcbparam(region_type * region,const char * key,size_t key_len,const char * val,size_t val_len)1152 zparser_conv_svcbparam(region_type *region, const char *key, size_t key_len
1153                                           , const char *val, size_t val_len)
1154 {
1155 	const char *eq;
1156 	uint16_t *r;
1157 	uint16_t svcparamkey;
1158 
1159 	/* Form <key>="<value>" (or at least with quoted value) */
1160 	if (val && val_len) {
1161 		/* Does key end with '=' */
1162 		if (key_len && key[key_len - 1] == '=')
1163 			return zparser_conv_svcbparam_key_value(
1164 			    region, key, key_len - 1, val, val_len);
1165 
1166 		zc_error_prev_line( "SvcParam syntax error in param: %s\"%s\""
1167 		                  , key, val);
1168 	}
1169 	assert(val == NULL);
1170 	if ((eq = memchr(key, '=', key_len))) {
1171 		size_t new_key_len = eq - key;
1172 
1173 		if (key_len - new_key_len - 1 > 0)
1174 			return zparser_conv_svcbparam_key_value(region,
1175 			    key, new_key_len, eq+1, key_len - new_key_len - 1);
1176 		key_len = new_key_len;
1177 	}
1178 	/* Some SvcParamKeys require values */
1179 	svcparamkey = svcbparam_lookup_key(key, key_len);
1180 	switch (svcparamkey) {
1181 		case SVCB_KEY_MANDATORY:
1182 		case SVCB_KEY_ALPN:
1183 		case SVCB_KEY_PORT:
1184 		case SVCB_KEY_IPV4HINT:
1185 		case SVCB_KEY_IPV6HINT:
1186 		case SVCB_KEY_DOHPATH:
1187 			if(zone_is_slave(parser->current_zone->opts))
1188 				zc_warning_prev_line("value expected for SvcParam: %s", key);
1189 			else
1190 				zc_error_prev_line("value expected for SvcParam: %s", key);
1191 			break;
1192 		default:
1193 			break;
1194 	}
1195 	/* SvcParam is only a SvcParamKey */
1196 	r = alloc_rdata(region, 2 * sizeof(uint16_t));
1197 	r[1] = htons(svcparamkey);
1198 	r[2] = 0;
1199 	return r;
1200 }
1201 
1202 /* Parse an int terminated in the specified range. */
1203 static int
parse_int(const char * str,char ** end,int * result,const char * name,int min,int max)1204 parse_int(const char *str,
1205 	  char **end,
1206 	  int *result,
1207 	  const char *name,
1208 	  int min,
1209 	  int max)
1210 {
1211 	*result = (int) strtol(str, end, 10);
1212 	if (*result < min || *result > max) {
1213 		zc_error_prev_line("%s must be within the range [%d .. %d]",
1214 				   name,
1215 				   min,
1216 				   max);
1217 		return 0;
1218 	} else {
1219 		return 1;
1220 	}
1221 }
1222 
1223 /* RFC1876 conversion routines */
1224 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1225 				1000000,10000000,100000000,1000000000};
1226 
1227 /*
1228  * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
1229  * Sets the given pointer to the last used character.
1230  *
1231  */
1232 static uint8_t
precsize_aton(char * cp,char ** endptr)1233 precsize_aton (char *cp, char **endptr)
1234 {
1235 	unsigned int mval = 0, cmval = 0;
1236 	uint8_t retval = 0;
1237 	int exponent;
1238 	int mantissa;
1239 
1240 	while (isdigit((unsigned char)*cp))
1241 		mval = mval * 10 + hexdigit_to_int(*cp++);
1242 
1243 	if (*cp == '.') {	/* centimeters */
1244 		cp++;
1245 		if (isdigit((unsigned char)*cp)) {
1246 			cmval = hexdigit_to_int(*cp++) * 10;
1247 			if (isdigit((unsigned char)*cp)) {
1248 				cmval += hexdigit_to_int(*cp++);
1249 			}
1250 		}
1251 	}
1252 
1253 	if(mval >= poweroften[7]) {
1254 		assert(poweroften[7] != 0);
1255 		/* integer overflow possible for *100 */
1256 		mantissa = mval / poweroften[7];
1257 		exponent = 9; /* max */
1258 	}
1259 	else {
1260 		cmval = (mval * 100) + cmval;
1261 
1262 		for (exponent = 0; exponent < 9; exponent++)
1263 			if (cmval < poweroften[exponent+1])
1264 				break;
1265 
1266 		assert(poweroften[exponent] != 0);
1267 		mantissa = cmval / poweroften[exponent];
1268 	}
1269 	if (mantissa > 9)
1270 		mantissa = 9;
1271 
1272 	retval = (mantissa << 4) | exponent;
1273 
1274 	if (*cp == 'm') cp++;
1275 
1276 	*endptr = cp;
1277 
1278 	return (retval);
1279 }
1280 
1281 /*
1282  * Parses a specific part of rdata.
1283  *
1284  * Returns:
1285  *
1286  *	number of elements parsed
1287  *	zero on error
1288  *
1289  */
1290 uint16_t *
zparser_conv_loc(region_type * region,char * str)1291 zparser_conv_loc(region_type *region, char *str)
1292 {
1293 	uint16_t *r;
1294 	uint32_t *p;
1295 	int i;
1296 	int deg, min, secs;	/* Secs is stored times 1000.  */
1297 	uint32_t lat = 0, lon = 0, alt = 0;
1298 	/* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
1299 	uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
1300 	char *start;
1301 	double d;
1302 
1303 	for(;;) {
1304 		deg = min = secs = 0;
1305 
1306 		/* Degrees */
1307 		if (*str == '\0') {
1308 			zc_error_prev_line("unexpected end of LOC data");
1309 			return NULL;
1310 		}
1311 
1312 		if (!parse_int(str, &str, &deg, "degrees", 0, 180))
1313 			return NULL;
1314 		if (!isspace((unsigned char)*str)) {
1315 			zc_error_prev_line("space expected after degrees");
1316 			return NULL;
1317 		}
1318 		++str;
1319 
1320 		/* Minutes? */
1321 		if (isdigit((unsigned char)*str)) {
1322 			if (!parse_int(str, &str, &min, "minutes", 0, 60))
1323 				return NULL;
1324 			if (!isspace((unsigned char)*str)) {
1325 				zc_error_prev_line("space expected after minutes");
1326 				return NULL;
1327 			}
1328 			++str;
1329 		}
1330 
1331 		/* Seconds? */
1332 		if (isdigit((unsigned char)*str)) {
1333 			start = str;
1334 			if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
1335 				return NULL;
1336 			}
1337 
1338 			if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
1339 				return NULL;
1340 			}
1341 
1342 			if (!isspace((unsigned char)*str)) {
1343 				zc_error_prev_line("space expected after seconds");
1344 				return NULL;
1345 			}
1346 			/* No need for precision specifiers, it's a double */
1347 			if (sscanf(start, "%lf", &d) != 1) {
1348 				zc_error_prev_line("error parsing seconds");
1349 			}
1350 
1351 			if (d < 0.0 || d > 60.0) {
1352 				zc_error_prev_line("seconds not in range 0.0 .. 60.0");
1353 			}
1354 
1355 			secs = (int) (d * 1000.0 + 0.5);
1356 			++str;
1357 		}
1358 
1359 		switch(*str) {
1360 		case 'N':
1361 		case 'n':
1362 			lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1363 			break;
1364 		case 'E':
1365 		case 'e':
1366 			lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1367 			break;
1368 		case 'S':
1369 		case 's':
1370 			lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1371 			break;
1372 		case 'W':
1373 		case 'w':
1374 			lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1375 			break;
1376 		default:
1377 			zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
1378 			return NULL;
1379 		}
1380 		++str;
1381 
1382 		if (lat != 0 && lon != 0)
1383 			break;
1384 
1385 		if (!isspace((unsigned char)*str)) {
1386 			zc_error_prev_line("space expected after latitude/longitude");
1387 			return NULL;
1388 		}
1389 		++str;
1390 	}
1391 
1392 	/* Altitude */
1393 	if (*str == '\0') {
1394 		zc_error_prev_line("unexpected end of LOC data");
1395 		return NULL;
1396 	}
1397 
1398 	if (!isspace((unsigned char)*str)) {
1399 		zc_error_prev_line("space expected before altitude");
1400 		return NULL;
1401 	}
1402 	++str;
1403 
1404 	start = str;
1405 
1406 	/* Sign */
1407 	if (*str == '+' || *str == '-') {
1408 		++str;
1409 	}
1410 
1411 	/* Meters of altitude... */
1412 	if(strtol(str, &str, 10) == LONG_MAX) {
1413 		zc_error_prev_line("altitude too large, number overflow");
1414 		return NULL;
1415 	}
1416 	switch(*str) {
1417 	case ' ':
1418 	case '\0':
1419 	case 'm':
1420 		break;
1421 	case '.':
1422 		if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
1423 			return NULL;
1424 		}
1425 		if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
1426 			zc_error_prev_line("altitude fraction must be a number");
1427 			return NULL;
1428 		}
1429 		break;
1430 	default:
1431 		zc_error_prev_line("altitude must be expressed in meters");
1432 		return NULL;
1433 	}
1434 	if (!isspace((unsigned char)*str) && *str != '\0')
1435 		++str;
1436 
1437 	if (sscanf(start, "%lf", &d) != 1) {
1438 		zc_error_prev_line("error parsing altitude");
1439 	}
1440 
1441 	alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
1442 
1443 	if (!isspace((unsigned char)*str) && *str != '\0') {
1444 		zc_error_prev_line("unexpected character after altitude");
1445 		return NULL;
1446 	}
1447 
1448 	/* Now parse size, horizontal precision and vertical precision if any */
1449 	for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
1450 		vszhpvp[i] = precsize_aton(str + 1, &str);
1451 
1452 		if (!isspace((unsigned char)*str) && *str != '\0') {
1453 			zc_error_prev_line("invalid size or precision");
1454 			return NULL;
1455 		}
1456 	}
1457 
1458 	/* Allocate required space... */
1459 	r = alloc_rdata(region, 16);
1460 	p = (uint32_t *) (r + 1);
1461 
1462 	memmove(p, vszhpvp, 4);
1463 	write_uint32(p + 1, lat);
1464 	write_uint32(p + 2, lon);
1465 	write_uint32(p + 3, alt);
1466 
1467 	return r;
1468 }
1469 
1470 /*
1471  * Convert an APL RR RDATA element.
1472  */
1473 uint16_t *
zparser_conv_apl_rdata(region_type * region,char * str)1474 zparser_conv_apl_rdata(region_type *region, char *str)
1475 {
1476 	int negated = 0;
1477 	uint16_t address_family;
1478 	uint8_t prefix;
1479 	uint8_t maximum_prefix;
1480 	uint8_t length;
1481 	uint8_t address[IP6ADDRLEN];
1482 	char *colon = strchr(str, ':');
1483 	char *slash = strchr(str, '/');
1484 	int af;
1485 	int rc;
1486 	uint16_t rdlength;
1487 	uint16_t *r;
1488 	uint8_t *t;
1489 	char *end;
1490 	long p;
1491 
1492 	if (!colon) {
1493 		zc_error("address family separator is missing");
1494 		return NULL;
1495 	}
1496 	if (!slash) {
1497 		zc_error("prefix separator is missing");
1498 		return NULL;
1499 	}
1500 
1501 	*colon = '\0';
1502 	*slash = '\0';
1503 
1504 	if (*str == '!') {
1505 		negated = 1;
1506 		++str;
1507 	}
1508 
1509 	if (strcmp(str, "1") == 0) {
1510 		address_family = htons(1);
1511 		af = AF_INET;
1512 		length = sizeof(in_addr_t);
1513 		maximum_prefix = length * 8;
1514 	} else if (strcmp(str, "2") == 0) {
1515 		address_family = htons(2);
1516 		af = AF_INET6;
1517 		length = IP6ADDRLEN;
1518 		maximum_prefix = length * 8;
1519 	} else {
1520 		zc_error("invalid address family '%s'", str);
1521 		return NULL;
1522 	}
1523 
1524 	rc = inet_pton(af, colon + 1, address);
1525 	if (rc == 0) {
1526 		zc_error("invalid address '%s'", colon + 1);
1527 		return NULL;
1528 	} else if (rc == -1) {
1529 		zc_error("inet_pton failed: %s", strerror(errno));
1530 		return NULL;
1531 	}
1532 
1533 	/* Strip trailing zero octets.	*/
1534 	while (length > 0 && address[length - 1] == 0)
1535 		--length;
1536 
1537 
1538 	p = strtol(slash + 1, &end, 10);
1539 	if (p < 0 || p > maximum_prefix) {
1540 		zc_error("prefix not in the range 0 .. %d", maximum_prefix);
1541 		return NULL;
1542 	} else if (*end != '\0') {
1543 		zc_error("invalid prefix '%s'", slash + 1);
1544 		return NULL;
1545 	}
1546 	prefix = (uint8_t) p;
1547 
1548 	rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
1549 		    + length);
1550 	r = alloc_rdata(region, rdlength);
1551 	t = (uint8_t *) (r + 1);
1552 
1553 	memcpy(t, &address_family, sizeof(address_family));
1554 	t += sizeof(address_family);
1555 	memcpy(t, &prefix, sizeof(prefix));
1556 	t += sizeof(prefix);
1557 	memcpy(t, &length, sizeof(length));
1558 	if (negated) {
1559 		*t |= APL_NEGATION_MASK;
1560 	}
1561 	t += sizeof(length);
1562 	memcpy(t, address, length);
1563 
1564 	return r;
1565 }
1566 
1567 /*
1568  * Below some function that also convert but not to wireformat
1569  * but to "normal" (int,long,char) types
1570  */
1571 
1572 uint32_t
zparser_ttl2int(const char * ttlstr,int * error)1573 zparser_ttl2int(const char *ttlstr, int* error)
1574 {
1575 	/* convert a ttl value to a integer
1576 	 * return the ttl in a int
1577 	 * -1 on error
1578 	 */
1579 
1580 	uint32_t ttl;
1581 	const char *t;
1582 
1583 	ttl = strtottl(ttlstr, &t);
1584 	if (*t != 0) {
1585 		zc_error_prev_line("invalid TTL value: %s",ttlstr);
1586 		*error = 1;
1587 	}
1588 
1589 	return ttl;
1590 }
1591 
1592 
1593 void
zadd_rdata_wireformat(uint16_t * data)1594 zadd_rdata_wireformat(uint16_t *data)
1595 {
1596 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1597 		zc_error_prev_line("too many rdata elements");
1598 	} else {
1599 		parser->current_rr.rdatas[parser->current_rr.rdata_count].data
1600 			= data;
1601 		++parser->current_rr.rdata_count;
1602 	}
1603 }
1604 
1605 /**
1606  * Used for TXT RR's to grow with undefined number of strings.
1607  */
1608 void
zadd_rdata_txt_wireformat(uint16_t * data,int first)1609 zadd_rdata_txt_wireformat(uint16_t *data, int first)
1610 {
1611 	rdata_atom_type *rd;
1612 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1613 		zc_error_prev_line("too many rdata txt elements");
1614 		return;
1615 	}
1616 
1617 	/* First STR in str_seq, allocate 65K in first unused rdata
1618 	 * else find last used rdata */
1619 	if (first) {
1620 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1621 		if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1622 			sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
1623 			zc_error_prev_line("Could not allocate memory for TXT RR");
1624 			return;
1625 		}
1626 		parser->current_rr.rdata_count++;
1627 		rd->data[0] = 0;
1628 	}
1629 	else
1630 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1631 
1632 	if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1633 		zc_error_prev_line("too large rdata element");
1634 		return;
1635 	}
1636 
1637 	memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1638 	rd->data[0] += data[0];
1639 }
1640 
1641 /**
1642  * Clean up after last call of zadd_rdata_txt_wireformat
1643  */
1644 void
zadd_rdata_txt_clean_wireformat()1645 zadd_rdata_txt_clean_wireformat()
1646 {
1647 	uint16_t *tmp_data;
1648 	rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1649 	if(!rd || !rd->data)
1650 		return; /* previous syntax failure */
1651 	if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1652 		((size_t)rd->data[0]) + ((size_t)2))) != NULL) {
1653 		memcpy(tmp_data, rd->data, rd->data[0] + 2);
1654 		/* rd->data of u16+65535 freed when rr_region is freed */
1655 		rd->data = tmp_data;
1656 	}
1657 	else {
1658 		/* We could not get memory in non-volatile region */
1659 		zc_error_prev_line("could not allocate memory for rdata");
1660 		return;
1661 	}
1662 }
1663 
1664 static int
svcparam_key_cmp(const void * a,const void * b)1665 svcparam_key_cmp(const void *a, const void *b)
1666 {
1667 	return ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)a)))
1668 	     - ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)b)));
1669 }
1670 
1671 void
zadd_rdata_svcb_check_wireformat()1672 zadd_rdata_svcb_check_wireformat()
1673 {
1674 	size_t i;
1675 	uint8_t paramkeys[65536];
1676 	int prev_key = - 1;
1677 	int key = 0;
1678 	size_t size;
1679 	uint16_t *mandatory_values;
1680 
1681 	if (parser->current_rr.rdata_count <= 2) {
1682 		if (!parser->error_occurred)
1683 			zc_error_prev_line("invalid SVCB or HTTPS rdata");
1684 		return;
1685 	} else for (i = 2; i < parser->current_rr.rdata_count; i++) {
1686 		if (parser->current_rr.rdatas[i].data == NULL
1687 		||  rdata_atom_data(parser->current_rr.rdatas[i]) == NULL
1688 		||  rdata_atom_size(parser->current_rr.rdatas[i]) < 4) {
1689 			if (!parser->error_occurred)
1690 				zc_error_prev_line("invalid SVCB or HTTPS rdata");
1691 			return;
1692 		}
1693 	}
1694 	/* After this point, all rdatas do have data larger than 4 bytes.
1695 	 * So we may assume a uint16_t SVCB key followed by uint16_t length
1696 	 * in each rdata in the remainder of this function.
1697 	 */
1698 	memset(paramkeys, 0, sizeof(paramkeys));
1699 	/*
1700 	 * In draft-ietf-dnsop-svcb-https-04 Section 7:
1701 	 * In wire format, the keys are represented by their numeric values in
1702 	 * network byte order, concatenated in ascending order.
1703 	 *
1704 	 * svcparam_key_cmp assumes the rdatas to have a SVCB key, which is
1705 	 * safe because we checked.
1706 	 *
1707 	 */
1708 	qsort( (void *)&parser->current_rr.rdatas[2]
1709 	     , parser->current_rr.rdata_count - 2
1710 	     , sizeof(rdata_atom_type)
1711 	     , svcparam_key_cmp
1712 	     );
1713 
1714 	for (i = 2; i < parser->current_rr.rdata_count; i++) {
1715 		assert(parser->current_rr.rdatas[i].data);
1716 		assert(rdata_atom_data(parser->current_rr.rdatas[i]));
1717 		assert(rdata_atom_size(parser->current_rr.rdatas[i]) >= sizeof(uint16_t));
1718 
1719 		key = read_uint16(rdata_atom_data(parser->current_rr.rdatas[i]));
1720 
1721 		/* In draft-ietf-dnsop-svcb-https-04 Section 7:
1722 		 *
1723 		 *     Keys (...) MUST NOT appear more than once.
1724 		 *
1725 		 * If they key has already been seen, we have a duplicate
1726 		 */
1727 		if (!paramkeys[key])
1728 			/* keep track of keys that are present */
1729 			paramkeys[key] = 1;
1730 
1731 		else if (key < SVCPARAMKEY_COUNT) {
1732 			if(zone_is_slave(parser->current_zone->opts))
1733 				zc_warning_prev_line(
1734 					"Duplicate key found: %s",
1735 					svcparamkey_strs[key]);
1736 			else {
1737 				zc_error_prev_line(
1738 					"Duplicate key found: %s",
1739 					svcparamkey_strs[key]);
1740 			}
1741 		} else if(zone_is_slave(parser->current_zone->opts))
1742 			zc_warning_prev_line(
1743 					"Duplicate key found: key%d", key);
1744 		else
1745 			zc_error_prev_line(
1746 					"Duplicate key found: key%d", key);
1747 	}
1748 	/* Checks when a mandatory key is present */
1749 	if (!paramkeys[SVCB_KEY_MANDATORY])
1750 		return;
1751 
1752 	size = rdata_atom_size(parser->current_rr.rdatas[2]);
1753 	assert(size >= 4);
1754 	mandatory_values = (void*)rdata_atom_data(parser->current_rr.rdatas[2]);
1755 	mandatory_values += 2; /* skip the key type and length */
1756 
1757 	if (size % 2)
1758 		zc_error_prev_line("mandatory rdata must be a multiple of shorts");
1759 
1760 	else for (i = 0; i < (size - 4)/2; i++) {
1761 		key = ntohs(mandatory_values[i]);
1762 
1763 		if (paramkeys[key])
1764 			; /* pass */
1765 
1766 		else if (key < SVCPARAMKEY_COUNT) {
1767 			if(zone_is_slave(parser->current_zone->opts))
1768 				zc_warning_prev_line("mandatory SvcParamKey: %s is missing "
1769 						     "the record", svcparamkey_strs[key]);
1770 			else
1771 				zc_error_prev_line("mandatory SvcParamKey: %s is missing "
1772 						   "the record", svcparamkey_strs[key]);
1773 		} else {
1774 			if(zone_is_slave(parser->current_zone->opts))
1775 				zc_warning_prev_line("mandatory SvcParamKey: key%d is missing "
1776 						     "the record", key);
1777 			else
1778 				zc_error_prev_line("mandatory SvcParamKey: key%d is missing "
1779 						   "the record", key);
1780 		}
1781 
1782 		/* In draft-ietf-dnsop-svcb-https-04 Section 8
1783 		 * automatically mandatory MUST NOT appear in its own value-list
1784 		 */
1785 		if (key == SVCB_KEY_MANDATORY) {
1786 			if(zone_is_slave(parser->current_zone->opts))
1787 				zc_warning_prev_line("mandatory MUST not be included"
1788 						     " as mandatory parameter");
1789 			else
1790 				zc_error_prev_line("mandatory MUST not be included"
1791 						   " as mandatory parameter");
1792 		}
1793 		if (key == prev_key) {
1794 			if(zone_is_slave(parser->current_zone->opts))
1795 				zc_warning_prev_line("Keys inSvcParam mandatory "
1796 				                   "MUST NOT appear more than once.");
1797 			else
1798 				zc_error_prev_line("Keys in SvcParam mandatory "
1799 				                   "MUST NOT appear more than once.");
1800 		}
1801 		prev_key = key;
1802 	}
1803 }
1804 
1805 void
zadd_rdata_domain(domain_type * domain)1806 zadd_rdata_domain(domain_type *domain)
1807 {
1808 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1809 		zc_error_prev_line("too many rdata elements");
1810 	} else {
1811 		parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1812 			= domain;
1813 		domain->usage ++; /* new reference to domain */
1814 		++parser->current_rr.rdata_count;
1815 	}
1816 }
1817 
1818 void
parse_unknown_rdata(uint16_t type,uint16_t * wireformat)1819 parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1820 {
1821 	buffer_type packet;
1822 	uint16_t size;
1823 	ssize_t rdata_count;
1824 	ssize_t i;
1825 	rdata_atom_type *rdatas;
1826 
1827 	if (wireformat) {
1828 		size = *wireformat;
1829 	} else {
1830 		return;
1831 	}
1832 
1833 	buffer_create_from(&packet, wireformat + 1, *wireformat);
1834 	rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1835 						      parser->db->domains,
1836 						      type,
1837 						      size,
1838 						      &packet,
1839 						      &rdatas);
1840 	if (rdata_count == -1) {
1841 		zc_error_prev_line("bad unknown RDATA");
1842 		return;
1843 	}
1844 
1845 	for (i = 0; i < rdata_count; ++i) {
1846 		if (rdata_atom_is_domain(type, i)) {
1847 			zadd_rdata_domain(rdatas[i].domain);
1848 		} else {
1849 			zadd_rdata_wireformat(rdatas[i].data);
1850 		}
1851 	}
1852 	region_recycle(parser->region, rdatas,
1853 		rdata_count*sizeof(rdata_atom_type));
1854 }
1855 
1856 
1857 /*
1858  * Compares two rdata arrays.
1859  *
1860  * Returns:
1861  *
1862  *	zero if they are equal
1863  *	non-zero if not
1864  *
1865  */
1866 static int
zrdatacmp(uint16_t type,rr_type * a,rr_type * b)1867 zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1868 {
1869 	int i = 0;
1870 
1871 	assert(a);
1872 	assert(b);
1873 
1874 	/* One is shorter than another */
1875 	if (a->rdata_count != b->rdata_count)
1876 		return 1;
1877 
1878 	/* Compare element by element */
1879 	for (i = 0; i < a->rdata_count; ++i) {
1880 		if (rdata_atom_is_domain(type, i)) {
1881 			if (rdata_atom_domain(a->rdatas[i])
1882 			    != rdata_atom_domain(b->rdatas[i]))
1883 			{
1884 				return 1;
1885 			}
1886 		} else if(rdata_atom_is_literal_domain(type, i)) {
1887 			if (rdata_atom_size(a->rdatas[i])
1888 			    != rdata_atom_size(b->rdatas[i]))
1889 				return 1;
1890 			if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1891 				   rdata_atom_data(b->rdatas[i]),
1892 				   rdata_atom_size(a->rdatas[i])))
1893 				return 1;
1894 		} else {
1895 			if (rdata_atom_size(a->rdatas[i])
1896 			    != rdata_atom_size(b->rdatas[i]))
1897 			{
1898 				return 1;
1899 			}
1900 			if (memcmp(rdata_atom_data(a->rdatas[i]),
1901 				   rdata_atom_data(b->rdatas[i]),
1902 				   rdata_atom_size(a->rdatas[i])) != 0)
1903 			{
1904 				return 1;
1905 			}
1906 		}
1907 	}
1908 
1909 	/* Otherwise they are equal */
1910 	return 0;
1911 }
1912 
1913 /*
1914  *
1915  * Opens a zone file.
1916  *
1917  * Returns:
1918  *
1919  *	- pointer to the parser structure
1920  *	- NULL on error and errno set
1921  *
1922  */
1923 static int
zone_open(const char * filename,uint32_t ttl,uint16_t klass,const dname_type * origin)1924 zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1925 	  const dname_type *origin)
1926 {
1927 	/* Open the zone file... */
1928 	if (strcmp(filename, "-") == 0) {
1929 		yyin = stdin;
1930 		filename = "<stdin>";
1931 		warn_if_directory("zonefile from stdin", yyin, filename);
1932 	} else {
1933 		if (!(yyin = fopen(filename, "r"))) {
1934 			return 0;
1935 		}
1936 		warn_if_directory("zonefile", yyin, filename);
1937 	}
1938 
1939 	zparser_init(filename, ttl, klass, origin);
1940 
1941 	return 1;
1942 }
1943 
1944 
1945 void
set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],uint16_t index)1946 set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
1947 	    uint16_t index)
1948 {
1949 	/*
1950 	 * The bits are counted from left to right, so bit #0 is the
1951 	 * left most bit.
1952 	 */
1953 	uint8_t window = index / 256;
1954 	uint8_t bit = index % 256;
1955 
1956 	bits[window][bit / 8] |= (1 << (7 - bit % 8));
1957 }
1958 
1959 
1960 static int
has_soa(domain_type * domain)1961 has_soa(domain_type* domain)
1962 {
1963 	rrset_type* p = NULL;
1964 	if(!domain) return 0;
1965 	for(p = domain->rrsets; p; p = p->next)
1966 		if(rrset_rrtype(p) == TYPE_SOA)
1967 			return 1;
1968 	return 0;
1969 }
1970 
1971 int
process_rr(void)1972 process_rr(void)
1973 {
1974 	zone_type *zone = parser->current_zone;
1975 	rr_type *rr = &parser->current_rr;
1976 	rrset_type *rrset;
1977 	size_t max_rdlength;
1978 	int i;
1979 	rrtype_descriptor_type *descriptor
1980 		= rrtype_descriptor_by_type(rr->type);
1981 
1982 	/* We only support IN class */
1983 	if (rr->klass != CLASS_IN) {
1984 		if(zone_is_slave(zone->opts))
1985 			zc_warning_prev_line("only class IN is supported");
1986 		else
1987 			zc_error_prev_line("only class IN is supported");
1988 		return 0;
1989 	}
1990 
1991 	/* Make sure the maximum RDLENGTH does not exceed 65535 bytes.	*/
1992 	max_rdlength = rdata_maximum_wireformat_size(
1993 		descriptor, rr->rdata_count, rr->rdatas);
1994 
1995 	if (max_rdlength > MAX_RDLENGTH) {
1996 		zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
1997 		return 0;
1998 	}
1999 
2000 	/* We cannot print invalid owner names,
2001 	 * so error on that before it is used in printing other errors.
2002 	 */
2003 	if (rr->owner == error_domain
2004 	||  domain_dname(rr->owner) == error_dname) {
2005 		zc_error_prev_line("invalid owner name");
2006 		return 0;
2007 	}
2008 
2009 	/* we have the zone already */
2010 	assert(zone);
2011 	if (rr->type == TYPE_SOA) {
2012 		if (rr->owner != zone->apex) {
2013 			char s[MAXDOMAINLEN*5];
2014 			snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2015 			zc_error_prev_line(
2016 				"SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s);
2017 			return 0;
2018 		}
2019 		if(has_soa(rr->owner)) {
2020 			if(zone_is_slave(zone->opts))
2021 				zc_warning_prev_line("this SOA record was already encountered");
2022 			else
2023 				zc_error_prev_line("this SOA record was already encountered");
2024 			return 0;
2025 		}
2026 		rr->owner->is_apex = 1;
2027 	}
2028 
2029 	if (!domain_is_subdomain(rr->owner, zone->apex))
2030 	{
2031 		char s[MAXDOMAINLEN*5];
2032 		snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2033 		if(zone_is_slave(zone->opts))
2034 			zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2035 		else
2036 			zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2037 		return 0;
2038 	}
2039 
2040 	/* Do we have this type of rrset already? */
2041 	rrset = domain_find_rrset(rr->owner, zone, rr->type);
2042 	if (!rrset) {
2043 		rrset = (rrset_type *) region_alloc(parser->region,
2044 						    sizeof(rrset_type));
2045 		rrset->zone = zone;
2046 		rrset->rr_count = 1;
2047 		rrset->rrs = (rr_type *) region_alloc(parser->region,
2048 						      sizeof(rr_type));
2049 		rrset->rrs[0] = *rr;
2050 
2051 		/* Add it */
2052 		domain_add_rrset(rr->owner, rrset);
2053 	} else {
2054 		rr_type* o;
2055 		if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
2056 			zc_warning_prev_line(
2057 				"%s TTL %u does not match the TTL %u of the %s RRset",
2058 				domain_to_string(rr->owner), (unsigned)rr->ttl,
2059 				(unsigned)rrset->rrs[0].ttl,
2060 				rrtype_to_string(rr->type));
2061 		}
2062 
2063 		/* Search for possible duplicates... */
2064 		for (i = 0; i < rrset->rr_count; i++) {
2065 			if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
2066 				break;
2067 			}
2068 		}
2069 
2070 		/* Discard the duplicates... */
2071 		if (i < rrset->rr_count) {
2072 			/* add rdatas to recycle bin. */
2073 			size_t i;
2074 			for (i = 0; i < rr->rdata_count; i++) {
2075 				if(!rdata_atom_is_domain(rr->type, i))
2076 					region_recycle(parser->region, rr->rdatas[i].data,
2077 						rdata_atom_size(rr->rdatas[i])
2078 						+ sizeof(uint16_t));
2079 			}
2080 			region_recycle(parser->region, rr->rdatas,
2081 				sizeof(rdata_atom_type)*rr->rdata_count);
2082 			return 0;
2083 		}
2084 		if(rrset->rr_count == 65535) {
2085 			zc_error_prev_line("too many RRs for domain RRset");
2086 			return 0;
2087 		}
2088 
2089 		/* Add it... */
2090 		o = rrset->rrs;
2091 		rrset->rrs = (rr_type *) region_alloc_array(parser->region,
2092 			(rrset->rr_count + 1), sizeof(rr_type));
2093 		memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
2094 		region_recycle(parser->region, o,
2095 			(rrset->rr_count) * sizeof(rr_type));
2096 		rrset->rrs[rrset->rr_count] = *rr;
2097 		++rrset->rr_count;
2098 	}
2099 
2100 	if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
2101 		if(zone_is_slave(zone->opts))
2102 			zc_warning_prev_line("multiple DNAMEs at the same name");
2103 		else
2104 			zc_error_prev_line("multiple DNAMEs at the same name");
2105 	}
2106 	if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
2107 		if(zone_is_slave(zone->opts))
2108 			zc_warning_prev_line("multiple CNAMEs at the same name");
2109 		else
2110 			zc_error_prev_line("multiple CNAMEs at the same name");
2111 	}
2112 	if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
2113 	 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
2114 		if(zone_is_slave(zone->opts))
2115 			zc_warning_prev_line("DNAME and CNAME at the same name");
2116 		else
2117 			zc_error_prev_line("DNAME and CNAME at the same name");
2118 	}
2119 	if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
2120 		domain_find_non_cname_rrset(rr->owner, zone)) {
2121 		if(zone_is_slave(zone->opts))
2122 			zc_warning_prev_line("CNAME and other data at the same name");
2123 		else
2124 			zc_error_prev_line("CNAME and other data at the same name");
2125 	}
2126 
2127 	/* Check we have SOA */
2128 	if(rr->owner == zone->apex)
2129 		apex_rrset_checks(parser->db, rrset, rr->owner);
2130 
2131 	if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
2132 		struct stat buf;
2133 		startzonec = time(NULL);
2134 		buf.st_size = 0;
2135 		fstat(fileno(yyin), &buf);
2136 		if(buf.st_size == 0) buf.st_size = 1;
2137 		VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
2138 			parser->current_zone->opts->name,
2139 			(int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
2140 	}
2141 	++totalrrs;
2142 	return 1;
2143 }
2144 
2145 /*
2146  * Find rrset type for any zone
2147  */
2148 static rrset_type*
domain_find_rrset_any(domain_type * domain,uint16_t type)2149 domain_find_rrset_any(domain_type *domain, uint16_t type)
2150 {
2151 	rrset_type *result = domain->rrsets;
2152 	while (result) {
2153 		if (rrset_rrtype(result) == type) {
2154 			return result;
2155 		}
2156 		result = result->next;
2157 	}
2158 	return NULL;
2159 }
2160 
2161 /*
2162  * Check for DNAME type. Nothing is allowed below it
2163  */
2164 static void
check_dname(zone_type * zone)2165 check_dname(zone_type* zone)
2166 {
2167 	domain_type* domain;
2168 	for(domain = zone->apex; domain && domain_is_subdomain(domain,
2169 		zone->apex); domain=domain_next(domain))
2170 	{
2171 		if(domain->is_existing) {
2172 			/* there may not be DNAMEs above it */
2173 			domain_type* parent = domain->parent;
2174 #ifdef NSEC3
2175 			if(domain_has_only_NSEC3(domain, NULL))
2176 				continue;
2177 #endif
2178 			while(parent) {
2179 				if(domain_find_rrset_any(parent, TYPE_DNAME)) {
2180 					zc_error("While checking node %s,",
2181 						domain_to_string(domain));
2182 					zc_error("DNAME at %s has data below it. "
2183 						"This is not allowed (rfc 2672).",
2184 						domain_to_string(parent));
2185 					return;
2186 				}
2187 				parent = parent->parent;
2188 			}
2189 		}
2190 	}
2191 }
2192 
2193 /*
2194  * Reads the specified zone into the memory
2195  * nsd_options can be NULL if no config file is passed.
2196  */
2197 unsigned int
zonec_read(const char * name,const char * zonefile,zone_type * zone)2198 zonec_read(const char* name, const char* zonefile, zone_type* zone)
2199 {
2200 	const dname_type *dname;
2201 
2202 	totalrrs = 0;
2203 	startzonec = time(NULL);
2204 	parser->errors = 0;
2205 
2206 	dname = dname_parse(parser->rr_region, name);
2207 	if (!dname) {
2208 		zc_error("incorrect zone name '%s'", name);
2209 		return 1;
2210 	}
2211 
2212 	/* Open the zone file */
2213 	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
2214 		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
2215 		return 1;
2216 	}
2217 	parser->current_zone = zone;
2218 
2219 	/* Parse and process all RRs.  */
2220 	yyparse();
2221 
2222 	/* remove origin if it was unused */
2223 	if(parser->origin != error_domain)
2224 		domain_table_deldomain(parser->db, parser->origin);
2225 	/* rr_region has been emptied by now */
2226 	dname = dname_parse(parser->rr_region, name);
2227 
2228 	/* check if zone file contained a correct SOA record */
2229 	if (!parser->current_zone) {
2230 		zc_error("zone configured as '%s' has no content.", name);
2231 	} else if(!parser->current_zone->soa_rrset ||
2232 		parser->current_zone->soa_rrset->rr_count == 0) {
2233 		zc_error("zone configured as '%s' has no SOA record.", name);
2234 	} else if(dname_compare(domain_dname(
2235 		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
2236 		zc_error("zone configured as '%s', but SOA has owner '%s'.",
2237 			name, domain_to_string(
2238 			parser->current_zone->soa_rrset->rrs[0].owner));
2239 	}
2240 	region_free_all(parser->rr_region);
2241 
2242 	parser_flush();
2243 	fclose(yyin);
2244 	if(!zone_is_slave(zone->opts))
2245 		check_dname(zone);
2246 
2247 	parser->filename = NULL;
2248 	return parser->errors;
2249 }
2250 
2251 
2252 /*
2253  * setup parse
2254  */
2255 void
zonec_setup_parser(namedb_type * db)2256 zonec_setup_parser(namedb_type* db)
2257 {
2258 	region_type* rr_region = region_create(xalloc, free);
2259 	parser = zparser_create(db->region, rr_region, db);
2260 	assert(parser);
2261 	/* Unique pointers used to mark errors.	 */
2262 	error_dname = (dname_type *) region_alloc(db->region, 1);
2263 	error_domain = (domain_type *) region_alloc(db->region, 1);
2264 	/* Open the network database */
2265 	setprotoent(1);
2266 	setservent(1);
2267 }
2268 
2269 /** desetup parse */
2270 void
zonec_desetup_parser(void)2271 zonec_desetup_parser(void)
2272 {
2273 	if(parser) {
2274 		endservent();
2275 		endprotoent();
2276 		region_destroy(parser->rr_region);
2277 		/* removed when parser->region(=db->region) is destroyed:
2278 		 * region_recycle(parser->region, (void*)error_dname, 1);
2279 		 * region_recycle(parser->region, (void*)error_domain, 1); */
2280 		/* clear memory for exit, but this is not portable to
2281 		 * other versions of lex. yylex_destroy(); */
2282 #ifdef MEMCLEAN /* OS collects memory pages */
2283 		yylex_destroy();
2284 #endif
2285 	}
2286 }
2287 
2288 static domain_table_type* orig_domains = NULL;
2289 static region_type* orig_region = NULL;
2290 static region_type* orig_dbregion = NULL;
2291 
2292 /** setup for string parse */
2293 void
zonec_setup_string_parser(region_type * region,domain_table_type * domains)2294 zonec_setup_string_parser(region_type* region, domain_table_type* domains)
2295 {
2296 	assert(parser); /* global parser must be setup */
2297 	orig_domains = parser->db->domains;
2298 	orig_region = parser->region;
2299 	orig_dbregion = parser->db->region;
2300 	parser->region = region;
2301 	parser->db->region = region;
2302 	parser->db->domains = domains;
2303 	zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
2304 }
2305 
2306 /** desetup string parse */
2307 void
zonec_desetup_string_parser(void)2308 zonec_desetup_string_parser(void)
2309 {
2310 	parser->region = orig_region;
2311 	parser->db->domains = orig_domains;
2312 	parser->db->region = orig_dbregion;
2313 }
2314 
2315 /** parse a string into temporary storage */
2316 int
zonec_parse_string(region_type * region,domain_table_type * domains,zone_type * zone,char * str,domain_type ** parsed,int * num_rrs)2317 zonec_parse_string(region_type* region, domain_table_type* domains,
2318 	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
2319 {
2320 	int errors;
2321 	zonec_setup_string_parser(region, domains);
2322 	parser->current_zone = zone;
2323 	parser->errors = 0;
2324 	totalrrs = 0;
2325 	startzonec = time(NULL)+100000; /* disable */
2326 	parser_push_stringbuf(str);
2327 	yyparse();
2328 	parser_pop_stringbuf();
2329 	errors = parser->errors;
2330 	*num_rrs = totalrrs;
2331 	if(*num_rrs == 0)
2332 		*parsed = NULL;
2333 	else	*parsed = parser->prev_dname;
2334 	/* remove origin if it was not used during the parse */
2335 	if(parser->origin != error_domain)
2336 		domain_table_deldomain(parser->db, parser->origin);
2337 	region_free_all(parser->rr_region);
2338 	zonec_desetup_string_parser();
2339 	parser_flush();
2340 	return errors;
2341 }
2342 
2343 /** check SSHFP type for failures and emit warnings */
check_sshfp(void)2344 void check_sshfp(void)
2345 {
2346 	uint8_t hash;
2347 	uint16_t size;
2348 	if(parser->current_rr.rdata_count < 3)
2349 		return; /* cannot check it, too few rdata elements */
2350 	if(!parser->current_rr.rdatas[0].data ||
2351 		!parser->current_rr.rdatas[1].data ||
2352 		!parser->current_rr.rdatas[2].data ||
2353 		!parser->current_rr.owner)
2354 		return; /* cannot check, NULLs (due to earlier errors) */
2355 	if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1)
2356 		return; /* wrong size of the hash type rdata element */
2357 	hash = rdata_atom_data(parser->current_rr.rdatas[1])[0];
2358 	size = rdata_atom_size(parser->current_rr.rdatas[2]);
2359 	if(hash == 1 && size != 20) {
2360 		zc_warning_prev_line("SSHFP %s of type SHA1 has hash of "
2361 			"wrong length, %d bytes, should be 20",
2362 			domain_to_string(parser->current_rr.owner),
2363 			(int)size);
2364 	} else if(hash == 2 && size != 32) {
2365 		zc_warning_prev_line("SSHFP %s of type SHA256 has hash of "
2366 			"wrong length, %d bytes, should be 32",
2367 			domain_to_string(parser->current_rr.owner),
2368 			(int)size);
2369 	}
2370 }
2371 
2372 void
apex_rrset_checks(namedb_type * db,rrset_type * rrset,domain_type * domain)2373 apex_rrset_checks(namedb_type* db, rrset_type* rrset, domain_type* domain)
2374 {
2375 	uint32_t soa_minimum;
2376 	unsigned i;
2377 	zone_type* zone = rrset->zone;
2378 	assert(domain == zone->apex);
2379 	(void)domain;
2380 	if (rrset_rrtype(rrset) == TYPE_SOA) {
2381 		zone->soa_rrset = rrset;
2382 
2383 		/* BUG #103 add another soa with a tweaked ttl */
2384 		if(zone->soa_nx_rrset == 0) {
2385 			zone->soa_nx_rrset = region_alloc(db->region,
2386 				sizeof(rrset_type));
2387 			zone->soa_nx_rrset->rr_count = 1;
2388 			zone->soa_nx_rrset->next = 0;
2389 			zone->soa_nx_rrset->zone = zone;
2390 			zone->soa_nx_rrset->rrs = region_alloc(db->region,
2391 				sizeof(rr_type));
2392 		}
2393 		memcpy(zone->soa_nx_rrset->rrs, rrset->rrs, sizeof(rr_type));
2394 
2395 		/* check the ttl and MINIMUM value and set accordingly */
2396 		memcpy(&soa_minimum, rdata_atom_data(rrset->rrs->rdatas[6]),
2397 				rdata_atom_size(rrset->rrs->rdatas[6]));
2398 		if (rrset->rrs->ttl > ntohl(soa_minimum)) {
2399 			zone->soa_nx_rrset->rrs[0].ttl = ntohl(soa_minimum);
2400 		}
2401 	} else if (rrset_rrtype(rrset) == TYPE_NS) {
2402 		zone->ns_rrset = rrset;
2403 	} else if (rrset_rrtype(rrset) == TYPE_RRSIG) {
2404 		for (i = 0; i < rrset->rr_count; ++i) {
2405 			if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY){
2406 				zone->is_secure = 1;
2407 				break;
2408 			}
2409 		}
2410 	}
2411 }
2412