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