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