1/* $NetBSD: name.c,v 1.14 2024/02/21 22:52:07 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16/*! \file */ 17 18#include <ctype.h> 19#include <inttypes.h> 20#include <stdbool.h> 21#include <stdlib.h> 22 23#include <isc/buffer.h> 24#include <isc/hash.h> 25#include <isc/mem.h> 26#include <isc/once.h> 27#include <isc/print.h> 28#include <isc/random.h> 29#include <isc/result.h> 30#include <isc/string.h> 31#include <isc/thread.h> 32#include <isc/util.h> 33 34#include <dns/compress.h> 35#include <dns/fixedname.h> 36#include <dns/name.h> 37 38#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC) 39 40typedef enum { 41 ft_init = 0, 42 ft_start, 43 ft_ordinary, 44 ft_initialescape, 45 ft_escape, 46 ft_escdecimal, 47 ft_at 48} ft_state; 49 50typedef enum { fw_start = 0, fw_ordinary, fw_newcurrent } fw_state; 51 52static char digitvalue[256] = { 53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ 54 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ 55 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ 56 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ 57 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ 58 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ 59 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ 60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ 61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ 69}; 70 71static unsigned char maptolower[] = { 72 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 73 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 74 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 75 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 76 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 77 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 78 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 79 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 80 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 81 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 82 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 83 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 84 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 85 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 86 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 87 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 88 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 89 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 90 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 91 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 92 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 93 0xfc, 0xfd, 0xfe, 0xff 94}; 95 96#define CONVERTTOASCII(c) 97#define CONVERTFROMASCII(c) 98 99#define INIT_OFFSETS(name, var, default_offsets) \ 100 if ((name)->offsets != NULL) \ 101 var = (name)->offsets; \ 102 else \ 103 var = (default_offsets); 104 105#define SETUP_OFFSETS(name, var, default_offsets) \ 106 if ((name)->offsets != NULL) { \ 107 var = (name)->offsets; \ 108 } else { \ 109 var = (default_offsets); \ 110 set_offsets(name, var, NULL); \ 111 } 112 113/*% 114 * Note: If additional attributes are added that should not be set for 115 * empty names, MAKE_EMPTY() must be changed so it clears them. 116 */ 117#define MAKE_EMPTY(name) \ 118 do { \ 119 name->ndata = NULL; \ 120 name->length = 0; \ 121 name->labels = 0; \ 122 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ 123 } while (0) 124 125/*% 126 * A name is "bindable" if it can be set to point to a new value, i.e. 127 * name->ndata and name->length may be changed. 128 */ 129#define BINDABLE(name) \ 130 ((name->attributes & \ 131 (DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC)) == 0) 132 133/*% 134 * Note that the name data must be a char array, not a string 135 * literal, to avoid compiler warnings about discarding 136 * the const attribute of a string. 137 */ 138static unsigned char root_ndata[] = { "" }; 139static unsigned char root_offsets[] = { 0 }; 140 141static dns_name_t root = DNS_NAME_INITABSOLUTE(root_ndata, root_offsets); 142const dns_name_t *dns_rootname = &root; 143 144static unsigned char wild_ndata[] = { "\001*" }; 145static unsigned char wild_offsets[] = { 0 }; 146 147static dns_name_t const wild = DNS_NAME_INITNONABSOLUTE(wild_ndata, 148 wild_offsets); 149 150const dns_name_t *dns_wildcardname = &wild; 151 152/* 153 * dns_name_t to text post-conversion procedure. 154 */ 155static thread_local dns_name_totextfilter_t *totext_filter_proc = NULL; 156 157static void 158set_offsets(const dns_name_t *name, unsigned char *offsets, 159 dns_name_t *set_name); 160 161void 162dns_name_init(dns_name_t *name, unsigned char *offsets) { 163 /* 164 * Initialize 'name'. 165 */ 166 DNS_NAME_INIT(name, offsets); 167} 168 169void 170dns_name_reset(dns_name_t *name) { 171 REQUIRE(VALID_NAME(name)); 172 REQUIRE(BINDABLE(name)); 173 174 DNS_NAME_RESET(name); 175} 176 177void 178dns_name_invalidate(dns_name_t *name) { 179 /* 180 * Make 'name' invalid. 181 */ 182 183 REQUIRE(VALID_NAME(name)); 184 185 name->magic = 0; 186 name->ndata = NULL; 187 name->length = 0; 188 name->labels = 0; 189 name->attributes = 0; 190 name->offsets = NULL; 191 name->buffer = NULL; 192 ISC_LINK_INIT(name, link); 193 INSIST(name->ht == NULL); 194} 195 196bool 197dns_name_isvalid(const dns_name_t *name) { 198 unsigned char *ndata, *offsets; 199 unsigned int offset, count, length, nlabels; 200 201 if (!VALID_NAME(name)) { 202 return (false); 203 } 204 205 if (name->length > 255U || name->labels > 127U) { 206 return (false); 207 } 208 209 ndata = name->ndata; 210 length = name->length; 211 offsets = name->offsets; 212 offset = 0; 213 nlabels = 0; 214 215 while (offset != length) { 216 count = *ndata; 217 if (count > 63U) { 218 return (false); 219 } 220 if (offsets != NULL && offsets[nlabels] != offset) { 221 return (false); 222 } 223 224 nlabels++; 225 offset += count + 1; 226 ndata += count + 1; 227 if (offset > length) { 228 return (false); 229 } 230 231 if (count == 0) { 232 break; 233 } 234 } 235 236 if (nlabels != name->labels || offset != name->length) { 237 return (false); 238 } 239 240 return (true); 241} 242 243void 244dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) { 245 /* 246 * Dedicate a buffer for use with 'name'. 247 */ 248 249 REQUIRE(VALID_NAME(name)); 250 REQUIRE((buffer != NULL && name->buffer == NULL) || (buffer == NULL)); 251 252 name->buffer = buffer; 253} 254 255bool 256dns_name_hasbuffer(const dns_name_t *name) { 257 /* 258 * Does 'name' have a dedicated buffer? 259 */ 260 261 REQUIRE(VALID_NAME(name)); 262 263 if (name->buffer != NULL) { 264 return (true); 265 } 266 267 return (false); 268} 269 270bool 271dns_name_isabsolute(const dns_name_t *name) { 272 /* 273 * Does 'name' end in the root label? 274 */ 275 276 REQUIRE(VALID_NAME(name)); 277 278 if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 279 return (true); 280 } 281 return (false); 282} 283 284#define hyphenchar(c) ((c) == 0x2d) 285#define asterchar(c) ((c) == 0x2a) 286#define alphachar(c) \ 287 (((c) >= 0x41 && (c) <= 0x5a) || ((c) >= 0x61 && (c) <= 0x7a)) 288#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) 289#define borderchar(c) (alphachar(c) || digitchar(c)) 290#define middlechar(c) (borderchar(c) || hyphenchar(c)) 291#define domainchar(c) ((c) > 0x20 && (c) < 0x7f) 292 293bool 294dns_name_ismailbox(const dns_name_t *name) { 295 unsigned char *ndata, ch; 296 unsigned int n; 297 bool first; 298 299 REQUIRE(VALID_NAME(name)); 300 REQUIRE(name->labels > 0); 301 REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE); 302 303 /* 304 * Root label. 305 */ 306 if (name->length == 1) { 307 return (true); 308 } 309 310 ndata = name->ndata; 311 n = *ndata++; 312 INSIST(n <= 63); 313 while (n--) { 314 ch = *ndata++; 315 if (!domainchar(ch)) { 316 return (false); 317 } 318 } 319 320 if (ndata == name->ndata + name->length) { 321 return (false); 322 } 323 324 /* 325 * RFC952/RFC1123 hostname. 326 */ 327 while (ndata < (name->ndata + name->length)) { 328 n = *ndata++; 329 INSIST(n <= 63); 330 first = true; 331 while (n--) { 332 ch = *ndata++; 333 if (first || n == 0) { 334 if (!borderchar(ch)) { 335 return (false); 336 } 337 } else { 338 if (!middlechar(ch)) { 339 return (false); 340 } 341 } 342 first = false; 343 } 344 } 345 return (true); 346} 347 348bool 349dns_name_ishostname(const dns_name_t *name, bool wildcard) { 350 unsigned char *ndata, ch; 351 unsigned int n; 352 bool first; 353 354 REQUIRE(VALID_NAME(name)); 355 REQUIRE(name->labels > 0); 356 REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE); 357 358 /* 359 * Root label. 360 */ 361 if (name->length == 1) { 362 return (true); 363 } 364 365 /* 366 * Skip wildcard if this is a ownername. 367 */ 368 ndata = name->ndata; 369 if (wildcard && ndata[0] == 1 && ndata[1] == '*') { 370 ndata += 2; 371 } 372 373 /* 374 * RFC952/RFC1123 hostname. 375 */ 376 while (ndata < (name->ndata + name->length)) { 377 n = *ndata++; 378 INSIST(n <= 63); 379 first = true; 380 while (n--) { 381 ch = *ndata++; 382 if (first || n == 0) { 383 if (!borderchar(ch)) { 384 return (false); 385 } 386 } else { 387 if (!middlechar(ch)) { 388 return (false); 389 } 390 } 391 first = false; 392 } 393 } 394 return (true); 395} 396 397bool 398dns_name_iswildcard(const dns_name_t *name) { 399 unsigned char *ndata; 400 401 /* 402 * Is 'name' a wildcard name? 403 */ 404 405 REQUIRE(VALID_NAME(name)); 406 REQUIRE(name->labels > 0); 407 408 if (name->length >= 2) { 409 ndata = name->ndata; 410 if (ndata[0] == 1 && ndata[1] == '*') { 411 return (true); 412 } 413 } 414 415 return (false); 416} 417 418bool 419dns_name_internalwildcard(const dns_name_t *name) { 420 unsigned char *ndata; 421 unsigned int count; 422 unsigned int label; 423 424 /* 425 * Does 'name' contain a internal wildcard? 426 */ 427 428 REQUIRE(VALID_NAME(name)); 429 REQUIRE(name->labels > 0); 430 431 /* 432 * Skip first label. 433 */ 434 ndata = name->ndata; 435 count = *ndata++; 436 INSIST(count <= 63); 437 ndata += count; 438 label = 1; 439 /* 440 * Check all but the last of the remaining labels. 441 */ 442 while (label + 1 < name->labels) { 443 count = *ndata++; 444 INSIST(count <= 63); 445 if (count == 1 && *ndata == '*') { 446 return (true); 447 } 448 ndata += count; 449 label++; 450 } 451 return (false); 452} 453 454unsigned int 455dns_name_hash(const dns_name_t *name, bool case_sensitive) { 456 unsigned int length; 457 458 /* 459 * Provide a hash value for 'name'. 460 */ 461 REQUIRE(VALID_NAME(name)); 462 463 if (name->labels == 0) { 464 return (0); 465 } 466 467 length = name->length; 468 if (length > 16) { 469 length = 16; 470 } 471 472 /* High bits are more random. */ 473 return (isc_hash32(name->ndata, length, case_sensitive)); 474} 475 476unsigned int 477dns_name_fullhash(const dns_name_t *name, bool case_sensitive) { 478 /* 479 * Provide a hash value for 'name'. 480 */ 481 REQUIRE(VALID_NAME(name)); 482 483 if (name->labels == 0) { 484 return (0); 485 } 486 487 /* High bits are more random. */ 488 return (isc_hash32(name->ndata, name->length, case_sensitive)); 489} 490 491dns_namereln_t 492dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, 493 int *orderp, unsigned int *nlabelsp) { 494 unsigned int l1, l2, l, count1, count2, count, nlabels; 495 int cdiff, ldiff, chdiff; 496 unsigned char *label1, *label2; 497 unsigned char *offsets1, *offsets2; 498 dns_offsets_t odata1, odata2; 499 dns_namereln_t namereln = dns_namereln_none; 500 501 /* 502 * Determine the relative ordering under the DNSSEC order relation of 503 * 'name1' and 'name2', and also determine the hierarchical 504 * relationship of the names. 505 * 506 * Note: It makes no sense for one of the names to be relative and the 507 * other absolute. If both names are relative, then to be meaningfully 508 * compared the caller must ensure that they are both relative to the 509 * same domain. 510 */ 511 512 REQUIRE(VALID_NAME(name1)); 513 REQUIRE(VALID_NAME(name2)); 514 REQUIRE(orderp != NULL); 515 REQUIRE(nlabelsp != NULL); 516 /* 517 * Either name1 is absolute and name2 is absolute, or neither is. 518 */ 519 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == 520 (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); 521 522 if (name1 == name2) { 523 *orderp = 0; 524 *nlabelsp = name1->labels; 525 return (dns_namereln_equal); 526 } 527 528 SETUP_OFFSETS(name1, offsets1, odata1); 529 SETUP_OFFSETS(name2, offsets2, odata2); 530 531 nlabels = 0; 532 l1 = name1->labels; 533 l2 = name2->labels; 534 if (l2 > l1) { 535 l = l1; 536 ldiff = 0 - (l2 - l1); 537 } else { 538 l = l2; 539 ldiff = l1 - l2; 540 } 541 542 offsets1 += l1; 543 offsets2 += l2; 544 545 while (l > 0) { 546 l--; 547 offsets1--; 548 offsets2--; 549 label1 = &name1->ndata[*offsets1]; 550 label2 = &name2->ndata[*offsets2]; 551 count1 = *label1++; 552 count2 = *label2++; 553 554 /* 555 * We dropped bitstring labels, and we don't support any 556 * other extended label types. 557 */ 558 INSIST(count1 <= 63 && count2 <= 63); 559 560 cdiff = (int)count1 - (int)count2; 561 if (cdiff < 0) { 562 count = count1; 563 } else { 564 count = count2; 565 } 566 567 /* Loop unrolled for performance */ 568 while (count > 3) { 569 chdiff = (int)maptolower[label1[0]] - 570 (int)maptolower[label2[0]]; 571 if (chdiff != 0) { 572 *orderp = chdiff; 573 goto done; 574 } 575 chdiff = (int)maptolower[label1[1]] - 576 (int)maptolower[label2[1]]; 577 if (chdiff != 0) { 578 *orderp = chdiff; 579 goto done; 580 } 581 chdiff = (int)maptolower[label1[2]] - 582 (int)maptolower[label2[2]]; 583 if (chdiff != 0) { 584 *orderp = chdiff; 585 goto done; 586 } 587 chdiff = (int)maptolower[label1[3]] - 588 (int)maptolower[label2[3]]; 589 if (chdiff != 0) { 590 *orderp = chdiff; 591 goto done; 592 } 593 count -= 4; 594 label1 += 4; 595 label2 += 4; 596 } 597 while (count-- > 0) { 598 chdiff = (int)maptolower[*label1++] - 599 (int)maptolower[*label2++]; 600 if (chdiff != 0) { 601 *orderp = chdiff; 602 goto done; 603 } 604 } 605 if (cdiff != 0) { 606 *orderp = cdiff; 607 goto done; 608 } 609 nlabels++; 610 } 611 612 *orderp = ldiff; 613 if (ldiff < 0) { 614 namereln = dns_namereln_contains; 615 } else if (ldiff > 0) { 616 namereln = dns_namereln_subdomain; 617 } else { 618 namereln = dns_namereln_equal; 619 } 620 *nlabelsp = nlabels; 621 return (namereln); 622 623done: 624 *nlabelsp = nlabels; 625 if (nlabels > 0) { 626 namereln = dns_namereln_commonancestor; 627 } 628 629 return (namereln); 630} 631 632int 633dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) { 634 int order; 635 unsigned int nlabels; 636 637 /* 638 * Determine the relative ordering under the DNSSEC order relation of 639 * 'name1' and 'name2'. 640 * 641 * Note: It makes no sense for one of the names to be relative and the 642 * other absolute. If both names are relative, then to be meaningfully 643 * compared the caller must ensure that they are both relative to the 644 * same domain. 645 */ 646 647 (void)dns_name_fullcompare(name1, name2, &order, &nlabels); 648 649 return (order); 650} 651 652bool 653dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { 654 unsigned int l, count; 655 unsigned char c; 656 unsigned char *label1, *label2; 657 658 /* 659 * Are 'name1' and 'name2' equal? 660 * 661 * Note: It makes no sense for one of the names to be relative and the 662 * other absolute. If both names are relative, then to be meaningfully 663 * compared the caller must ensure that they are both relative to the 664 * same domain. 665 */ 666 667 REQUIRE(VALID_NAME(name1)); 668 REQUIRE(VALID_NAME(name2)); 669 /* 670 * Either name1 is absolute and name2 is absolute, or neither is. 671 */ 672 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == 673 (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); 674 675 if (name1 == name2) { 676 return (true); 677 } 678 679 if (name1->length != name2->length) { 680 return (false); 681 } 682 683 l = name1->labels; 684 685 if (l != name2->labels) { 686 return (false); 687 } 688 689 label1 = name1->ndata; 690 label2 = name2->ndata; 691 while (l-- > 0) { 692 count = *label1++; 693 if (count != *label2++) { 694 return (false); 695 } 696 697 INSIST(count <= 63); /* no bitstring support */ 698 699 /* Loop unrolled for performance */ 700 while (count > 3) { 701 c = maptolower[label1[0]]; 702 if (c != maptolower[label2[0]]) { 703 return (false); 704 } 705 c = maptolower[label1[1]]; 706 if (c != maptolower[label2[1]]) { 707 return (false); 708 } 709 c = maptolower[label1[2]]; 710 if (c != maptolower[label2[2]]) { 711 return (false); 712 } 713 c = maptolower[label1[3]]; 714 if (c != maptolower[label2[3]]) { 715 return (false); 716 } 717 count -= 4; 718 label1 += 4; 719 label2 += 4; 720 } 721 while (count-- > 0) { 722 c = maptolower[*label1++]; 723 if (c != maptolower[*label2++]) { 724 return (false); 725 } 726 } 727 } 728 729 return (true); 730} 731 732bool 733dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) { 734 /* 735 * Are 'name1' and 'name2' equal? 736 * 737 * Note: It makes no sense for one of the names to be relative and the 738 * other absolute. If both names are relative, then to be meaningfully 739 * compared the caller must ensure that they are both relative to the 740 * same domain. 741 */ 742 743 REQUIRE(VALID_NAME(name1)); 744 REQUIRE(VALID_NAME(name2)); 745 /* 746 * Either name1 is absolute and name2 is absolute, or neither is. 747 */ 748 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == 749 (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); 750 751 if (name1->length != name2->length) { 752 return (false); 753 } 754 755 if (memcmp(name1->ndata, name2->ndata, name1->length) != 0) { 756 return (false); 757 } 758 759 return (true); 760} 761 762int 763dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) { 764 unsigned int l1, l2, l, count1, count2, count; 765 unsigned char c1, c2; 766 unsigned char *label1, *label2; 767 768 /* 769 * Compare two absolute names as rdata. 770 */ 771 772 REQUIRE(VALID_NAME(name1)); 773 REQUIRE(name1->labels > 0); 774 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); 775 REQUIRE(VALID_NAME(name2)); 776 REQUIRE(name2->labels > 0); 777 REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); 778 779 l1 = name1->labels; 780 l2 = name2->labels; 781 782 l = (l1 < l2) ? l1 : l2; 783 784 label1 = name1->ndata; 785 label2 = name2->ndata; 786 while (l > 0) { 787 l--; 788 count1 = *label1++; 789 count2 = *label2++; 790 791 /* no bitstring support */ 792 INSIST(count1 <= 63 && count2 <= 63); 793 794 if (count1 != count2) { 795 return ((count1 < count2) ? -1 : 1); 796 } 797 count = count1; 798 while (count > 0) { 799 count--; 800 c1 = maptolower[*label1++]; 801 c2 = maptolower[*label2++]; 802 if (c1 < c2) { 803 return (-1); 804 } else if (c1 > c2) { 805 return (1); 806 } 807 } 808 } 809 810 /* 811 * If one name had more labels than the other, their common 812 * prefix must have been different because the shorter name 813 * ended with the root label and the longer one can't have 814 * a root label in the middle of it. Therefore, if we get 815 * to this point, the lengths must be equal. 816 */ 817 INSIST(l1 == l2); 818 819 return (0); 820} 821 822bool 823dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) { 824 int order; 825 unsigned int nlabels; 826 dns_namereln_t namereln; 827 828 /* 829 * Is 'name1' a subdomain of 'name2'? 830 * 831 * Note: It makes no sense for one of the names to be relative and the 832 * other absolute. If both names are relative, then to be meaningfully 833 * compared the caller must ensure that they are both relative to the 834 * same domain. 835 */ 836 837 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); 838 if (namereln == dns_namereln_subdomain || 839 namereln == dns_namereln_equal) 840 { 841 return (true); 842 } 843 844 return (false); 845} 846 847bool 848dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) { 849 int order; 850 unsigned int nlabels, labels; 851 dns_name_t tname; 852 853 REQUIRE(VALID_NAME(name)); 854 REQUIRE(name->labels > 0); 855 REQUIRE(VALID_NAME(wname)); 856 labels = wname->labels; 857 REQUIRE(labels > 0); 858 REQUIRE(dns_name_iswildcard(wname)); 859 860 DNS_NAME_INIT(&tname, NULL); 861 dns_name_getlabelsequence(wname, 1, labels - 1, &tname); 862 if (dns_name_fullcompare(name, &tname, &order, &nlabels) == 863 dns_namereln_subdomain) 864 { 865 return (true); 866 } 867 return (false); 868} 869 870unsigned int 871dns_name_countlabels(const dns_name_t *name) { 872 /* 873 * How many labels does 'name' have? 874 */ 875 876 REQUIRE(VALID_NAME(name)); 877 878 ENSURE(name->labels <= 128); 879 880 return (name->labels); 881} 882 883void 884dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) { 885 unsigned char *offsets; 886 dns_offsets_t odata; 887 888 /* 889 * Make 'label' refer to the 'n'th least significant label of 'name'. 890 */ 891 892 REQUIRE(VALID_NAME(name)); 893 REQUIRE(name->labels > 0); 894 REQUIRE(n < name->labels); 895 REQUIRE(label != NULL); 896 897 SETUP_OFFSETS(name, offsets, odata); 898 899 label->base = &name->ndata[offsets[n]]; 900 if (n == name->labels - 1) { 901 label->length = name->length - offsets[n]; 902 } else { 903 label->length = offsets[n + 1] - offsets[n]; 904 } 905} 906 907void 908dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, 909 unsigned int n, dns_name_t *target) { 910 unsigned char *p, l; 911 unsigned int firstoffset, endoffset; 912 unsigned int i; 913 914 /* 915 * Make 'target' refer to the 'n' labels including and following 916 * 'first' in 'source'. 917 */ 918 919 REQUIRE(VALID_NAME(source)); 920 REQUIRE(VALID_NAME(target)); 921 REQUIRE(first <= source->labels); 922 REQUIRE(n <= source->labels - first); /* note first+n could overflow */ 923 REQUIRE(BINDABLE(target)); 924 925 p = source->ndata; 926 if (first == source->labels) { 927 firstoffset = source->length; 928 } else { 929 for (i = 0; i < first; i++) { 930 l = *p; 931 p += l + 1; 932 } 933 firstoffset = (unsigned int)(p - source->ndata); 934 } 935 936 if (first + n == source->labels) { 937 endoffset = source->length; 938 } else { 939 for (i = 0; i < n; i++) { 940 l = *p; 941 p += l + 1; 942 } 943 endoffset = (unsigned int)(p - source->ndata); 944 } 945 946 target->ndata = &source->ndata[firstoffset]; 947 target->length = endoffset - firstoffset; 948 949 if (first + n == source->labels && n > 0 && 950 (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) 951 { 952 target->attributes |= DNS_NAMEATTR_ABSOLUTE; 953 } else { 954 target->attributes &= ~DNS_NAMEATTR_ABSOLUTE; 955 } 956 957 target->labels = n; 958 959 /* 960 * If source and target are the same, and we're making target 961 * a prefix of source, the offsets table is correct already 962 * so we don't need to call set_offsets(). 963 */ 964 if (target->offsets != NULL && (target != source || first != 0)) { 965 set_offsets(target, target->offsets, NULL); 966 } 967} 968 969void 970dns_name_clone(const dns_name_t *source, dns_name_t *target) { 971 /* 972 * Make 'target' refer to the same name as 'source'. 973 */ 974 975 REQUIRE(VALID_NAME(source)); 976 REQUIRE(VALID_NAME(target)); 977 REQUIRE(BINDABLE(target)); 978 979 target->ndata = source->ndata; 980 target->length = source->length; 981 target->labels = source->labels; 982 target->attributes = source->attributes & 983 (unsigned int)~(DNS_NAMEATTR_READONLY | 984 DNS_NAMEATTR_DYNAMIC | 985 DNS_NAMEATTR_DYNOFFSETS); 986 if (target->offsets != NULL && source->labels > 0) { 987 if (source->offsets != NULL) { 988 memmove(target->offsets, source->offsets, 989 source->labels); 990 } else { 991 set_offsets(target, target->offsets, NULL); 992 } 993 } 994} 995 996void 997dns_name_fromregion(dns_name_t *name, const isc_region_t *r) { 998 unsigned char *offsets; 999 dns_offsets_t odata; 1000 unsigned int len; 1001 isc_region_t r2; 1002 1003 /* 1004 * Make 'name' refer to region 'r'. 1005 */ 1006 1007 REQUIRE(VALID_NAME(name)); 1008 REQUIRE(r != NULL); 1009 REQUIRE(BINDABLE(name)); 1010 1011 INIT_OFFSETS(name, offsets, odata); 1012 1013 if (name->buffer != NULL) { 1014 isc_buffer_clear(name->buffer); 1015 isc_buffer_availableregion(name->buffer, &r2); 1016 len = (r->length < r2.length) ? r->length : r2.length; 1017 if (len > DNS_NAME_MAXWIRE) { 1018 len = DNS_NAME_MAXWIRE; 1019 } 1020 if (len != 0) { 1021 memmove(r2.base, r->base, len); 1022 } 1023 name->ndata = r2.base; 1024 name->length = len; 1025 } else { 1026 name->ndata = r->base; 1027 name->length = (r->length <= DNS_NAME_MAXWIRE) 1028 ? r->length 1029 : DNS_NAME_MAXWIRE; 1030 } 1031 1032 if (r->length > 0) { 1033 set_offsets(name, offsets, name); 1034 } else { 1035 name->labels = 0; 1036 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; 1037 } 1038 1039 if (name->buffer != NULL) { 1040 isc_buffer_add(name->buffer, name->length); 1041 } 1042} 1043 1044void 1045dns_name_toregion(const dns_name_t *name, isc_region_t *r) { 1046 /* 1047 * Make 'r' refer to 'name'. 1048 */ 1049 1050 REQUIRE(VALID_NAME(name)); 1051 REQUIRE(r != NULL); 1052 1053 DNS_NAME_TOREGION(name, r); 1054} 1055 1056isc_result_t 1057dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, 1058 const dns_name_t *origin, unsigned int options, 1059 isc_buffer_t *target) { 1060 unsigned char *ndata, *label = NULL; 1061 char *tdata; 1062 char c; 1063 ft_state state; 1064 unsigned int value = 0, count = 0; 1065 unsigned int n1 = 0, n2 = 0; 1066 unsigned int tlen, nrem, nused, digits = 0, labels, tused; 1067 bool done; 1068 unsigned char *offsets; 1069 dns_offsets_t odata; 1070 bool downcase; 1071 1072 /* 1073 * Convert the textual representation of a DNS name at source 1074 * into uncompressed wire form stored in target. 1075 * 1076 * Notes: 1077 * Relative domain names will have 'origin' appended to them 1078 * unless 'origin' is NULL, in which case relative domain names 1079 * will remain relative. 1080 */ 1081 1082 REQUIRE(VALID_NAME(name)); 1083 REQUIRE(ISC_BUFFER_VALID(source)); 1084 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || 1085 (target == NULL && ISC_BUFFER_VALID(name->buffer))); 1086 1087 downcase = ((options & DNS_NAME_DOWNCASE) != 0); 1088 1089 if (target == NULL && name->buffer != NULL) { 1090 target = name->buffer; 1091 isc_buffer_clear(target); 1092 } 1093 1094 REQUIRE(BINDABLE(name)); 1095 1096 INIT_OFFSETS(name, offsets, odata); 1097 offsets[0] = 0; 1098 1099 /* 1100 * Make 'name' empty in case of failure. 1101 */ 1102 MAKE_EMPTY(name); 1103 1104 /* 1105 * Set up the state machine. 1106 */ 1107 tdata = (char *)source->base + source->current; 1108 tlen = isc_buffer_remaininglength(source); 1109 tused = 0; 1110 ndata = isc_buffer_used(target); 1111 nrem = isc_buffer_availablelength(target); 1112 if (nrem > 255) { 1113 nrem = 255; 1114 } 1115 nused = 0; 1116 labels = 0; 1117 done = false; 1118 state = ft_init; 1119 1120 while (nrem > 0 && tlen > 0 && !done) { 1121 c = *tdata++; 1122 tlen--; 1123 tused++; 1124 1125 switch (state) { 1126 case ft_init: 1127 /* 1128 * Is this the root name? 1129 */ 1130 if (c == '.') { 1131 if (tlen != 0) { 1132 return (DNS_R_EMPTYLABEL); 1133 } 1134 labels++; 1135 *ndata++ = 0; 1136 nrem--; 1137 nused++; 1138 done = true; 1139 break; 1140 } 1141 if (c == '@' && tlen == 0) { 1142 state = ft_at; 1143 break; 1144 } 1145 1146 FALLTHROUGH; 1147 case ft_start: 1148 label = ndata; 1149 ndata++; 1150 nrem--; 1151 nused++; 1152 count = 0; 1153 if (c == '\\') { 1154 state = ft_initialescape; 1155 break; 1156 } 1157 state = ft_ordinary; 1158 if (nrem == 0) { 1159 return (ISC_R_NOSPACE); 1160 } 1161 FALLTHROUGH; 1162 case ft_ordinary: 1163 if (c == '.') { 1164 if (count == 0) { 1165 return (DNS_R_EMPTYLABEL); 1166 } 1167 *label = count; 1168 labels++; 1169 INSIST(labels <= 127); 1170 offsets[labels] = nused; 1171 if (tlen == 0) { 1172 labels++; 1173 *ndata++ = 0; 1174 nrem--; 1175 nused++; 1176 done = true; 1177 } 1178 state = ft_start; 1179 } else if (c == '\\') { 1180 state = ft_escape; 1181 } else { 1182 if (count >= 63) { 1183 return (DNS_R_LABELTOOLONG); 1184 } 1185 count++; 1186 CONVERTTOASCII(c); 1187 if (downcase) { 1188 c = maptolower[c & 0xff]; 1189 } 1190 *ndata++ = c; 1191 nrem--; 1192 nused++; 1193 } 1194 break; 1195 case ft_initialescape: 1196 if (c == '[') { 1197 /* 1198 * This looks like a bitstring label, which 1199 * was deprecated. Intentionally drop it. 1200 */ 1201 return (DNS_R_BADLABELTYPE); 1202 } 1203 state = ft_escape; 1204 POST(state); 1205 FALLTHROUGH; 1206 case ft_escape: 1207 if (!isdigit((unsigned char)c)) { 1208 if (count >= 63) { 1209 return (DNS_R_LABELTOOLONG); 1210 } 1211 count++; 1212 CONVERTTOASCII(c); 1213 if (downcase) { 1214 c = maptolower[c & 0xff]; 1215 } 1216 *ndata++ = c; 1217 nrem--; 1218 nused++; 1219 state = ft_ordinary; 1220 break; 1221 } 1222 digits = 0; 1223 value = 0; 1224 state = ft_escdecimal; 1225 FALLTHROUGH; 1226 case ft_escdecimal: 1227 if (!isdigit((unsigned char)c)) { 1228 return (DNS_R_BADESCAPE); 1229 } 1230 value *= 10; 1231 value += digitvalue[c & 0xff]; 1232 digits++; 1233 if (digits == 3) { 1234 if (value > 255) { 1235 return (DNS_R_BADESCAPE); 1236 } 1237 if (count >= 63) { 1238 return (DNS_R_LABELTOOLONG); 1239 } 1240 count++; 1241 if (downcase) { 1242 value = maptolower[value]; 1243 } 1244 *ndata++ = value; 1245 nrem--; 1246 nused++; 1247 state = ft_ordinary; 1248 } 1249 break; 1250 default: 1251 FATAL_ERROR("Unexpected state %d", state); 1252 /* Does not return. */ 1253 } 1254 } 1255 1256 if (!done) { 1257 if (nrem == 0) { 1258 return (ISC_R_NOSPACE); 1259 } 1260 INSIST(tlen == 0); 1261 if (state != ft_ordinary && state != ft_at) { 1262 return (ISC_R_UNEXPECTEDEND); 1263 } 1264 if (state == ft_ordinary) { 1265 INSIST(count != 0); 1266 INSIST(label != NULL); 1267 *label = count; 1268 labels++; 1269 INSIST(labels <= 127); 1270 offsets[labels] = nused; 1271 } 1272 if (origin != NULL) { 1273 if (nrem < origin->length) { 1274 return (ISC_R_NOSPACE); 1275 } 1276 label = origin->ndata; 1277 n1 = origin->length; 1278 nrem -= n1; 1279 POST(nrem); 1280 while (n1 > 0) { 1281 n2 = *label++; 1282 INSIST(n2 <= 63); /* no bitstring support */ 1283 *ndata++ = n2; 1284 n1 -= n2 + 1; 1285 nused += n2 + 1; 1286 while (n2 > 0) { 1287 c = *label++; 1288 if (downcase) { 1289 c = maptolower[c & 0xff]; 1290 } 1291 *ndata++ = c; 1292 n2--; 1293 } 1294 labels++; 1295 if (n1 > 0) { 1296 INSIST(labels <= 127); 1297 offsets[labels] = nused; 1298 } 1299 } 1300 if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 1301 name->attributes |= DNS_NAMEATTR_ABSOLUTE; 1302 } 1303 } 1304 } else { 1305 name->attributes |= DNS_NAMEATTR_ABSOLUTE; 1306 } 1307 1308 name->ndata = (unsigned char *)target->base + target->used; 1309 name->labels = labels; 1310 name->length = nused; 1311 1312 isc_buffer_forward(source, tused); 1313 isc_buffer_add(target, name->length); 1314 1315 return (ISC_R_SUCCESS); 1316} 1317 1318isc_result_t 1319dns_name_totext(const dns_name_t *name, bool omit_final_dot, 1320 isc_buffer_t *target) { 1321 unsigned int options = DNS_NAME_MASTERFILE; 1322 1323 if (omit_final_dot) { 1324 options |= DNS_NAME_OMITFINALDOT; 1325 } 1326 return (dns_name_totext2(name, options, target)); 1327} 1328 1329isc_result_t 1330dns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target) { 1331 return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target)); 1332} 1333 1334isc_result_t 1335dns_name_totext2(const dns_name_t *name, unsigned int options, 1336 isc_buffer_t *target) { 1337 unsigned char *ndata; 1338 char *tdata; 1339 unsigned int nlen, tlen; 1340 unsigned char c; 1341 unsigned int trem, count; 1342 unsigned int labels; 1343 bool saw_root = false; 1344 unsigned int oused; 1345 bool omit_final_dot = ((options & DNS_NAME_OMITFINALDOT) != 0); 1346 1347 /* 1348 * This function assumes the name is in proper uncompressed 1349 * wire format. 1350 */ 1351 REQUIRE(VALID_NAME(name)); 1352 REQUIRE(ISC_BUFFER_VALID(target)); 1353 1354 oused = target->used; 1355 1356 ndata = name->ndata; 1357 nlen = name->length; 1358 labels = name->labels; 1359 tdata = isc_buffer_used(target); 1360 tlen = isc_buffer_availablelength(target); 1361 1362 trem = tlen; 1363 1364 if (labels == 0 && nlen == 0) { 1365 /* 1366 * Special handling for an empty name. 1367 */ 1368 if (trem == 0) { 1369 return (ISC_R_NOSPACE); 1370 } 1371 1372 /* 1373 * The names of these booleans are misleading in this case. 1374 * This empty name is not necessarily from the root node of 1375 * the DNS root zone, nor is a final dot going to be included. 1376 * They need to be set this way, though, to keep the "@" 1377 * from being trounced. 1378 */ 1379 saw_root = true; 1380 omit_final_dot = false; 1381 *tdata++ = '@'; 1382 trem--; 1383 1384 /* 1385 * Skip the while() loop. 1386 */ 1387 nlen = 0; 1388 } else if (nlen == 1 && labels == 1 && *ndata == '\0') { 1389 /* 1390 * Special handling for the root label. 1391 */ 1392 if (trem == 0) { 1393 return (ISC_R_NOSPACE); 1394 } 1395 1396 saw_root = true; 1397 omit_final_dot = false; 1398 *tdata++ = '.'; 1399 trem--; 1400 1401 /* 1402 * Skip the while() loop. 1403 */ 1404 nlen = 0; 1405 } 1406 1407 while (labels > 0 && nlen > 0 && trem > 0) { 1408 labels--; 1409 count = *ndata++; 1410 nlen--; 1411 if (count == 0) { 1412 saw_root = true; 1413 break; 1414 } 1415 if (count < 64) { 1416 INSIST(nlen >= count); 1417 while (count > 0) { 1418 c = *ndata; 1419 switch (c) { 1420 /* Special modifiers in zone files. */ 1421 case 0x40: /* '@' */ 1422 case 0x24: /* '$' */ 1423 if ((options & DNS_NAME_MASTERFILE) == 1424 0) 1425 { 1426 goto no_escape; 1427 } 1428 FALLTHROUGH; 1429 case 0x22: /* '"' */ 1430 case 0x28: /* '(' */ 1431 case 0x29: /* ')' */ 1432 case 0x2E: /* '.' */ 1433 case 0x3B: /* ';' */ 1434 case 0x5C: /* '\\' */ 1435 if (trem < 2) { 1436 return (ISC_R_NOSPACE); 1437 } 1438 *tdata++ = '\\'; 1439 CONVERTFROMASCII(c); 1440 *tdata++ = c; 1441 ndata++; 1442 trem -= 2; 1443 nlen--; 1444 break; 1445 no_escape: 1446 default: 1447 if (c > 0x20 && c < 0x7f) { 1448 if (trem == 0) { 1449 return (ISC_R_NOSPACE); 1450 } 1451 CONVERTFROMASCII(c); 1452 *tdata++ = c; 1453 ndata++; 1454 trem--; 1455 nlen--; 1456 } else { 1457 if (trem < 4) { 1458 return (ISC_R_NOSPACE); 1459 } 1460 *tdata++ = 0x5c; 1461 *tdata++ = 0x30 + 1462 ((c / 100) % 10); 1463 *tdata++ = 0x30 + 1464 ((c / 10) % 10); 1465 *tdata++ = 0x30 + (c % 10); 1466 trem -= 4; 1467 ndata++; 1468 nlen--; 1469 } 1470 } 1471 count--; 1472 } 1473 } else { 1474 FATAL_ERROR("Unexpected label type %02x", count); 1475 UNREACHABLE(); 1476 } 1477 1478 /* 1479 * The following assumes names are absolute. If not, we 1480 * fix things up later. Note that this means that in some 1481 * cases one more byte of text buffer is required than is 1482 * needed in the final output. 1483 */ 1484 if (trem == 0) { 1485 return (ISC_R_NOSPACE); 1486 } 1487 *tdata++ = '.'; 1488 trem--; 1489 } 1490 1491 if (nlen != 0 && trem == 0) { 1492 return (ISC_R_NOSPACE); 1493 } 1494 1495 if (!saw_root || omit_final_dot) { 1496 trem++; 1497 tdata--; 1498 } 1499 if (trem > 0) { 1500 *tdata = 0; 1501 } 1502 isc_buffer_add(target, tlen - trem); 1503 1504 if (totext_filter_proc != NULL) { 1505 return ((totext_filter_proc)(target, oused)); 1506 } 1507 1508 return (ISC_R_SUCCESS); 1509} 1510 1511isc_result_t 1512dns_name_tofilenametext(const dns_name_t *name, bool omit_final_dot, 1513 isc_buffer_t *target) { 1514 unsigned char *ndata; 1515 char *tdata; 1516 unsigned int nlen, tlen; 1517 unsigned char c; 1518 unsigned int trem, count; 1519 unsigned int labels; 1520 1521 /* 1522 * This function assumes the name is in proper uncompressed 1523 * wire format. 1524 */ 1525 REQUIRE(VALID_NAME(name)); 1526 REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); 1527 REQUIRE(ISC_BUFFER_VALID(target)); 1528 1529 ndata = name->ndata; 1530 nlen = name->length; 1531 labels = name->labels; 1532 tdata = isc_buffer_used(target); 1533 tlen = isc_buffer_availablelength(target); 1534 1535 trem = tlen; 1536 1537 if (nlen == 1 && labels == 1 && *ndata == '\0') { 1538 /* 1539 * Special handling for the root label. 1540 */ 1541 if (trem == 0) { 1542 return (ISC_R_NOSPACE); 1543 } 1544 1545 omit_final_dot = false; 1546 *tdata++ = '.'; 1547 trem--; 1548 1549 /* 1550 * Skip the while() loop. 1551 */ 1552 nlen = 0; 1553 } 1554 1555 while (labels > 0 && nlen > 0 && trem > 0) { 1556 labels--; 1557 count = *ndata++; 1558 nlen--; 1559 if (count == 0) { 1560 break; 1561 } 1562 if (count < 64) { 1563 INSIST(nlen >= count); 1564 while (count > 0) { 1565 c = *ndata; 1566 if ((c >= 0x30 && c <= 0x39) || /* digit */ 1567 (c >= 0x41 && c <= 0x5A) || /* uppercase */ 1568 (c >= 0x61 && c <= 0x7A) || /* lowercase */ 1569 c == 0x2D || /* hyphen */ 1570 c == 0x5F) /* underscore */ 1571 { 1572 if (trem == 0) { 1573 return (ISC_R_NOSPACE); 1574 } 1575 /* downcase */ 1576 if (c >= 0x41 && c <= 0x5A) { 1577 c += 0x20; 1578 } 1579 CONVERTFROMASCII(c); 1580 *tdata++ = c; 1581 ndata++; 1582 trem--; 1583 nlen--; 1584 } else { 1585 if (trem < 4) { 1586 return (ISC_R_NOSPACE); 1587 } 1588 snprintf(tdata, trem, "%%%02X", c); 1589 tdata += 3; 1590 trem -= 3; 1591 ndata++; 1592 nlen--; 1593 } 1594 count--; 1595 } 1596 } else { 1597 FATAL_ERROR("Unexpected label type %02x", count); 1598 UNREACHABLE(); 1599 } 1600 1601 /* 1602 * The following assumes names are absolute. If not, we 1603 * fix things up later. Note that this means that in some 1604 * cases one more byte of text buffer is required than is 1605 * needed in the final output. 1606 */ 1607 if (trem == 0) { 1608 return (ISC_R_NOSPACE); 1609 } 1610 *tdata++ = '.'; 1611 trem--; 1612 } 1613 1614 if (nlen != 0 && trem == 0) { 1615 return (ISC_R_NOSPACE); 1616 } 1617 1618 if (omit_final_dot) { 1619 trem++; 1620 } 1621 1622 isc_buffer_add(target, tlen - trem); 1623 1624 return (ISC_R_SUCCESS); 1625} 1626 1627isc_result_t 1628dns_name_downcase(const dns_name_t *source, dns_name_t *name, 1629 isc_buffer_t *target) { 1630 unsigned char *sndata, *ndata; 1631 unsigned int nlen, count, labels; 1632 isc_buffer_t buffer; 1633 1634 /* 1635 * Downcase 'source'. 1636 */ 1637 1638 REQUIRE(VALID_NAME(source)); 1639 REQUIRE(VALID_NAME(name)); 1640 if (source == name) { 1641 REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0); 1642 isc_buffer_init(&buffer, source->ndata, source->length); 1643 target = &buffer; 1644 ndata = source->ndata; 1645 } else { 1646 REQUIRE(BINDABLE(name)); 1647 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || 1648 (target == NULL && ISC_BUFFER_VALID(name->buffer))); 1649 if (target == NULL) { 1650 target = name->buffer; 1651 isc_buffer_clear(name->buffer); 1652 } 1653 ndata = (unsigned char *)target->base + target->used; 1654 name->ndata = ndata; 1655 } 1656 1657 sndata = source->ndata; 1658 nlen = source->length; 1659 labels = source->labels; 1660 1661 if (nlen > (target->length - target->used)) { 1662 MAKE_EMPTY(name); 1663 return (ISC_R_NOSPACE); 1664 } 1665 1666 while (labels > 0 && nlen > 0) { 1667 labels--; 1668 count = *sndata++; 1669 *ndata++ = count; 1670 nlen--; 1671 if (count < 64) { 1672 INSIST(nlen >= count); 1673 while (count > 0) { 1674 *ndata++ = maptolower[(*sndata++)]; 1675 nlen--; 1676 count--; 1677 } 1678 } else { 1679 FATAL_ERROR("Unexpected label type %02x", count); 1680 /* Does not return. */ 1681 } 1682 } 1683 1684 if (source != name) { 1685 name->labels = source->labels; 1686 name->length = source->length; 1687 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 1688 name->attributes = DNS_NAMEATTR_ABSOLUTE; 1689 } else { 1690 name->attributes = 0; 1691 } 1692 if (name->labels > 0 && name->offsets != NULL) { 1693 set_offsets(name, name->offsets, NULL); 1694 } 1695 } 1696 1697 isc_buffer_add(target, name->length); 1698 1699 return (ISC_R_SUCCESS); 1700} 1701 1702static void 1703set_offsets(const dns_name_t *name, unsigned char *offsets, 1704 dns_name_t *set_name) { 1705 unsigned int offset, count, length, nlabels; 1706 unsigned char *ndata; 1707 bool absolute; 1708 1709 ndata = name->ndata; 1710 length = name->length; 1711 offset = 0; 1712 nlabels = 0; 1713 absolute = false; 1714 while (offset != length) { 1715 INSIST(nlabels < 128); 1716 offsets[nlabels++] = offset; 1717 count = *ndata; 1718 INSIST(count <= 63); 1719 offset += count + 1; 1720 ndata += count + 1; 1721 INSIST(offset <= length); 1722 if (count == 0) { 1723 absolute = true; 1724 break; 1725 } 1726 } 1727 if (set_name != NULL) { 1728 INSIST(set_name == name); 1729 1730 set_name->labels = nlabels; 1731 set_name->length = offset; 1732 if (absolute) { 1733 set_name->attributes |= DNS_NAMEATTR_ABSOLUTE; 1734 } else { 1735 set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; 1736 } 1737 } 1738 INSIST(nlabels == name->labels); 1739 INSIST(offset == name->length); 1740} 1741 1742isc_result_t 1743dns_name_fromwire(dns_name_t *const name, isc_buffer_t *const source, 1744 dns_decompress_t *const dctx, unsigned int options, 1745 isc_buffer_t *target) { 1746 /* 1747 * Copy the name at source into target, decompressing it. 1748 * 1749 * *** WARNING *** 1750 * 1751 * dns_name_fromwire() deals with raw network data. An error in this 1752 * routine could result in the failure or hijacking of the server. 1753 * 1754 * The description of name compression in RFC 1035 section 4.1.4 is 1755 * subtle wrt certain edge cases. The first important sentence is: 1756 * 1757 * > In this scheme, an entire domain name or a list of labels at the 1758 * > end of a domain name is replaced with a pointer to a prior 1759 * > occurance of the same name. 1760 * 1761 * The key word is "prior". This says that compression pointers must 1762 * point strictly earlier in the message (before our "marker" variable), 1763 * which is enough to prevent DoS attacks due to compression loops. 1764 * 1765 * The next important sentence is: 1766 * 1767 * > If a domain name is contained in a part of the message subject to a 1768 * > length field (such as the RDATA section of an RR), and compression 1769 * > is used, the length of the compressed name is used in the length 1770 * > calculation, rather than the length of the expanded name. 1771 * 1772 * When decompressing, this means that the amount of the source buffer 1773 * that we consumed (which is checked wrt the container's length field) 1774 * is the length of the compressed name. A compressed name is defined as 1775 * a sequence of labels ending with the root label or a compression 1776 * pointer, that is, the segment of the name that dns_name_fromwire() 1777 * examines first. 1778 * 1779 * This matters when handling names that play dirty tricks, like: 1780 * 1781 * +---+---+---+---+---+---+ 1782 * | 4 | 1 |'a'|192| 0 | 0 | 1783 * +---+---+---+---+---+---+ 1784 * 1785 * We start at octet 1. There is an ordinary single character label "a", 1786 * followed by a compression pointer that refers back to octet zero. 1787 * Here there is a label of length 4, which weirdly re-uses the octets 1788 * we already examined as the data for the label. It is followed by the 1789 * root label, 1790 * 1791 * The specification says that the compressed name ends after the first 1792 * zero octet (after the compression pointer) not the second zero octet, 1793 * even though the second octet is later in the message. This shows the 1794 * correct way to set our "consumed" variable. 1795 */ 1796 1797 REQUIRE((options & DNS_NAME_DOWNCASE) == 0); 1798 REQUIRE(VALID_NAME(name)); 1799 REQUIRE(BINDABLE(name)); 1800 REQUIRE(dctx != NULL); 1801 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || 1802 (target == NULL && ISC_BUFFER_VALID(name->buffer))); 1803 1804 if (target == NULL && name->buffer != NULL) { 1805 target = name->buffer; 1806 isc_buffer_clear(target); 1807 } 1808 1809 uint8_t *const name_buf = isc_buffer_used(target); 1810 const uint32_t name_max = ISC_MIN(DNS_NAME_MAXWIRE, 1811 isc_buffer_availablelength(target)); 1812 uint32_t name_len = 0; 1813 MAKE_EMPTY(name); /* in case of failure */ 1814 1815 dns_offsets_t odata; 1816 uint8_t *offsets = NULL; 1817 uint32_t labels = 0; 1818 INIT_OFFSETS(name, offsets, odata); 1819 1820 /* 1821 * After chasing a compression pointer, these variables refer to the 1822 * source buffer as follows: 1823 * 1824 * sb --- mr --- cr --- st --- cd --- sm 1825 * 1826 * sb = source_buf (const) 1827 * mr = marker 1828 * cr = cursor 1829 * st = start (const) 1830 * cd = consumed 1831 * sm = source_max (const) 1832 * 1833 * The marker hops backwards for each pointer. 1834 * The cursor steps forwards for each label. 1835 * The amount of the source we consumed is set once. 1836 */ 1837 const uint8_t *const source_buf = isc_buffer_base(source); 1838 const uint8_t *const source_max = isc_buffer_used(source); 1839 const uint8_t *const start = isc_buffer_current(source); 1840 const uint8_t *marker = start; 1841 const uint8_t *cursor = start; 1842 const uint8_t *consumed = NULL; 1843 1844 /* 1845 * One iteration per label. 1846 */ 1847 while (cursor < source_max) { 1848 const uint8_t label_len = *cursor++; 1849 if (label_len < 64) { 1850 /* 1851 * Normal label: record its offset, and check bounds on 1852 * the name length, which also ensures we don't overrun 1853 * the offsets array. Don't touch any source bytes yet! 1854 * The source bounds check will happen when we loop. 1855 */ 1856 offsets[labels++] = name_len; 1857 /* and then a step to the ri-i-i-i-i-ight */ 1858 cursor += label_len; 1859 name_len += label_len + 1; 1860 if (name_len > name_max) { 1861 return (name_max == DNS_NAME_MAXWIRE 1862 ? DNS_R_NAMETOOLONG 1863 : ISC_R_NOSPACE); 1864 } else if (label_len == 0) { 1865 goto root_label; 1866 } 1867 } else if (label_len < 192) { 1868 return (DNS_R_BADLABELTYPE); 1869 } else if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) == 0) { 1870 return (DNS_R_DISALLOWED); 1871 } else if (cursor < source_max) { 1872 /* 1873 * Compression pointer. Ensure it does not loop. 1874 * 1875 * Copy multiple labels in one go, to make the most of 1876 * memmove() performance. Start at the marker and finish 1877 * just before the pointer's hi+lo bytes, before the 1878 * cursor. Bounds were already checked. 1879 */ 1880 const uint32_t hi = label_len & 0x3F; 1881 const uint32_t lo = *cursor++; 1882 const uint8_t *pointer = source_buf + (256 * hi + lo); 1883 if (pointer >= marker) { 1884 return (DNS_R_BADPOINTER); 1885 } 1886 const uint32_t copy_len = (cursor - 2) - marker; 1887 uint8_t *const dest = name_buf + name_len - copy_len; 1888 memmove(dest, marker, copy_len); 1889 consumed = consumed != NULL ? consumed : cursor; 1890 /* it's just a jump to the left */ 1891 cursor = marker = pointer; 1892 } 1893 } 1894 return (ISC_R_UNEXPECTEDEND); 1895root_label:; 1896 /* 1897 * Copy labels almost like we do for compression pointers, 1898 * from the marker up to and including the root label. 1899 */ 1900 const uint32_t copy_len = cursor - marker; 1901 memmove(name_buf + name_len - copy_len, marker, copy_len); 1902 consumed = consumed != NULL ? consumed : cursor; 1903 isc_buffer_forward(source, consumed - start); 1904 1905 name->attributes |= DNS_NAMEATTR_ABSOLUTE; 1906 name->ndata = name_buf; 1907 name->labels = labels; 1908 name->length = name_len; 1909 isc_buffer_add(target, name_len); 1910 1911 return (ISC_R_SUCCESS); 1912} 1913 1914isc_result_t 1915dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, 1916 isc_buffer_t *target) { 1917 return (dns_name_towire2(name, cctx, target, NULL)); 1918} 1919 1920isc_result_t 1921dns_name_towire2(const dns_name_t *name, dns_compress_t *cctx, 1922 isc_buffer_t *target, uint16_t *comp_offsetp) { 1923 unsigned int methods; 1924 uint16_t offset; 1925 dns_name_t gp; /* Global compression prefix */ 1926 bool gf; /* Global compression target found */ 1927 uint16_t go; /* Global compression offset */ 1928 dns_offsets_t clo; 1929 dns_name_t clname; 1930 1931 /* 1932 * Convert 'name' into wire format, compressing it as specified by the 1933 * compression context 'cctx', and storing the result in 'target'. 1934 */ 1935 1936 REQUIRE(VALID_NAME(name)); 1937 REQUIRE(cctx != NULL); 1938 REQUIRE(ISC_BUFFER_VALID(target)); 1939 1940 /* 1941 * If this exact name was already rendered before, and the 1942 * offset of the previously rendered name is passed to us, write 1943 * a compression pointer directly. 1944 */ 1945 methods = dns_compress_getmethods(cctx); 1946 if (comp_offsetp != NULL && *comp_offsetp < 0x4000 && 1947 (name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 && 1948 (methods & DNS_COMPRESS_GLOBAL14) != 0) 1949 { 1950 if (target->length - target->used < 2) { 1951 return (ISC_R_NOSPACE); 1952 } 1953 offset = *comp_offsetp; 1954 offset |= 0xc000; 1955 isc_buffer_putuint16(target, offset); 1956 return (ISC_R_SUCCESS); 1957 } 1958 1959 /* 1960 * If 'name' doesn't have an offsets table, make a clone which 1961 * has one. 1962 */ 1963 if (name->offsets == NULL) { 1964 DNS_NAME_INIT(&clname, clo); 1965 dns_name_clone(name, &clname); 1966 name = &clname; 1967 } 1968 DNS_NAME_INIT(&gp, NULL); 1969 1970 offset = target->used; /*XXX*/ 1971 1972 if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 && 1973 (methods & DNS_COMPRESS_GLOBAL14) != 0) 1974 { 1975 gf = dns_compress_findglobal(cctx, name, &gp, &go); 1976 } else { 1977 gf = false; 1978 } 1979 1980 /* 1981 * If the offset is too high for 14 bit global compression, we're 1982 * out of luck. 1983 */ 1984 if (gf && go >= 0x4000) { 1985 gf = false; 1986 } 1987 1988 /* 1989 * Will the compression pointer reduce the message size? 1990 */ 1991 if (gf && (gp.length + 2) >= name->length) { 1992 gf = false; 1993 } 1994 1995 if (gf) { 1996 if (target->length - target->used < gp.length) { 1997 return (ISC_R_NOSPACE); 1998 } 1999 if (gp.length != 0) { 2000 unsigned char *base = target->base; 2001 (void)memmove(base + target->used, gp.ndata, 2002 (size_t)gp.length); 2003 } 2004 isc_buffer_add(target, gp.length); 2005 if (target->length - target->used < 2) { 2006 return (ISC_R_NOSPACE); 2007 } 2008 isc_buffer_putuint16(target, go | 0xc000); 2009 if (gp.length != 0) { 2010 dns_compress_add(cctx, name, &gp, offset); 2011 if (comp_offsetp != NULL) { 2012 *comp_offsetp = offset; 2013 } 2014 } else if (comp_offsetp != NULL) { 2015 *comp_offsetp = go; 2016 } 2017 } else { 2018 if (target->length - target->used < name->length) { 2019 return (ISC_R_NOSPACE); 2020 } 2021 if (name->length != 0) { 2022 unsigned char *base = target->base; 2023 (void)memmove(base + target->used, name->ndata, 2024 (size_t)name->length); 2025 } 2026 isc_buffer_add(target, name->length); 2027 dns_compress_add(cctx, name, name, offset); 2028 if (comp_offsetp != NULL) { 2029 *comp_offsetp = offset; 2030 } 2031 } 2032 2033 return (ISC_R_SUCCESS); 2034} 2035 2036isc_result_t 2037dns_name_concatenate(const dns_name_t *prefix, const dns_name_t *suffix, 2038 dns_name_t *name, isc_buffer_t *target) { 2039 unsigned char *ndata, *offsets; 2040 unsigned int nrem, labels, prefix_length, length; 2041 bool copy_prefix = true; 2042 bool copy_suffix = true; 2043 bool absolute = false; 2044 dns_name_t tmp_name; 2045 dns_offsets_t odata; 2046 2047 /* 2048 * Concatenate 'prefix' and 'suffix'. 2049 */ 2050 2051 REQUIRE(prefix == NULL || VALID_NAME(prefix)); 2052 REQUIRE(suffix == NULL || VALID_NAME(suffix)); 2053 REQUIRE(name == NULL || VALID_NAME(name)); 2054 REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || 2055 (target == NULL && name != NULL && 2056 ISC_BUFFER_VALID(name->buffer))); 2057 if (prefix == NULL || prefix->labels == 0) { 2058 copy_prefix = false; 2059 } 2060 if (suffix == NULL || suffix->labels == 0) { 2061 copy_suffix = false; 2062 } 2063 if (copy_prefix && (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 2064 absolute = true; 2065 REQUIRE(!copy_suffix); 2066 } 2067 if (name == NULL) { 2068 DNS_NAME_INIT(&tmp_name, odata); 2069 name = &tmp_name; 2070 } 2071 if (target == NULL) { 2072 INSIST(name->buffer != NULL); 2073 target = name->buffer; 2074 isc_buffer_clear(name->buffer); 2075 } 2076 2077 REQUIRE(BINDABLE(name)); 2078 2079 /* 2080 * Set up. 2081 */ 2082 nrem = target->length - target->used; 2083 ndata = (unsigned char *)target->base + target->used; 2084 if (nrem > DNS_NAME_MAXWIRE) { 2085 nrem = DNS_NAME_MAXWIRE; 2086 } 2087 length = 0; 2088 prefix_length = 0; 2089 labels = 0; 2090 if (copy_prefix) { 2091 prefix_length = prefix->length; 2092 length += prefix_length; 2093 labels += prefix->labels; 2094 } 2095 if (copy_suffix) { 2096 length += suffix->length; 2097 labels += suffix->labels; 2098 } 2099 if (length > DNS_NAME_MAXWIRE) { 2100 MAKE_EMPTY(name); 2101 return (DNS_R_NAMETOOLONG); 2102 } 2103 if (length > nrem) { 2104 MAKE_EMPTY(name); 2105 return (ISC_R_NOSPACE); 2106 } 2107 2108 if (copy_suffix) { 2109 if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 2110 absolute = true; 2111 } 2112 memmove(ndata + prefix_length, suffix->ndata, suffix->length); 2113 } 2114 2115 /* 2116 * If 'prefix' and 'name' are the same object, and the object has 2117 * a dedicated buffer, and we're using it, then we don't have to 2118 * copy anything. 2119 */ 2120 if (copy_prefix && (prefix != name || prefix->buffer != target)) { 2121 memmove(ndata, prefix->ndata, prefix_length); 2122 } 2123 2124 name->ndata = ndata; 2125 name->labels = labels; 2126 name->length = length; 2127 if (absolute) { 2128 name->attributes = DNS_NAMEATTR_ABSOLUTE; 2129 } else { 2130 name->attributes = 0; 2131 } 2132 2133 if (name->labels > 0 && name->offsets != NULL) { 2134 INIT_OFFSETS(name, offsets, odata); 2135 set_offsets(name, offsets, NULL); 2136 } 2137 2138 isc_buffer_add(target, name->length); 2139 2140 return (ISC_R_SUCCESS); 2141} 2142 2143void 2144dns_name_split(const dns_name_t *name, unsigned int suffixlabels, 2145 dns_name_t *prefix, dns_name_t *suffix) 2146 2147{ 2148 unsigned int splitlabel; 2149 2150 REQUIRE(VALID_NAME(name)); 2151 REQUIRE(suffixlabels > 0); 2152 REQUIRE(suffixlabels <= name->labels); 2153 REQUIRE(prefix != NULL || suffix != NULL); 2154 REQUIRE(prefix == NULL || (VALID_NAME(prefix) && BINDABLE(prefix))); 2155 REQUIRE(suffix == NULL || (VALID_NAME(suffix) && BINDABLE(suffix))); 2156 2157 splitlabel = name->labels - suffixlabels; 2158 2159 if (prefix != NULL) { 2160 dns_name_getlabelsequence(name, 0, splitlabel, prefix); 2161 } 2162 2163 if (suffix != NULL) { 2164 dns_name_getlabelsequence(name, splitlabel, suffixlabels, 2165 suffix); 2166 } 2167 2168 return; 2169} 2170 2171void 2172dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { 2173 /* 2174 * Make 'target' a dynamically allocated copy of 'source'. 2175 */ 2176 2177 REQUIRE(VALID_NAME(source)); 2178 REQUIRE(source->length > 0); 2179 REQUIRE(VALID_NAME(target)); 2180 REQUIRE(BINDABLE(target)); 2181 2182 /* 2183 * Make 'target' empty in case of failure. 2184 */ 2185 MAKE_EMPTY(target); 2186 2187 target->ndata = isc_mem_get(mctx, source->length); 2188 2189 memmove(target->ndata, source->ndata, source->length); 2190 2191 target->length = source->length; 2192 target->labels = source->labels; 2193 target->attributes = DNS_NAMEATTR_DYNAMIC; 2194 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 2195 target->attributes |= DNS_NAMEATTR_ABSOLUTE; 2196 } 2197 if (target->offsets != NULL) { 2198 if (source->offsets != NULL) { 2199 memmove(target->offsets, source->offsets, 2200 source->labels); 2201 } else { 2202 set_offsets(target, target->offsets, NULL); 2203 } 2204 } 2205} 2206 2207isc_result_t 2208dns_name_dupwithoffsets(const dns_name_t *source, isc_mem_t *mctx, 2209 dns_name_t *target) { 2210 /* 2211 * Make 'target' a read-only dynamically allocated copy of 'source'. 2212 * 'target' will also have a dynamically allocated offsets table. 2213 */ 2214 2215 REQUIRE(VALID_NAME(source)); 2216 REQUIRE(source->length > 0); 2217 REQUIRE(VALID_NAME(target)); 2218 REQUIRE(BINDABLE(target)); 2219 REQUIRE(target->offsets == NULL); 2220 2221 /* 2222 * Make 'target' empty in case of failure. 2223 */ 2224 MAKE_EMPTY(target); 2225 2226 target->ndata = isc_mem_get(mctx, source->length + source->labels); 2227 2228 memmove(target->ndata, source->ndata, source->length); 2229 2230 target->length = source->length; 2231 target->labels = source->labels; 2232 target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS | 2233 DNS_NAMEATTR_READONLY; 2234 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 2235 target->attributes |= DNS_NAMEATTR_ABSOLUTE; 2236 } 2237 target->offsets = target->ndata + source->length; 2238 if (source->offsets != NULL) { 2239 memmove(target->offsets, source->offsets, source->labels); 2240 } else { 2241 set_offsets(target, target->offsets, NULL); 2242 } 2243 2244 return (ISC_R_SUCCESS); 2245} 2246 2247void 2248dns_name_free(dns_name_t *name, isc_mem_t *mctx) { 2249 size_t size; 2250 2251 /* 2252 * Free 'name'. 2253 */ 2254 2255 REQUIRE(VALID_NAME(name)); 2256 REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0); 2257 2258 size = name->length; 2259 if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0) { 2260 size += name->labels; 2261 } 2262 isc_mem_put(mctx, name->ndata, size); 2263 dns_name_invalidate(name); 2264} 2265 2266isc_result_t 2267dns_name_digest(const dns_name_t *name, dns_digestfunc_t digest, void *arg) { 2268 dns_name_t downname; 2269 unsigned char data[256]; 2270 isc_buffer_t buffer; 2271 isc_result_t result; 2272 isc_region_t r; 2273 2274 /* 2275 * Send 'name' in DNSSEC canonical form to 'digest'. 2276 */ 2277 2278 REQUIRE(VALID_NAME(name)); 2279 REQUIRE(digest != NULL); 2280 2281 DNS_NAME_INIT(&downname, NULL); 2282 2283 isc_buffer_init(&buffer, data, sizeof(data)); 2284 2285 result = dns_name_downcase(name, &downname, &buffer); 2286 if (result != ISC_R_SUCCESS) { 2287 return (result); 2288 } 2289 2290 isc_buffer_usedregion(&buffer, &r); 2291 2292 return ((digest)(arg, &r)); 2293} 2294 2295bool 2296dns_name_dynamic(const dns_name_t *name) { 2297 REQUIRE(VALID_NAME(name)); 2298 2299 /* 2300 * Returns whether there is dynamic memory associated with this name. 2301 */ 2302 2303 return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ? true : false); 2304} 2305 2306isc_result_t 2307dns_name_print(const dns_name_t *name, FILE *stream) { 2308 isc_result_t result; 2309 isc_buffer_t b; 2310 isc_region_t r; 2311 char t[1024]; 2312 2313 /* 2314 * Print 'name' on 'stream'. 2315 */ 2316 2317 REQUIRE(VALID_NAME(name)); 2318 2319 isc_buffer_init(&b, t, sizeof(t)); 2320 result = dns_name_totext(name, false, &b); 2321 if (result != ISC_R_SUCCESS) { 2322 return (result); 2323 } 2324 isc_buffer_usedregion(&b, &r); 2325 fprintf(stream, "%.*s", (int)r.length, (char *)r.base); 2326 2327 return (ISC_R_SUCCESS); 2328} 2329 2330isc_result_t 2331dns_name_settotextfilter(dns_name_totextfilter_t *proc) { 2332 /* 2333 * If we already have been here set / clear as appropriate. 2334 */ 2335 if (totext_filter_proc != NULL && proc != NULL) { 2336 if (totext_filter_proc == proc) { 2337 return (ISC_R_SUCCESS); 2338 } 2339 } 2340 if (proc == NULL && totext_filter_proc != NULL) { 2341 totext_filter_proc = NULL; 2342 return (ISC_R_SUCCESS); 2343 } 2344 2345 totext_filter_proc = proc; 2346 2347 return (ISC_R_SUCCESS); 2348} 2349 2350void 2351dns_name_format(const dns_name_t *name, char *cp, unsigned int size) { 2352 isc_result_t result; 2353 isc_buffer_t buf; 2354 2355 REQUIRE(size > 0); 2356 2357 /* 2358 * Leave room for null termination after buffer. 2359 */ 2360 isc_buffer_init(&buf, cp, size - 1); 2361 result = dns_name_totext(name, true, &buf); 2362 if (result == ISC_R_SUCCESS) { 2363 isc_buffer_putuint8(&buf, (uint8_t)'\0'); 2364 } else { 2365 snprintf(cp, size, "<unknown>"); 2366 } 2367} 2368 2369/* 2370 * dns_name_tostring() -- similar to dns_name_format() but allocates its own 2371 * memory. 2372 */ 2373isc_result_t 2374dns_name_tostring(const dns_name_t *name, char **target, isc_mem_t *mctx) { 2375 isc_result_t result; 2376 isc_buffer_t buf; 2377 isc_region_t reg; 2378 char *p, txt[DNS_NAME_FORMATSIZE]; 2379 2380 REQUIRE(VALID_NAME(name)); 2381 REQUIRE(target != NULL && *target == NULL); 2382 2383 isc_buffer_init(&buf, txt, sizeof(txt)); 2384 result = dns_name_totext(name, false, &buf); 2385 if (result != ISC_R_SUCCESS) { 2386 return (result); 2387 } 2388 2389 isc_buffer_usedregion(&buf, ®); 2390 p = isc_mem_allocate(mctx, reg.length + 1); 2391 memmove(p, (char *)reg.base, (int)reg.length); 2392 p[reg.length] = '\0'; 2393 2394 *target = p; 2395 return (ISC_R_SUCCESS); 2396} 2397 2398/* 2399 * dns_name_fromstring() -- convert directly from a string to a name, 2400 * allocating memory as needed 2401 */ 2402isc_result_t 2403dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options, 2404 isc_mem_t *mctx) { 2405 return (dns_name_fromstring2(target, src, dns_rootname, options, mctx)); 2406} 2407 2408isc_result_t 2409dns_name_fromstring2(dns_name_t *target, const char *src, 2410 const dns_name_t *origin, unsigned int options, 2411 isc_mem_t *mctx) { 2412 isc_result_t result; 2413 isc_buffer_t buf; 2414 dns_fixedname_t fn; 2415 dns_name_t *name; 2416 2417 REQUIRE(src != NULL); 2418 2419 isc_buffer_constinit(&buf, src, strlen(src)); 2420 isc_buffer_add(&buf, strlen(src)); 2421 if (BINDABLE(target) && target->buffer != NULL) { 2422 name = target; 2423 } else { 2424 name = dns_fixedname_initname(&fn); 2425 } 2426 2427 result = dns_name_fromtext(name, &buf, origin, options, NULL); 2428 if (result != ISC_R_SUCCESS) { 2429 return (result); 2430 } 2431 2432 if (name != target) { 2433 result = dns_name_dupwithoffsets(name, mctx, target); 2434 } 2435 return (result); 2436} 2437 2438void 2439dns_name_copy(const dns_name_t *source, dns_name_t *dest) { 2440 isc_buffer_t *target = NULL; 2441 unsigned char *ndata = NULL; 2442 2443 REQUIRE(VALID_NAME(source)); 2444 REQUIRE(VALID_NAME(dest)); 2445 REQUIRE(BINDABLE(dest)); 2446 2447 target = dest->buffer; 2448 2449 REQUIRE(target != NULL); 2450 REQUIRE(target->length >= source->length); 2451 2452 isc_buffer_clear(target); 2453 2454 ndata = (unsigned char *)target->base; 2455 dest->ndata = target->base; 2456 2457 if (source->length != 0) { 2458 memmove(ndata, source->ndata, source->length); 2459 } 2460 2461 dest->ndata = ndata; 2462 dest->labels = source->labels; 2463 dest->length = source->length; 2464 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { 2465 dest->attributes = DNS_NAMEATTR_ABSOLUTE; 2466 } else { 2467 dest->attributes = 0; 2468 } 2469 2470 if (dest->labels > 0 && dest->offsets != NULL) { 2471 if (source->offsets != NULL && source->labels != 0) { 2472 memmove(dest->offsets, source->offsets, source->labels); 2473 } else { 2474 set_offsets(dest, dest->offsets, NULL); 2475 } 2476 } 2477 2478 isc_buffer_add(target, dest->length); 2479} 2480 2481/* 2482 * Service Discovery Prefixes RFC 6763. 2483 */ 2484static unsigned char b_dns_sd_udp_data[] = "\001b\007_dns-sd\004_udp"; 2485static unsigned char b_dns_sd_udp_offsets[] = { 0, 2, 10 }; 2486static unsigned char db_dns_sd_udp_data[] = "\002db\007_dns-sd\004_udp"; 2487static unsigned char db_dns_sd_udp_offsets[] = { 0, 3, 11 }; 2488static unsigned char r_dns_sd_udp_data[] = "\001r\007_dns-sd\004_udp"; 2489static unsigned char r_dns_sd_udp_offsets[] = { 0, 2, 10 }; 2490static unsigned char dr_dns_sd_udp_data[] = "\002dr\007_dns-sd\004_udp"; 2491static unsigned char dr_dns_sd_udp_offsets[] = { 0, 3, 11 }; 2492static unsigned char lb_dns_sd_udp_data[] = "\002lb\007_dns-sd\004_udp"; 2493static unsigned char lb_dns_sd_udp_offsets[] = { 0, 3, 11 }; 2494 2495static dns_name_t const dns_sd[] = { 2496 DNS_NAME_INITNONABSOLUTE(b_dns_sd_udp_data, b_dns_sd_udp_offsets), 2497 DNS_NAME_INITNONABSOLUTE(db_dns_sd_udp_data, db_dns_sd_udp_offsets), 2498 DNS_NAME_INITNONABSOLUTE(r_dns_sd_udp_data, r_dns_sd_udp_offsets), 2499 DNS_NAME_INITNONABSOLUTE(dr_dns_sd_udp_data, dr_dns_sd_udp_offsets), 2500 DNS_NAME_INITNONABSOLUTE(lb_dns_sd_udp_data, lb_dns_sd_udp_offsets) 2501}; 2502 2503bool 2504dns_name_isdnssd(const dns_name_t *name) { 2505 size_t i; 2506 dns_name_t prefix; 2507 2508 if (dns_name_countlabels(name) > 3U) { 2509 dns_name_init(&prefix, NULL); 2510 dns_name_getlabelsequence(name, 0, 3, &prefix); 2511 for (i = 0; i < (sizeof(dns_sd) / sizeof(dns_sd[0])); i++) { 2512 if (dns_name_equal(&prefix, &dns_sd[i])) { 2513 return (true); 2514 } 2515 } 2516 } 2517 2518 return (false); 2519} 2520 2521static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; 2522static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; 2523static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; 2524 2525static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; 2526 2527static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; 2528static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; 2529static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; 2530static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; 2531static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; 2532static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; 2533static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; 2534static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; 2535static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; 2536static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; 2537static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; 2538static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; 2539static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; 2540static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; 2541static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; 2542static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; 2543 2544static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; 2545 2546static dns_name_t const rfc1918names[] = { 2547 DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets), 2548 DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets), 2549 DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets), 2550 DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets), 2551 DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets), 2552 DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets), 2553 DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets), 2554 DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets), 2555 DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets), 2556 DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets), 2557 DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets), 2558 DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets), 2559 DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets), 2560 DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets), 2561 DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets), 2562 DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets), 2563 DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets), 2564 DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets) 2565}; 2566 2567bool 2568dns_name_isrfc1918(const dns_name_t *name) { 2569 size_t i; 2570 2571 for (i = 0; i < (sizeof(rfc1918names) / sizeof(*rfc1918names)); i++) { 2572 if (dns_name_issubdomain(name, &rfc1918names[i])) { 2573 return (true); 2574 } 2575 } 2576 return (false); 2577} 2578 2579static unsigned char ulaoffsets[] = { 0, 2, 4, 8, 13 }; 2580static unsigned char ip6fc[] = "\001c\001f\003ip6\004ARPA"; 2581static unsigned char ip6fd[] = "\001d\001f\003ip6\004ARPA"; 2582 2583static dns_name_t const ulanames[] = { DNS_NAME_INITABSOLUTE(ip6fc, ulaoffsets), 2584 DNS_NAME_INITABSOLUTE(ip6fd, 2585 ulaoffsets) }; 2586 2587bool 2588dns_name_isula(const dns_name_t *name) { 2589 size_t i; 2590 2591 for (i = 0; i < (sizeof(ulanames) / sizeof(*ulanames)); i++) { 2592 if (dns_name_issubdomain(name, &ulanames[i])) { 2593 return (true); 2594 } 2595 } 2596 return (false); 2597} 2598 2599/* 2600 * Use a simple table as we don't want all the locale stuff 2601 * associated with ishexdigit(). 2602 */ 2603const char ishex[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2605 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2606 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2607 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2608 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2609 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2611 2612bool 2613dns_name_istat(const dns_name_t *name) { 2614 unsigned char len; 2615 const unsigned char *ndata; 2616 2617 REQUIRE(VALID_NAME(name)); 2618 2619 if (name->labels < 1) { 2620 return (false); 2621 } 2622 2623 ndata = name->ndata; 2624 len = ndata[0]; 2625 INSIST(len <= name->length); 2626 ndata++; 2627 2628 /* 2629 * Is there at least one trust anchor reported and is the 2630 * label length consistent with a trust-anchor-telemetry label. 2631 */ 2632 if ((len < 8) || (len - 3) % 5 != 0) { 2633 return (false); 2634 } 2635 2636 if (ndata[0] != '_' || maptolower[ndata[1]] != 't' || 2637 maptolower[ndata[2]] != 'a') 2638 { 2639 return (false); 2640 } 2641 ndata += 3; 2642 len -= 3; 2643 2644 while (len > 0) { 2645 INSIST(len >= 5); 2646 if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] || 2647 !ishex[ndata[3]] || !ishex[ndata[4]]) 2648 { 2649 return (false); 2650 } 2651 ndata += 5; 2652 len -= 5; 2653 } 2654 return (true); 2655} 2656