1/* 2 * Copyright (C) 2004, 2005, 2007, 2009, 2011, 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 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 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 211 RETERR(str_totext(" ) ", target)); 212 else 213 RETERR(str_totext(" ", target)); 214 isc_region_consume(&sr, n); 215 216 /* 217 * Original ID. 218 */ 219 n = uint16_fromregion(&sr); 220 isc_region_consume(&sr, 2); 221 sprintf(buf, "%u ", n); 222 RETERR(str_totext(buf, target)); 223 224 /* 225 * Error. 226 */ 227 n = uint16_fromregion(&sr); 228 isc_region_consume(&sr, 2); 229 RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); 230 231 /* 232 * Other Size. 233 */ 234 n = uint16_fromregion(&sr); 235 isc_region_consume(&sr, 2); 236 sprintf(buf, " %u ", n); 237 RETERR(str_totext(buf, target)); 238 239 /* 240 * Other. 241 */ 242 if (tctx->width == 0) /* No splitting */ 243 return (isc_base64_totext(&sr, 60, "", target)); 244 else 245 return (isc_base64_totext(&sr, 60, " ", target)); 246} 247 248static inline isc_result_t 249fromwire_any_tsig(ARGS_FROMWIRE) { 250 isc_region_t sr; 251 dns_name_t name; 252 unsigned long n; 253 254 REQUIRE(type == 250); 255 REQUIRE(rdclass == 255); 256 257 UNUSED(type); 258 UNUSED(rdclass); 259 260 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 261 262 /* 263 * Algorithm Name. 264 */ 265 dns_name_init(&name, NULL); 266 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 267 268 isc_buffer_activeregion(source, &sr); 269 /* 270 * Time Signed + Fudge. 271 */ 272 if (sr.length < 8) 273 return (ISC_R_UNEXPECTEDEND); 274 RETERR(mem_tobuffer(target, sr.base, 8)); 275 isc_region_consume(&sr, 8); 276 isc_buffer_forward(source, 8); 277 278 /* 279 * Signature Length + Signature. 280 */ 281 if (sr.length < 2) 282 return (ISC_R_UNEXPECTEDEND); 283 n = uint16_fromregion(&sr); 284 if (sr.length < n + 2) 285 return (ISC_R_UNEXPECTEDEND); 286 RETERR(mem_tobuffer(target, sr.base, n + 2)); 287 isc_region_consume(&sr, n + 2); 288 isc_buffer_forward(source, n + 2); 289 290 /* 291 * Original ID + Error. 292 */ 293 if (sr.length < 4) 294 return (ISC_R_UNEXPECTEDEND); 295 RETERR(mem_tobuffer(target, sr.base, 4)); 296 isc_region_consume(&sr, 4); 297 isc_buffer_forward(source, 4); 298 299 /* 300 * Other Length + Other. 301 */ 302 if (sr.length < 2) 303 return (ISC_R_UNEXPECTEDEND); 304 n = uint16_fromregion(&sr); 305 if (sr.length < n + 2) 306 return (ISC_R_UNEXPECTEDEND); 307 isc_buffer_forward(source, n + 2); 308 return (mem_tobuffer(target, sr.base, n + 2)); 309} 310 311static inline isc_result_t 312towire_any_tsig(ARGS_TOWIRE) { 313 isc_region_t sr; 314 dns_name_t name; 315 dns_offsets_t offsets; 316 317 REQUIRE(rdata->type == 250); 318 REQUIRE(rdata->rdclass == 255); 319 REQUIRE(rdata->length != 0); 320 321 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 322 dns_rdata_toregion(rdata, &sr); 323 dns_name_init(&name, offsets); 324 dns_name_fromregion(&name, &sr); 325 RETERR(dns_name_towire(&name, cctx, target)); 326 isc_region_consume(&sr, name_length(&name)); 327 return (mem_tobuffer(target, sr.base, sr.length)); 328} 329 330static inline int 331compare_any_tsig(ARGS_COMPARE) { 332 isc_region_t r1; 333 isc_region_t r2; 334 dns_name_t name1; 335 dns_name_t name2; 336 int order; 337 338 REQUIRE(rdata1->type == rdata2->type); 339 REQUIRE(rdata1->rdclass == rdata2->rdclass); 340 REQUIRE(rdata1->type == 250); 341 REQUIRE(rdata1->rdclass == 255); 342 REQUIRE(rdata1->length != 0); 343 REQUIRE(rdata2->length != 0); 344 345 dns_rdata_toregion(rdata1, &r1); 346 dns_rdata_toregion(rdata2, &r2); 347 dns_name_init(&name1, NULL); 348 dns_name_init(&name2, NULL); 349 dns_name_fromregion(&name1, &r1); 350 dns_name_fromregion(&name2, &r2); 351 order = dns_name_rdatacompare(&name1, &name2); 352 if (order != 0) 353 return (order); 354 isc_region_consume(&r1, name_length(&name1)); 355 isc_region_consume(&r2, name_length(&name2)); 356 return (isc_region_compare(&r1, &r2)); 357} 358 359static inline isc_result_t 360fromstruct_any_tsig(ARGS_FROMSTRUCT) { 361 dns_rdata_any_tsig_t *tsig = source; 362 isc_region_t tr; 363 364 REQUIRE(type == 250); 365 REQUIRE(rdclass == 255); 366 REQUIRE(source != NULL); 367 REQUIRE(tsig->common.rdclass == rdclass); 368 REQUIRE(tsig->common.rdtype == type); 369 370 UNUSED(type); 371 UNUSED(rdclass); 372 373 /* 374 * Algorithm Name. 375 */ 376 RETERR(name_tobuffer(&tsig->algorithm, target)); 377 378 isc_buffer_availableregion(target, &tr); 379 if (tr.length < 6 + 2 + 2) 380 return (ISC_R_NOSPACE); 381 382 /* 383 * Time Signed: 48 bits. 384 */ 385 RETERR(uint16_tobuffer((isc_uint16_t)(tsig->timesigned >> 32), 386 target)); 387 RETERR(uint32_tobuffer((isc_uint32_t)(tsig->timesigned & 0xffffffffU), 388 target)); 389 390 /* 391 * Fudge. 392 */ 393 RETERR(uint16_tobuffer(tsig->fudge, target)); 394 395 /* 396 * Signature Size. 397 */ 398 RETERR(uint16_tobuffer(tsig->siglen, target)); 399 400 /* 401 * Signature. 402 */ 403 RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen)); 404 405 isc_buffer_availableregion(target, &tr); 406 if (tr.length < 2 + 2 + 2) 407 return (ISC_R_NOSPACE); 408 409 /* 410 * Original ID. 411 */ 412 RETERR(uint16_tobuffer(tsig->originalid, target)); 413 414 /* 415 * Error. 416 */ 417 RETERR(uint16_tobuffer(tsig->error, target)); 418 419 /* 420 * Other Len. 421 */ 422 RETERR(uint16_tobuffer(tsig->otherlen, target)); 423 424 /* 425 * Other Data. 426 */ 427 return (mem_tobuffer(target, tsig->other, tsig->otherlen)); 428} 429 430static inline isc_result_t 431tostruct_any_tsig(ARGS_TOSTRUCT) { 432 dns_rdata_any_tsig_t *tsig; 433 dns_name_t alg; 434 isc_region_t sr; 435 436 REQUIRE(rdata->type == 250); 437 REQUIRE(rdata->rdclass == 255); 438 REQUIRE(rdata->length != 0); 439 440 tsig = (dns_rdata_any_tsig_t *) target; 441 tsig->common.rdclass = rdata->rdclass; 442 tsig->common.rdtype = rdata->type; 443 ISC_LINK_INIT(&tsig->common, link); 444 445 dns_rdata_toregion(rdata, &sr); 446 447 /* 448 * Algorithm Name. 449 */ 450 dns_name_init(&alg, NULL); 451 dns_name_fromregion(&alg, &sr); 452 dns_name_init(&tsig->algorithm, NULL); 453 RETERR(name_duporclone(&alg, mctx, &tsig->algorithm)); 454 455 isc_region_consume(&sr, name_length(&tsig->algorithm)); 456 457 /* 458 * Time Signed. 459 */ 460 INSIST(sr.length >= 6); 461 tsig->timesigned = ((isc_uint64_t)sr.base[0] << 40) | 462 ((isc_uint64_t)sr.base[1] << 32) | 463 ((isc_uint64_t)sr.base[2] << 24) | 464 ((isc_uint64_t)sr.base[3] << 16) | 465 ((isc_uint64_t)sr.base[4] << 8) | 466 (isc_uint64_t)sr.base[5]; 467 isc_region_consume(&sr, 6); 468 469 /* 470 * Fudge. 471 */ 472 tsig->fudge = uint16_fromregion(&sr); 473 isc_region_consume(&sr, 2); 474 475 /* 476 * Signature Size. 477 */ 478 tsig->siglen = uint16_fromregion(&sr); 479 isc_region_consume(&sr, 2); 480 481 /* 482 * Signature. 483 */ 484 INSIST(sr.length >= tsig->siglen); 485 tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen); 486 if (tsig->signature == NULL) 487 goto cleanup; 488 isc_region_consume(&sr, tsig->siglen); 489 490 /* 491 * Original ID. 492 */ 493 tsig->originalid = uint16_fromregion(&sr); 494 isc_region_consume(&sr, 2); 495 496 /* 497 * Error. 498 */ 499 tsig->error = uint16_fromregion(&sr); 500 isc_region_consume(&sr, 2); 501 502 /* 503 * Other Size. 504 */ 505 tsig->otherlen = uint16_fromregion(&sr); 506 isc_region_consume(&sr, 2); 507 508 /* 509 * Other. 510 */ 511 INSIST(sr.length == tsig->otherlen); 512 tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen); 513 if (tsig->other == NULL) 514 goto cleanup; 515 516 tsig->mctx = mctx; 517 return (ISC_R_SUCCESS); 518 519 cleanup: 520 if (mctx != NULL) 521 dns_name_free(&tsig->algorithm, tsig->mctx); 522 if (mctx != NULL && tsig->signature != NULL) 523 isc_mem_free(mctx, tsig->signature); 524 return (ISC_R_NOMEMORY); 525} 526 527static inline void 528freestruct_any_tsig(ARGS_FREESTRUCT) { 529 dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *) source; 530 531 REQUIRE(source != NULL); 532 REQUIRE(tsig->common.rdclass == 255); 533 REQUIRE(tsig->common.rdtype == 250); 534 535 if (tsig->mctx == NULL) 536 return; 537 538 dns_name_free(&tsig->algorithm, tsig->mctx); 539 if (tsig->signature != NULL) 540 isc_mem_free(tsig->mctx, tsig->signature); 541 if (tsig->other != NULL) 542 isc_mem_free(tsig->mctx, tsig->other); 543 tsig->mctx = NULL; 544} 545 546static inline isc_result_t 547additionaldata_any_tsig(ARGS_ADDLDATA) { 548 REQUIRE(rdata->type == 250); 549 REQUIRE(rdata->rdclass == 255); 550 551 UNUSED(rdata); 552 UNUSED(add); 553 UNUSED(arg); 554 555 return (ISC_R_SUCCESS); 556} 557 558static inline isc_result_t 559digest_any_tsig(ARGS_DIGEST) { 560 561 REQUIRE(rdata->type == 250); 562 REQUIRE(rdata->rdclass == 255); 563 564 UNUSED(rdata); 565 UNUSED(digest); 566 UNUSED(arg); 567 568 return (ISC_R_NOTIMPLEMENTED); 569} 570 571static inline isc_boolean_t 572checkowner_any_tsig(ARGS_CHECKOWNER) { 573 574 REQUIRE(type == 250); 575 REQUIRE(rdclass == 255); 576 577 UNUSED(name); 578 UNUSED(type); 579 UNUSED(rdclass); 580 UNUSED(wildcard); 581 582 return (ISC_TRUE); 583} 584 585static inline isc_boolean_t 586checknames_any_tsig(ARGS_CHECKNAMES) { 587 588 REQUIRE(rdata->type == 250); 589 REQUIRE(rdata->rdclass == 250); 590 591 UNUSED(rdata); 592 UNUSED(owner); 593 UNUSED(bad); 594 595 return (ISC_TRUE); 596} 597 598static inline int 599casecompare_any_tsig(ARGS_COMPARE) { 600 return (compare_any_tsig(rdata1, rdata2)); 601} 602 603#endif /* RDATA_ANY_255_TSIG_250_C */ 604