zonec.c revision 1.1.1.6
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("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 821static uint16_t * 822zparser_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 843static uint16_t * 844zparser_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 899static uint16_t * 900zparser_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 954static int 955network_uint16_cmp(const void *a, const void *b) 956{ 957 return ((int)read_uint16(a)) - ((int)read_uint16(b)); 958} 959 960static uint16_t * 961zparser_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 1006static uint16_t * 1007zparser_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 1030static 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 1046static size_t 1047parse_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 1064static uint16_t * 1065zparser_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 1109static uint16_t * 1110zparser_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 1145uint16_t * 1146zparser_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. */ 1196static int 1197parse_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 */ 1217static 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 */ 1225static uint8_t 1226precsize_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 */ 1283uint16_t * 1284zparser_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 */ 1466uint16_t * 1467zparser_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 1565uint32_t 1566zparser_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 1586void 1587zadd_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 */ 1601void 1602zadd_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 */ 1637void 1638zadd_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 1657static int 1658svcparam_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 1664void 1665zadd_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 1798void 1799zadd_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 1811void 1812parse_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 */ 1859static int 1860zrdatacmp(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 */ 1916static int 1917zone_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 1938void 1939set_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 1953static int 1954has_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 1964int 1965process_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 */ 2141static rrset_type* 2142domain_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 */ 2157static void 2158check_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 */ 2190unsigned int 2191zonec_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 */ 2256void 2257zonec_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 */ 2271void 2272zonec_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 2289static domain_table_type* orig_domains = NULL; 2290static region_type* orig_region = NULL; 2291static region_type* orig_dbregion = NULL; 2292 2293/** setup for string parse */ 2294void 2295zonec_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 */ 2308void 2309zonec_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 */ 2317int 2318zonec_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 */ 2345void 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 2373void 2374apex_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