static inline isc_result_t towire_rrsig(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == 46); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_rdata_toregion(rdata, &sr); /* * type covered: 2 * algorithm: 1 * labels: 1 * original ttl: 4 * signature expiration: 4 * time signed: 4 * key footprint: 2 */ RETERR(mem_tobuffer(target, sr.base, 18)); isc_region_consume(&sr, 18); /* * Signer. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_towire(&name, cctx, target)); /* * Signature. */ return (mem_tobuffer(target, sr.base, sr.length)); }
static inline isc_result_t tostruct_isdn(ARGS_TOSTRUCT) { dns_rdata_isdn_t *isdn = target; isc_region_t r; REQUIRE(rdata->type == 20); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); isdn->common.rdclass = rdata->rdclass; isdn->common.rdtype = rdata->type; ISC_LINK_INIT(&isdn->common, link); dns_rdata_toregion(rdata, &r); isdn->isdn_len = uint8_fromregion(&r); isc_region_consume(&r, 1); isdn->isdn = mem_maybedup(mctx, r.base, isdn->isdn_len); if (isdn->isdn == NULL) return (ISC_R_NOMEMORY); isc_region_consume(&r, isdn->isdn_len); isdn->subaddress_len = uint8_fromregion(&r); isc_region_consume(&r, 1); isdn->subaddress = mem_maybedup(mctx, r.base, isdn->subaddress_len); if (isdn->subaddress == NULL) goto cleanup; isdn->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && isdn->isdn != NULL) isc_mem_free(mctx, isdn->isdn); return (ISC_R_NOMEMORY); }
static inline isc_result_t totext_afsdb(ARGS_TOTEXT) { dns_name_t name; dns_name_t prefix; isc_region_t region; char buf[sizeof("64000 ")]; isc_boolean_t sub; unsigned int num; REQUIRE(rdata->type == dns_rdatatype_afsdb); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); }
static inline isc_result_t towire_afsdb(ARGS_TOWIRE) { isc_region_t tr; isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_afsdb); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); isc_buffer_availableregion(target, &tr); dns_rdata_toregion(rdata, &sr); if (tr.length < 2) return (ISC_R_NOSPACE); memmove(tr.base, sr.base, 2); isc_region_consume(&sr, 2); isc_buffer_add(target, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); return (dns_name_towire(&name, cctx, target)); }
static inline isc_result_t towire_in_srv(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t sr; REQUIRE(rdata->type == 33); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); /* * Priority, weight, port. */ dns_rdata_toregion(rdata, &sr); RETERR(mem_tobuffer(target, sr.base, 6)); isc_region_consume(&sr, 6); /* * Target. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); return (dns_name_towire(&name, cctx, target)); }
static inline isc_result_t tostruct_mx(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_mx_t *mx = target; dns_name_t name; REQUIRE(rdata->type == 15); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); mx->common.rdclass = rdata->rdclass; mx->common.rdtype = rdata->type; ISC_LINK_INIT(&mx->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); mx->pref = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&mx->mx, NULL); RETERR(name_duporclone(&name, mctx, &mx->mx)); mx->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t totext_dnskey(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; char algbuf[DNS_NAME_FORMATSIZE]; const char *keyinfo; REQUIRE(rdata->type == 48); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if ((flags & DNS_KEYFLAG_KSK) != 0) { if (flags & DNS_KEYFLAG_REVOKE) keyinfo = "revoked KSK"; else keyinfo = "KSK"; } else keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); dns_name_format(&name, algbuf, sizeof(algbuf)); } else { dns_secalg_format((dns_secalg_t) algorithm, algbuf, sizeof(algbuf)); } /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 0, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; RETERR(str_totext(" ; ", target)); RETERR(str_totext(keyinfo, target)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(algbuf, target)); RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } return (ISC_R_SUCCESS); }
static inline isc_result_t totext_keydata(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; unsigned long refresh, add, remove; char algbuf[DNS_NAME_FORMATSIZE]; const char *keyinfo; REQUIRE(rdata->type == 65533); if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16) return (unknown_totext(rdata, tctx, target)); dns_rdata_toregion(rdata, &sr); /* refresh timer */ refresh = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(refresh, target)); RETERR(str_totext(" ", target)); /* add hold-down */ add = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(add, target)); RETERR(str_totext(" ", target)); /* remove hold-down */ remove = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(remove, target)); RETERR(str_totext(" ", target)); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if ((flags & DNS_KEYFLAG_KSK) != 0) { if (flags & DNS_KEYFLAG_REVOKE) keyinfo = "revoked KSK"; else keyinfo = "KSK"; } else keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; isc_time_t t; RETERR(str_totext(" ; ", target)); RETERR(str_totext(keyinfo, target)); dns_secalg_format((dns_secalg_t) algorithm, algbuf, sizeof(algbuf)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(algbuf, target)); RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); /* Skip over refresh, addhd, and removehd */ isc_region_consume(&tmpr, 12); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { isc_stdtime_t now; isc_stdtime_get(&now); RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; next refresh: ", target)); isc_time_set(&t, refresh, 0); isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf)); RETERR(str_totext(rbuf, target)); if (add == 0) { RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; no trust", target)); } else { RETERR(str_totext(tctx->linebreak, target)); if (add < now) { RETERR(str_totext("; trusted since: ", target)); } else { RETERR(str_totext("; trust pending: ", target)); } isc_time_set(&t, add, 0); isc_time_formathttptimestamp(&t, abuf, sizeof(abuf)); RETERR(str_totext(abuf, target)); } if (remove != 0) { RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; removal pending: ", target)); isc_time_set(&t, remove, 0); isc_time_formathttptimestamp(&t, dbuf, sizeof(dbuf)); RETERR(str_totext(dbuf, target)); } } } return (ISC_R_SUCCESS); }
static inline isc_result_t totext_nsec3(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j; unsigned char hash; unsigned char flags; char buf[sizeof("TYPE65535")]; isc_uint32_t iterations; REQUIRE(rdata->type == dns_rdatatype_nsec3); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* Hash */ hash = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", hash); RETERR(str_totext(buf, target)); /* Flags */ flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", flags); RETERR(str_totext(buf, target)); /* Iterations */ iterations = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", iterations); RETERR(str_totext(buf, target)); /* Salt */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); if (j != 0) { i = sr.length; sr.length = j; RETERR(isc_hex_totext(&sr, 1, "", target)); sr.length = i - j; } else RETERR(str_totext("-", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* Next hash */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); i = sr.length; sr.length = j; RETERR(isc_base32hexnp_totext(&sr, 1, "", target)); sr.length = i - j; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) RETERR(str_totext(" ", target)); RETERR(typemap_totext(&sr, tctx, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_tkey(ARGS_TOSTRUCT) { dns_rdata_tkey_t *tkey = target; dns_name_t alg; isc_region_t sr; REQUIRE(rdata->type == 249); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); tkey->common.rdclass = rdata->rdclass; tkey->common.rdtype = rdata->type; ISC_LINK_INIT(&tkey->common, link); dns_rdata_toregion(rdata, &sr); /* * Algorithm Name. */ dns_name_init(&alg, NULL); dns_name_fromregion(&alg, &sr); dns_name_init(&tkey->algorithm, NULL); RETERR(name_duporclone(&alg, mctx, &tkey->algorithm)); isc_region_consume(&sr, name_length(&tkey->algorithm)); /* * Inception. */ tkey->inception = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Expire. */ tkey->expire = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Mode. */ tkey->mode = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Error. */ tkey->error = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Key size. */ tkey->keylen = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Key. */ tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen); if (tkey->key == NULL) goto cleanup; isc_region_consume(&sr, tkey->keylen); /* * Other size. */ tkey->otherlen = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Other. */ tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen); if (tkey->other == NULL) goto cleanup; tkey->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&tkey->algorithm, mctx); if (mctx != NULL && tkey->key != NULL) isc_mem_free(mctx, tkey->key); return (ISC_R_NOMEMORY); }
static inline isc_result_t tostruct_sig(ARGS_TOSTRUCT) { isc_region_t sr; dns_rdata_sig_t *sig = target; dns_name_t signer; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sig->common.rdclass = rdata->rdclass; sig->common.rdtype = rdata->type; ISC_LINK_INIT(&sig->common, link); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ sig->covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Algorithm. */ sig->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Labels. */ sig->labels = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Original TTL. */ sig->originalttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Expire time. */ sig->timeexpire = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Time signed. */ sig->timesigned = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Key ID. */ sig->keyid = uint16_fromregion(&sr); isc_region_consume(&sr, 2); dns_name_init(&signer, NULL); dns_name_fromregion(&signer, &sr); dns_name_init(&sig->signer, NULL); RETERR(name_duporclone(&signer, mctx, &sig->signer)); isc_region_consume(&sr, name_length(&sig->signer)); /* * Signature. */ sig->siglen = sr.length; sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); if (sig->signature == NULL) goto cleanup; sig->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&sig->signer, mctx); return (ISC_R_NOMEMORY); }
static inline isc_result_t totext_in_apl(ARGS_TOTEXT) { isc_region_t sr; isc_region_t ir; isc_uint16_t afi; isc_uint8_t prefix; isc_uint8_t len; isc_boolean_t neg; unsigned char buf[16]; char txt[sizeof(" !64000:")]; const char *sep = ""; int n; REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); ir.base = buf; ir.length = sizeof(buf); while (sr.length > 0) { INSIST(sr.length >= 4); afi = uint16_fromregion(&sr); isc_region_consume(&sr, 2); prefix = *sr.base; isc_region_consume(&sr, 1); len = (*sr.base & 0x7f); neg = ISC_TF((*sr.base & 0x80) != 0); isc_region_consume(&sr, 1); INSIST(len <= sr.length); n = snprintf(txt, sizeof(txt), "%s%s%u:", sep, neg ? "!" : "", afi); INSIST(n < (int)sizeof(txt)); RETERR(str_totext(txt, target)); switch (afi) { case 1: INSIST(len <= 4); INSIST(prefix <= 32); memset(buf, 0, sizeof(buf)); memmove(buf, sr.base, len); RETERR(inet_totext(AF_INET, &ir, target)); break; case 2: INSIST(len <= 16); INSIST(prefix <= 128); memset(buf, 0, sizeof(buf)); memmove(buf, sr.base, len); RETERR(inet_totext(AF_INET6, &ir, target)); break; default: return (ISC_R_NOTIMPLEMENTED); } n = snprintf(txt, sizeof(txt), "/%u", prefix); INSIST(n < (int)sizeof(txt)); RETERR(str_totext(txt, target)); isc_region_consume(&sr, len); sep = " "; } return (ISC_R_SUCCESS); }
static inline isc_result_t totext_hip(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; unsigned int length, key_len, hit_len; unsigned char algorithm; char buf[sizeof("225 ")]; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); hit_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); key_len = uint16_fromregion(®ion); isc_region_consume(®ion, 2); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Algorithm */ sprintf(buf, "%u ", algorithm); RETERR(str_totext(buf, target)); /* * HIT. */ INSIST(hit_len < region.length); length = region.length; region.length = hit_len; RETERR(isc_hex_totext(®ion, 1, "", target)); region.length = length - hit_len; RETERR(str_totext(tctx->linebreak, target)); /* * Public KEY. */ INSIST(key_len <= region.length); length = region.length; region.length = key_len; RETERR(isc_base64_totext(®ion, 1, "", target)); region.length = length - key_len; RETERR(str_totext(tctx->linebreak, target)); /* * Rendezvous Servers. */ dns_name_init(&name, NULL); while (region.length > 0) { dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name.length); if (region.length > 0) RETERR(str_totext(tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_naptr(ARGS_TOSTRUCT) { dns_rdata_naptr_t *naptr = target; isc_region_t r; isc_result_t result; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_naptr); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); naptr->common.rdclass = rdata->rdclass; naptr->common.rdtype = rdata->type; ISC_LINK_INIT(&naptr->common, link); naptr->flags = NULL; naptr->service = NULL; naptr->regexp = NULL; dns_rdata_toregion(rdata, &r); naptr->order = uint16_fromregion(&r); isc_region_consume(&r, 2); naptr->preference = uint16_fromregion(&r); isc_region_consume(&r, 2); naptr->flags_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->flags_len <= r.length); naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len); if (naptr->flags == NULL) goto cleanup; isc_region_consume(&r, naptr->flags_len); naptr->service_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->service_len <= r.length); naptr->service = mem_maybedup(mctx, r.base, naptr->service_len); if (naptr->service == NULL) goto cleanup; isc_region_consume(&r, naptr->service_len); naptr->regexp_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->regexp_len <= r.length); naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len); if (naptr->regexp == NULL) goto cleanup; isc_region_consume(&r, naptr->regexp_len); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); dns_name_init(&naptr->replacement, NULL); result = name_duporclone(&name, mctx, &naptr->replacement); if (result != ISC_R_SUCCESS) goto cleanup; naptr->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && naptr->flags != NULL) isc_mem_free(mctx, naptr->flags); if (mctx != NULL && naptr->service != NULL) isc_mem_free(mctx, naptr->service); if (mctx != NULL && naptr->regexp != NULL) isc_mem_free(mctx, naptr->regexp); return (ISC_R_NOMEMORY); }
static inline int compare_naptr(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order, len; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_naptr); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); /* * Order, preference. */ order = memcmp(region1.base, region2.base, 4); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, 4); isc_region_consume(®ion2, 4); /* * Flags. */ len = ISC_MIN(region1.base[0], region2.base[0]); order = memcmp(region1.base, region2.base, len + 1); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, region1.base[0] + 1); isc_region_consume(®ion2, region2.base[0] + 1); /* * Service. */ len = ISC_MIN(region1.base[0], region2.base[0]); order = memcmp(region1.base, region2.base, len + 1); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, region1.base[0] + 1); isc_region_consume(®ion2, region2.base[0] + 1); /* * Regexp. */ len = ISC_MIN(region1.base[0], region2.base[0]); order = memcmp(region1.base, region2.base, len + 1); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, region1.base[0] + 1); isc_region_consume(®ion2, region2.base[0] + 1); /* * Replacement. */ dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); }
/*% * Configure static-stub zone. */ static isc_result_t configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone, const char *zname, const char *dbtype) { int i = 0; const cfg_obj_t *obj; isc_mem_t *mctx = dns_zone_getmctx(zone); dns_db_t *db = NULL; dns_dbversion_t *dbversion = NULL; dns_dbnode_t *apexnode = NULL; dns_name_t apexname; isc_result_t result; dns_rdataset_t rdataset; dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa; dns_rdatalist_t* rdatalists[] = { &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL }; dns_rdata_t *rdata; isc_region_t region; /* Create the DB beforehand */ RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone), dns_dbtype_stub, dns_zone_getclass(zone), 0, NULL, &db)); dns_zone_setdb(zone, db); dns_rdatalist_init(&rdatalist_ns); rdatalist_ns.rdclass = dns_zone_getclass(zone); rdatalist_ns.type = dns_rdatatype_ns; rdatalist_ns.ttl = STATICSTUB_SERVER_TTL; dns_rdatalist_init(&rdatalist_a); rdatalist_a.rdclass = dns_zone_getclass(zone); rdatalist_a.type = dns_rdatatype_a; rdatalist_a.ttl = STATICSTUB_SERVER_TTL; dns_rdatalist_init(&rdatalist_aaaa); rdatalist_aaaa.rdclass = dns_zone_getclass(zone); rdatalist_aaaa.type = dns_rdatatype_aaaa; rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL; /* Prepare zone RRs from the configuration */ obj = NULL; result = cfg_map_get(zconfig, "server-addresses", &obj); if (result == ISC_R_SUCCESS) { INSIST(obj != NULL); result = configure_staticstub_serveraddrs(obj, zone, &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa); if (result != ISC_R_SUCCESS) goto cleanup; } obj = NULL; result = cfg_map_get(zconfig, "server-names", &obj); if (result == ISC_R_SUCCESS) { INSIST(obj != NULL); result = configure_staticstub_servernames(obj, zone, &rdatalist_ns, zname); if (result != ISC_R_SUCCESS) goto cleanup; } /* * Sanity check: there should be at least one NS RR at the zone apex * to trigger delegation. */ if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "No NS record is configured for a " "static-stub zone '%s'", zname); result = ISC_R_FAILURE; goto cleanup; } /* * Now add NS and glue A/AAAA RRsets to the zone DB. * First open a new version for the add operation and get a pointer * to the apex node (all RRs are of the apex name). */ result = dns_db_newversion(db, &dbversion); if (result != ISC_R_SUCCESS) goto cleanup; dns_name_init(&apexname, NULL); dns_name_clone(dns_zone_getorigin(zone), &apexname); result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode); if (result != ISC_R_SUCCESS) goto cleanup; /* Add NS RRset */ dns_rdataset_init(&rdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset) == ISC_R_SUCCESS); result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0, NULL); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup; /* Add glue A RRset, if any */ if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) { RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset) == ISC_R_SUCCESS); result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0, NULL); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup; } /* Add glue AAAA RRset, if any */ if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) { RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa, &rdataset) == ISC_R_SUCCESS); result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0, NULL); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup; } result = ISC_R_SUCCESS; cleanup: if (apexnode != NULL) dns_db_detachnode(db, &apexnode); if (dbversion != NULL) dns_db_closeversion(db, &dbversion, ISC_TRUE); if (db != NULL) dns_db_detach(&db); for (i = 0; rdatalists[i] != NULL; i++) { while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) { ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link); dns_rdata_toregion(rdata, ®ion); isc_mem_put(mctx, rdata, sizeof(*rdata) + region.length); } } return (result); }
isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { dns_fixedname_t fname; dns_name_t *name; unsigned char digest[ISC_SHA256_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; isc_sha1_t sha1; isc_sha256_t sha256; #ifdef HAVE_OPENSSL_GOST EVP_MD_CTX ctx; const EVP_MD *md; #endif REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); if (!dns_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); (void)dns_name_downcase(owner, name, NULL); memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); switch (digest_type) { case DNS_DSDIGEST_SHA1: isc_sha1_init(&sha1); dns_name_toregion(name, &r); isc_sha1_update(&sha1, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); break; #ifdef HAVE_OPENSSL_GOST #define CHECK(x) \ if ((x) != 1) { \ EVP_MD_CTX_cleanup(&ctx); \ return (DST_R_OPENSSLFAILURE); \ } case DNS_DSDIGEST_GOST: md = EVP_gost(); if (md == NULL) return (DST_R_OPENSSLFAILURE); EVP_MD_CTX_init(&ctx); CHECK(EVP_DigestInit(&ctx, md)); dns_name_toregion(name, &r); CHECK(EVP_DigestUpdate(&ctx, (const void *) r.base, (size_t) r.length)); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); CHECK(EVP_DigestUpdate(&ctx, (const void *) r.base, (size_t) r.length)); CHECK(EVP_DigestFinal(&ctx, digest, NULL)); break; #endif default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); isc_sha256_update(&sha256, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha256_update(&sha256, r.base, r.length); isc_sha256_final(digest, &sha256); break; } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); ds.digest_type = digest_type; switch (digest_type) { case DNS_DSDIGEST_SHA1: ds.length = ISC_SHA1_DIGESTLENGTH; break; #ifdef HAVE_OPENSSL_GOST case DNS_DSDIGEST_GOST: ds.length = ISC_GOST_DIGESTLENGTH; break; #endif default: ds.length = ISC_SHA256_DIGESTLENGTH; break; } ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, &ds, &b)); }
static isc_result_t add_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl, dns_namelist_t *namelist) { isc_result_t result; isc_region_t r, newr; dns_rdata_t *newrdata = NULL; dns_name_t *newname = NULL; dns_rdatalist_t *newlist = NULL; dns_rdataset_t *newset = NULL; isc_buffer_t *tmprdatabuf = NULL; RETERR(dns_message_gettemprdata(msg, &newrdata)); dns_rdata_toregion(rdata, &r); RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length)); isc_buffer_availableregion(tmprdatabuf, &newr); memmove(newr.base, r.base, r.length); dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr); dns_message_takebuffer(msg, &tmprdatabuf); RETERR(dns_message_gettempname(msg, &newname)); dns_name_init(newname, NULL); RETERR(dns_name_dup(name, msg->mctx, newname)); RETERR(dns_message_gettemprdatalist(msg, &newlist)); newlist->rdclass = newrdata->rdclass; newlist->type = newrdata->type; newlist->covers = 0; newlist->ttl = ttl; ISC_LIST_INIT(newlist->rdata); ISC_LIST_APPEND(newlist->rdata, newrdata, link); RETERR(dns_message_gettemprdataset(msg, &newset)); dns_rdataset_init(newset); RETERR(dns_rdatalist_tordataset(newlist, newset)); ISC_LIST_INIT(newname->list); ISC_LIST_APPEND(newname->list, newset, link); ISC_LIST_APPEND(*namelist, newname, link); return (ISC_R_SUCCESS); failure: if (newrdata != NULL) { if (ISC_LINK_LINKED(newrdata, link)) { INSIST(newlist != NULL); ISC_LIST_UNLINK(newlist->rdata, newrdata, link); } dns_message_puttemprdata(msg, &newrdata); } if (newname != NULL) dns_message_puttempname(msg, &newname); if (newset != NULL) { dns_rdataset_disassociate(newset); dns_message_puttemprdataset(msg, &newset); } if (newlist != NULL) dns_message_puttemprdatalist(msg, &newlist); return (result); }
isc_result_t dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, dst_key_t *key) { dns_rdata_sig_t sig; /* SIG(0) */ unsigned char header[DNS_MESSAGE_HEADERLEN]; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r, source_r, sig_r, header_r; isc_stdtime_t now; dst_context_t *ctx = NULL; isc_mem_t *mctx; isc_result_t result; isc_uint16_t addcount; isc_boolean_t signeedsfree = ISC_FALSE; REQUIRE(source != NULL); REQUIRE(msg != NULL); REQUIRE(key != NULL); mctx = msg->mctx; msg->verify_attempted = 1; if (is_response(msg)) { if (msg->query.base == NULL) return (DNS_R_UNEXPECTEDTSIG); } isc_buffer_usedregion(source, &source_r); RETERR(dns_rdataset_first(msg->sig0)); dns_rdataset_current(msg->sig0, &rdata); RETERR(dns_rdata_tostruct(&rdata, &sig, NULL)); signeedsfree = ISC_TRUE; if (sig.labels != 0) { result = DNS_R_SIGINVALID; goto failure; } if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { result = DNS_R_SIGINVALID; msg->sig0status = dns_tsigerror_badtime; goto failure; } isc_stdtime_get(&now); if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) { result = DNS_R_SIGFUTURE; msg->sig0status = dns_tsigerror_badtime; goto failure; } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) { result = DNS_R_SIGEXPIRED; msg->sig0status = dns_tsigerror_badtime; goto failure; } if (!dns_name_equal(dst_key_name(key), &sig.signer)) { result = DNS_R_SIGINVALID; msg->sig0status = dns_tsigerror_badkey; goto failure; } RETERR(dst_context_create(key, mctx, &ctx)); /* * Digest the SIG(0) record, except for the signature. */ dns_rdata_toregion(&rdata, &r); r.length -= sig.siglen; RETERR(dst_context_adddata(ctx, &r)); /* * If this is a response, digest the query. */ if (is_response(msg)) RETERR(dst_context_adddata(ctx, &msg->query)); /* * Extract the header. */ memcpy(header, source_r.base, DNS_MESSAGE_HEADERLEN); /* * Decrement the additional field counter. */ memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); addcount = htons((isc_uint16_t)(ntohs(addcount) - 1)); memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); /* * Digest the modified header. */ header_r.base = (unsigned char *) header; header_r.length = DNS_MESSAGE_HEADERLEN; RETERR(dst_context_adddata(ctx, &header_r)); /* * Digest all non-SIG(0) records. */ r.base = source_r.base + DNS_MESSAGE_HEADERLEN; r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; RETERR(dst_context_adddata(ctx, &r)); sig_r.base = sig.signature; sig_r.length = sig.siglen; result = dst_context_verify(ctx, &sig_r); if (result != ISC_R_SUCCESS) { msg->sig0status = dns_tsigerror_badsig; goto failure; } msg->verified_sig = 1; dst_context_destroy(&ctx); dns_rdata_freestruct(&sig); return (ISC_R_SUCCESS); failure: if (signeedsfree) dns_rdata_freestruct(&sig); if (ctx != NULL) dst_context_destroy(&ctx); return (result); }
static inline isc_result_t totext_ipseckey(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; char buf[sizeof("255 ")]; unsigned short num; unsigned short gateway; REQUIRE(rdata->type == 45); REQUIRE(rdata->length >= 3); dns_name_init(&name, NULL); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Precedence. */ dns_rdata_toregion(rdata, ®ion); num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway type. */ gateway = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", gateway); RETERR(str_totext(buf, target)); /* * Algorithm. */ num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway. */ switch (gateway) { case 0: RETERR(str_totext(".", target)); break; case 1: RETERR(inet_totext(AF_INET, ®ion, target)); isc_region_consume(®ion, 4); break; case 2: RETERR(inet_totext(AF_INET6, ®ion, target)); isc_region_consume(®ion, 16); break; case 3: dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name_length(&name)); break; } /* * Key. */ if (region.length > 0U) { RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(®ion, 60, "", target)); else RETERR(isc_base64_totext(®ion, tctx->width - 2, tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t totext_sig(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("4294967295")]; dns_rdatatype_t covered; unsigned long ttl; unsigned long when; unsigned long exp; unsigned long foot; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * XXXAG We should have something like dns_rdatatype_isknown() * that does the right thing with type 0. */ if (dns_rdatatype_isknown(covered) && covered != 0) { RETERR(dns_rdatatype_totext(covered, target)); } else { sprintf(buf, "%u", covered); RETERR(str_totext(buf, target)); } RETERR(str_totext(" ", target)); /* * Algorithm. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Labels. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Ttl. */ ttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu", ttl); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Sig exp. */ exp = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(exp, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* * Time signed. */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* * Footprint. */ foot = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", foot); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Signer. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); /* * Sig. */ RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t tostruct_ipseckey(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_ipseckey_t *ipseckey = target; dns_name_t name; isc_uint32_t n; REQUIRE(rdata->type == 45); REQUIRE(target != NULL); REQUIRE(rdata->length >= 3); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); ipseckey->common.rdclass = rdata->rdclass; ipseckey->common.rdtype = rdata->type; ISC_LINK_INIT(&ipseckey->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); ipseckey->precedence = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ipseckey->gateway_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ipseckey->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); switch (ipseckey->gateway_type) { case 0: break; case 1: n = uint32_fromregion(®ion); ipseckey->in_addr.s_addr = htonl(n); isc_region_consume(®ion, 4); break; case 2: memmove(ipseckey->in6_addr.s6_addr, region.base, 16); isc_region_consume(®ion, 16); break; case 3: dns_name_init(&ipseckey->gateway, NULL); dns_name_fromregion(&name, ®ion); RETERR(name_duporclone(&name, mctx, &ipseckey->gateway)); isc_region_consume(®ion, name_length(&name)); break; } ipseckey->keylength = region.length; if (ipseckey->keylength != 0U) { ipseckey->key = mem_maybedup(mctx, region.base, ipseckey->keylength); if (ipseckey->key == NULL) { if (ipseckey->gateway_type == 3) dns_name_free(&ipseckey->gateway, ipseckey->mctx); return (ISC_R_NOMEMORY); } } else ipseckey->key = NULL; ipseckey->mctx = mctx; return (ISC_R_SUCCESS); }
static inline isc_result_t totext_tkey(ARGS_TOTEXT) { isc_region_t sr, dr; char buf[sizeof("4294967295 ")]; unsigned long n; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == 249); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Algorithm. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); isc_region_consume(&sr, name_length(&name)); /* * Inception. */ n = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); /* * Expiration. */ n = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); /* * Mode. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); /* * Error. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) RETERR(str_totext(" ", target)); else { sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); } /* * Key Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", n); RETERR(str_totext(buf, target)); /* * Key Data. */ REQUIRE(n <= sr.length); dr = sr; dr.length = n; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ) ", target)); else RETERR(str_totext(" ", target)); isc_region_consume(&sr, n); /* * Other Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", n); RETERR(str_totext(buf, target)); /* * Other Data. */ REQUIRE(n <= sr.length); if (n != 0U) { dr = sr; dr.length = n; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); } return (ISC_R_SUCCESS); }
static inline isc_result_t totext_soa(ARGS_TOTEXT) { isc_region_t dregion; dns_name_t mname; dns_name_t rname; dns_name_t prefix; isc_boolean_t sub; int i; isc_boolean_t multiline; isc_boolean_t comment; REQUIRE(rdata->type == 6); REQUIRE(rdata->length != 0); multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0); comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0); dns_name_init(&mname, NULL); dns_name_init(&rname, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, &dregion); dns_name_fromregion(&mname, &dregion); isc_region_consume(&dregion, name_length(&mname)); dns_name_fromregion(&rname, &dregion); isc_region_consume(&dregion, name_length(&rname)); sub = name_prefix(&mname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&rname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); if (multiline) RETERR(str_totext(" (" , target)); RETERR(str_totext(tctx->linebreak, target)); for (i = 0; i < 5; i++) { char buf[sizeof("2147483647")]; unsigned long num; int numlen; num = uint32_fromregion(&dregion); isc_region_consume(&dregion, 4); numlen = snprintf(buf, sizeof(buf), "%lu", num); INSIST(numlen != -1 && (size_t)numlen < sizeof(buf)); RETERR(str_totext(buf, target)); if (multiline && comment) { RETERR(str_totext(" ; " + (unsigned int)numlen, target)); RETERR(str_totext(soa_fieldnames[i], target)); /* Print times in week/day/hour/minute/second form */ if (i >= 1) { RETERR(str_totext(" (", target)); RETERR(dns_ttl_totext(num, ISC_TRUE, target)); RETERR(str_totext(")", target)); } RETERR(str_totext(tctx->linebreak, target)); } else if (i < 4) { RETERR(str_totext(tctx->linebreak, target)); } } if (multiline) RETERR(str_totext(")", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t totext_keydata(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; unsigned long when; char algbuf[DNS_NAME_FORMATSIZE]; const char *keyinfo; REQUIRE(rdata->type == 65533); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* refresh timer */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* add hold-down */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* remove hold-down */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if ((flags & DNS_KEYFLAG_KSK) != 0) { if (flags & DNS_KEYFLAG_REVOKE) keyinfo = "revoked KSK"; else keyinfo = "KSK"; } else keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; RETERR(str_totext(" ; ", target)); RETERR(str_totext(keyinfo, target)); dns_secalg_format((dns_secalg_t) algorithm, algbuf, sizeof(algbuf)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(algbuf, target)); RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); /* Skip over refresh, addhd, and removehd */ isc_region_consume(&tmpr, 12); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } return (ISC_R_SUCCESS); }
isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { dns_fixedname_t fname; dns_name_t *name; unsigned char digest[ISC_SHA384_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; isc_sha1_t sha1; isc_sha256_t sha256; isc_sha384_t sha384; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) isc_gost_t gost; #endif REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); if (!dst_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); (void)dns_name_downcase(owner, name, NULL); memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); switch (digest_type) { case DNS_DSDIGEST_SHA1: isc_sha1_init(&sha1); dns_name_toregion(name, &r); isc_sha1_update(&sha1, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); break; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) #define RETERR(x) do { \ isc_result_t ret = (x); \ if (ret != ISC_R_SUCCESS) { \ isc_gost_invalidate(&gost); \ return (ret); \ } \ } while (/*CONSTCOND*/0) case DNS_DSDIGEST_GOST: RETERR(isc_gost_init(&gost)); dns_name_toregion(name, &r); RETERR(isc_gost_update(&gost, r.base, r.length)); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); RETERR(isc_gost_update(&gost, r.base, r.length)); RETERR(isc_gost_final(&gost, digest)); break; #endif case DNS_DSDIGEST_SHA384: isc_sha384_init(&sha384); dns_name_toregion(name, &r); isc_sha384_update(&sha384, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha384_update(&sha384, r.base, r.length); isc_sha384_final(digest, &sha384); break; case DNS_DSDIGEST_SHA256: default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); isc_sha256_update(&sha256, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha256_update(&sha256, r.base, r.length); isc_sha256_final(digest, &sha256); break; } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); ds.digest_type = digest_type; switch (digest_type) { case DNS_DSDIGEST_SHA1: ds.length = ISC_SHA1_DIGESTLENGTH; break; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) case DNS_DSDIGEST_GOST: ds.length = ISC_GOST_DIGESTLENGTH; break; #endif case DNS_DSDIGEST_SHA384: ds.length = ISC_SHA384_DIGESTLENGTH; break; case DNS_DSDIGEST_SHA256: default: ds.length = ISC_SHA256_DIGESTLENGTH; break; } ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, &ds, &b)); }
static inline isc_result_t totext_keydata(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; unsigned long when; REQUIRE(rdata->type == 65533); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* refresh timer */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* add hold-down */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* remove hold-down */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) { isc_region_t tmpr; RETERR(str_totext(" ; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); /* Skip over refresh, addhd, and removehd */ isc_region_consume(&tmpr, 12); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } return (ISC_R_SUCCESS); }
static inline isc_result_t totext_soa(ARGS_TOTEXT) { isc_region_t dregion; dns_name_t mname; dns_name_t rname; dns_name_t prefix; isc_boolean_t sub; int i; isc_boolean_t multiline; isc_boolean_t comment; REQUIRE(rdata->type == 6); REQUIRE(rdata->length != 0); multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0); if (multiline) comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0); else comment = ISC_FALSE; dns_name_init(&mname, NULL); dns_name_init(&rname, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, &dregion); dns_name_fromregion(&mname, &dregion); isc_region_consume(&dregion, name_length(&mname)); dns_name_fromregion(&rname, &dregion); isc_region_consume(&dregion, name_length(&rname)); sub = name_prefix(&mname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&rname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); if (multiline) RETERR(str_totext(" (" , target)); RETERR(str_totext(tctx->linebreak, target)); for (i = 0; i < 5; i++) { unsigned long num; unsigned int len = target->used; num = uint32_fromregion(&dregion); isc_region_consume(&dregion, 4); if (i >= 1 && (tctx->flags & DNS_STYLEFLAG_TTL_UNITS) != 0) { RETERR(dns_ttl_totext(num, ISC_FALSE, target)); } else { char buf[12]; sprintf(buf, "%lu", num); RETERR(str_totext(buf, target)); } if (comment) { len = target->used - len; INSIST(len <= 10); /* "0123456789 ; " */ RETERR(str_totext(len+" ; ", target)); RETERR(str_totext(soa_fieldnames[i], target)); /* Print times in week/day/hour/minute/second form */ if (i >= 1) { RETERR(str_totext(" (", target)); RETERR(dns_ttl_totext(num, ISC_TRUE, target)); RETERR(str_totext(")", target)); } RETERR(str_totext(tctx->linebreak, target)); } else if (i < 4) { RETERR(str_totext(tctx->linebreak, target)); } } if (multiline) RETERR(str_totext(")", target)); return (ISC_R_SUCCESS); }