xref: /netbsd/external/bsd/nsd/dist/zonec.c (revision 66a1527d)
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("ech")-1:
802 		if (!strncmp(key, "ech", sizeof("ech")-1))
803 			return SVCB_KEY_ECH;
804 		break;
805 	default:
806 		break;
807 	}
808 	if (key_len > sizeof(buf) - 1)
809 		zc_error_prev_line("Unknown SvcParamKey");
810 	else {
811 		memcpy(buf, key, key_len);
812 		buf[key_len] = 0;
813 		zc_error_prev_line("Unknown SvcParamKey: %s", buf);
814 	}
815 	/* Although the returned value might be used by the caller,
816 	 * the parser has erred, so the zone will not be loaded.
817 	 */
818 	return -1;
819 }
820 
821 static uint16_t *
zparser_conv_svcbparam_port_value(region_type * region,const char * val)822 zparser_conv_svcbparam_port_value(region_type *region, const char *val)
823 {
824 	unsigned long int port;
825 	char *endptr;
826 	uint16_t *r;
827 
828 	port = strtoul(val, &endptr, 10);
829 	if (endptr > val	/* digits seen */
830 	&& *endptr == 0		/* no non-digit chars after digits */
831 	&&  port <= 65535) {	/* no overflow */
832 
833 		r = alloc_rdata(region, 3 * sizeof(uint16_t));
834 		r[1] = htons(SVCB_KEY_PORT);
835 		r[2] = htons(sizeof(uint16_t));
836 		r[3] = htons(port);
837 		return r;
838 	}
839 	zc_error_prev_line("Could not parse port SvcParamValue: \"%s\"", val);
840 	return NULL;
841 }
842 
843 static uint16_t *
zparser_conv_svcbparam_ipv4hint_value(region_type * region,const char * val)844 zparser_conv_svcbparam_ipv4hint_value(region_type *region, const char *val)
845 {
846 	uint16_t *r;
847 	int count;
848 	char ip_str[INET_ADDRSTRLEN+1];
849 	char *next_ip_str;
850 	uint32_t *ip_wire_dst;
851 	size_t i;
852 
853 	for (i = 0, count = 1; val[i]; i++) {
854 		if (val[i] == ',')
855 			count += 1;
856 		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
857 			zc_error_prev_line("Too many IPV4 addresses in ipv4hint");
858 			return NULL;
859 		}
860 	}
861 
862 	/* count == number of comma's in val + 1, so the actual number of IPv4
863 	 * addresses in val
864 	 */
865 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP4ADDRLEN * count);
866 	r[1] = htons(SVCB_KEY_IPV4HINT);
867 	r[2] = htons(IP4ADDRLEN * count);
868 	ip_wire_dst = (void *)&r[3];
869 
870 	while (count) {
871 		if (!(next_ip_str = strchr(val, ','))) {
872 			if (inet_pton(AF_INET, val, ip_wire_dst) != 1)
873 				break;
874 
875 			assert(count == 1);
876 
877 		} else if (next_ip_str - val >= (int)sizeof(ip_str))
878 			break;
879 
880 		else {
881 			memcpy(ip_str, val, next_ip_str - val);
882 			ip_str[next_ip_str - val] = 0;
883 			if (inet_pton(AF_INET, ip_str, ip_wire_dst) != 1) {
884 				val = ip_str; /* to use in error reporting below */
885 				break;
886 			}
887 
888 			val = next_ip_str + 1;
889 		}
890 		ip_wire_dst++;
891 		count--;
892 	}
893 	if (count)
894 		zc_error_prev_line("Could not parse ipv4hint SvcParamValue: %s", val);
895 
896 	return r;
897 }
898 
899 static uint16_t *
zparser_conv_svcbparam_ipv6hint_value(region_type * region,const char * val)900 zparser_conv_svcbparam_ipv6hint_value(region_type *region, const char *val)
901 {
902 	uint16_t *r;
903 	int i, count;
904 	char ip6_str[INET6_ADDRSTRLEN+1];
905 	char *next_ip6_str;
906 	uint8_t *ipv6_wire_dst;
907 
908 	for (i = 0, count = 1; val[i]; i++) {
909 		if (val[i] == ',')
910 			count += 1;
911 		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
912 			zc_error_prev_line("Too many IPV6 addresses in ipv6hint");
913 			return NULL;
914 		}
915 	}
916 
917 	/* count == number of comma's in val + 1
918 	 * so actually the number of IPv6 addresses in val
919 	 */
920 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP6ADDRLEN * count);
921 	r[1] = htons(SVCB_KEY_IPV6HINT);
922 	r[2] = htons(IP6ADDRLEN * count);
923 	ipv6_wire_dst = (void *)&r[3];
924 
925 	while (count) {
926 		if (!(next_ip6_str = strchr(val, ','))) {
927 			if ((inet_pton(AF_INET6, val, ipv6_wire_dst) != 1))
928 				break;
929 
930 			assert(count == 1);
931 
932 		} else if (next_ip6_str - val >= (int)sizeof(ip6_str))
933 			break;
934 
935 		else {
936 			memcpy(ip6_str, val, next_ip6_str - val);
937 			ip6_str[next_ip6_str - val] = 0;
938 			if (inet_pton(AF_INET6, ip6_str, ipv6_wire_dst) != 1) {
939 				val = ip6_str; /* for error reporting below */
940 				break;
941 			}
942 
943 			val = next_ip6_str + 1; /* skip the comma */
944 		}
945 		ipv6_wire_dst += IP6ADDRLEN;
946 		count--;
947 	}
948 	if (count)
949 		zc_error_prev_line("Could not parse ipv6hint SvcParamValue: %s", val);
950 
951 	return r;
952 }
953 
954 static int
network_uint16_cmp(const void * a,const void * b)955 network_uint16_cmp(const void *a, const void *b)
956 {
957 	return ((int)read_uint16(a)) - ((int)read_uint16(b));
958 }
959 
960 static uint16_t *
zparser_conv_svcbparam_mandatory_value(region_type * region,const char * val,size_t val_len)961 zparser_conv_svcbparam_mandatory_value(region_type *region,
962 		const char *val, size_t val_len)
963 {
964 	uint16_t *r;
965 	size_t i, count;
966 	char* next_key;
967 	uint16_t* key_dst;
968 
969 	for (i = 0, count = 1; val[i]; i++) {
970 		if (val[i] == ',')
971 			count += 1;
972 		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
973 			zc_error_prev_line("Too many keys in mandatory");
974 			return NULL;
975 		}
976 	}
977 
978 	r = alloc_rdata(region, (2 + count) * sizeof(uint16_t));
979 	r[1] = htons(SVCB_KEY_MANDATORY);
980 	r[2] = htons(sizeof(uint16_t) * count);
981 	key_dst = (void *)&r[3];
982 
983 	for(;;) {
984 		if (!(next_key = strchr(val, ','))) {
985 			*key_dst = htons(svcbparam_lookup_key(val, val_len));
986 			break;
987 		} else {
988 			*key_dst = htons(svcbparam_lookup_key(val, next_key - val));
989 		}
990 
991 		val_len -= next_key - val + 1;
992 		val = next_key + 1; /* skip the comma */
993 		key_dst += 1;
994 	}
995 
996 	/* In draft-ietf-dnsop-svcb-https-04 Section 7:
997 	 *
998 	 *     In wire format, the keys are represented by their numeric
999 	 *     values in network byte order, concatenated in ascending order.
1000 	 */
1001 	qsort((void *)&r[3], count, sizeof(uint16_t), network_uint16_cmp);
1002 
1003 	return r;
1004 }
1005 
1006 static uint16_t *
zparser_conv_svcbparam_ech_value(region_type * region,const char * b64)1007 zparser_conv_svcbparam_ech_value(region_type *region, const char *b64)
1008 {
1009 	uint8_t buffer[B64BUFSIZE];
1010 	uint16_t *r = NULL;
1011 	int wire_len;
1012 
1013 	if(strcmp(b64, "0") == 0) {
1014 		/* single 0 represents empty buffer */
1015 		return alloc_rdata(region, 0);
1016 	}
1017 	wire_len = b64_pton(b64, buffer, B64BUFSIZE);
1018 	if (wire_len == -1) {
1019 		zc_error_prev_line("invalid base64 data in ech");
1020 	} else {
1021 		r = alloc_rdata(region, 2 * sizeof(uint16_t) + wire_len);
1022 		r[1] = htons(SVCB_KEY_ECH);
1023 		r[2] = htons(wire_len);
1024 		memcpy(&r[3], buffer, wire_len);
1025 	}
1026 
1027 	return r;
1028 }
1029 
parse_alpn_next_unescaped_comma(const char * val)1030 static const char* parse_alpn_next_unescaped_comma(const char *val)
1031 {
1032 	while (*val) {
1033 		/* Only return when the comma is not escaped*/
1034 		if (*val == '\\'){
1035 			++val;
1036 			if (!*val)
1037 				break;
1038 		} else if (*val == ',')
1039 				return val;
1040 
1041 		val++;
1042 	}
1043 	return NULL;
1044 }
1045 
1046 static size_t
parse_alpn_copy_unescaped(uint8_t * dst,const char * src,size_t len)1047 parse_alpn_copy_unescaped(uint8_t *dst, const char *src, size_t len)
1048 {
1049 	uint8_t *orig_dst = dst;
1050 
1051 	while (len) {
1052 		if (*src == '\\') {
1053 			src++;
1054 			len--;
1055 			if (!len)
1056 				break;
1057 		}
1058 		*dst++ = *src++;
1059 		len--;
1060 	}
1061 	return (size_t)(dst - orig_dst);
1062 }
1063 
1064 static uint16_t *
zparser_conv_svcbparam_alpn_value(region_type * region,const char * val,size_t val_len)1065 zparser_conv_svcbparam_alpn_value(region_type *region,
1066 		const char *val, size_t val_len)
1067 {
1068 	uint8_t     unescaped_dst[65536];
1069 	uint8_t    *dst = unescaped_dst;
1070 	const char *next_str;
1071 	size_t      str_len;
1072 	size_t      dst_len;
1073 	uint16_t   *r = NULL;
1074 
1075 	if (val_len > sizeof(unescaped_dst)) {
1076 		zc_error_prev_line("invalid alpn");
1077 		return r;
1078 	}
1079 	while (val_len) {
1080 		size_t dst_len;
1081 
1082 		str_len = (next_str = parse_alpn_next_unescaped_comma(val))
1083 		        ? (size_t)(next_str - val) : val_len;
1084 
1085 		if (str_len > 255) {
1086 			zc_error_prev_line("alpn strings need to be"
1087 					   " smaller than 255 chars");
1088 			return r;
1089 		}
1090 		dst_len = parse_alpn_copy_unescaped(dst + 1, val, str_len);
1091 		*dst++ = dst_len;
1092 		 dst  += dst_len;
1093 
1094 		if (!next_str)
1095 			break;
1096 
1097 		/* skip the comma for the next iteration */
1098 		val_len -= next_str - val + 1;
1099 		val = next_str + 1;
1100 	}
1101 	dst_len = dst - unescaped_dst;
1102 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + dst_len);
1103 	r[1] = htons(SVCB_KEY_ALPN);
1104 	r[2] = htons(dst_len);
1105 	memcpy(&r[3], unescaped_dst, dst_len);
1106 	return r;
1107 }
1108 
1109 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)1110 zparser_conv_svcbparam_key_value(region_type *region,
1111     const char *key, size_t key_len, const char *val, size_t val_len)
1112 {
1113 	uint16_t svcparamkey = svcbparam_lookup_key(key, key_len);
1114 	uint16_t *r;
1115 
1116 	switch (svcparamkey) {
1117 	case SVCB_KEY_PORT:
1118 		return zparser_conv_svcbparam_port_value(region, val);
1119 	case SVCB_KEY_IPV4HINT:
1120 		return zparser_conv_svcbparam_ipv4hint_value(region, val);
1121 	case SVCB_KEY_IPV6HINT:
1122 		return zparser_conv_svcbparam_ipv6hint_value(region, val);
1123 	case SVCB_KEY_MANDATORY:
1124 		return zparser_conv_svcbparam_mandatory_value(region, val, val_len);
1125 	case SVCB_KEY_NO_DEFAULT_ALPN:
1126 		if(zone_is_slave(parser->current_zone->opts))
1127 			zc_warning_prev_line("no-default-alpn should not have a value");
1128 		else
1129 			zc_error_prev_line("no-default-alpn should not have a value");
1130 		break;
1131 	case SVCB_KEY_ECH:
1132 		return zparser_conv_svcbparam_ech_value(region, val);
1133 	case SVCB_KEY_ALPN:
1134 		return zparser_conv_svcbparam_alpn_value(region, val, val_len);
1135 	default:
1136 		break;
1137 	}
1138 	r = alloc_rdata(region, 2 * sizeof(uint16_t) + val_len);
1139 	r[1] = htons(svcparamkey);
1140 	r[2] = htons(val_len);
1141 	memcpy(r + 3, val, val_len);
1142 	return r;
1143 }
1144 
1145 uint16_t *
zparser_conv_svcbparam(region_type * region,const char * key,size_t key_len,const char * val,size_t val_len)1146 zparser_conv_svcbparam(region_type *region, const char *key, size_t key_len
1147                                           , const char *val, size_t val_len)
1148 {
1149 	const char *eq;
1150 	uint16_t *r;
1151 	uint16_t svcparamkey;
1152 
1153 	/* Form <key>="<value>" (or at least with quoted value) */
1154 	if (val && val_len) {
1155 		/* Does key end with '=' */
1156 		if (key_len && key[key_len - 1] == '=')
1157 			return zparser_conv_svcbparam_key_value(
1158 			    region, key, key_len - 1, val, val_len);
1159 
1160 		zc_error_prev_line( "SvcParam syntax error in param: %s\"%s\""
1161 		                  , key, val);
1162 	}
1163 	assert(val == NULL);
1164 	if ((eq = memchr(key, '=', key_len))) {
1165 		size_t new_key_len = eq - key;
1166 
1167 		if (key_len - new_key_len - 1 > 0)
1168 			return zparser_conv_svcbparam_key_value(region,
1169 			    key, new_key_len, eq+1, key_len - new_key_len - 1);
1170 		key_len = new_key_len;
1171 	}
1172 	/* Some SvcParamKeys require values */
1173 	svcparamkey = svcbparam_lookup_key(key, key_len);
1174 	switch (svcparamkey) {
1175 		case SVCB_KEY_MANDATORY:
1176 		case SVCB_KEY_ALPN:
1177 		case SVCB_KEY_PORT:
1178 		case SVCB_KEY_IPV4HINT:
1179 		case SVCB_KEY_IPV6HINT:
1180 			if(zone_is_slave(parser->current_zone->opts))
1181 				zc_warning_prev_line("value expected for SvcParam: %s", key);
1182 			else
1183 				zc_error_prev_line("value expected for SvcParam: %s", key);
1184 			break;
1185 		default:
1186 			break;
1187 	}
1188 	/* SvcParam is only a SvcParamKey */
1189 	r = alloc_rdata(region, 2 * sizeof(uint16_t));
1190 	r[1] = htons(svcparamkey);
1191 	r[2] = 0;
1192 	return r;
1193 }
1194 
1195 /* Parse an int terminated in the specified range. */
1196 static int
parse_int(const char * str,char ** end,int * result,const char * name,int min,int max)1197 parse_int(const char *str,
1198 	  char **end,
1199 	  int *result,
1200 	  const char *name,
1201 	  int min,
1202 	  int max)
1203 {
1204 	*result = (int) strtol(str, end, 10);
1205 	if (*result < min || *result > max) {
1206 		zc_error_prev_line("%s must be within the range [%d .. %d]",
1207 				   name,
1208 				   min,
1209 				   max);
1210 		return 0;
1211 	} else {
1212 		return 1;
1213 	}
1214 }
1215 
1216 /* RFC1876 conversion routines */
1217 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1218 				1000000,10000000,100000000,1000000000};
1219 
1220 /*
1221  * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
1222  * Sets the given pointer to the last used character.
1223  *
1224  */
1225 static uint8_t
precsize_aton(char * cp,char ** endptr)1226 precsize_aton (char *cp, char **endptr)
1227 {
1228 	unsigned int mval = 0, cmval = 0;
1229 	uint8_t retval = 0;
1230 	int exponent;
1231 	int mantissa;
1232 
1233 	while (isdigit((unsigned char)*cp))
1234 		mval = mval * 10 + hexdigit_to_int(*cp++);
1235 
1236 	if (*cp == '.') {	/* centimeters */
1237 		cp++;
1238 		if (isdigit((unsigned char)*cp)) {
1239 			cmval = hexdigit_to_int(*cp++) * 10;
1240 			if (isdigit((unsigned char)*cp)) {
1241 				cmval += hexdigit_to_int(*cp++);
1242 			}
1243 		}
1244 	}
1245 
1246 	if(mval >= poweroften[7]) {
1247 		assert(poweroften[7] != 0);
1248 		/* integer overflow possible for *100 */
1249 		mantissa = mval / poweroften[7];
1250 		exponent = 9; /* max */
1251 	}
1252 	else {
1253 		cmval = (mval * 100) + cmval;
1254 
1255 		for (exponent = 0; exponent < 9; exponent++)
1256 			if (cmval < poweroften[exponent+1])
1257 				break;
1258 
1259 		assert(poweroften[exponent] != 0);
1260 		mantissa = cmval / poweroften[exponent];
1261 	}
1262 	if (mantissa > 9)
1263 		mantissa = 9;
1264 
1265 	retval = (mantissa << 4) | exponent;
1266 
1267 	if (*cp == 'm') cp++;
1268 
1269 	*endptr = cp;
1270 
1271 	return (retval);
1272 }
1273 
1274 /*
1275  * Parses a specific part of rdata.
1276  *
1277  * Returns:
1278  *
1279  *	number of elements parsed
1280  *	zero on error
1281  *
1282  */
1283 uint16_t *
zparser_conv_loc(region_type * region,char * str)1284 zparser_conv_loc(region_type *region, char *str)
1285 {
1286 	uint16_t *r;
1287 	uint32_t *p;
1288 	int i;
1289 	int deg, min, secs;	/* Secs is stored times 1000.  */
1290 	uint32_t lat = 0, lon = 0, alt = 0;
1291 	/* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
1292 	uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
1293 	char *start;
1294 	double d;
1295 
1296 	for(;;) {
1297 		deg = min = secs = 0;
1298 
1299 		/* Degrees */
1300 		if (*str == '\0') {
1301 			zc_error_prev_line("unexpected end of LOC data");
1302 			return NULL;
1303 		}
1304 
1305 		if (!parse_int(str, &str, &deg, "degrees", 0, 180))
1306 			return NULL;
1307 		if (!isspace((unsigned char)*str)) {
1308 			zc_error_prev_line("space expected after degrees");
1309 			return NULL;
1310 		}
1311 		++str;
1312 
1313 		/* Minutes? */
1314 		if (isdigit((unsigned char)*str)) {
1315 			if (!parse_int(str, &str, &min, "minutes", 0, 60))
1316 				return NULL;
1317 			if (!isspace((unsigned char)*str)) {
1318 				zc_error_prev_line("space expected after minutes");
1319 				return NULL;
1320 			}
1321 			++str;
1322 		}
1323 
1324 		/* Seconds? */
1325 		if (isdigit((unsigned char)*str)) {
1326 			start = str;
1327 			if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
1328 				return NULL;
1329 			}
1330 
1331 			if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
1332 				return NULL;
1333 			}
1334 
1335 			if (!isspace((unsigned char)*str)) {
1336 				zc_error_prev_line("space expected after seconds");
1337 				return NULL;
1338 			}
1339 			/* No need for precision specifiers, it's a double */
1340 			if (sscanf(start, "%lf", &d) != 1) {
1341 				zc_error_prev_line("error parsing seconds");
1342 			}
1343 
1344 			if (d < 0.0 || d > 60.0) {
1345 				zc_error_prev_line("seconds not in range 0.0 .. 60.0");
1346 			}
1347 
1348 			secs = (int) (d * 1000.0 + 0.5);
1349 			++str;
1350 		}
1351 
1352 		switch(*str) {
1353 		case 'N':
1354 		case 'n':
1355 			lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1356 			break;
1357 		case 'E':
1358 		case 'e':
1359 			lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1360 			break;
1361 		case 'S':
1362 		case 's':
1363 			lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1364 			break;
1365 		case 'W':
1366 		case 'w':
1367 			lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1368 			break;
1369 		default:
1370 			zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
1371 			return NULL;
1372 		}
1373 		++str;
1374 
1375 		if (lat != 0 && lon != 0)
1376 			break;
1377 
1378 		if (!isspace((unsigned char)*str)) {
1379 			zc_error_prev_line("space expected after latitude/longitude");
1380 			return NULL;
1381 		}
1382 		++str;
1383 	}
1384 
1385 	/* Altitude */
1386 	if (*str == '\0') {
1387 		zc_error_prev_line("unexpected end of LOC data");
1388 		return NULL;
1389 	}
1390 
1391 	if (!isspace((unsigned char)*str)) {
1392 		zc_error_prev_line("space expected before altitude");
1393 		return NULL;
1394 	}
1395 	++str;
1396 
1397 	start = str;
1398 
1399 	/* Sign */
1400 	if (*str == '+' || *str == '-') {
1401 		++str;
1402 	}
1403 
1404 	/* Meters of altitude... */
1405 	if(strtol(str, &str, 10) == LONG_MAX) {
1406 		zc_error_prev_line("altitude too large, number overflow");
1407 		return NULL;
1408 	}
1409 	switch(*str) {
1410 	case ' ':
1411 	case '\0':
1412 	case 'm':
1413 		break;
1414 	case '.':
1415 		if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
1416 			return NULL;
1417 		}
1418 		if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
1419 			zc_error_prev_line("altitude fraction must be a number");
1420 			return NULL;
1421 		}
1422 		break;
1423 	default:
1424 		zc_error_prev_line("altitude must be expressed in meters");
1425 		return NULL;
1426 	}
1427 	if (!isspace((unsigned char)*str) && *str != '\0')
1428 		++str;
1429 
1430 	if (sscanf(start, "%lf", &d) != 1) {
1431 		zc_error_prev_line("error parsing altitude");
1432 	}
1433 
1434 	alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
1435 
1436 	if (!isspace((unsigned char)*str) && *str != '\0') {
1437 		zc_error_prev_line("unexpected character after altitude");
1438 		return NULL;
1439 	}
1440 
1441 	/* Now parse size, horizontal precision and vertical precision if any */
1442 	for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
1443 		vszhpvp[i] = precsize_aton(str + 1, &str);
1444 
1445 		if (!isspace((unsigned char)*str) && *str != '\0') {
1446 			zc_error_prev_line("invalid size or precision");
1447 			return NULL;
1448 		}
1449 	}
1450 
1451 	/* Allocate required space... */
1452 	r = alloc_rdata(region, 16);
1453 	p = (uint32_t *) (r + 1);
1454 
1455 	memmove(p, vszhpvp, 4);
1456 	write_uint32(p + 1, lat);
1457 	write_uint32(p + 2, lon);
1458 	write_uint32(p + 3, alt);
1459 
1460 	return r;
1461 }
1462 
1463 /*
1464  * Convert an APL RR RDATA element.
1465  */
1466 uint16_t *
zparser_conv_apl_rdata(region_type * region,char * str)1467 zparser_conv_apl_rdata(region_type *region, char *str)
1468 {
1469 	int negated = 0;
1470 	uint16_t address_family;
1471 	uint8_t prefix;
1472 	uint8_t maximum_prefix;
1473 	uint8_t length;
1474 	uint8_t address[IP6ADDRLEN];
1475 	char *colon = strchr(str, ':');
1476 	char *slash = strchr(str, '/');
1477 	int af;
1478 	int rc;
1479 	uint16_t rdlength;
1480 	uint16_t *r;
1481 	uint8_t *t;
1482 	char *end;
1483 	long p;
1484 
1485 	if (!colon) {
1486 		zc_error("address family separator is missing");
1487 		return NULL;
1488 	}
1489 	if (!slash) {
1490 		zc_error("prefix separator is missing");
1491 		return NULL;
1492 	}
1493 
1494 	*colon = '\0';
1495 	*slash = '\0';
1496 
1497 	if (*str == '!') {
1498 		negated = 1;
1499 		++str;
1500 	}
1501 
1502 	if (strcmp(str, "1") == 0) {
1503 		address_family = htons(1);
1504 		af = AF_INET;
1505 		length = sizeof(in_addr_t);
1506 		maximum_prefix = length * 8;
1507 	} else if (strcmp(str, "2") == 0) {
1508 		address_family = htons(2);
1509 		af = AF_INET6;
1510 		length = IP6ADDRLEN;
1511 		maximum_prefix = length * 8;
1512 	} else {
1513 		zc_error("invalid address family '%s'", str);
1514 		return NULL;
1515 	}
1516 
1517 	rc = inet_pton(af, colon + 1, address);
1518 	if (rc == 0) {
1519 		zc_error("invalid address '%s'", colon + 1);
1520 		return NULL;
1521 	} else if (rc == -1) {
1522 		zc_error("inet_pton failed: %s", strerror(errno));
1523 		return NULL;
1524 	}
1525 
1526 	/* Strip trailing zero octets.	*/
1527 	while (length > 0 && address[length - 1] == 0)
1528 		--length;
1529 
1530 
1531 	p = strtol(slash + 1, &end, 10);
1532 	if (p < 0 || p > maximum_prefix) {
1533 		zc_error("prefix not in the range 0 .. %d", maximum_prefix);
1534 		return NULL;
1535 	} else if (*end != '\0') {
1536 		zc_error("invalid prefix '%s'", slash + 1);
1537 		return NULL;
1538 	}
1539 	prefix = (uint8_t) p;
1540 
1541 	rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
1542 		    + length);
1543 	r = alloc_rdata(region, rdlength);
1544 	t = (uint8_t *) (r + 1);
1545 
1546 	memcpy(t, &address_family, sizeof(address_family));
1547 	t += sizeof(address_family);
1548 	memcpy(t, &prefix, sizeof(prefix));
1549 	t += sizeof(prefix);
1550 	memcpy(t, &length, sizeof(length));
1551 	if (negated) {
1552 		*t |= APL_NEGATION_MASK;
1553 	}
1554 	t += sizeof(length);
1555 	memcpy(t, address, length);
1556 
1557 	return r;
1558 }
1559 
1560 /*
1561  * Below some function that also convert but not to wireformat
1562  * but to "normal" (int,long,char) types
1563  */
1564 
1565 uint32_t
zparser_ttl2int(const char * ttlstr,int * error)1566 zparser_ttl2int(const char *ttlstr, int* error)
1567 {
1568 	/* convert a ttl value to a integer
1569 	 * return the ttl in a int
1570 	 * -1 on error
1571 	 */
1572 
1573 	uint32_t ttl;
1574 	const char *t;
1575 
1576 	ttl = strtottl(ttlstr, &t);
1577 	if (*t != 0) {
1578 		zc_error_prev_line("invalid TTL value: %s",ttlstr);
1579 		*error = 1;
1580 	}
1581 
1582 	return ttl;
1583 }
1584 
1585 
1586 void
zadd_rdata_wireformat(uint16_t * data)1587 zadd_rdata_wireformat(uint16_t *data)
1588 {
1589 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1590 		zc_error_prev_line("too many rdata elements");
1591 	} else {
1592 		parser->current_rr.rdatas[parser->current_rr.rdata_count].data
1593 			= data;
1594 		++parser->current_rr.rdata_count;
1595 	}
1596 }
1597 
1598 /**
1599  * Used for TXT RR's to grow with undefined number of strings.
1600  */
1601 void
zadd_rdata_txt_wireformat(uint16_t * data,int first)1602 zadd_rdata_txt_wireformat(uint16_t *data, int first)
1603 {
1604 	rdata_atom_type *rd;
1605 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1606 		zc_error_prev_line("too many rdata txt elements");
1607 		return;
1608 	}
1609 
1610 	/* First STR in str_seq, allocate 65K in first unused rdata
1611 	 * else find last used rdata */
1612 	if (first) {
1613 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1614 		if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1615 			sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
1616 			zc_error_prev_line("Could not allocate memory for TXT RR");
1617 			return;
1618 		}
1619 		parser->current_rr.rdata_count++;
1620 		rd->data[0] = 0;
1621 	}
1622 	else
1623 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1624 
1625 	if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1626 		zc_error_prev_line("too large rdata element");
1627 		return;
1628 	}
1629 
1630 	memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1631 	rd->data[0] += data[0];
1632 }
1633 
1634 /**
1635  * Clean up after last call of zadd_rdata_txt_wireformat
1636  */
1637 void
zadd_rdata_txt_clean_wireformat()1638 zadd_rdata_txt_clean_wireformat()
1639 {
1640 	uint16_t *tmp_data;
1641 	rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1642 	if(!rd || !rd->data)
1643 		return; /* previous syntax failure */
1644 	if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1645 		((size_t)rd->data[0]) + ((size_t)2))) != NULL) {
1646 		memcpy(tmp_data, rd->data, rd->data[0] + 2);
1647 		/* rd->data of u16+65535 freed when rr_region is freed */
1648 		rd->data = tmp_data;
1649 	}
1650 	else {
1651 		/* We could not get memory in non-volatile region */
1652 		zc_error_prev_line("could not allocate memory for rdata");
1653 		return;
1654 	}
1655 }
1656 
1657 static int
svcparam_key_cmp(const void * a,const void * b)1658 svcparam_key_cmp(const void *a, const void *b)
1659 {
1660 	return ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)a)))
1661 	     - ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)b)));
1662 }
1663 
1664 void
zadd_rdata_svcb_check_wireformat()1665 zadd_rdata_svcb_check_wireformat()
1666 {
1667 	size_t i;
1668 	uint8_t paramkeys[65536];
1669 	int prev_key = - 1;
1670 	int key = 0;
1671 	size_t size;
1672 	uint16_t *mandatory_values;
1673 
1674 	if (parser->current_rr.rdata_count <= 2) {
1675 		if (!parser->error_occurred)
1676 			zc_error_prev_line("invalid SVCB or HTTPS rdata");
1677 		return;
1678 	} else for (i = 2; i < parser->current_rr.rdata_count; i++) {
1679 		if (parser->current_rr.rdatas[i].data == NULL
1680 		||  rdata_atom_data(parser->current_rr.rdatas[i]) == NULL
1681 		||  rdata_atom_size(parser->current_rr.rdatas[i]) < 4) {
1682 			if (!parser->error_occurred)
1683 				zc_error_prev_line("invalid SVCB or HTTPS rdata");
1684 			return;
1685 		}
1686 	}
1687 	/* After this point, all rdatas do have data larger than 4 bytes.
1688 	 * So we may assume a uint16_t SVCB key followed by uint16_t length
1689 	 * in each rdata in the remainder of this function.
1690 	 */
1691 	memset(paramkeys, 0, sizeof(paramkeys));
1692 	/*
1693 	 * In draft-ietf-dnsop-svcb-https-04 Section 7:
1694 	 * In wire format, the keys are represented by their numeric values in
1695 	 * network byte order, concatenated in ascending order.
1696 	 *
1697 	 * svcparam_key_cmp assumes the rdatas to have a SVCB key, which is
1698 	 * safe because we checked.
1699 	 *
1700 	 */
1701 	qsort( (void *)&parser->current_rr.rdatas[2]
1702 	     , parser->current_rr.rdata_count - 2
1703 	     , sizeof(rdata_atom_type)
1704 	     , svcparam_key_cmp
1705 	     );
1706 
1707 	for (i = 2; i < parser->current_rr.rdata_count; i++) {
1708 		assert(parser->current_rr.rdatas[i].data);
1709 		assert(rdata_atom_data(parser->current_rr.rdatas[i]));
1710 		assert(rdata_atom_size(parser->current_rr.rdatas[i]) >= sizeof(uint16_t));
1711 
1712 		key = read_uint16(rdata_atom_data(parser->current_rr.rdatas[i]));
1713 
1714 		/* In draft-ietf-dnsop-svcb-https-04 Section 7:
1715 		 *
1716 		 *     Keys (...) MUST NOT appear more than once.
1717 		 *
1718 		 * If they key has already been seen, we have a duplicate
1719 		 */
1720 		if (!paramkeys[key])
1721 			/* keep track of keys that are present */
1722 			paramkeys[key] = 1;
1723 
1724 		else if (key < SVCPARAMKEY_COUNT) {
1725 			if(zone_is_slave(parser->current_zone->opts))
1726 				zc_warning_prev_line(
1727 					"Duplicate key found: %s",
1728 					svcparamkey_strs[key]);
1729 			else {
1730 				zc_error_prev_line(
1731 					"Duplicate key found: %s",
1732 					svcparamkey_strs[key]);
1733 			}
1734 		} else if(zone_is_slave(parser->current_zone->opts))
1735 			zc_warning_prev_line(
1736 					"Duplicate key found: key%d", key);
1737 		else
1738 			zc_error_prev_line(
1739 					"Duplicate key found: key%d", key);
1740 	}
1741 	/* Checks when a mandatory key is present */
1742 	if (!paramkeys[SVCB_KEY_MANDATORY])
1743 		return;
1744 
1745 	size = rdata_atom_size(parser->current_rr.rdatas[2]);
1746 	assert(size >= 4);
1747 	mandatory_values = (void*)rdata_atom_data(parser->current_rr.rdatas[2]);
1748 	mandatory_values += 2; /* skip the key type and length */
1749 
1750 	if (size % 2)
1751 		zc_error_prev_line("mandatory rdata must be a multiple of shorts");
1752 
1753 	else for (i = 0; i < (size - 4)/2; i++) {
1754 		key = ntohs(mandatory_values[i]);
1755 
1756 		if (paramkeys[key])
1757 			; /* pass */
1758 
1759 		else if (key < SVCPARAMKEY_COUNT) {
1760 			if(zone_is_slave(parser->current_zone->opts))
1761 				zc_warning_prev_line("mandatory SvcParamKey: %s is missing "
1762 						     "the record", svcparamkey_strs[key]);
1763 			else
1764 				zc_error_prev_line("mandatory SvcParamKey: %s is missing "
1765 						   "the record", svcparamkey_strs[key]);
1766 		} else {
1767 			if(zone_is_slave(parser->current_zone->opts))
1768 				zc_warning_prev_line("mandatory SvcParamKey: key%d is missing "
1769 						     "the record", key);
1770 			else
1771 				zc_error_prev_line("mandatory SvcParamKey: key%d is missing "
1772 						   "the record", key);
1773 		}
1774 
1775 		/* In draft-ietf-dnsop-svcb-https-04 Section 8
1776 		 * automatically mandatory MUST NOT appear in its own value-list
1777 		 */
1778 		if (key == SVCB_KEY_MANDATORY) {
1779 			if(zone_is_slave(parser->current_zone->opts))
1780 				zc_warning_prev_line("mandatory MUST not be included"
1781 						     " as mandatory parameter");
1782 			else
1783 				zc_error_prev_line("mandatory MUST not be included"
1784 						   " as mandatory parameter");
1785 		}
1786 		if (key == prev_key) {
1787 			if(zone_is_slave(parser->current_zone->opts))
1788 				zc_warning_prev_line("Keys inSvcParam mandatory "
1789 				                   "MUST NOT appear more than once.");
1790 			else
1791 				zc_error_prev_line("Keys in SvcParam mandatory "
1792 				                   "MUST NOT appear more than once.");
1793 		}
1794 		prev_key = key;
1795 	}
1796 }
1797 
1798 void
zadd_rdata_domain(domain_type * domain)1799 zadd_rdata_domain(domain_type *domain)
1800 {
1801 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1802 		zc_error_prev_line("too many rdata elements");
1803 	} else {
1804 		parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1805 			= domain;
1806 		domain->usage ++; /* new reference to domain */
1807 		++parser->current_rr.rdata_count;
1808 	}
1809 }
1810 
1811 void
parse_unknown_rdata(uint16_t type,uint16_t * wireformat)1812 parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1813 {
1814 	buffer_type packet;
1815 	uint16_t size;
1816 	ssize_t rdata_count;
1817 	ssize_t i;
1818 	rdata_atom_type *rdatas;
1819 
1820 	if (wireformat) {
1821 		size = *wireformat;
1822 	} else {
1823 		return;
1824 	}
1825 
1826 	buffer_create_from(&packet, wireformat + 1, *wireformat);
1827 	rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1828 						      parser->db->domains,
1829 						      type,
1830 						      size,
1831 						      &packet,
1832 						      &rdatas);
1833 	if (rdata_count == -1) {
1834 		zc_error_prev_line("bad unknown RDATA");
1835 		return;
1836 	}
1837 
1838 	for (i = 0; i < rdata_count; ++i) {
1839 		if (rdata_atom_is_domain(type, i)) {
1840 			zadd_rdata_domain(rdatas[i].domain);
1841 		} else {
1842 			zadd_rdata_wireformat(rdatas[i].data);
1843 		}
1844 	}
1845 	region_recycle(parser->region, rdatas,
1846 		rdata_count*sizeof(rdata_atom_type));
1847 }
1848 
1849 
1850 /*
1851  * Compares two rdata arrays.
1852  *
1853  * Returns:
1854  *
1855  *	zero if they are equal
1856  *	non-zero if not
1857  *
1858  */
1859 static int
zrdatacmp(uint16_t type,rr_type * a,rr_type * b)1860 zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1861 {
1862 	int i = 0;
1863 
1864 	assert(a);
1865 	assert(b);
1866 
1867 	/* One is shorter than another */
1868 	if (a->rdata_count != b->rdata_count)
1869 		return 1;
1870 
1871 	/* Compare element by element */
1872 	for (i = 0; i < a->rdata_count; ++i) {
1873 		if (rdata_atom_is_domain(type, i)) {
1874 			if (rdata_atom_domain(a->rdatas[i])
1875 			    != rdata_atom_domain(b->rdatas[i]))
1876 			{
1877 				return 1;
1878 			}
1879 		} else if(rdata_atom_is_literal_domain(type, i)) {
1880 			if (rdata_atom_size(a->rdatas[i])
1881 			    != rdata_atom_size(b->rdatas[i]))
1882 				return 1;
1883 			if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1884 				   rdata_atom_data(b->rdatas[i]),
1885 				   rdata_atom_size(a->rdatas[i])))
1886 				return 1;
1887 		} else {
1888 			if (rdata_atom_size(a->rdatas[i])
1889 			    != rdata_atom_size(b->rdatas[i]))
1890 			{
1891 				return 1;
1892 			}
1893 			if (memcmp(rdata_atom_data(a->rdatas[i]),
1894 				   rdata_atom_data(b->rdatas[i]),
1895 				   rdata_atom_size(a->rdatas[i])) != 0)
1896 			{
1897 				return 1;
1898 			}
1899 		}
1900 	}
1901 
1902 	/* Otherwise they are equal */
1903 	return 0;
1904 }
1905 
1906 /*
1907  *
1908  * Opens a zone file.
1909  *
1910  * Returns:
1911  *
1912  *	- pointer to the parser structure
1913  *	- NULL on error and errno set
1914  *
1915  */
1916 static int
zone_open(const char * filename,uint32_t ttl,uint16_t klass,const dname_type * origin)1917 zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1918 	  const dname_type *origin)
1919 {
1920 	/* Open the zone file... */
1921 	if (strcmp(filename, "-") == 0) {
1922 		yyin = stdin;
1923 		filename = "<stdin>";
1924 		warn_if_directory("zonefile from stdin", yyin, filename);
1925 	} else {
1926 		if (!(yyin = fopen(filename, "r"))) {
1927 			return 0;
1928 		}
1929 		warn_if_directory("zonefile", yyin, filename);
1930 	}
1931 
1932 	zparser_init(filename, ttl, klass, origin);
1933 
1934 	return 1;
1935 }
1936 
1937 
1938 void
set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],uint16_t index)1939 set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
1940 	    uint16_t index)
1941 {
1942 	/*
1943 	 * The bits are counted from left to right, so bit #0 is the
1944 	 * left most bit.
1945 	 */
1946 	uint8_t window = index / 256;
1947 	uint8_t bit = index % 256;
1948 
1949 	bits[window][bit / 8] |= (1 << (7 - bit % 8));
1950 }
1951 
1952 
1953 static int
has_soa(domain_type * domain)1954 has_soa(domain_type* domain)
1955 {
1956 	rrset_type* p = NULL;
1957 	if(!domain) return 0;
1958 	for(p = domain->rrsets; p; p = p->next)
1959 		if(rrset_rrtype(p) == TYPE_SOA)
1960 			return 1;
1961 	return 0;
1962 }
1963 
1964 int
process_rr(void)1965 process_rr(void)
1966 {
1967 	zone_type *zone = parser->current_zone;
1968 	rr_type *rr = &parser->current_rr;
1969 	rrset_type *rrset;
1970 	size_t max_rdlength;
1971 	int i;
1972 	rrtype_descriptor_type *descriptor
1973 		= rrtype_descriptor_by_type(rr->type);
1974 
1975 	/* We only support IN class */
1976 	if (rr->klass != CLASS_IN) {
1977 		if(zone_is_slave(zone->opts))
1978 			zc_warning_prev_line("only class IN is supported");
1979 		else
1980 			zc_error_prev_line("only class IN is supported");
1981 		return 0;
1982 	}
1983 
1984 	/* Make sure the maximum RDLENGTH does not exceed 65535 bytes.	*/
1985 	max_rdlength = rdata_maximum_wireformat_size(
1986 		descriptor, rr->rdata_count, rr->rdatas);
1987 
1988 	if (max_rdlength > MAX_RDLENGTH) {
1989 		zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
1990 		return 0;
1991 	}
1992 
1993 	/* We cannot print invalid owner names,
1994 	 * so error on that before it is used in printing other errors.
1995 	 */
1996 	if (rr->owner == error_domain
1997 	||  domain_dname(rr->owner) == error_dname) {
1998 		zc_error_prev_line("invalid owner name");
1999 		return 0;
2000 	}
2001 
2002 	/* we have the zone already */
2003 	assert(zone);
2004 	if (rr->type == TYPE_SOA) {
2005 		if (rr->owner != zone->apex) {
2006 			char s[MAXDOMAINLEN*5];
2007 			snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2008 			zc_error_prev_line(
2009 				"SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s);
2010 			return 0;
2011 		}
2012 		if(has_soa(rr->owner)) {
2013 			if(zone_is_slave(zone->opts))
2014 				zc_warning_prev_line("this SOA record was already encountered");
2015 			else
2016 				zc_error_prev_line("this SOA record was already encountered");
2017 			return 0;
2018 		}
2019 		rr->owner->is_apex = 1;
2020 	}
2021 
2022 	if (!domain_is_subdomain(rr->owner, zone->apex))
2023 	{
2024 		char s[MAXDOMAINLEN*5];
2025 		snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2026 		if(zone_is_slave(zone->opts))
2027 			zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2028 		else
2029 			zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2030 		return 0;
2031 	}
2032 
2033 	/* Do we have this type of rrset already? */
2034 	rrset = domain_find_rrset(rr->owner, zone, rr->type);
2035 	if (!rrset) {
2036 		rrset = (rrset_type *) region_alloc(parser->region,
2037 						    sizeof(rrset_type));
2038 		rrset->zone = zone;
2039 		rrset->rr_count = 1;
2040 		rrset->rrs = (rr_type *) region_alloc(parser->region,
2041 						      sizeof(rr_type));
2042 		rrset->rrs[0] = *rr;
2043 
2044 		/* Add it */
2045 		domain_add_rrset(rr->owner, rrset);
2046 	} else {
2047 		rr_type* o;
2048 		if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
2049 			zc_warning_prev_line(
2050 				"%s TTL %u does not match the TTL %u of the %s RRset",
2051 				domain_to_string(rr->owner), (unsigned)rr->ttl,
2052 				(unsigned)rrset->rrs[0].ttl,
2053 				rrtype_to_string(rr->type));
2054 		}
2055 
2056 		/* Search for possible duplicates... */
2057 		for (i = 0; i < rrset->rr_count; i++) {
2058 			if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
2059 				break;
2060 			}
2061 		}
2062 
2063 		/* Discard the duplicates... */
2064 		if (i < rrset->rr_count) {
2065 			/* add rdatas to recycle bin. */
2066 			size_t i;
2067 			for (i = 0; i < rr->rdata_count; i++) {
2068 				if(!rdata_atom_is_domain(rr->type, i))
2069 					region_recycle(parser->region, rr->rdatas[i].data,
2070 						rdata_atom_size(rr->rdatas[i])
2071 						+ sizeof(uint16_t));
2072 			}
2073 			region_recycle(parser->region, rr->rdatas,
2074 				sizeof(rdata_atom_type)*rr->rdata_count);
2075 			return 0;
2076 		}
2077 		if(rrset->rr_count == 65535) {
2078 			zc_error_prev_line("too many RRs for domain RRset");
2079 			return 0;
2080 		}
2081 
2082 		/* Add it... */
2083 		o = rrset->rrs;
2084 		rrset->rrs = (rr_type *) region_alloc_array(parser->region,
2085 			(rrset->rr_count + 1), sizeof(rr_type));
2086 		memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
2087 		region_recycle(parser->region, o,
2088 			(rrset->rr_count) * sizeof(rr_type));
2089 		rrset->rrs[rrset->rr_count] = *rr;
2090 		++rrset->rr_count;
2091 	}
2092 
2093 	if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
2094 		if(zone_is_slave(zone->opts))
2095 			zc_warning_prev_line("multiple DNAMEs at the same name");
2096 		else
2097 			zc_error_prev_line("multiple DNAMEs at the same name");
2098 	}
2099 	if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
2100 		if(zone_is_slave(zone->opts))
2101 			zc_warning_prev_line("multiple CNAMEs at the same name");
2102 		else
2103 			zc_error_prev_line("multiple CNAMEs at the same name");
2104 	}
2105 	if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
2106 	 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
2107 		if(zone_is_slave(zone->opts))
2108 			zc_warning_prev_line("DNAME and CNAME at the same name");
2109 		else
2110 			zc_error_prev_line("DNAME and CNAME at the same name");
2111 	}
2112 	if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
2113 		domain_find_non_cname_rrset(rr->owner, zone)) {
2114 		if(zone_is_slave(zone->opts))
2115 			zc_warning_prev_line("CNAME and other data at the same name");
2116 		else
2117 			zc_error_prev_line("CNAME and other data at the same name");
2118 	}
2119 
2120 	/* Check we have SOA */
2121 	if(rr->owner == zone->apex)
2122 		apex_rrset_checks(parser->db, rrset, rr->owner);
2123 
2124 	if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
2125 		struct stat buf;
2126 		startzonec = time(NULL);
2127 		buf.st_size = 0;
2128 		fstat(fileno(yyin), &buf);
2129 		if(buf.st_size == 0) buf.st_size = 1;
2130 		VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
2131 			parser->current_zone->opts->name,
2132 			(int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
2133 	}
2134 	++totalrrs;
2135 	return 1;
2136 }
2137 
2138 /*
2139  * Find rrset type for any zone
2140  */
2141 static rrset_type*
domain_find_rrset_any(domain_type * domain,uint16_t type)2142 domain_find_rrset_any(domain_type *domain, uint16_t type)
2143 {
2144 	rrset_type *result = domain->rrsets;
2145 	while (result) {
2146 		if (rrset_rrtype(result) == type) {
2147 			return result;
2148 		}
2149 		result = result->next;
2150 	}
2151 	return NULL;
2152 }
2153 
2154 /*
2155  * Check for DNAME type. Nothing is allowed below it
2156  */
2157 static void
check_dname(zone_type * zone)2158 check_dname(zone_type* zone)
2159 {
2160 	domain_type* domain;
2161 	for(domain = zone->apex; domain && domain_is_subdomain(domain,
2162 		zone->apex); domain=domain_next(domain))
2163 	{
2164 		if(domain->is_existing) {
2165 			/* there may not be DNAMEs above it */
2166 			domain_type* parent = domain->parent;
2167 #ifdef NSEC3
2168 			if(domain_has_only_NSEC3(domain, NULL))
2169 				continue;
2170 #endif
2171 			while(parent) {
2172 				if(domain_find_rrset_any(parent, TYPE_DNAME)) {
2173 					zc_error("While checking node %s,",
2174 						domain_to_string(domain));
2175 					zc_error("DNAME at %s has data below it. "
2176 						"This is not allowed (rfc 2672).",
2177 						domain_to_string(parent));
2178 					return;
2179 				}
2180 				parent = parent->parent;
2181 			}
2182 		}
2183 	}
2184 }
2185 
2186 /*
2187  * Reads the specified zone into the memory
2188  * nsd_options can be NULL if no config file is passed.
2189  */
2190 unsigned int
zonec_read(const char * name,const char * zonefile,zone_type * zone)2191 zonec_read(const char* name, const char* zonefile, zone_type* zone)
2192 {
2193 	const dname_type *dname;
2194 
2195 	totalrrs = 0;
2196 	startzonec = time(NULL);
2197 	parser->errors = 0;
2198 
2199 	dname = dname_parse(parser->rr_region, name);
2200 	if (!dname) {
2201 		zc_error("incorrect zone name '%s'", name);
2202 		return 1;
2203 	}
2204 
2205 #ifndef ROOT_SERVER
2206 	/* Is it a root zone? Are we a root server then? Idiot proof. */
2207 	if (dname->label_count == 1) {
2208 		zc_error("not configured as a root server");
2209 		return 1;
2210 	}
2211 #endif
2212 
2213 	/* Open the zone file */
2214 	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
2215 		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
2216 		return 1;
2217 	}
2218 	parser->current_zone = zone;
2219 
2220 	/* Parse and process all RRs.  */
2221 	yyparse();
2222 
2223 	/* remove origin if it was unused */
2224 	if(parser->origin != error_domain)
2225 		domain_table_deldomain(parser->db, parser->origin);
2226 	/* rr_region has been emptied by now */
2227 	dname = dname_parse(parser->rr_region, name);
2228 
2229 	/* check if zone file contained a correct SOA record */
2230 	if (!parser->current_zone) {
2231 		zc_error("zone configured as '%s' has no content.", name);
2232 	} else if(!parser->current_zone->soa_rrset ||
2233 		parser->current_zone->soa_rrset->rr_count == 0) {
2234 		zc_error("zone configured as '%s' has no SOA record.", name);
2235 	} else if(dname_compare(domain_dname(
2236 		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
2237 		zc_error("zone configured as '%s', but SOA has owner '%s'.",
2238 			name, domain_to_string(
2239 			parser->current_zone->soa_rrset->rrs[0].owner));
2240 	}
2241 	region_free_all(parser->rr_region);
2242 
2243 	parser_flush();
2244 	fclose(yyin);
2245 	if(!zone_is_slave(zone->opts))
2246 		check_dname(zone);
2247 
2248 	parser->filename = NULL;
2249 	return parser->errors;
2250 }
2251 
2252 
2253 /*
2254  * setup parse
2255  */
2256 void
zonec_setup_parser(namedb_type * db)2257 zonec_setup_parser(namedb_type* db)
2258 {
2259 	region_type* rr_region = region_create(xalloc, free);
2260 	parser = zparser_create(db->region, rr_region, db);
2261 	assert(parser);
2262 	/* Unique pointers used to mark errors.	 */
2263 	error_dname = (dname_type *) region_alloc(db->region, 1);
2264 	error_domain = (domain_type *) region_alloc(db->region, 1);
2265 	/* Open the network database */
2266 	setprotoent(1);
2267 	setservent(1);
2268 }
2269 
2270 /** desetup parse */
2271 void
zonec_desetup_parser(void)2272 zonec_desetup_parser(void)
2273 {
2274 	if(parser) {
2275 		endservent();
2276 		endprotoent();
2277 		region_destroy(parser->rr_region);
2278 		/* removed when parser->region(=db->region) is destroyed:
2279 		 * region_recycle(parser->region, (void*)error_dname, 1);
2280 		 * region_recycle(parser->region, (void*)error_domain, 1); */
2281 		/* clear memory for exit, but this is not portable to
2282 		 * other versions of lex. yylex_destroy(); */
2283 #ifdef MEMCLEAN /* OS collects memory pages */
2284 		yylex_destroy();
2285 #endif
2286 	}
2287 }
2288 
2289 static domain_table_type* orig_domains = NULL;
2290 static region_type* orig_region = NULL;
2291 static region_type* orig_dbregion = NULL;
2292 
2293 /** setup for string parse */
2294 void
zonec_setup_string_parser(region_type * region,domain_table_type * domains)2295 zonec_setup_string_parser(region_type* region, domain_table_type* domains)
2296 {
2297 	assert(parser); /* global parser must be setup */
2298 	orig_domains = parser->db->domains;
2299 	orig_region = parser->region;
2300 	orig_dbregion = parser->db->region;
2301 	parser->region = region;
2302 	parser->db->region = region;
2303 	parser->db->domains = domains;
2304 	zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
2305 }
2306 
2307 /** desetup string parse */
2308 void
zonec_desetup_string_parser(void)2309 zonec_desetup_string_parser(void)
2310 {
2311 	parser->region = orig_region;
2312 	parser->db->domains = orig_domains;
2313 	parser->db->region = orig_dbregion;
2314 }
2315 
2316 /** parse a string into temporary storage */
2317 int
zonec_parse_string(region_type * region,domain_table_type * domains,zone_type * zone,char * str,domain_type ** parsed,int * num_rrs)2318 zonec_parse_string(region_type* region, domain_table_type* domains,
2319 	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
2320 {
2321 	int errors;
2322 	zonec_setup_string_parser(region, domains);
2323 	parser->current_zone = zone;
2324 	parser->errors = 0;
2325 	totalrrs = 0;
2326 	startzonec = time(NULL)+100000; /* disable */
2327 	parser_push_stringbuf(str);
2328 	yyparse();
2329 	parser_pop_stringbuf();
2330 	errors = parser->errors;
2331 	*num_rrs = totalrrs;
2332 	if(*num_rrs == 0)
2333 		*parsed = NULL;
2334 	else	*parsed = parser->prev_dname;
2335 	/* remove origin if it was not used during the parse */
2336 	if(parser->origin != error_domain)
2337 		domain_table_deldomain(parser->db, parser->origin);
2338 	region_free_all(parser->rr_region);
2339 	zonec_desetup_string_parser();
2340 	parser_flush();
2341 	return errors;
2342 }
2343 
2344 /** check SSHFP type for failures and emit warnings */
check_sshfp(void)2345 void check_sshfp(void)
2346 {
2347 	uint8_t hash;
2348 	uint16_t size;
2349 	if(parser->current_rr.rdata_count < 3)
2350 		return; /* cannot check it, too few rdata elements */
2351 	if(!parser->current_rr.rdatas[0].data ||
2352 		!parser->current_rr.rdatas[1].data ||
2353 		!parser->current_rr.rdatas[2].data ||
2354 		!parser->current_rr.owner)
2355 		return; /* cannot check, NULLs (due to earlier errors) */
2356 	if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1)
2357 		return; /* wrong size of the hash type rdata element */
2358 	hash = rdata_atom_data(parser->current_rr.rdatas[1])[0];
2359 	size = rdata_atom_size(parser->current_rr.rdatas[2]);
2360 	if(hash == 1 && size != 20) {
2361 		zc_warning_prev_line("SSHFP %s of type SHA1 has hash of "
2362 			"wrong length, %d bytes, should be 20",
2363 			domain_to_string(parser->current_rr.owner),
2364 			(int)size);
2365 	} else if(hash == 2 && size != 32) {
2366 		zc_warning_prev_line("SSHFP %s of type SHA256 has hash of "
2367 			"wrong length, %d bytes, should be 32",
2368 			domain_to_string(parser->current_rr.owner),
2369 			(int)size);
2370 	}
2371 }
2372 
2373 void
apex_rrset_checks(namedb_type * db,rrset_type * rrset,domain_type * domain)2374 apex_rrset_checks(namedb_type* db, rrset_type* rrset, domain_type* domain)
2375 {
2376 	uint32_t soa_minimum;
2377 	unsigned i;
2378 	zone_type* zone = rrset->zone;
2379 	assert(domain == zone->apex);
2380 	(void)domain;
2381 	if (rrset_rrtype(rrset) == TYPE_SOA) {
2382 		zone->soa_rrset = rrset;
2383 
2384 		/* BUG #103 add another soa with a tweaked ttl */
2385 		if(zone->soa_nx_rrset == 0) {
2386 			zone->soa_nx_rrset = region_alloc(db->region,
2387 				sizeof(rrset_type));
2388 			zone->soa_nx_rrset->rr_count = 1;
2389 			zone->soa_nx_rrset->next = 0;
2390 			zone->soa_nx_rrset->zone = zone;
2391 			zone->soa_nx_rrset->rrs = region_alloc(db->region,
2392 				sizeof(rr_type));
2393 		}
2394 		memcpy(zone->soa_nx_rrset->rrs, rrset->rrs, sizeof(rr_type));
2395 
2396 		/* check the ttl and MINIMUM value and set accordingly */
2397 		memcpy(&soa_minimum, rdata_atom_data(rrset->rrs->rdatas[6]),
2398 				rdata_atom_size(rrset->rrs->rdatas[6]));
2399 		if (rrset->rrs->ttl > ntohl(soa_minimum)) {
2400 			zone->soa_nx_rrset->rrs[0].ttl = ntohl(soa_minimum);
2401 		}
2402 	} else if (rrset_rrtype(rrset) == TYPE_NS) {
2403 		zone->ns_rrset = rrset;
2404 	} else if (rrset_rrtype(rrset) == TYPE_RRSIG) {
2405 		for (i = 0; i < rrset->rr_count; ++i) {
2406 			if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY){
2407 				zone->is_secure = 1;
2408 				break;
2409 			}
2410 		}
2411 	}
2412 }
2413