tsig_250.c revision 1.6
1/* $NetBSD: tsig_250.c,v 1.6 2021/02/19 16:42:17 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14#ifndef RDATA_ANY_255_TSIG_250_C 15#define RDATA_ANY_255_TSIG_250_C 16 17#define RRTYPE_TSIG_ATTRIBUTES \ 18 (DNS_RDATATYPEATTR_META | DNS_RDATATYPEATTR_NOTQUESTION) 19 20static inline isc_result_t 21fromtext_any_tsig(ARGS_FROMTEXT) { 22 isc_token_t token; 23 dns_name_t name; 24 uint64_t sigtime; 25 isc_buffer_t buffer; 26 dns_rcode_t rcode; 27 long i; 28 char *e; 29 30 REQUIRE(type == dns_rdatatype_tsig); 31 REQUIRE(rdclass == dns_rdataclass_any); 32 33 UNUSED(type); 34 UNUSED(rdclass); 35 UNUSED(callbacks); 36 37 /* 38 * Algorithm Name. 39 */ 40 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 41 false)); 42 dns_name_init(&name, NULL); 43 buffer_fromregion(&buffer, &token.value.as_region); 44 if (origin == NULL) { 45 origin = dns_rootname; 46 } 47 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 48 49 /* 50 * Time Signed: 48 bits. 51 */ 52 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 53 false)); 54 sigtime = strtoull(DNS_AS_STR(token), &e, 10); 55 if (*e != 0) { 56 RETTOK(DNS_R_SYNTAX); 57 } 58 if ((sigtime >> 48) != 0) { 59 RETTOK(ISC_R_RANGE); 60 } 61 RETERR(uint16_tobuffer((uint16_t)(sigtime >> 32), target)); 62 RETERR(uint32_tobuffer((uint32_t)(sigtime & 0xffffffffU), target)); 63 64 /* 65 * Fudge. 66 */ 67 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 68 false)); 69 if (token.value.as_ulong > 0xffffU) { 70 RETTOK(ISC_R_RANGE); 71 } 72 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 73 74 /* 75 * Signature Size. 76 */ 77 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 78 false)); 79 if (token.value.as_ulong > 0xffffU) { 80 RETTOK(ISC_R_RANGE); 81 } 82 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 83 84 /* 85 * Signature. 86 */ 87 RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); 88 89 /* 90 * Original ID. 91 */ 92 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 93 false)); 94 if (token.value.as_ulong > 0xffffU) { 95 RETTOK(ISC_R_RANGE); 96 } 97 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 98 99 /* 100 * Error. 101 */ 102 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 103 false)); 104 if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) != 105 ISC_R_SUCCESS) { 106 i = strtol(DNS_AS_STR(token), &e, 10); 107 if (*e != 0) { 108 RETTOK(DNS_R_UNKNOWN); 109 } 110 if (i < 0 || i > 0xffff) { 111 RETTOK(ISC_R_RANGE); 112 } 113 rcode = (dns_rcode_t)i; 114 } 115 RETERR(uint16_tobuffer(rcode, target)); 116 117 /* 118 * Other Len. 119 */ 120 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 121 false)); 122 if (token.value.as_ulong > 0xffffU) { 123 RETTOK(ISC_R_RANGE); 124 } 125 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 126 127 /* 128 * Other Data. 129 */ 130 return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); 131} 132 133static inline isc_result_t 134totext_any_tsig(ARGS_TOTEXT) { 135 isc_region_t sr; 136 isc_region_t sigr; 137 char buf[sizeof(" 281474976710655 ")]; 138 char *bufp; 139 dns_name_t name; 140 dns_name_t prefix; 141 bool sub; 142 uint64_t sigtime; 143 unsigned short n; 144 145 REQUIRE(rdata->type == dns_rdatatype_tsig); 146 REQUIRE(rdata->rdclass == dns_rdataclass_any); 147 REQUIRE(rdata->length != 0); 148 149 dns_rdata_toregion(rdata, &sr); 150 /* 151 * Algorithm Name. 152 */ 153 dns_name_init(&name, NULL); 154 dns_name_init(&prefix, NULL); 155 dns_name_fromregion(&name, &sr); 156 sub = name_prefix(&name, tctx->origin, &prefix); 157 RETERR(dns_name_totext(&prefix, sub, target)); 158 RETERR(str_totext(" ", target)); 159 isc_region_consume(&sr, name_length(&name)); 160 161 /* 162 * Time Signed. 163 */ 164 sigtime = ((uint64_t)sr.base[0] << 40) | ((uint64_t)sr.base[1] << 32) | 165 ((uint64_t)sr.base[2] << 24) | ((uint64_t)sr.base[3] << 16) | 166 ((uint64_t)sr.base[4] << 8) | (uint64_t)sr.base[5]; 167 isc_region_consume(&sr, 6); 168 bufp = &buf[sizeof(buf) - 1]; 169 *bufp-- = 0; 170 *bufp-- = ' '; 171 do { 172 *bufp-- = decdigits[sigtime % 10]; 173 sigtime /= 10; 174 } while (sigtime != 0); 175 bufp++; 176 RETERR(str_totext(bufp, target)); 177 178 /* 179 * Fudge. 180 */ 181 n = uint16_fromregion(&sr); 182 isc_region_consume(&sr, 2); 183 snprintf(buf, sizeof(buf), "%u ", n); 184 RETERR(str_totext(buf, target)); 185 186 /* 187 * Signature Size. 188 */ 189 n = uint16_fromregion(&sr); 190 isc_region_consume(&sr, 2); 191 snprintf(buf, sizeof(buf), "%u", n); 192 RETERR(str_totext(buf, target)); 193 194 /* 195 * Signature. 196 */ 197 if (n != 0U) { 198 REQUIRE(n <= sr.length); 199 sigr = sr; 200 sigr.length = n; 201 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 202 RETERR(str_totext(" (", target)); 203 } 204 RETERR(str_totext(tctx->linebreak, target)); 205 if (tctx->width == 0) { /* No splitting */ 206 RETERR(isc_base64_totext(&sigr, 60, "", target)); 207 } else { 208 RETERR(isc_base64_totext(&sigr, tctx->width - 2, 209 tctx->linebreak, target)); 210 } 211 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 212 RETERR(str_totext(" ) ", target)); 213 } else { 214 RETERR(str_totext(" ", target)); 215 } 216 isc_region_consume(&sr, n); 217 } else { 218 RETERR(str_totext(" ", target)); 219 } 220 221 /* 222 * Original ID. 223 */ 224 n = uint16_fromregion(&sr); 225 isc_region_consume(&sr, 2); 226 snprintf(buf, sizeof(buf), "%u ", n); 227 RETERR(str_totext(buf, target)); 228 229 /* 230 * Error. 231 */ 232 n = uint16_fromregion(&sr); 233 isc_region_consume(&sr, 2); 234 RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); 235 236 /* 237 * Other Size. 238 */ 239 n = uint16_fromregion(&sr); 240 isc_region_consume(&sr, 2); 241 snprintf(buf, sizeof(buf), " %u ", n); 242 RETERR(str_totext(buf, target)); 243 244 /* 245 * Other. 246 */ 247 if (tctx->width == 0) { /* No splitting */ 248 return (isc_base64_totext(&sr, 60, "", target)); 249 } else { 250 return (isc_base64_totext(&sr, 60, " ", target)); 251 } 252} 253 254static inline isc_result_t 255fromwire_any_tsig(ARGS_FROMWIRE) { 256 isc_region_t sr; 257 dns_name_t name; 258 unsigned long n; 259 260 REQUIRE(type == dns_rdatatype_tsig); 261 REQUIRE(rdclass == dns_rdataclass_any); 262 263 UNUSED(type); 264 UNUSED(rdclass); 265 266 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 267 268 /* 269 * Algorithm Name. 270 */ 271 dns_name_init(&name, NULL); 272 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 273 274 isc_buffer_activeregion(source, &sr); 275 /* 276 * Time Signed + Fudge. 277 */ 278 if (sr.length < 8) { 279 return (ISC_R_UNEXPECTEDEND); 280 } 281 RETERR(mem_tobuffer(target, sr.base, 8)); 282 isc_region_consume(&sr, 8); 283 isc_buffer_forward(source, 8); 284 285 /* 286 * Signature Length + Signature. 287 */ 288 if (sr.length < 2) { 289 return (ISC_R_UNEXPECTEDEND); 290 } 291 n = uint16_fromregion(&sr); 292 if (sr.length < n + 2) { 293 return (ISC_R_UNEXPECTEDEND); 294 } 295 RETERR(mem_tobuffer(target, sr.base, n + 2)); 296 isc_region_consume(&sr, n + 2); 297 isc_buffer_forward(source, n + 2); 298 299 /* 300 * Original ID + Error. 301 */ 302 if (sr.length < 4) { 303 return (ISC_R_UNEXPECTEDEND); 304 } 305 RETERR(mem_tobuffer(target, sr.base, 4)); 306 isc_region_consume(&sr, 4); 307 isc_buffer_forward(source, 4); 308 309 /* 310 * Other Length + Other. 311 */ 312 if (sr.length < 2) { 313 return (ISC_R_UNEXPECTEDEND); 314 } 315 n = uint16_fromregion(&sr); 316 if (sr.length < n + 2) { 317 return (ISC_R_UNEXPECTEDEND); 318 } 319 isc_buffer_forward(source, n + 2); 320 return (mem_tobuffer(target, sr.base, n + 2)); 321} 322 323static inline isc_result_t 324towire_any_tsig(ARGS_TOWIRE) { 325 isc_region_t sr; 326 dns_name_t name; 327 dns_offsets_t offsets; 328 329 REQUIRE(rdata->type == dns_rdatatype_tsig); 330 REQUIRE(rdata->rdclass == dns_rdataclass_any); 331 REQUIRE(rdata->length != 0); 332 333 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 334 dns_rdata_toregion(rdata, &sr); 335 dns_name_init(&name, offsets); 336 dns_name_fromregion(&name, &sr); 337 RETERR(dns_name_towire(&name, cctx, target)); 338 isc_region_consume(&sr, name_length(&name)); 339 return (mem_tobuffer(target, sr.base, sr.length)); 340} 341 342static inline int 343compare_any_tsig(ARGS_COMPARE) { 344 isc_region_t r1; 345 isc_region_t r2; 346 dns_name_t name1; 347 dns_name_t name2; 348 int order; 349 350 REQUIRE(rdata1->type == rdata2->type); 351 REQUIRE(rdata1->rdclass == rdata2->rdclass); 352 REQUIRE(rdata1->type == dns_rdatatype_tsig); 353 REQUIRE(rdata1->rdclass == dns_rdataclass_any); 354 REQUIRE(rdata1->length != 0); 355 REQUIRE(rdata2->length != 0); 356 357 dns_rdata_toregion(rdata1, &r1); 358 dns_rdata_toregion(rdata2, &r2); 359 dns_name_init(&name1, NULL); 360 dns_name_init(&name2, NULL); 361 dns_name_fromregion(&name1, &r1); 362 dns_name_fromregion(&name2, &r2); 363 order = dns_name_rdatacompare(&name1, &name2); 364 if (order != 0) { 365 return (order); 366 } 367 isc_region_consume(&r1, name_length(&name1)); 368 isc_region_consume(&r2, name_length(&name2)); 369 return (isc_region_compare(&r1, &r2)); 370} 371 372static inline isc_result_t 373fromstruct_any_tsig(ARGS_FROMSTRUCT) { 374 dns_rdata_any_tsig_t *tsig = source; 375 isc_region_t tr; 376 377 REQUIRE(type == dns_rdatatype_tsig); 378 REQUIRE(rdclass == dns_rdataclass_any); 379 REQUIRE(tsig != NULL); 380 REQUIRE(tsig->common.rdclass == rdclass); 381 REQUIRE(tsig->common.rdtype == type); 382 383 UNUSED(type); 384 UNUSED(rdclass); 385 386 /* 387 * Algorithm Name. 388 */ 389 RETERR(name_tobuffer(&tsig->algorithm, target)); 390 391 isc_buffer_availableregion(target, &tr); 392 if (tr.length < 6 + 2 + 2) { 393 return (ISC_R_NOSPACE); 394 } 395 396 /* 397 * Time Signed: 48 bits. 398 */ 399 RETERR(uint16_tobuffer((uint16_t)(tsig->timesigned >> 32), target)); 400 RETERR(uint32_tobuffer((uint32_t)(tsig->timesigned & 0xffffffffU), 401 target)); 402 403 /* 404 * Fudge. 405 */ 406 RETERR(uint16_tobuffer(tsig->fudge, target)); 407 408 /* 409 * Signature Size. 410 */ 411 RETERR(uint16_tobuffer(tsig->siglen, target)); 412 413 /* 414 * Signature. 415 */ 416 RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen)); 417 418 isc_buffer_availableregion(target, &tr); 419 if (tr.length < 2 + 2 + 2) { 420 return (ISC_R_NOSPACE); 421 } 422 423 /* 424 * Original ID. 425 */ 426 RETERR(uint16_tobuffer(tsig->originalid, target)); 427 428 /* 429 * Error. 430 */ 431 RETERR(uint16_tobuffer(tsig->error, target)); 432 433 /* 434 * Other Len. 435 */ 436 RETERR(uint16_tobuffer(tsig->otherlen, target)); 437 438 /* 439 * Other Data. 440 */ 441 return (mem_tobuffer(target, tsig->other, tsig->otherlen)); 442} 443 444static inline isc_result_t 445tostruct_any_tsig(ARGS_TOSTRUCT) { 446 dns_rdata_any_tsig_t *tsig; 447 dns_name_t alg; 448 isc_region_t sr; 449 450 REQUIRE(rdata->type == dns_rdatatype_tsig); 451 REQUIRE(rdata->rdclass == dns_rdataclass_any); 452 REQUIRE(rdata->length != 0); 453 454 tsig = (dns_rdata_any_tsig_t *)target; 455 tsig->common.rdclass = rdata->rdclass; 456 tsig->common.rdtype = rdata->type; 457 ISC_LINK_INIT(&tsig->common, link); 458 459 dns_rdata_toregion(rdata, &sr); 460 461 /* 462 * Algorithm Name. 463 */ 464 dns_name_init(&alg, NULL); 465 dns_name_fromregion(&alg, &sr); 466 dns_name_init(&tsig->algorithm, NULL); 467 RETERR(name_duporclone(&alg, mctx, &tsig->algorithm)); 468 469 isc_region_consume(&sr, name_length(&tsig->algorithm)); 470 471 /* 472 * Time Signed. 473 */ 474 INSIST(sr.length >= 6); 475 tsig->timesigned = ((uint64_t)sr.base[0] << 40) | 476 ((uint64_t)sr.base[1] << 32) | 477 ((uint64_t)sr.base[2] << 24) | 478 ((uint64_t)sr.base[3] << 16) | 479 ((uint64_t)sr.base[4] << 8) | (uint64_t)sr.base[5]; 480 isc_region_consume(&sr, 6); 481 482 /* 483 * Fudge. 484 */ 485 tsig->fudge = uint16_fromregion(&sr); 486 isc_region_consume(&sr, 2); 487 488 /* 489 * Signature Size. 490 */ 491 tsig->siglen = uint16_fromregion(&sr); 492 isc_region_consume(&sr, 2); 493 494 /* 495 * Signature. 496 */ 497 INSIST(sr.length >= tsig->siglen); 498 tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen); 499 if (tsig->signature == NULL) { 500 goto cleanup; 501 } 502 isc_region_consume(&sr, tsig->siglen); 503 504 /* 505 * Original ID. 506 */ 507 tsig->originalid = uint16_fromregion(&sr); 508 isc_region_consume(&sr, 2); 509 510 /* 511 * Error. 512 */ 513 tsig->error = uint16_fromregion(&sr); 514 isc_region_consume(&sr, 2); 515 516 /* 517 * Other Size. 518 */ 519 tsig->otherlen = uint16_fromregion(&sr); 520 isc_region_consume(&sr, 2); 521 522 /* 523 * Other. 524 */ 525 INSIST(sr.length == tsig->otherlen); 526 tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen); 527 if (tsig->other == NULL) { 528 goto cleanup; 529 } 530 531 tsig->mctx = mctx; 532 return (ISC_R_SUCCESS); 533 534cleanup: 535 if (mctx != NULL) { 536 dns_name_free(&tsig->algorithm, tsig->mctx); 537 } 538 if (mctx != NULL && tsig->signature != NULL) { 539 isc_mem_free(mctx, tsig->signature); 540 } 541 return (ISC_R_NOMEMORY); 542} 543 544static inline void 545freestruct_any_tsig(ARGS_FREESTRUCT) { 546 dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *)source; 547 548 REQUIRE(tsig != NULL); 549 REQUIRE(tsig->common.rdtype == dns_rdatatype_tsig); 550 REQUIRE(tsig->common.rdclass == dns_rdataclass_any); 551 552 if (tsig->mctx == NULL) { 553 return; 554 } 555 556 dns_name_free(&tsig->algorithm, tsig->mctx); 557 if (tsig->signature != NULL) { 558 isc_mem_free(tsig->mctx, tsig->signature); 559 } 560 if (tsig->other != NULL) { 561 isc_mem_free(tsig->mctx, tsig->other); 562 } 563 tsig->mctx = NULL; 564} 565 566static inline isc_result_t 567additionaldata_any_tsig(ARGS_ADDLDATA) { 568 REQUIRE(rdata->type == dns_rdatatype_tsig); 569 REQUIRE(rdata->rdclass == dns_rdataclass_any); 570 571 UNUSED(rdata); 572 UNUSED(add); 573 UNUSED(arg); 574 575 return (ISC_R_SUCCESS); 576} 577 578static inline isc_result_t 579digest_any_tsig(ARGS_DIGEST) { 580 REQUIRE(rdata->type == dns_rdatatype_tsig); 581 REQUIRE(rdata->rdclass == dns_rdataclass_any); 582 583 UNUSED(rdata); 584 UNUSED(digest); 585 UNUSED(arg); 586 587 return (ISC_R_NOTIMPLEMENTED); 588} 589 590static inline bool 591checkowner_any_tsig(ARGS_CHECKOWNER) { 592 REQUIRE(type == dns_rdatatype_tsig); 593 REQUIRE(rdclass == dns_rdataclass_any); 594 595 UNUSED(name); 596 UNUSED(type); 597 UNUSED(rdclass); 598 UNUSED(wildcard); 599 600 return (true); 601} 602 603static inline bool 604checknames_any_tsig(ARGS_CHECKNAMES) { 605 REQUIRE(rdata->type == dns_rdatatype_tsig); 606 REQUIRE(rdata->rdclass == dns_rdataclass_any); 607 608 UNUSED(rdata); 609 UNUSED(owner); 610 UNUSED(bad); 611 612 return (true); 613} 614 615static inline int 616casecompare_any_tsig(ARGS_COMPARE) { 617 return (compare_any_tsig(rdata1, rdata2)); 618} 619 620#endif /* RDATA_ANY_255_TSIG_250_C */ 621