zonec.c revision 1.1.1.4
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 50const dname_type *error_dname; 51domain_type *error_domain; 52 53static time_t startzonec = 0; 54static long int totalrrs = 0; 55 56extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; 57extern uint16_t nsec_highest_rcode; 58 59 60/* 61 * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first 62 * element. Return a pointer to the allocation. 63 */ 64static uint16_t * 65alloc_rdata(region_type *region, size_t size) 66{ 67 uint16_t *result = region_alloc(region, sizeof(uint16_t) + size); 68 *result = size; 69 return result; 70} 71 72uint16_t * 73alloc_rdata_init(region_type *region, const void *data, size_t size) 74{ 75 uint16_t *result = region_alloc(region, sizeof(uint16_t) + size); 76 *result = size; 77 memcpy(result + 1, data, size); 78 return result; 79} 80 81/* 82 * These are parser function for generic zone file stuff. 83 */ 84uint16_t * 85zparser_conv_hex(region_type *region, const char *hex, size_t len) 86{ 87 /* convert a hex value to wireformat */ 88 uint16_t *r = NULL; 89 uint8_t *t; 90 int i; 91 92 if(len == 1 && hex[0] == '0') { 93 /* single 0 represents empty buffer */ 94 return alloc_rdata(region, 0); 95 } 96 if (len % 2 != 0) { 97 zc_error_prev_line("number of hex digits must be a multiple of 2"); 98 } else if (len > MAX_RDLENGTH * 2) { 99 zc_error_prev_line("hex data exceeds maximum rdata length (%d)", 100 MAX_RDLENGTH); 101 } else { 102 /* the length part */ 103 r = alloc_rdata(region, len/2); 104 t = (uint8_t *)(r + 1); 105 106 /* Now process octet by octet... */ 107 while (*hex) { 108 *t = 0; 109 for (i = 16; i >= 1; i -= 15) { 110 if (isxdigit((unsigned char)*hex)) { 111 *t += hexdigit_to_int(*hex) * i; 112 } else { 113 zc_error_prev_line( 114 "illegal hex character '%c'", 115 (int) *hex); 116 return NULL; 117 } 118 ++hex; 119 } 120 ++t; 121 } 122 } 123 return r; 124} 125 126/* convert hex, precede by a 1-byte length */ 127uint16_t * 128zparser_conv_hex_length(region_type *region, const char *hex, size_t len) 129{ 130 uint16_t *r = NULL; 131 uint8_t *t; 132 int i; 133 if (len % 2 != 0) { 134 zc_error_prev_line("number of hex digits must be a multiple of 2"); 135 } else if (len > 255 * 2) { 136 zc_error_prev_line("hex data exceeds 255 bytes"); 137 } else { 138 uint8_t *l; 139 140 /* the length part */ 141 r = alloc_rdata(region, len/2+1); 142 t = (uint8_t *)(r + 1); 143 144 l = t++; 145 *l = '\0'; 146 147 /* Now process octet by octet... */ 148 while (*hex) { 149 *t = 0; 150 for (i = 16; i >= 1; i -= 15) { 151 if (isxdigit((unsigned char)*hex)) { 152 *t += hexdigit_to_int(*hex) * i; 153 } else { 154 zc_error_prev_line( 155 "illegal hex character '%c'", 156 (int) *hex); 157 return NULL; 158 } 159 ++hex; 160 } 161 ++t; 162 ++*l; 163 } 164 } 165 return r; 166} 167 168uint16_t * 169zparser_conv_time(region_type *region, const char *time) 170{ 171 /* convert a time YYHM to wireformat */ 172 uint16_t *r = NULL; 173 struct tm tm; 174 175 /* Try to scan the time... */ 176 if (!strptime(time, "%Y%m%d%H%M%S", &tm)) { 177 zc_error_prev_line("date and time is expected"); 178 } else { 179 uint32_t l = htonl(mktime_from_utc(&tm)); 180 r = alloc_rdata_init(region, &l, sizeof(l)); 181 } 182 return r; 183} 184 185uint16_t * 186zparser_conv_services(region_type *region, const char *protostr, 187 char *servicestr) 188{ 189 /* 190 * Convert a protocol and a list of service port numbers 191 * (separated by spaces) in the rdata to wireformat 192 */ 193 uint16_t *r = NULL; 194 uint8_t *p; 195 uint8_t bitmap[65536/8]; 196 char sep[] = " "; 197 char *word; 198 int max_port = -8; 199 /* convert a protocol in the rdata to wireformat */ 200 struct protoent *proto; 201 202 memset(bitmap, 0, sizeof(bitmap)); 203 204 proto = getprotobyname(protostr); 205 if (!proto) { 206 proto = getprotobynumber(atoi(protostr)); 207 } 208 if (!proto) { 209 zc_error_prev_line("unknown protocol '%s'", protostr); 210 return NULL; 211 } 212 213 for (word = strtok(servicestr, sep); word; word = strtok(NULL, sep)) { 214 struct servent *service; 215 int port; 216 217 service = getservbyname(word, proto->p_name); 218 if (service) { 219 /* Note: ntohs not ntohl! Strange but true. */ 220 port = ntohs((uint16_t) service->s_port); 221 } else { 222 char *end; 223 port = strtol(word, &end, 10); 224 if (*end != '\0') { 225 zc_error_prev_line("unknown service '%s' for protocol '%s'", 226 word, protostr); 227 continue; 228 } 229 } 230 231 if (port < 0 || port > 65535) { 232 zc_error_prev_line("bad port number %d", port); 233 } else { 234 set_bit(bitmap, port); 235 if (port > max_port) 236 max_port = port; 237 } 238 } 239 240 r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1); 241 p = (uint8_t *) (r + 1); 242 *p = proto->p_proto; 243 memcpy(p + 1, bitmap, *r-1); 244 245 return r; 246} 247 248uint16_t * 249zparser_conv_serial(region_type *region, const char *serialstr) 250{ 251 uint16_t *r = NULL; 252 uint32_t serial; 253 const char *t; 254 255 serial = strtoserial(serialstr, &t); 256 if (*t != '\0') { 257 zc_error_prev_line("serial is expected or serial too big"); 258 } else { 259 serial = htonl(serial); 260 r = alloc_rdata_init(region, &serial, sizeof(serial)); 261 } 262 return r; 263} 264 265uint16_t * 266zparser_conv_period(region_type *region, const char *periodstr) 267{ 268 /* convert a time period (think TTL's) to wireformat) */ 269 uint16_t *r = NULL; 270 uint32_t period; 271 const char *end; 272 273 /* Allocate required space... */ 274 period = strtottl(periodstr, &end); 275 if (*end != '\0') { 276 zc_error_prev_line("time period is expected"); 277 } else { 278 period = htonl(period); 279 r = alloc_rdata_init(region, &period, sizeof(period)); 280 } 281 return r; 282} 283 284uint16_t * 285zparser_conv_short(region_type *region, const char *text) 286{ 287 uint16_t *r = NULL; 288 uint16_t value; 289 char *end; 290 291 value = htons((uint16_t) strtol(text, &end, 10)); 292 if (*end != '\0') { 293 zc_error_prev_line("integer value is expected"); 294 } else { 295 r = alloc_rdata_init(region, &value, sizeof(value)); 296 } 297 return r; 298} 299 300uint16_t * 301zparser_conv_byte(region_type *region, const char *text) 302{ 303 uint16_t *r = NULL; 304 uint8_t value; 305 char *end; 306 307 value = (uint8_t) strtol(text, &end, 10); 308 if (*end != '\0') { 309 zc_error_prev_line("integer value is expected"); 310 } else { 311 r = alloc_rdata_init(region, &value, sizeof(value)); 312 } 313 return r; 314} 315 316uint16_t * 317zparser_conv_algorithm(region_type *region, const char *text) 318{ 319 const lookup_table_type *alg; 320 uint8_t id; 321 322 alg = lookup_by_name(dns_algorithms, text); 323 if (alg) { 324 id = (uint8_t) alg->id; 325 } else { 326 char *end; 327 id = (uint8_t) strtol(text, &end, 10); 328 if (*end != '\0') { 329 zc_error_prev_line("algorithm is expected"); 330 return NULL; 331 } 332 } 333 334 return alloc_rdata_init(region, &id, sizeof(id)); 335} 336 337uint16_t * 338zparser_conv_certificate_type(region_type *region, const char *text) 339{ 340 /* convert an algorithm string to integer */ 341 const lookup_table_type *type; 342 uint16_t id; 343 344 type = lookup_by_name(dns_certificate_types, text); 345 if (type) { 346 id = htons((uint16_t) type->id); 347 } else { 348 char *end; 349 id = htons((uint16_t) strtol(text, &end, 10)); 350 if (*end != '\0') { 351 zc_error_prev_line("certificate type is expected"); 352 return NULL; 353 } 354 } 355 356 return alloc_rdata_init(region, &id, sizeof(id)); 357} 358 359uint16_t * 360zparser_conv_a(region_type *region, const char *text) 361{ 362 in_addr_t address; 363 uint16_t *r = NULL; 364 365 if (inet_pton(AF_INET, text, &address) != 1) { 366 zc_error_prev_line("invalid IPv4 address '%s'", text); 367 } else { 368 r = alloc_rdata_init(region, &address, sizeof(address)); 369 } 370 return r; 371} 372 373uint16_t * 374zparser_conv_aaaa(region_type *region, const char *text) 375{ 376 uint8_t address[IP6ADDRLEN]; 377 uint16_t *r = NULL; 378 379 if (inet_pton(AF_INET6, text, address) != 1) { 380 zc_error_prev_line("invalid IPv6 address '%s'", text); 381 } else { 382 r = alloc_rdata_init(region, address, sizeof(address)); 383 } 384 return r; 385} 386 387 388uint16_t * 389zparser_conv_ilnp64(region_type *region, const char *text) 390{ 391 uint16_t *r = NULL; 392 int ngroups, num; 393 unsigned long hex; 394 const char *ch; 395 char digits[ILNP_MAXDIGITS+1]; 396 unsigned int ui[ILNP_NUMGROUPS]; 397 uint16_t a[ILNP_NUMGROUPS]; 398 399 ngroups = 1; /* Always at least one group */ 400 num = 0; 401 for (ch = text; *ch != '\0'; ch++) { 402 if (*ch == ':') { 403 if (num <= 0) { 404 zc_error_prev_line("ilnp64: empty group of " 405 "digits is not allowed"); 406 return NULL; 407 } 408 digits[num] = '\0'; 409 hex = (unsigned long) strtol(digits, NULL, 16); 410 num = 0; 411 ui[ngroups - 1] = hex; 412 if (ngroups >= ILNP_NUMGROUPS) { 413 zc_error_prev_line("ilnp64: more than %d groups " 414 "of digits", ILNP_NUMGROUPS); 415 return NULL; 416 } 417 ngroups++; 418 } else { 419 /* Our grammar is stricter than the one accepted by 420 * strtol. */ 421 if (!isxdigit((unsigned char)*ch)) { 422 zc_error_prev_line("ilnp64: invalid " 423 "(non-hexadecimal) character %c", *ch); 424 return NULL; 425 } 426 if (num >= ILNP_MAXDIGITS) { 427 zc_error_prev_line("ilnp64: more than %d digits " 428 "in a group", ILNP_MAXDIGITS); 429 return NULL; 430 } 431 digits[num++] = *ch; 432 } 433 } 434 if (num <= 0) { 435 zc_error_prev_line("ilnp64: empty group of digits is not " 436 "allowed"); 437 return NULL; 438 } 439 digits[num] = '\0'; 440 hex = (unsigned long) strtol(digits, NULL, 16); 441 ui[ngroups - 1] = hex; 442 if (ngroups < 4) { 443 zc_error_prev_line("ilnp64: less than %d groups of digits", 444 ILNP_NUMGROUPS); 445 return NULL; 446 } 447 448 a[0] = htons(ui[0]); 449 a[1] = htons(ui[1]); 450 a[2] = htons(ui[2]); 451 a[3] = htons(ui[3]); 452 r = alloc_rdata_init(region, a, sizeof(a)); 453 return r; 454} 455 456static uint16_t * 457zparser_conv_eui48(region_type *region, const char *text) 458{ 459 uint8_t nums[6]; 460 uint16_t *r = NULL; 461 unsigned int a, b, c, d, e, f; 462 int l; 463 464 if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n", 465 &a, &b, &c, &d, &e, &f, &l) != 6 || 466 l != (int)strlen(text)){ 467 zc_error_prev_line("eui48: invalid rr"); 468 return NULL; 469 } 470 nums[0] = (uint8_t)a; 471 nums[1] = (uint8_t)b; 472 nums[2] = (uint8_t)c; 473 nums[3] = (uint8_t)d; 474 nums[4] = (uint8_t)e; 475 nums[5] = (uint8_t)f; 476 r = alloc_rdata_init(region, nums, sizeof(nums)); 477 return r; 478} 479 480static uint16_t * 481zparser_conv_eui64(region_type *region, const char *text) 482{ 483 uint8_t nums[8]; 484 uint16_t *r = NULL; 485 unsigned int a, b, c, d, e, f, g, h; 486 int l; 487 if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n", 488 &a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 || 489 l != (int)strlen(text)) { 490 zc_error_prev_line("eui64: invalid rr"); 491 return NULL; 492 } 493 nums[0] = (uint8_t)a; 494 nums[1] = (uint8_t)b; 495 nums[2] = (uint8_t)c; 496 nums[3] = (uint8_t)d; 497 nums[4] = (uint8_t)e; 498 nums[5] = (uint8_t)f; 499 nums[6] = (uint8_t)g; 500 nums[7] = (uint8_t)h; 501 r = alloc_rdata_init(region, nums, sizeof(nums)); 502 return r; 503} 504 505uint16_t * 506zparser_conv_eui(region_type *region, const char *text, size_t len) 507{ 508 uint16_t *r = NULL; 509 int nnum, num; 510 const char* ch; 511 512 nnum = len/8; 513 num = 1; 514 for (ch = text; *ch != '\0'; ch++) { 515 if (*ch == '-') { 516 num++; 517 } else if (!isxdigit((unsigned char)*ch)) { 518 zc_error_prev_line("eui%u: invalid (non-hexadecimal) " 519 "character %c", (unsigned) len, *ch); 520 return NULL; 521 } 522 } 523 if (num != nnum) { 524 zc_error_prev_line("eui%u: wrong number of hex numbers", 525 (unsigned) len); 526 return NULL; 527 } 528 529 switch (len) { 530 case 48: 531 r = zparser_conv_eui48(region, text); 532 break; 533 case 64: 534 r = zparser_conv_eui64(region, text); 535 break; 536 default: 537 zc_error_prev_line("eui%u: invalid length", 538 (unsigned) len); 539 return NULL; 540 break; 541 } 542 return r; 543} 544 545uint16_t * 546zparser_conv_text(region_type *region, const char *text, size_t len) 547{ 548 uint16_t *r = NULL; 549 uint8_t *p; 550 551 if (len > 255) { 552 zc_error_prev_line("text string is longer than 255 characters," 553 " try splitting it into multiple parts"); 554 len = 255; 555 } 556 r = alloc_rdata(region, len + 1); 557 p = (uint8_t *) (r + 1); 558 *p = len; 559 memcpy(p + 1, text, len); 560 return r; 561} 562 563/* for CAA Value [RFC 6844] */ 564uint16_t * 565zparser_conv_long_text(region_type *region, const char *text, size_t len) 566{ 567 uint16_t *r = NULL; 568 if (len > MAX_RDLENGTH) { 569 zc_error_prev_line("text string is longer than max rdlen"); 570 return NULL; 571 } 572 r = alloc_rdata_init(region, text, len); 573 return r; 574} 575 576/* for CAA Tag [RFC 6844] */ 577uint16_t * 578zparser_conv_tag(region_type *region, const char *text, size_t len) 579{ 580 uint16_t *r = NULL; 581 uint8_t *p; 582 const char* ptr; 583 584 if (len < 1) { 585 zc_error_prev_line("invalid tag: zero length"); 586 return NULL; 587 } 588 if (len > 15) { 589 zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)", 590 text, (unsigned) len); 591 return NULL; 592 } 593 for (ptr = text; *ptr; ptr++) { 594 if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) { 595 zc_error_prev_line("invalid tag %s: contains invalid char %c", 596 text, *ptr); 597 return NULL; 598 } 599 } 600 r = alloc_rdata(region, len + 1); 601 p = (uint8_t *) (r + 1); 602 *p = len; 603 memmove(p + 1, text, len); 604 return r; 605} 606 607uint16_t * 608zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len) 609{ 610 uint16_t* r = NULL; 611 uint8_t* p = NULL; 612 r = alloc_rdata(region, len); 613 p = (uint8_t *) (r + 1); 614 memcpy(p, name, len); 615 616 return r; 617} 618 619uint16_t * 620zparser_conv_b32(region_type *region, const char *b32) 621{ 622 uint8_t buffer[B64BUFSIZE]; 623 uint16_t *r = NULL; 624 int i; 625 626 if(strcmp(b32, "-") == 0) { 627 return alloc_rdata_init(region, "", 1); 628 } 629 i = b32_pton(b32, buffer+1, B64BUFSIZE-1); 630 if (i == -1 || i > 255) { 631 zc_error_prev_line("invalid base32 data"); 632 } else { 633 buffer[0] = i; /* store length byte */ 634 r = alloc_rdata_init(region, buffer, i+1); 635 } 636 return r; 637} 638 639uint16_t * 640zparser_conv_b64(region_type *region, const char *b64) 641{ 642 uint8_t buffer[B64BUFSIZE]; 643 uint16_t *r = NULL; 644 int i; 645 646 if(strcmp(b64, "0") == 0) { 647 /* single 0 represents empty buffer */ 648 return alloc_rdata(region, 0); 649 } 650 i = b64_pton(b64, buffer, B64BUFSIZE); 651 if (i == -1) { 652 zc_error_prev_line("invalid base64 data"); 653 } else { 654 r = alloc_rdata_init(region, buffer, i); 655 } 656 return r; 657} 658 659uint16_t * 660zparser_conv_rrtype(region_type *region, const char *text) 661{ 662 uint16_t *r = NULL; 663 uint16_t type = rrtype_from_string(text); 664 665 if (type == 0) { 666 zc_error_prev_line("unrecognized RR type '%s'", text); 667 } else { 668 type = htons(type); 669 r = alloc_rdata_init(region, &type, sizeof(type)); 670 } 671 return r; 672} 673 674uint16_t * 675zparser_conv_nxt(region_type *region, uint8_t nxtbits[]) 676{ 677 /* nxtbits[] consists of 16 bytes with some zero's in it 678 * copy every byte with zero to r and write the length in 679 * the first byte 680 */ 681 uint16_t i; 682 uint16_t last = 0; 683 684 for (i = 0; i < 16; i++) { 685 if (nxtbits[i] != 0) 686 last = i + 1; 687 } 688 689 return alloc_rdata_init(region, nxtbits, last); 690} 691 692 693/* we potentially have 256 windows, each one is numbered. empty ones 694 * should be discarded 695 */ 696uint16_t * 697zparser_conv_nsec(region_type *region, 698 uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]) 699{ 700 /* nsecbits contains up to 64K of bits which represent the 701 * types available for a name. Walk the bits according to 702 * nsec++ draft from jakob 703 */ 704 uint16_t *r; 705 uint8_t *ptr; 706 size_t i,j; 707 uint16_t window_count = 0; 708 uint16_t total_size = 0; 709 uint16_t window_max = 0; 710 711 /* The used windows. */ 712 int used[NSEC_WINDOW_COUNT]; 713 /* The last byte used in each the window. */ 714 int size[NSEC_WINDOW_COUNT]; 715 716 window_max = 1 + (nsec_highest_rcode / 256); 717 718 /* used[i] is the i-th window included in the nsec 719 * size[used[0]] is the size of window 0 720 */ 721 722 /* walk through the 256 windows */ 723 for (i = 0; i < window_max; ++i) { 724 int empty_window = 1; 725 /* check each of the 32 bytes */ 726 for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) { 727 if (nsecbits[i][j] != 0) { 728 size[i] = j + 1; 729 empty_window = 0; 730 } 731 } 732 if (!empty_window) { 733 used[window_count] = i; 734 window_count++; 735 } 736 } 737 738 for (i = 0; i < window_count; ++i) { 739 total_size += sizeof(uint16_t) + size[used[i]]; 740 } 741 742 r = alloc_rdata(region, total_size); 743 ptr = (uint8_t *) (r + 1); 744 745 /* now walk used and copy it */ 746 for (i = 0; i < window_count; ++i) { 747 ptr[0] = used[i]; 748 ptr[1] = size[used[i]]; 749 memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]); 750 ptr += size[used[i]] + 2; 751 } 752 753 return r; 754} 755 756/* Parse an int terminated in the specified range. */ 757static int 758parse_int(const char *str, 759 char **end, 760 int *result, 761 const char *name, 762 int min, 763 int max) 764{ 765 *result = (int) strtol(str, end, 10); 766 if (*result < min || *result > max) { 767 zc_error_prev_line("%s must be within the range [%d .. %d]", 768 name, 769 min, 770 max); 771 return 0; 772 } else { 773 return 1; 774 } 775} 776 777/* RFC1876 conversion routines */ 778static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, 779 1000000,10000000,100000000,1000000000}; 780 781/* 782 * Converts ascii size/precision X * 10**Y(cm) to 0xXY. 783 * Sets the given pointer to the last used character. 784 * 785 */ 786static uint8_t 787precsize_aton (char *cp, char **endptr) 788{ 789 unsigned int mval = 0, cmval = 0; 790 uint8_t retval = 0; 791 int exponent; 792 int mantissa; 793 794 while (isdigit((unsigned char)*cp)) 795 mval = mval * 10 + hexdigit_to_int(*cp++); 796 797 if (*cp == '.') { /* centimeters */ 798 cp++; 799 if (isdigit((unsigned char)*cp)) { 800 cmval = hexdigit_to_int(*cp++) * 10; 801 if (isdigit((unsigned char)*cp)) { 802 cmval += hexdigit_to_int(*cp++); 803 } 804 } 805 } 806 807 if(mval >= poweroften[7]) { 808 assert(poweroften[7] != 0); 809 /* integer overflow possible for *100 */ 810 mantissa = mval / poweroften[7]; 811 exponent = 9; /* max */ 812 } 813 else { 814 cmval = (mval * 100) + cmval; 815 816 for (exponent = 0; exponent < 9; exponent++) 817 if (cmval < poweroften[exponent+1]) 818 break; 819 820 assert(poweroften[exponent] != 0); 821 mantissa = cmval / poweroften[exponent]; 822 } 823 if (mantissa > 9) 824 mantissa = 9; 825 826 retval = (mantissa << 4) | exponent; 827 828 if (*cp == 'm') cp++; 829 830 *endptr = cp; 831 832 return (retval); 833} 834 835/* 836 * Parses a specific part of rdata. 837 * 838 * Returns: 839 * 840 * number of elements parsed 841 * zero on error 842 * 843 */ 844uint16_t * 845zparser_conv_loc(region_type *region, char *str) 846{ 847 uint16_t *r; 848 uint32_t *p; 849 int i; 850 int deg, min, secs; /* Secs is stored times 1000. */ 851 uint32_t lat = 0, lon = 0, alt = 0; 852 /* encoded defaults: version=0 sz=1m hp=10000m vp=10m */ 853 uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13}; 854 char *start; 855 double d; 856 857 for(;;) { 858 deg = min = secs = 0; 859 860 /* Degrees */ 861 if (*str == '\0') { 862 zc_error_prev_line("unexpected end of LOC data"); 863 return NULL; 864 } 865 866 if (!parse_int(str, &str, °, "degrees", 0, 180)) 867 return NULL; 868 if (!isspace((unsigned char)*str)) { 869 zc_error_prev_line("space expected after degrees"); 870 return NULL; 871 } 872 ++str; 873 874 /* Minutes? */ 875 if (isdigit((unsigned char)*str)) { 876 if (!parse_int(str, &str, &min, "minutes", 0, 60)) 877 return NULL; 878 if (!isspace((unsigned char)*str)) { 879 zc_error_prev_line("space expected after minutes"); 880 return NULL; 881 } 882 ++str; 883 } 884 885 /* Seconds? */ 886 if (isdigit((unsigned char)*str)) { 887 start = str; 888 if (!parse_int(str, &str, &i, "seconds", 0, 60)) { 889 return NULL; 890 } 891 892 if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) { 893 return NULL; 894 } 895 896 if (!isspace((unsigned char)*str)) { 897 zc_error_prev_line("space expected after seconds"); 898 return NULL; 899 } 900 /* No need for precision specifiers, it's a double */ 901 if (sscanf(start, "%lf", &d) != 1) { 902 zc_error_prev_line("error parsing seconds"); 903 } 904 905 if (d < 0.0 || d > 60.0) { 906 zc_error_prev_line("seconds not in range 0.0 .. 60.0"); 907 } 908 909 secs = (int) (d * 1000.0 + 0.5); 910 ++str; 911 } 912 913 switch(*str) { 914 case 'N': 915 case 'n': 916 lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs); 917 break; 918 case 'E': 919 case 'e': 920 lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs); 921 break; 922 case 'S': 923 case 's': 924 lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs); 925 break; 926 case 'W': 927 case 'w': 928 lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs); 929 break; 930 default: 931 zc_error_prev_line("invalid latitude/longtitude: '%c'", *str); 932 return NULL; 933 } 934 ++str; 935 936 if (lat != 0 && lon != 0) 937 break; 938 939 if (!isspace((unsigned char)*str)) { 940 zc_error_prev_line("space expected after latitude/longitude"); 941 return NULL; 942 } 943 ++str; 944 } 945 946 /* Altitude */ 947 if (*str == '\0') { 948 zc_error_prev_line("unexpected end of LOC data"); 949 return NULL; 950 } 951 952 if (!isspace((unsigned char)*str)) { 953 zc_error_prev_line("space expected before altitude"); 954 return NULL; 955 } 956 ++str; 957 958 start = str; 959 960 /* Sign */ 961 if (*str == '+' || *str == '-') { 962 ++str; 963 } 964 965 /* Meters of altitude... */ 966 if(strtol(str, &str, 10) == LONG_MAX) { 967 zc_error_prev_line("altitude too large, number overflow"); 968 return NULL; 969 } 970 switch(*str) { 971 case ' ': 972 case '\0': 973 case 'm': 974 break; 975 case '.': 976 if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) { 977 return NULL; 978 } 979 if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') { 980 zc_error_prev_line("altitude fraction must be a number"); 981 return NULL; 982 } 983 break; 984 default: 985 zc_error_prev_line("altitude must be expressed in meters"); 986 return NULL; 987 } 988 if (!isspace((unsigned char)*str) && *str != '\0') 989 ++str; 990 991 if (sscanf(start, "%lf", &d) != 1) { 992 zc_error_prev_line("error parsing altitude"); 993 } 994 995 alt = (uint32_t) (10000000.0 + d * 100 + 0.5); 996 997 if (!isspace((unsigned char)*str) && *str != '\0') { 998 zc_error_prev_line("unexpected character after altitude"); 999 return NULL; 1000 } 1001 1002 /* Now parse size, horizontal precision and vertical precision if any */ 1003 for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) { 1004 vszhpvp[i] = precsize_aton(str + 1, &str); 1005 1006 if (!isspace((unsigned char)*str) && *str != '\0') { 1007 zc_error_prev_line("invalid size or precision"); 1008 return NULL; 1009 } 1010 } 1011 1012 /* Allocate required space... */ 1013 r = alloc_rdata(region, 16); 1014 p = (uint32_t *) (r + 1); 1015 1016 memmove(p, vszhpvp, 4); 1017 write_uint32(p + 1, lat); 1018 write_uint32(p + 2, lon); 1019 write_uint32(p + 3, alt); 1020 1021 return r; 1022} 1023 1024/* 1025 * Convert an APL RR RDATA element. 1026 */ 1027uint16_t * 1028zparser_conv_apl_rdata(region_type *region, char *str) 1029{ 1030 int negated = 0; 1031 uint16_t address_family; 1032 uint8_t prefix; 1033 uint8_t maximum_prefix; 1034 uint8_t length; 1035 uint8_t address[IP6ADDRLEN]; 1036 char *colon = strchr(str, ':'); 1037 char *slash = strchr(str, '/'); 1038 int af; 1039 int rc; 1040 uint16_t rdlength; 1041 uint16_t *r; 1042 uint8_t *t; 1043 char *end; 1044 long p; 1045 1046 if (!colon) { 1047 zc_error("address family separator is missing"); 1048 return NULL; 1049 } 1050 if (!slash) { 1051 zc_error("prefix separator is missing"); 1052 return NULL; 1053 } 1054 1055 *colon = '\0'; 1056 *slash = '\0'; 1057 1058 if (*str == '!') { 1059 negated = 1; 1060 ++str; 1061 } 1062 1063 if (strcmp(str, "1") == 0) { 1064 address_family = htons(1); 1065 af = AF_INET; 1066 length = sizeof(in_addr_t); 1067 maximum_prefix = length * 8; 1068 } else if (strcmp(str, "2") == 0) { 1069 address_family = htons(2); 1070 af = AF_INET6; 1071 length = IP6ADDRLEN; 1072 maximum_prefix = length * 8; 1073 } else { 1074 zc_error("invalid address family '%s'", str); 1075 return NULL; 1076 } 1077 1078 rc = inet_pton(af, colon + 1, address); 1079 if (rc == 0) { 1080 zc_error("invalid address '%s'", colon + 1); 1081 return NULL; 1082 } else if (rc == -1) { 1083 zc_error("inet_pton failed: %s", strerror(errno)); 1084 return NULL; 1085 } 1086 1087 /* Strip trailing zero octets. */ 1088 while (length > 0 && address[length - 1] == 0) 1089 --length; 1090 1091 1092 p = strtol(slash + 1, &end, 10); 1093 if (p < 0 || p > maximum_prefix) { 1094 zc_error("prefix not in the range 0 .. %d", maximum_prefix); 1095 return NULL; 1096 } else if (*end != '\0') { 1097 zc_error("invalid prefix '%s'", slash + 1); 1098 return NULL; 1099 } 1100 prefix = (uint8_t) p; 1101 1102 rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length) 1103 + length); 1104 r = alloc_rdata(region, rdlength); 1105 t = (uint8_t *) (r + 1); 1106 1107 memcpy(t, &address_family, sizeof(address_family)); 1108 t += sizeof(address_family); 1109 memcpy(t, &prefix, sizeof(prefix)); 1110 t += sizeof(prefix); 1111 memcpy(t, &length, sizeof(length)); 1112 if (negated) { 1113 *t |= APL_NEGATION_MASK; 1114 } 1115 t += sizeof(length); 1116 memcpy(t, address, length); 1117 1118 return r; 1119} 1120 1121/* 1122 * Below some function that also convert but not to wireformat 1123 * but to "normal" (int,long,char) types 1124 */ 1125 1126uint32_t 1127zparser_ttl2int(const char *ttlstr, int* error) 1128{ 1129 /* convert a ttl value to a integer 1130 * return the ttl in a int 1131 * -1 on error 1132 */ 1133 1134 uint32_t ttl; 1135 const char *t; 1136 1137 ttl = strtottl(ttlstr, &t); 1138 if (*t != 0) { 1139 zc_error_prev_line("invalid TTL value: %s",ttlstr); 1140 *error = 1; 1141 } 1142 1143 return ttl; 1144} 1145 1146 1147void 1148zadd_rdata_wireformat(uint16_t *data) 1149{ 1150 if (parser->current_rr.rdata_count >= MAXRDATALEN) { 1151 zc_error_prev_line("too many rdata elements"); 1152 } else { 1153 parser->current_rr.rdatas[parser->current_rr.rdata_count].data 1154 = data; 1155 ++parser->current_rr.rdata_count; 1156 } 1157} 1158 1159/** 1160 * Used for TXT RR's to grow with undefined number of strings. 1161 */ 1162void 1163zadd_rdata_txt_wireformat(uint16_t *data, int first) 1164{ 1165 rdata_atom_type *rd; 1166 if (parser->current_rr.rdata_count >= MAXRDATALEN) { 1167 zc_error_prev_line("too many rdata txt elements"); 1168 return; 1169 } 1170 1171 /* First STR in str_seq, allocate 65K in first unused rdata 1172 * else find last used rdata */ 1173 if (first) { 1174 rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count]; 1175 if ((rd->data = (uint16_t *) region_alloc(parser->rr_region, 1176 sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) { 1177 zc_error_prev_line("Could not allocate memory for TXT RR"); 1178 return; 1179 } 1180 parser->current_rr.rdata_count++; 1181 rd->data[0] = 0; 1182 } 1183 else 1184 rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; 1185 1186 if ((size_t)rd->data[0] + (size_t)data[0] > 65535) { 1187 zc_error_prev_line("too large rdata element"); 1188 return; 1189 } 1190 1191 memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]); 1192 rd->data[0] += data[0]; 1193} 1194 1195/** 1196 * Clean up after last call of zadd_rdata_txt_wireformat 1197 */ 1198void 1199zadd_rdata_txt_clean_wireformat() 1200{ 1201 uint16_t *tmp_data; 1202 rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; 1203 if(!rd || !rd->data) 1204 return; /* previous syntax failure */ 1205 if ((tmp_data = (uint16_t *) region_alloc(parser->region, 1206 ((size_t)rd->data[0]) + ((size_t)2))) != NULL) { 1207 memcpy(tmp_data, rd->data, rd->data[0] + 2); 1208 /* rd->data of u16+65535 freed when rr_region is freed */ 1209 rd->data = tmp_data; 1210 } 1211 else { 1212 /* We could not get memory in non-volatile region */ 1213 zc_error_prev_line("could not allocate memory for rdata"); 1214 return; 1215 } 1216} 1217 1218void 1219zadd_rdata_domain(domain_type *domain) 1220{ 1221 if (parser->current_rr.rdata_count >= MAXRDATALEN) { 1222 zc_error_prev_line("too many rdata elements"); 1223 } else { 1224 parser->current_rr.rdatas[parser->current_rr.rdata_count].domain 1225 = domain; 1226 domain->usage ++; /* new reference to domain */ 1227 ++parser->current_rr.rdata_count; 1228 } 1229} 1230 1231void 1232parse_unknown_rdata(uint16_t type, uint16_t *wireformat) 1233{ 1234 buffer_type packet; 1235 uint16_t size; 1236 ssize_t rdata_count; 1237 ssize_t i; 1238 rdata_atom_type *rdatas; 1239 1240 if (wireformat) { 1241 size = *wireformat; 1242 } else { 1243 return; 1244 } 1245 1246 buffer_create_from(&packet, wireformat + 1, *wireformat); 1247 rdata_count = rdata_wireformat_to_rdata_atoms(parser->region, 1248 parser->db->domains, 1249 type, 1250 size, 1251 &packet, 1252 &rdatas); 1253 if (rdata_count == -1) { 1254 zc_error_prev_line("bad unknown RDATA"); 1255 return; 1256 } 1257 1258 for (i = 0; i < rdata_count; ++i) { 1259 if (rdata_atom_is_domain(type, i)) { 1260 zadd_rdata_domain(rdatas[i].domain); 1261 } else { 1262 zadd_rdata_wireformat(rdatas[i].data); 1263 } 1264 } 1265 region_recycle(parser->region, rdatas, 1266 rdata_count*sizeof(rdata_atom_type)); 1267} 1268 1269 1270/* 1271 * Compares two rdata arrays. 1272 * 1273 * Returns: 1274 * 1275 * zero if they are equal 1276 * non-zero if not 1277 * 1278 */ 1279static int 1280zrdatacmp(uint16_t type, rr_type *a, rr_type *b) 1281{ 1282 int i = 0; 1283 1284 assert(a); 1285 assert(b); 1286 1287 /* One is shorter than another */ 1288 if (a->rdata_count != b->rdata_count) 1289 return 1; 1290 1291 /* Compare element by element */ 1292 for (i = 0; i < a->rdata_count; ++i) { 1293 if (rdata_atom_is_domain(type, i)) { 1294 if (rdata_atom_domain(a->rdatas[i]) 1295 != rdata_atom_domain(b->rdatas[i])) 1296 { 1297 return 1; 1298 } 1299 } else if(rdata_atom_is_literal_domain(type, i)) { 1300 if (rdata_atom_size(a->rdatas[i]) 1301 != rdata_atom_size(b->rdatas[i])) 1302 return 1; 1303 if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]), 1304 rdata_atom_data(b->rdatas[i]), 1305 rdata_atom_size(a->rdatas[i]))) 1306 return 1; 1307 } else { 1308 if (rdata_atom_size(a->rdatas[i]) 1309 != rdata_atom_size(b->rdatas[i])) 1310 { 1311 return 1; 1312 } 1313 if (memcmp(rdata_atom_data(a->rdatas[i]), 1314 rdata_atom_data(b->rdatas[i]), 1315 rdata_atom_size(a->rdatas[i])) != 0) 1316 { 1317 return 1; 1318 } 1319 } 1320 } 1321 1322 /* Otherwise they are equal */ 1323 return 0; 1324} 1325 1326/* 1327 * 1328 * Opens a zone file. 1329 * 1330 * Returns: 1331 * 1332 * - pointer to the parser structure 1333 * - NULL on error and errno set 1334 * 1335 */ 1336static int 1337zone_open(const char *filename, uint32_t ttl, uint16_t klass, 1338 const dname_type *origin) 1339{ 1340 /* Open the zone file... */ 1341 if (strcmp(filename, "-") == 0) { 1342 yyin = stdin; 1343 filename = "<stdin>"; 1344 } else if (!(yyin = fopen(filename, "r"))) { 1345 return 0; 1346 } 1347 1348 zparser_init(filename, ttl, klass, origin); 1349 1350 return 1; 1351} 1352 1353 1354void 1355set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], 1356 uint16_t index) 1357{ 1358 /* 1359 * The bits are counted from left to right, so bit #0 is the 1360 * left most bit. 1361 */ 1362 uint8_t window = index / 256; 1363 uint8_t bit = index % 256; 1364 1365 bits[window][bit / 8] |= (1 << (7 - bit % 8)); 1366} 1367 1368 1369static int 1370has_soa(domain_type* domain) 1371{ 1372 rrset_type* p = NULL; 1373 if(!domain) return 0; 1374 for(p = domain->rrsets; p; p = p->next) 1375 if(rrset_rrtype(p) == TYPE_SOA) 1376 return 1; 1377 return 0; 1378} 1379 1380int 1381process_rr(void) 1382{ 1383 zone_type *zone = parser->current_zone; 1384 rr_type *rr = &parser->current_rr; 1385 rrset_type *rrset; 1386 size_t max_rdlength; 1387 int i; 1388 rrtype_descriptor_type *descriptor 1389 = rrtype_descriptor_by_type(rr->type); 1390 1391 /* We only support IN class */ 1392 if (rr->klass != CLASS_IN) { 1393 if(zone_is_slave(zone->opts)) 1394 zc_warning_prev_line("only class IN is supported"); 1395 else 1396 zc_error_prev_line("only class IN is supported"); 1397 return 0; 1398 } 1399 1400 /* Make sure the maximum RDLENGTH does not exceed 65535 bytes. */ 1401 max_rdlength = rdata_maximum_wireformat_size( 1402 descriptor, rr->rdata_count, rr->rdatas); 1403 1404 if (max_rdlength > MAX_RDLENGTH) { 1405 zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH); 1406 return 0; 1407 } 1408 /* we have the zone already */ 1409 assert(zone); 1410 if (rr->type == TYPE_SOA) { 1411 if (rr->owner != zone->apex) { 1412 char s[MAXDOMAINLEN*5]; 1413 snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex)); 1414 zc_error_prev_line( 1415 "SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s); 1416 return 0; 1417 } 1418 if(has_soa(rr->owner)) { 1419 if(zone_is_slave(zone->opts)) 1420 zc_warning_prev_line("this SOA record was already encountered"); 1421 else 1422 zc_error_prev_line("this SOA record was already encountered"); 1423 return 0; 1424 } 1425 rr->owner->is_apex = 1; 1426 } 1427 1428 if (!domain_is_subdomain(rr->owner, zone->apex)) 1429 { 1430 char s[MAXDOMAINLEN*5]; 1431 snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex)); 1432 if(zone_is_slave(zone->opts)) 1433 zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s); 1434 else 1435 zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s); 1436 return 0; 1437 } 1438 1439 /* Do we have this type of rrset already? */ 1440 rrset = domain_find_rrset(rr->owner, zone, rr->type); 1441 if (!rrset) { 1442 rrset = (rrset_type *) region_alloc(parser->region, 1443 sizeof(rrset_type)); 1444 rrset->zone = zone; 1445 rrset->rr_count = 1; 1446 rrset->rrs = (rr_type *) region_alloc(parser->region, 1447 sizeof(rr_type)); 1448 rrset->rrs[0] = *rr; 1449 1450 /* Add it */ 1451 domain_add_rrset(rr->owner, rrset); 1452 } else { 1453 rr_type* o; 1454 if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) { 1455 zc_warning_prev_line( 1456 "%s TTL %u does not match the TTL %u of the %s RRset", 1457 domain_to_string(rr->owner), (unsigned)rr->ttl, 1458 (unsigned)rrset->rrs[0].ttl, 1459 rrtype_to_string(rr->type)); 1460 } 1461 1462 /* Search for possible duplicates... */ 1463 for (i = 0; i < rrset->rr_count; i++) { 1464 if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) { 1465 break; 1466 } 1467 } 1468 1469 /* Discard the duplicates... */ 1470 if (i < rrset->rr_count) { 1471 /* add rdatas to recycle bin. */ 1472 size_t i; 1473 for (i = 0; i < rr->rdata_count; i++) { 1474 if(!rdata_atom_is_domain(rr->type, i)) 1475 region_recycle(parser->region, rr->rdatas[i].data, 1476 rdata_atom_size(rr->rdatas[i]) 1477 + sizeof(uint16_t)); 1478 } 1479 region_recycle(parser->region, rr->rdatas, 1480 sizeof(rdata_atom_type)*rr->rdata_count); 1481 return 0; 1482 } 1483 if(rrset->rr_count == 65535) { 1484 zc_error_prev_line("too many RRs for domain RRset"); 1485 return 0; 1486 } 1487 1488 /* Add it... */ 1489 o = rrset->rrs; 1490 rrset->rrs = (rr_type *) region_alloc_array(parser->region, 1491 (rrset->rr_count + 1), sizeof(rr_type)); 1492 memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type)); 1493 region_recycle(parser->region, o, 1494 (rrset->rr_count) * sizeof(rr_type)); 1495 rrset->rrs[rrset->rr_count] = *rr; 1496 ++rrset->rr_count; 1497 } 1498 1499 if(rr->type == TYPE_DNAME && rrset->rr_count > 1) { 1500 if(zone_is_slave(zone->opts)) 1501 zc_warning_prev_line("multiple DNAMEs at the same name"); 1502 else 1503 zc_error_prev_line("multiple DNAMEs at the same name"); 1504 } 1505 if(rr->type == TYPE_CNAME && rrset->rr_count > 1) { 1506 if(zone_is_slave(zone->opts)) 1507 zc_warning_prev_line("multiple CNAMEs at the same name"); 1508 else 1509 zc_error_prev_line("multiple CNAMEs at the same name"); 1510 } 1511 if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME)) 1512 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) { 1513 if(zone_is_slave(zone->opts)) 1514 zc_warning_prev_line("DNAME and CNAME at the same name"); 1515 else 1516 zc_error_prev_line("DNAME and CNAME at the same name"); 1517 } 1518 if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) && 1519 domain_find_non_cname_rrset(rr->owner, zone)) { 1520 if(zone_is_slave(zone->opts)) 1521 zc_warning_prev_line("CNAME and other data at the same name"); 1522 else 1523 zc_error_prev_line("CNAME and other data at the same name"); 1524 } 1525 1526 /* Check we have SOA */ 1527 if(rr->owner == zone->apex) 1528 apex_rrset_checks(parser->db, rrset, rr->owner); 1529 1530 if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) { 1531 struct stat buf; 1532 startzonec = time(NULL); 1533 buf.st_size = 0; 1534 fstat(fileno(yyin), &buf); 1535 if(buf.st_size == 0) buf.st_size = 1; 1536 VERBOSITY(1, (LOG_INFO, "parse %s %d %%", 1537 parser->current_zone->opts->name, 1538 (int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size))); 1539 } 1540 ++totalrrs; 1541 return 1; 1542} 1543 1544/* 1545 * Find rrset type for any zone 1546 */ 1547static rrset_type* 1548domain_find_rrset_any(domain_type *domain, uint16_t type) 1549{ 1550 rrset_type *result = domain->rrsets; 1551 while (result) { 1552 if (rrset_rrtype(result) == type) { 1553 return result; 1554 } 1555 result = result->next; 1556 } 1557 return NULL; 1558} 1559 1560/* 1561 * Check for DNAME type. Nothing is allowed below it 1562 */ 1563static void 1564check_dname(zone_type* zone) 1565{ 1566 domain_type* domain; 1567 for(domain = zone->apex; domain && domain_is_subdomain(domain, 1568 zone->apex); domain=domain_next(domain)) 1569 { 1570 if(domain->is_existing) { 1571 /* there may not be DNAMEs above it */ 1572 domain_type* parent = domain->parent; 1573#ifdef NSEC3 1574 if(domain_has_only_NSEC3(domain, NULL)) 1575 continue; 1576#endif 1577 while(parent) { 1578 if(domain_find_rrset_any(parent, TYPE_DNAME)) { 1579 zc_error("While checking node %s,", 1580 domain_to_string(domain)); 1581 zc_error("DNAME at %s has data below it. " 1582 "This is not allowed (rfc 2672).", 1583 domain_to_string(parent)); 1584 return; 1585 } 1586 parent = parent->parent; 1587 } 1588 } 1589 } 1590} 1591 1592/* 1593 * Reads the specified zone into the memory 1594 * nsd_options can be NULL if no config file is passed. 1595 */ 1596unsigned int 1597zonec_read(const char* name, const char* zonefile, zone_type* zone) 1598{ 1599 const dname_type *dname; 1600 1601 totalrrs = 0; 1602 startzonec = time(NULL); 1603 parser->errors = 0; 1604 1605 dname = dname_parse(parser->rr_region, name); 1606 if (!dname) { 1607 zc_error("incorrect zone name '%s'", name); 1608 return 1; 1609 } 1610 1611#ifndef ROOT_SERVER 1612 /* Is it a root zone? Are we a root server then? Idiot proof. */ 1613 if (dname->label_count == 1) { 1614 zc_error("not configured as a root server"); 1615 return 1; 1616 } 1617#endif 1618 1619 /* Open the zone file */ 1620 if (!zone_open(zonefile, 3600, CLASS_IN, dname)) { 1621 zc_error("cannot open '%s': %s", zonefile, strerror(errno)); 1622 return 1; 1623 } 1624 parser->current_zone = zone; 1625 1626 /* Parse and process all RRs. */ 1627 yyparse(); 1628 1629 /* remove origin if it was unused */ 1630 if(parser->origin != error_domain) 1631 domain_table_deldomain(parser->db, parser->origin); 1632 /* rr_region has been emptied by now */ 1633 dname = dname_parse(parser->rr_region, name); 1634 1635 /* check if zone file contained a correct SOA record */ 1636 if (!parser->current_zone) { 1637 zc_error("zone configured as '%s' has no content.", name); 1638 } else if(!parser->current_zone->soa_rrset || 1639 parser->current_zone->soa_rrset->rr_count == 0) { 1640 zc_error("zone configured as '%s' has no SOA record.", name); 1641 } else if(dname_compare(domain_dname( 1642 parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) { 1643 zc_error("zone configured as '%s', but SOA has owner '%s'.", 1644 name, domain_to_string( 1645 parser->current_zone->soa_rrset->rrs[0].owner)); 1646 } 1647 region_free_all(parser->rr_region); 1648 1649 parser_flush(); 1650 fclose(yyin); 1651 if(!zone_is_slave(zone->opts)) 1652 check_dname(zone); 1653 1654 parser->filename = NULL; 1655 return parser->errors; 1656} 1657 1658 1659/* 1660 * setup parse 1661 */ 1662void 1663zonec_setup_parser(namedb_type* db) 1664{ 1665 region_type* rr_region = region_create(xalloc, free); 1666 parser = zparser_create(db->region, rr_region, db); 1667 assert(parser); 1668 /* Unique pointers used to mark errors. */ 1669 error_dname = (dname_type *) region_alloc(db->region, 1); 1670 error_domain = (domain_type *) region_alloc(db->region, 1); 1671 /* Open the network database */ 1672 setprotoent(1); 1673 setservent(1); 1674} 1675 1676/** desetup parse */ 1677void 1678zonec_desetup_parser(void) 1679{ 1680 if(parser) { 1681 endservent(); 1682 endprotoent(); 1683 region_destroy(parser->rr_region); 1684 /* removed when parser->region(=db->region) is destroyed: 1685 * region_recycle(parser->region, (void*)error_dname, 1); 1686 * region_recycle(parser->region, (void*)error_domain, 1); */ 1687 /* clear memory for exit, but this is not portable to 1688 * other versions of lex. yylex_destroy(); */ 1689#ifdef MEMCLEAN /* OS collects memory pages */ 1690 yylex_destroy(); 1691#endif 1692 } 1693} 1694 1695static domain_table_type* orig_domains = NULL; 1696static region_type* orig_region = NULL; 1697static region_type* orig_dbregion = NULL; 1698 1699/** setup for string parse */ 1700void 1701zonec_setup_string_parser(region_type* region, domain_table_type* domains) 1702{ 1703 assert(parser); /* global parser must be setup */ 1704 orig_domains = parser->db->domains; 1705 orig_region = parser->region; 1706 orig_dbregion = parser->db->region; 1707 parser->region = region; 1708 parser->db->region = region; 1709 parser->db->domains = domains; 1710 zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root)); 1711} 1712 1713/** desetup string parse */ 1714void 1715zonec_desetup_string_parser(void) 1716{ 1717 parser->region = orig_region; 1718 parser->db->domains = orig_domains; 1719 parser->db->region = orig_dbregion; 1720} 1721 1722/** parse a string into temporary storage */ 1723int 1724zonec_parse_string(region_type* region, domain_table_type* domains, 1725 zone_type* zone, char* str, domain_type** parsed, int* num_rrs) 1726{ 1727 int errors; 1728 zonec_setup_string_parser(region, domains); 1729 parser->current_zone = zone; 1730 parser->errors = 0; 1731 totalrrs = 0; 1732 startzonec = time(NULL)+100000; /* disable */ 1733 parser_push_stringbuf(str); 1734 yyparse(); 1735 parser_pop_stringbuf(); 1736 errors = parser->errors; 1737 *num_rrs = totalrrs; 1738 if(*num_rrs == 0) 1739 *parsed = NULL; 1740 else *parsed = parser->prev_dname; 1741 /* remove origin if it was not used during the parse */ 1742 if(parser->origin != error_domain) 1743 domain_table_deldomain(parser->db, parser->origin); 1744 region_free_all(parser->rr_region); 1745 zonec_desetup_string_parser(); 1746 parser_flush(); 1747 return errors; 1748} 1749 1750/** check SSHFP type for failures and emit warnings */ 1751void check_sshfp(void) 1752{ 1753 uint8_t hash; 1754 uint16_t size; 1755 if(parser->current_rr.rdata_count < 3) 1756 return; /* cannot check it, too few rdata elements */ 1757 if(!parser->current_rr.rdatas[0].data || 1758 !parser->current_rr.rdatas[1].data || 1759 !parser->current_rr.rdatas[2].data || 1760 !parser->current_rr.owner) 1761 return; /* cannot check, NULLs (due to earlier errors) */ 1762 if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1) 1763 return; /* wrong size of the hash type rdata element */ 1764 hash = rdata_atom_data(parser->current_rr.rdatas[1])[0]; 1765 size = rdata_atom_size(parser->current_rr.rdatas[2]); 1766 if(hash == 1 && size != 20) { 1767 zc_warning_prev_line("SSHFP %s of type SHA1 has hash of " 1768 "wrong length, %d bytes, should be 20", 1769 domain_to_string(parser->current_rr.owner), 1770 (int)size); 1771 } else if(hash == 2 && size != 32) { 1772 zc_warning_prev_line("SSHFP %s of type SHA256 has hash of " 1773 "wrong length, %d bytes, should be 32", 1774 domain_to_string(parser->current_rr.owner), 1775 (int)size); 1776 } 1777} 1778