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, °, "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