static inline isc_result_t fromtext_dname(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == 39); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); }
static inline isc_boolean_t checknames_ch_a(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == 1); REQUIRE(rdata->rdclass == dns_rdataclass_ch); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); }
isc_result_t ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) { dns_name_t *newname; isc_result_t result; REQUIRE(VALID_LWSEARCHLIST(list)); REQUIRE(name != NULL); newname = isc_mem_get(list->mctx, sizeof(dns_name_t)); if (newname == NULL) return (ISC_R_NOMEMORY); dns_name_init(newname, NULL); result = dns_name_dup(name, list->mctx, newname); if (result != ISC_R_SUCCESS) { isc_mem_put(list->mctx, newname, sizeof(dns_name_t)); return (result); } ISC_LINK_INIT(newname, link); ISC_LIST_APPEND(list->names, newname, link); return (ISC_R_SUCCESS); }
static inline isc_result_t fromwire_mx(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; REQUIRE(type == 15); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sregion.base, 2)); isc_buffer_forward(source, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); }
static inline isc_result_t fromwire_cdnskey(ARGS_FROMWIRE) { unsigned char algorithm; isc_region_t sr; REQUIRE(type == dns_rdatatype_cdnskey); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); algorithm = sr.base[3]; RETERR(mem_tobuffer(target, sr.base, 4)); isc_region_consume(&sr, 4); isc_buffer_forward(source, 4); if (algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } /* * RSAMD5 computes key ID differently from other * algorithms: we need to ensure there's enough data * present for the computation */ if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) return (ISC_R_UNEXPECTEDEND); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); }
static inline isc_result_t fromtext_afsdb(ARGS_FROMTEXT) { isc_token_t token; isc_buffer_t buffer; dns_name_t name; isc_boolean_t ok; REQUIRE(type == 18); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Subtype. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Hostname. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); }
static inline isc_result_t additionaldata_rt(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; isc_result_t result; REQUIRE(rdata->type == 21); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); result = (add)(arg, &name, dns_rdatatype_x25); if (result != ISC_R_SUCCESS) return (result); result = (add)(arg, &name, dns_rdatatype_isdn); if (result != ISC_R_SUCCESS) return (result); return ((add)(arg, &name, dns_rdatatype_a)); }
/*% * Allocates a key structure and fills in some of the fields. */ static dst_key_t * get_key_struct(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, unsigned int bits, dns_rdataclass_t rdclass, isc_mem_t *mctx) { dst_key_t *key; isc_result_t result; key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t)); if (key == NULL) return (NULL); memset(key, 0, sizeof(dst_key_t)); key->magic = KEY_MAGIC; key->key_name = isc_mem_get(mctx, sizeof(dns_name_t)); if (key->key_name == NULL) { isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } dns_name_init(key->key_name, NULL); result = dns_name_dup(name, mctx, key->key_name); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } key->key_alg = alg; key->key_flags = flags; key->key_proto = protocol; key->mctx = mctx; key->opaque = NULL; key->key_size = bits; key->key_class = rdclass; key->func = dst_t_func[alg]; return (key); }
int main(int argc, char *argv[]) { isc_result_t result; dns_name_t origin; isc_buffer_t source; isc_buffer_t target; unsigned char name_buf[255]; dns_rdatacallbacks_t callbacks; UNUSED(argc); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); if (argv[1]) { isc_buffer_init(&source, argv[1], strlen(argv[1])); isc_buffer_add(&source, strlen(argv[1])); isc_buffer_setactive(&source, strlen(argv[1])); isc_buffer_init(&target, name_buf, 255); dns_name_init(&origin, NULL); result = dns_name_fromtext(&origin, &source, dns_rootname, 0, &target); if (result != ISC_R_SUCCESS) { fprintf(stdout, "dns_name_fromtext: %s\n", dns_result_totext(result)); exit(1); } dns_rdatacallbacks_init_stdio(&callbacks); callbacks.add = print_dataset; result = dns_master_loadfile(argv[1], &origin, &origin, dns_rdataclass_in, 0, &callbacks, mctx); fprintf(stdout, "dns_master_loadfile: %s\n", dns_result_totext(result)); } return (0); }
static inline isc_result_t fromtext_ch_a (ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE (type == 1); REQUIRE (rdclass == dns_rdataclass_ch); /* 3 */ UNUSED (type); UNUSED (callbacks); RETERR (isc_lex_getmastertoken (lexer, &token, isc_tokentype_string, ISC_FALSE)); /* get domain name */ dns_name_init (&name, NULL); buffer_fromregion (&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK (dns_name_fromtext (&name, &buffer, origin, options, target)); if ((options & DNS_RDATA_CHECKNAMES) != 0 && (options & DNS_RDATA_CHECKREVERSE) != 0) { isc_boolean_t ok; ok = dns_name_ishostname (&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK (DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname (&name, lexer, callbacks); } /* 16-bit octal address */ RETERR (isc_lex_getoctaltoken (lexer, &token, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK (ISC_R_RANGE); return (uint16_tobuffer (token.value.as_ulong, target)); }
static inline isc_result_t fromwire_hip(ARGS_FROMWIRE) { isc_region_t region, rr; dns_name_t name; isc_uint8_t hit_len; isc_uint16_t key_len; REQUIRE(type == dns_rdatatype_hip); UNUSED(type); UNUSED(rdclass); isc_buffer_activeregion(source, ®ion); if (region.length < 4U) RETERR(DNS_R_FORMERR); rr = region; hit_len = uint8_fromregion(®ion); if (hit_len == 0) RETERR(DNS_R_FORMERR); isc_region_consume(®ion, 2); /* hit length + algorithm */ key_len = uint16_fromregion(®ion); if (key_len == 0) RETERR(DNS_R_FORMERR); isc_region_consume(®ion, 2); if (region.length < (unsigned) (hit_len + key_len)) RETERR(DNS_R_FORMERR); RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len)); isc_buffer_forward(source, 4 + hit_len + key_len); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); while (isc_buffer_activelength(source) > 0) { dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } return (ISC_R_SUCCESS); }
isc_result_t ATTR_NONNULLS dns_ns_buildrdata(dns_name_t *origin, dns_name_t *ns_name, dns_rdataclass_t rdclass, unsigned char *buffer, dns_rdata_t *rdata) { dns_rdata_ns_t ns; isc_buffer_t rdatabuf; REQUIRE(origin != NULL); REQUIRE(ns_name != NULL); memset(buffer, 0, DNS_SOA_BUFFERSIZE); isc_buffer_init(&rdatabuf, buffer, DNS_SOA_BUFFERSIZE); ns.common.rdtype = dns_rdatatype_ns; ns.common.rdclass = rdclass; ns.mctx = NULL; dns_name_init(&ns.name, NULL); dns_name_clone(ns_name, &ns.name); return (dns_rdata_fromstruct(rdata, rdclass, dns_rdatatype_ns, &ns, &rdatabuf)); }
/* * Common routine to make query data */ static isc_result_t make_querymessage(dns_message_t *message, dns_name_t *qname0, dns_rdatatype_t rdtype) { dns_name_t *qname = NULL; dns_rdataset_t *qrdataset = NULL; isc_result_t result; message->opcode = dns_opcode_query; message->rdclass = dns_rdataclass_in; result = dns_message_gettempname(message, &qname); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(message, &qrdataset); if (result != ISC_R_SUCCESS) goto cleanup; dns_name_init(qname, NULL); dns_name_clone(qname0, qname); dns_rdataset_init(qrdataset); dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(message, qname, DNS_SECTION_QUESTION); return (ISC_R_SUCCESS); cleanup: if (qname != NULL) dns_message_puttempname(message, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(message, &qrdataset); if (message != NULL) dns_message_destroy(&message); return (result); }
static isc_result_t add_ns(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name, const dns_name_t *nsname) { dns_dbnode_t *node = NULL; dns_rdata_ns_t ns; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdatalist_t rdatalist; dns_rdataset_t rdataset; isc_result_t result; isc_buffer_t b; unsigned char buf[DNS_NAME_MAXWIRE]; isc_buffer_init(&b, buf, sizeof(buf)); dns_rdataset_init(&rdataset); dns_rdatalist_init(&rdatalist); ns.common.rdtype = dns_rdatatype_ns; ns.common.rdclass = dns_db_class(db); ns.mctx = NULL; dns_name_init(&ns.name, NULL); dns_name_clone(nsname, &ns.name); CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns, &ns, &b)); rdatalist.type = rdata.type; rdatalist.covers = 0; rdatalist.rdclass = rdata.rdclass; rdatalist.ttl = 86400; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset)); CHECK(dns_db_findnode(db, name, ISC_TRUE, &node)); CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL)); cleanup: if (node != NULL) dns_db_detachnode(db, &node); return (result); }
static inline isc_result_t towire_sig(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_sig); 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 towire_rt(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; isc_region_t tr; REQUIRE(rdata->type == 21); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); isc_buffer_availableregion(target, &tr); dns_rdata_toregion(rdata, ®ion); if (tr.length < 2) return (ISC_R_NOSPACE); memmove(tr.base, region.base, 2); isc_region_consume(®ion, 2); isc_buffer_add(target, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); }
static inline isc_boolean_t checknames_ptr(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == 12); if (rdata->rdclass != dns_rdataclass_in) return (ISC_TRUE); if (dns_name_issubdomain(owner, &in_addr_arpa) || dns_name_issubdomain(owner, &ip6_arpa) || dns_name_issubdomain(owner, &ip6_int)) { dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } } return (ISC_TRUE); }
static inline void name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer, gss_buffer_desc *gbuffer) { dns_name_t tname, *namep; isc_region_t r; isc_result_t result; if (!dns_name_isabsolute(name)) namep = name; else { unsigned int labels; dns_name_init(&tname, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 0, labels - 1, &tname); namep = &tname; } result = dns_name_toprincipal(namep, buffer); isc_buffer_putuint8(buffer, 0); isc_buffer_usedregion(buffer, &r); REGION_TO_GBUFFER(r, *gbuffer); }
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_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); }
isc_result_t dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dst_key_t *dstkey, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { dns_tsigkey_t *tkey; isc_result_t ret; unsigned int refs = 0; REQUIRE(key == NULL || *key == NULL); REQUIRE(name != NULL); REQUIRE(algorithm != NULL); REQUIRE(mctx != NULL); REQUIRE(key != NULL || ring != NULL); tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t)); if (tkey == NULL) return (ISC_R_NOMEMORY); dns_name_init(&tkey->name, NULL); ret = dns_name_dup(name, mctx, &tkey->name); if (ret != ISC_R_SUCCESS) goto cleanup_key; (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { tkey->algorithm = DNS_TSIG_HMACMD5_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA1_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA224_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA224) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA256_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA256) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA384_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA384) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA512_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA512) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPI_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else { if (dstkey != NULL) { ret = DNS_R_BADALG; goto cleanup_name; } tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->algorithm == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_name; } dns_name_init(tkey->algorithm, NULL); ret = dns_name_dup(algorithm, mctx, tkey->algorithm); if (ret != ISC_R_SUCCESS) goto cleanup_algorithm; (void)dns_name_downcase(tkey->algorithm, tkey->algorithm, NULL); } if (creator != NULL) { tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->creator == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_algorithm; } dns_name_init(tkey->creator, NULL); ret = dns_name_dup(creator, mctx, tkey->creator); if (ret != ISC_R_SUCCESS) { isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); goto cleanup_algorithm; } } else tkey->creator = NULL; tkey->key = NULL; if (dstkey != NULL) dst_key_attach(dstkey, &tkey->key); tkey->ring = ring; if (key != NULL) refs = 1; if (ring != NULL) refs++; ret = isc_refcount_init(&tkey->refs, refs); if (ret != ISC_R_SUCCESS) goto cleanup_creator; tkey->generated = generated; tkey->inception = inception; tkey->expire = expire; tkey->mctx = NULL; isc_mem_attach(mctx, &tkey->mctx); ISC_LINK_INIT(tkey, link); tkey->magic = TSIG_MAGIC; if (ring != NULL) { ret = keyring_add(ring, name, tkey); if (ret != ISC_R_SUCCESS) goto cleanup_refs; } /* * Ignore this if it's a GSS key, since the key size is meaningless. */ if (dstkey != NULL && dst_key_size(dstkey) < 64 && !dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) && !dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, ISC_LOG_INFO, "the key '%s' is too short to be secure", namestr); } if (key != NULL) *key = tkey; return (ISC_R_SUCCESS); cleanup_refs: tkey->magic = 0; while (refs-- > 0) isc_refcount_decrement(&tkey->refs, NULL); isc_refcount_destroy(&tkey->refs); cleanup_creator: if (tkey->key != NULL) dst_key_free(&tkey->key); if (tkey->creator != NULL) { dns_name_free(tkey->creator, mctx); isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); } cleanup_algorithm: if (algname_is_allocated(tkey->algorithm)) { if (dns_name_dynamic(tkey->algorithm)) dns_name_free(tkey->algorithm, mctx); isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t)); } cleanup_name: dns_name_free(&tkey->name, mctx); cleanup_key: isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t)); return (ret); }
isc_result_t dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, dns_name_t *identity, unsigned int matchtype, dns_name_t *name, unsigned int ntypes, dns_rdatatype_t *types) { dns_ssurule_t *rule; isc_mem_t *mctx; isc_result_t result; REQUIRE(VALID_SSUTABLE(table)); REQUIRE(dns_name_isabsolute(identity)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX); if (matchtype == DNS_SSUMATCHTYPE_WILDCARD) REQUIRE(dns_name_iswildcard(name)); if (ntypes > 0) REQUIRE(types != NULL); mctx = table->mctx; rule = isc_mem_get(mctx, sizeof(dns_ssurule_t)); if (rule == NULL) return (ISC_R_NOMEMORY); rule->identity = NULL; rule->name = NULL; rule->types = NULL; rule->grant = grant; rule->identity = isc_mem_get(mctx, sizeof(dns_name_t)); if (rule->identity == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(rule->identity, NULL); result = dns_name_dup(identity, mctx, rule->identity); if (result != ISC_R_SUCCESS) goto failure; rule->name = isc_mem_get(mctx, sizeof(dns_name_t)); if (rule->name == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(rule->name, NULL); result = dns_name_dup(name, mctx, rule->name); if (result != ISC_R_SUCCESS) goto failure; rule->matchtype = matchtype; rule->ntypes = ntypes; if (ntypes > 0) { rule->types = isc_mem_get(mctx, ntypes * sizeof(dns_rdatatype_t)); if (rule->types == NULL) { result = ISC_R_NOMEMORY; goto failure; } memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t)); } else rule->types = NULL; rule->magic = SSURULEMAGIC; ISC_LIST_INITANDAPPEND(table->rules, rule, link); return (ISC_R_SUCCESS); failure: if (rule->identity != NULL) { if (dns_name_dynamic(rule->identity)) dns_name_free(rule->identity, mctx); isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); } if (rule->name != NULL) { if (dns_name_dynamic(rule->name)) dns_name_free(rule->name, mctx); isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); } if (rule->types != NULL) isc_mem_put(mctx, rule->types, ntypes * sizeof(dns_rdatatype_t)); isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); return (result); }
/* * Arrange to send as much as we can of "stream" without blocking. * * Requires: * The stream iterator is initialized and points at an RR, * or possibly at the end of the stream (that is, the * _first method of the iterator has been called). */ static void sendstream(xfrout_ctx_t *xfr) { dns_message_t *tcpmsg = NULL; dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ isc_result_t result; isc_region_t used; isc_region_t region; dns_rdataset_t *qrdataset; dns_name_t *msgname = NULL; dns_rdata_t *msgrdata = NULL; dns_rdatalist_t *msgrdl = NULL; dns_rdataset_t *msgrds = NULL; dns_compress_t cctx; isc_boolean_t cleanup_cctx = ISC_FALSE; isc_boolean_t is_tcp; int n_rrs; isc_buffer_clear(&xfr->buf); isc_buffer_clear(&xfr->txlenbuf); isc_buffer_clear(&xfr->txbuf); is_tcp = ISC_TF((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0); if (!is_tcp) { /* * In the UDP case, we put the response data directly into * the client message. */ msg = xfr->client->message; CHECK(dns_message_reply(msg, ISC_TRUE)); } else { /* * TCP. Build a response dns_message_t, temporarily storing * the raw, uncompressed owner names and RR data contiguously * in xfr->buf. We know that if the uncompressed data fits * in xfr->buf, the compressed data will surely fit in a TCP * message. */ CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &tcpmsg)); msg = tcpmsg; msg->id = xfr->id; msg->rcode = dns_rcode_noerror; msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) msg->flags |= DNS_MESSAGEFLAG_RA; CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); /* * Add a EDNS option to the message? */ if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) { dns_rdataset_t *opt = NULL; CHECK(ns_client_addopt(xfr->client, msg, &opt)); CHECK(dns_message_setopt(msg, opt)); /* * Add to first message only. */ xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID; xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE; } /* * Account for reserved space. */ if (xfr->tsigkey != NULL) INSIST(msg->reserved != 0U); isc_buffer_add(&xfr->buf, msg->reserved); /* * Include a question section in the first message only. * BIND 8.2.1 will not recognize an IXFR if it does not * have a question section. */ if (xfr->nmsg == 0) { dns_name_t *qname = NULL; isc_region_t r; /* * Reserve space for the 12-byte message header * and 4 bytes of question. */ isc_buffer_add(&xfr->buf, 12 + 4); qrdataset = NULL; result = dns_message_gettemprdataset(msg, &qrdataset); if (result != ISC_R_SUCCESS) goto failure; dns_rdataset_makequestion(qrdataset, xfr->client->message->rdclass, xfr->qtype); result = dns_message_gettempname(msg, &qname); if (result != ISC_R_SUCCESS) goto failure; dns_name_init(qname, NULL); isc_buffer_availableregion(&xfr->buf, &r); INSIST(r.length >= xfr->qname->length); r.length = xfr->qname->length; isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, xfr->qname->length); dns_name_fromregion(qname, &r); ISC_LIST_INIT(qname->list); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(msg, qname, DNS_SECTION_QUESTION); } else { /* * Reserve space for the 12-byte message header */ isc_buffer_add(&xfr->buf, 12); msg->tcp_continuation = 1; } } /* * Try to fit in as many RRs as possible, unless "one-answer" * format has been requested. */ for (n_rrs = 0; ; n_rrs++) { dns_name_t *name = NULL; isc_uint32_t ttl; dns_rdata_t *rdata = NULL; unsigned int size; isc_region_t r; msgname = NULL; msgrdata = NULL; msgrdl = NULL; msgrds = NULL; xfr->stream->methods->current(xfr->stream, &name, &ttl, &rdata); size = name->length + 10 + rdata->length; isc_buffer_availableregion(&xfr->buf, &r); if (size >= r.length) { /* * RR would not fit. If there are other RRs in the * buffer, send them now and leave this RR to the * next message. If this RR overflows the buffer * all by itself, fail. * * In theory some RRs might fit in a TCP message * when compressed even if they do not fit when * uncompressed, but surely we don't want * to send such monstrosities to an unsuspecting * slave. */ if (n_rrs == 0) { xfrout_log(xfr, ISC_LOG_WARNING, "RR too large for zone transfer " "(%d bytes)", size); /* XXX DNS_R_RRTOOLARGE? */ result = ISC_R_NOSPACE; goto failure; } break; } if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) log_rr(name, rdata, ttl); /* XXX */ result = dns_message_gettempname(msg, &msgname); if (result != ISC_R_SUCCESS) goto failure; dns_name_init(msgname, NULL); isc_buffer_availableregion(&xfr->buf, &r); INSIST(r.length >= name->length); r.length = name->length; isc_buffer_putmem(&xfr->buf, name->ndata, name->length); dns_name_fromregion(msgname, &r); /* Reserve space for RR header. */ isc_buffer_add(&xfr->buf, 10); result = dns_message_gettemprdata(msg, &msgrdata); if (result != ISC_R_SUCCESS) goto failure; isc_buffer_availableregion(&xfr->buf, &r); r.length = rdata->length; isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); dns_rdata_init(msgrdata); dns_rdata_fromregion(msgrdata, rdata->rdclass, rdata->type, &r); result = dns_message_gettemprdatalist(msg, &msgrdl); if (result != ISC_R_SUCCESS) goto failure; msgrdl->type = rdata->type; msgrdl->rdclass = rdata->rdclass; msgrdl->ttl = ttl; if (rdata->type == dns_rdatatype_sig || rdata->type == dns_rdatatype_rrsig) msgrdl->covers = dns_rdata_covers(rdata); else msgrdl->covers = dns_rdatatype_none; ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); result = dns_message_gettemprdataset(msg, &msgrds); if (result != ISC_R_SUCCESS) goto failure; result = dns_rdatalist_tordataset(msgrdl, msgrds); INSIST(result == ISC_R_SUCCESS); ISC_LIST_APPEND(msgname->list, msgrds, link); dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); msgname = NULL; result = xfr->stream->methods->next(xfr->stream); if (result == ISC_R_NOMORE) { xfr->end_of_stream = ISC_TRUE; break; } CHECK(result); if (! xfr->many_answers) break; /* * At this stage, at least 1 RR has been rendered into * the message. Check if we want to clamp this message * here (TCP only). 20480 was set as an upper limit to * improve message compression. */ if ((isc_buffer_usedlength(&xfr->buf) >= 20480) && is_tcp) break; } if (is_tcp) { CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); dns_compress_setsensitive(&cctx, ISC_TRUE); cleanup_cctx = ISC_TRUE; CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); CHECK(dns_message_renderend(msg)); dns_compress_invalidate(&cctx); cleanup_cctx = ISC_FALSE; isc_buffer_usedregion(&xfr->txbuf, &used); isc_buffer_putuint16(&xfr->txlenbuf, (isc_uint16_t)used.length); region.base = xfr->txlenbuf.base; region.length = 2 + used.length; xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending TCP message of %d bytes", used.length); CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ ®ion, xfr->client->task, xfrout_senddone, xfr)); xfr->sends++; } else { xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); ns_client_send(xfr->client); xfr->stream->methods->pause(xfr->stream); xfrout_ctx_destroy(&xfr); return; } /* Advance lasttsig to be the last TSIG generated */ CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); xfr->nmsg++; failure: if (msgname != NULL) { if (msgrds != NULL) { if (dns_rdataset_isassociated(msgrds)) dns_rdataset_disassociate(msgrds); dns_message_puttemprdataset(msg, &msgrds); } if (msgrdl != NULL) { ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); dns_message_puttemprdatalist(msg, &msgrdl); } if (msgrdata != NULL) dns_message_puttemprdata(msg, &msgrdata); dns_message_puttempname(msg, &msgname); } if (tcpmsg != NULL) dns_message_destroy(&tcpmsg); if (cleanup_cctx) dns_compress_invalidate(&cctx); /* * Make sure to release any locks held by database * iterators before returning from the event handler. */ xfr->stream->methods->pause(xfr->stream); if (result == ISC_R_SUCCESS) return; xfrout_fail(xfr, result, "sending zone data"); }
isc_result_t dns_tsig_sign(dns_message_t *msg) { dns_tsigkey_t *key; dns_rdata_any_tsig_t tsig, querytsig; unsigned char data[128]; isc_buffer_t databuf, sigbuf; isc_buffer_t *dynbuf; dns_name_t *owner; dns_rdata_t *rdata = NULL; dns_rdatalist_t *datalist; dns_rdataset_t *dataset; isc_region_t r; isc_stdtime_t now; isc_mem_t *mctx; dst_context_t *ctx = NULL; isc_result_t ret; unsigned char badtimedata[BADTIMELEN]; unsigned int sigsize = 0; isc_boolean_t response = is_response(msg); REQUIRE(msg != NULL); REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg))); /* * If this is a response, there should be a query tsig. */ if (response && msg->querytsig == NULL) return (DNS_R_EXPECTEDTSIG); dynbuf = NULL; mctx = msg->mctx; key = dns_message_gettsigkey(msg); tsig.mctx = mctx; tsig.common.rdclass = dns_rdataclass_any; tsig.common.rdtype = dns_rdatatype_tsig; ISC_LINK_INIT(&tsig.common, link); dns_name_init(&tsig.algorithm, NULL); dns_name_clone(key->algorithm, &tsig.algorithm); isc_stdtime_get(&now); tsig.timesigned = now + msg->timeadjust; tsig.fudge = DNS_TSIG_FUDGE; tsig.originalid = msg->id; isc_buffer_init(&databuf, data, sizeof(data)); if (response) tsig.error = msg->querytsigstatus; else tsig.error = dns_rcode_noerror; if (tsig.error != dns_tsigerror_badtime) { tsig.otherlen = 0; tsig.other = NULL; } else { isc_buffer_t otherbuf; tsig.otherlen = BADTIMELEN; tsig.other = badtimedata; isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen); isc_buffer_putuint48(&otherbuf, tsig.timesigned); } if (key->key != NULL && tsig.error != dns_tsigerror_badsig) { unsigned char header[DNS_MESSAGE_HEADERLEN]; isc_buffer_t headerbuf; isc_uint16_t digestbits; ret = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx); if (ret != ISC_R_SUCCESS) return (ret); /* * If this is a response, digest the query signature. */ if (response) { dns_rdata_t querytsigrdata = DNS_RDATA_INIT; ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_rdataset_current(msg->querytsig, &querytsigrdata); ret = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_putuint16(&databuf, querytsig.siglen); if (isc_buffer_availablelength(&databuf) < querytsig.siglen) { ret = ISC_R_NOSPACE; goto cleanup_context; } isc_buffer_putmem(&databuf, querytsig.signature, querytsig.siglen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } #if defined(__clang__) && \ ( __clang_major__ < 3 || \ (__clang_major__ == 3 && __clang_minor__ < 2) || \ (__clang_major__ == 4 && __clang_minor__ < 2)) /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */ else memset(&querytsig, 0, sizeof(querytsig)); #endif /* * Digest the header. */ isc_buffer_init(&headerbuf, header, sizeof(header)); dns_message_renderheader(msg, &headerbuf); isc_buffer_usedregion(&headerbuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the remainder of the message. */ isc_buffer_usedregion(msg->buffer, &r); isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (msg->tcp_continuation == 0) { /* * Digest the name, class, ttl, alg. */ dns_name_toregion(&key->name, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_clear(&databuf); isc_buffer_putuint16(&databuf, dns_rdataclass_any); isc_buffer_putuint32(&databuf, 0); /* ttl */ isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_name_toregion(&tsig.algorithm, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } /* Digest the timesigned and fudge */ isc_buffer_clear(&databuf); if (tsig.error == dns_tsigerror_badtime) { INSIST(response); tsig.timesigned = querytsig.timesigned; } isc_buffer_putuint48(&databuf, tsig.timesigned); isc_buffer_putuint16(&databuf, tsig.fudge); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (msg->tcp_continuation == 0) { /* * Digest the error and other data length. */ isc_buffer_clear(&databuf); isc_buffer_putuint16(&databuf, tsig.error); isc_buffer_putuint16(&databuf, tsig.otherlen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest other data. */ if (tsig.otherlen > 0) { r.length = tsig.otherlen; r.base = tsig.other; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } } ret = dst_key_sigsize(key->key, &sigsize); if (ret != ISC_R_SUCCESS) goto cleanup_context; tsig.signature = (unsigned char *) isc_mem_get(mctx, sigsize); if (tsig.signature == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_context; } isc_buffer_init(&sigbuf, tsig.signature, sigsize); ret = dst_context_sign(ctx, &sigbuf); if (ret != ISC_R_SUCCESS) goto cleanup_signature; dst_context_destroy(&ctx); digestbits = dst_key_getbits(key->key); if (digestbits != 0) { unsigned int bytes = (digestbits + 1) / 8; if (response && bytes < querytsig.siglen) bytes = querytsig.siglen; if (bytes > isc_buffer_usedlength(&sigbuf)) bytes = isc_buffer_usedlength(&sigbuf); tsig.siglen = bytes; } else tsig.siglen = isc_buffer_usedlength(&sigbuf); } else { tsig.siglen = 0; tsig.signature = NULL; } ret = dns_message_gettemprdata(msg, &rdata); if (ret != ISC_R_SUCCESS) goto cleanup_signature; ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512); if (ret != ISC_R_SUCCESS) goto cleanup_rdata; ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &tsig, dynbuf); if (ret != ISC_R_SUCCESS) goto cleanup_dynbuf; dns_message_takebuffer(msg, &dynbuf); if (tsig.signature != NULL) { isc_mem_put(mctx, tsig.signature, sigsize); tsig.signature = NULL; } owner = NULL; ret = dns_message_gettempname(msg, &owner); if (ret != ISC_R_SUCCESS) goto cleanup_rdata; dns_name_init(owner, NULL); ret = dns_name_dup(&key->name, msg->mctx, owner); if (ret != ISC_R_SUCCESS) goto cleanup_owner; datalist = NULL; ret = dns_message_gettemprdatalist(msg, &datalist); if (ret != ISC_R_SUCCESS) goto cleanup_owner; dataset = NULL; ret = dns_message_gettemprdataset(msg, &dataset); if (ret != ISC_R_SUCCESS) goto cleanup_rdatalist; datalist->rdclass = dns_rdataclass_any; datalist->type = dns_rdatatype_tsig; datalist->covers = 0; datalist->ttl = 0; ISC_LIST_INIT(datalist->rdata); ISC_LIST_APPEND(datalist->rdata, rdata, link); RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS); msg->tsig = dataset; msg->tsigname = owner; /* Windows does not like the tsig name being compressed. */ msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; return (ISC_R_SUCCESS); cleanup_rdatalist: dns_message_puttemprdatalist(msg, &datalist); cleanup_owner: dns_message_puttempname(msg, &owner); goto cleanup_rdata; cleanup_dynbuf: isc_buffer_free(&dynbuf); cleanup_rdata: dns_message_puttemprdata(msg, &rdata); cleanup_signature: if (tsig.signature != NULL) isc_mem_put(mctx, tsig.signature, sigsize); cleanup_context: if (ctx != NULL) dst_context_destroy(&ctx); return (ret); }
void dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found, dns_rdataset_t *rdataset) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_trust_t trust; isc_region_t remaining, sigregion; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t type; unsigned int count; dns_rdata_rrsig_t rrsig; unsigned char *raw; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(found != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); dns_rdataset_current(ncacherdataset, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(found, &remaining); INSIST(remaining.length >= found->length); isc_buffer_forward(&source, found->length); remaining.length -= found->length; INSIST(remaining.length >= 5); type = isc_buffer_getuint16(&source); trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_buffer_remainingregion(&source, &remaining); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; if (type == dns_rdatatype_rrsig) { /* * Extract covers from RRSIG. */ raw = remaining.base; count = raw[0] * 256 + raw[1]; INSIST(count > 0); raw += 2; sigregion.length = raw[0] * 256 + raw[1]; raw += 2; sigregion.base = raw; dns_rdata_reset(&rdata); dns_rdata_fromregion(&rdata, rdataset->rdclass, rdataset->type, &sigregion); (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); rdataset->covers = rrsig.covered; } else rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; }
isc_result_t dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t covers, dns_rdataset_t *rdataset) { dns_name_t tname; dns_rdata_rrsig_t rrsig; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t clone; dns_rdatatype_t type; dns_trust_t trust = dns_trust_none; isc_buffer_t source; isc_region_t remaining, sigregion; isc_result_t result; unsigned char *raw; unsigned int count; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); dns_rdataset_init(&clone); dns_rdataset_clone(ncacherdataset, &clone); result = dns_rdataset_first(&clone); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&clone, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); isc_region_consume(&remaining, tname.length); INSIST(remaining.length >= 2); type = isc_buffer_getuint16(&source); isc_region_consume(&remaining, 2); if (type != dns_rdatatype_rrsig || !dns_name_equal(&tname, name)) { result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); continue; } INSIST(remaining.length >= 1); trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_region_consume(&remaining, 1); raw = remaining.base; count = raw[0] * 256 + raw[1]; INSIST(count > 0); raw += 2; sigregion.length = raw[0] * 256 + raw[1]; raw += 2; sigregion.base = raw; dns_rdata_reset(&rdata); dns_rdata_fromregion(&rdata, rdataset->rdclass, dns_rdatatype_rrsig, &sigregion); (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); if (rrsig.covered == covers) { isc_buffer_remainingregion(&source, &remaining); break; } result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&clone); if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); INSIST(remaining.length != 0); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = dns_rdatatype_rrsig; rdataset->covers = covers; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; return (ISC_R_SUCCESS); }
isc_result_t dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t remaining; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t ttype; dns_trust_t trust = dns_trust_none; dns_rdataset_t clone; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); REQUIRE(type != dns_rdatatype_rrsig); dns_rdataset_init(&clone); dns_rdataset_clone(ncacherdataset, &clone); result = dns_rdataset_first(&clone); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&clone, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); remaining.length -= tname.length; INSIST(remaining.length >= 3); ttype = isc_buffer_getuint16(&source); if (ttype == type && dns_name_equal(&tname, name)) { trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_buffer_remainingregion(&source, &remaining); break; } result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&clone); if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); INSIST(remaining.length != 0); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; return (ISC_R_SUCCESS); }
isc_result_t dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; isc_region_t remaining, tavailable; isc_buffer_t source, savedbuffer, rdlen; dns_name_t name; dns_rdatatype_t type; unsigned int i, rcount, count; /* * Convert the negative caching rdataset 'rdataset' to wire format, * compressing names as specified in 'cctx', and storing the result in * 'target'. */ REQUIRE(rdataset != NULL); REQUIRE(rdataset->type == 0); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); savedbuffer = *target; count = 0; result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&name, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&name, &remaining); INSIST(remaining.length >= name.length); isc_buffer_forward(&source, name.length); remaining.length -= name.length; INSIST(remaining.length >= 5); type = isc_buffer_getuint16(&source); isc_buffer_forward(&source, 1); rcount = isc_buffer_getuint16(&source); for (i = 0; i < rcount; i++) { /* * Get the length of this rdata and set up an * rdata structure for it. */ isc_buffer_remainingregion(&source, &remaining); INSIST(remaining.length >= 2); dns_rdata_reset(&rdata); rdata.length = isc_buffer_getuint16(&source); isc_buffer_remainingregion(&source, &remaining); rdata.data = remaining.base; rdata.type = type; rdata.rdclass = rdataset->rdclass; INSIST(remaining.length >= rdata.length); isc_buffer_forward(&source, rdata.length); if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 && dns_rdatatype_isdnssec(type)) continue; /* * Write the name. */ dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); result = dns_name_towire(&name, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; /* * See if we have space for type, class, ttl, and * rdata length. Write the type, class, and ttl. */ isc_buffer_availableregion(target, &tavailable); if (tavailable.length < 10) { result = ISC_R_NOSPACE; goto rollback; } isc_buffer_putuint16(target, type); isc_buffer_putuint16(target, rdataset->rdclass); isc_buffer_putuint32(target, rdataset->ttl); /* * Save space for rdata length. */ rdlen = *target; isc_buffer_add(target, 2); /* * Write the rdata. */ result = dns_rdata_towire(&rdata, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; /* * Set the rdata length field to the compressed * length. */ INSIST((target->used >= rdlen.used + 2) && (target->used - rdlen.used - 2 < 65536)); isc_buffer_putuint16(&rdlen, (isc_uint16_t)(target->used - rdlen.used - 2)); count++; } INSIST(isc_buffer_remaininglength(&source) == 0); result = dns_rdataset_next(rdataset); dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto rollback; *countp = count; return (ISC_R_SUCCESS); rollback: INSIST(savedbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used); *countp = 0; *target = savedbuffer; return (result); }
int main(int argc, char *argv[]) { dns_db_t *db; dns_dbnode_t *node; isc_result_t result; dns_name_t name; dns_offsets_t offsets; size_t len; isc_buffer_t source, target; char s[1000]; char b[255]; dns_rdataset_t rdataset, sigrdataset; int ch; dns_rdatatype_t type = 1; isc_boolean_t printnode = ISC_FALSE; isc_boolean_t addmode = ISC_FALSE; isc_boolean_t delmode = ISC_FALSE; isc_boolean_t holdmode = ISC_FALSE; isc_boolean_t verbose = ISC_FALSE; isc_boolean_t done = ISC_FALSE; isc_boolean_t quiet = ISC_FALSE; isc_boolean_t time_lookups = ISC_FALSE; isc_boolean_t found_as; isc_boolean_t find_zonecut = ISC_FALSE; isc_boolean_t noexact_zonecut = ISC_FALSE; int i, v; dns_rdatasetiter_t *rdsiter; char t1[256]; char t2[256]; isc_buffer_t tb1, tb2; isc_region_t r1, r2; dns_fixedname_t foundname; dns_name_t *fname; unsigned int options = 0, zcoptions; isc_time_t start, finish; char *origintext; dbinfo *dbi; dns_dbversion_t *version; dns_name_t *origin; size_t memory_quota = 0; dns_trust_t trust = 0; unsigned int addopts; isc_log_t *lctx = NULL; size_t n; dns_result_register(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) == ISC_R_SUCCESS); strcpy(dbtype, "rbt"); while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT")) != -1) { switch (ch) { case 'c': result = load(isc_commandline_argument, ".", ISC_TRUE); if (result != ISC_R_SUCCESS) printf("cache load(%s) %08x: %s\n", isc_commandline_argument, result, isc_result_totext(result)); break; case 'd': n = strlcpy(dbtype, isc_commandline_argument, sizeof(dbtype)); if (n >= sizeof(dbtype)) { fprintf(stderr, "bad db type '%s'\n", isc_commandline_argument); exit(1); } break; case 'g': options |= (DNS_DBFIND_GLUEOK|DNS_DBFIND_VALIDATEGLUE); break; case 'l': RUNTIME_CHECK(isc_log_create(mctx, &lctx, NULL) == ISC_R_SUCCESS); isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); break; case 'q': quiet = ISC_TRUE; verbose = ISC_FALSE; break; case 'p': printnode = ISC_TRUE; break; case 'P': pause_every = atoi(isc_commandline_argument); break; case 'Q': memory_quota = atoi(isc_commandline_argument); isc_mem_setquota(mctx, memory_quota); break; case 't': type = atoi(isc_commandline_argument); break; case 'T': time_lookups = ISC_TRUE; break; case 'v': verbose = ISC_TRUE; break; case 'z': origintext = strrchr(isc_commandline_argument, '/'); if (origintext == NULL) origintext = isc_commandline_argument; else origintext++; /* Skip '/'. */ result = load(isc_commandline_argument, origintext, ISC_FALSE); if (result != ISC_R_SUCCESS) printf("zone load(%s) %08x: %s\n", isc_commandline_argument, result, isc_result_totext(result)); break; } } argc -= isc_commandline_index; argv += isc_commandline_index; POST(argv); if (argc != 0) printf("ignoring trailing arguments\n"); /* * Some final initialization... */ dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); dbi = NULL; origin = dns_rootname; version = NULL; if (time_lookups) { TIME_NOW(&start); } while (!done) { if (!quiet) printf("\n"); if (fgets(s, sizeof(s), stdin) == NULL) { done = ISC_TRUE; continue; } len = strlen(s); if (len > 0U && s[len - 1] == '\n') { s[len - 1] = '\0'; len--; } if (verbose && dbi != NULL) { if (dbi->wversion != NULL) printf("future version (%p)\n", dbi->wversion); for (i = 0; i < dbi->rcount; i++) if (dbi->rversions[i] != NULL) printf("open version %d (%p)\n", i, dbi->rversions[i]); } dns_name_init(&name, offsets); if (strcmp(s, "!R") == 0) { DBI_CHECK(dbi); if (dbi->rcount == MAXVERSIONS) { printf("too many open versions\n"); continue; } dns_db_currentversion(dbi->db, &dbi->rversions[dbi->rcount]); printf("opened version %d\n", dbi->rcount); dbi->version = dbi->rversions[dbi->rcount]; version = dbi->version; dbi->rcount++; continue; } else if (strcmp(s, "!W") == 0) { DBI_CHECK(dbi); if (dbi->wversion != NULL) { printf("using existing future version\n"); dbi->version = dbi->wversion; version = dbi->version; continue; } result = dns_db_newversion(dbi->db, &dbi->wversion); if (result != ISC_R_SUCCESS) print_result("", result); else printf("newversion\n"); dbi->version = dbi->wversion; version = dbi->version; continue; } else if (strcmp(s, "!C") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_FALSE; if (dbi->version == NULL) continue; if (dbi->version == dbi->wversion) { printf("closing future version\n"); dbi->wversion = NULL; } else { for (i = 0; i < dbi->rcount; i++) { if (dbi->version == dbi->rversions[i]) { dbi->rversions[i] = NULL; printf("closing open version %d\n", i); break; } } } dns_db_closeversion(dbi->db, &dbi->version, ISC_TRUE); version = NULL; continue; } else if (strcmp(s, "!X") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_FALSE; if (dbi->version == NULL) continue; if (dbi->version == dbi->wversion) { printf("aborting future version\n"); dbi->wversion = NULL; } else { for (i = 0; i < dbi->rcount; i++) { if (dbi->version == dbi->rversions[i]) { dbi->rversions[i] = NULL; printf("closing open version %d\n", i); break; } } } dns_db_closeversion(dbi->db, &dbi->version, ISC_FALSE); version = NULL; continue; } else if (strcmp(s, "!A") == 0) { DBI_CHECK(dbi); delmode = ISC_FALSE; if (addmode) addmode = ISC_FALSE; else addmode = ISC_TRUE; printf("addmode = %s\n", addmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!D") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; if (delmode) delmode = ISC_FALSE; else delmode = ISC_TRUE; printf("delmode = %s\n", delmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!H") == 0) { DBI_CHECK(dbi); if (holdmode) holdmode = ISC_FALSE; else holdmode = ISC_TRUE; printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!HR") == 0) { DBI_CHECK(dbi); for (i = 0; i < dbi->hold_count; i++) dns_db_detachnode(dbi->db, &dbi->hold_nodes[i]); dbi->hold_count = 0; holdmode = ISC_FALSE; printf("held nodes have been detached\n"); continue; } else if (strcmp(s, "!VC") == 0) { DBI_CHECK(dbi); printf("switching to current version\n"); dbi->version = NULL; version = NULL; continue; } else if (strstr(s, "!V") == s) { DBI_CHECK(dbi); v = atoi(&s[2]); if (v >= dbi->rcount || v < 0) { printf("unknown open version %d\n", v); continue; } if (dbi->rversions[v] == NULL) { printf("version %d is not open\n", v); continue; } printf("switching to open version %d\n", v); dbi->version = dbi->rversions[v]; version = dbi->version; continue; } else if (strstr(s, "!TR") == s) { trust = (unsigned int)atoi(&s[3]); printf("trust level is now %u\n", (unsigned int)trust); continue; } else if (strstr(s, "!T") == s) { type = (unsigned int)atoi(&s[2]); printf("now searching for type %u\n", type); continue; } else if (strcmp(s, "!G") == 0) { if ((options & DNS_DBFIND_GLUEOK) != 0) options &= ~DNS_DBFIND_GLUEOK; else options |= DNS_DBFIND_GLUEOK; printf("glue ok = %s\n", ((options & DNS_DBFIND_GLUEOK) != 0) ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!GV") == 0) { if ((options & DNS_DBFIND_VALIDATEGLUE) != 0) options &= ~DNS_DBFIND_VALIDATEGLUE; else options |= DNS_DBFIND_VALIDATEGLUE; printf("validate glue = %s\n", ((options & DNS_DBFIND_VALIDATEGLUE) != 0) ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!WC") == 0) { if ((options & DNS_DBFIND_NOWILD) != 0) options &= ~DNS_DBFIND_NOWILD; else options |= DNS_DBFIND_NOWILD; printf("wildcard matching = %s\n", ((options & DNS_DBFIND_NOWILD) == 0) ? "TRUE" : "FALSE"); continue; } else if (strstr(s, "!LS ") == s) { DBI_CHECK(dbi); list(dbi, &s[4]); continue; } else if (strcmp(s, "!LS") == 0) { DBI_CHECK(dbi); list(dbi, NULL); continue; } else if (strstr(s, "!DU ") == s) { DBI_CHECK(dbi); result = dns_db_dump(dbi->db, dbi->version, s+4); if (result != ISC_R_SUCCESS) { printf("\n"); print_result("", result); } continue; } else if (strcmp(s, "!PN") == 0) { if (printnode) printnode = ISC_FALSE; else printnode = ISC_TRUE; printf("printnode = %s\n", printnode ? "TRUE" : "FALSE"); continue; } else if (strstr(s, "!P") == s) { DBI_CHECK(dbi); v = atoi(&s[2]); dbi->pause_every = v; continue; } else if (strcmp(s, "!+") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_TRUE; continue; } else if (strcmp(s, "!-") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_FALSE; continue; } else if (strcmp(s, "!DB") == 0) { dbi = NULL; origin = dns_rootname; version = NULL; printf("now searching all databases\n"); continue; } else if (strncmp(s, "!DB ", 4) == 0) { dbi = select_db(s+4); if (dbi != NULL) { db = dbi->db; origin = dns_db_origin(dbi->db); version = dbi->version; addmode = ISC_FALSE; delmode = ISC_FALSE; holdmode = ISC_FALSE; } else { db = NULL; version = NULL; origin = dns_rootname; printf("database not found; " "now searching all databases\n"); } continue; } else if (strcmp(s, "!ZC") == 0) { if (find_zonecut) find_zonecut = ISC_FALSE; else find_zonecut = ISC_TRUE; printf("find_zonecut = %s\n", find_zonecut ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!NZ") == 0) { if (noexact_zonecut) noexact_zonecut = ISC_FALSE; else noexact_zonecut = ISC_TRUE; printf("noexact_zonecut = %s\n", noexact_zonecut ? "TRUE" : "FALSE"); continue; } isc_buffer_init(&source, s, len); isc_buffer_add(&source, len); isc_buffer_init(&target, b, sizeof(b)); result = dns_name_fromtext(&name, &source, origin, 0, &target); if (result != ISC_R_SUCCESS) { print_result("bad name: ", result); continue; } if (dbi == NULL) { zcoptions = 0; if (noexact_zonecut) zcoptions |= DNS_DBTABLEFIND_NOEXACT; db = NULL; result = dns_dbtable_find(dbtable, &name, zcoptions, &db); if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) { if (!quiet) { printf("\n"); print_result("", result); } continue; } isc_buffer_init(&tb1, t1, sizeof(t1)); result = dns_name_totext(dns_db_origin(db), ISC_FALSE, &tb1); if (result != ISC_R_SUCCESS) { printf("\n"); print_result("", result); dns_db_detach(&db); continue; } isc_buffer_usedregion(&tb1, &r1); printf("\ndatabase = %.*s (%s)\n", (int)r1.length, r1.base, (dns_db_iszone(db)) ? "zone" : "cache"); } node = NULL; dns_rdataset_init(&rdataset); dns_rdataset_init(&sigrdataset); if (find_zonecut && dns_db_iscache(db)) { zcoptions = options; if (noexact_zonecut) zcoptions |= DNS_DBFIND_NOEXACT; result = dns_db_findzonecut(db, &name, zcoptions, 0, &node, fname, &rdataset, &sigrdataset); } else { result = dns_db_find(db, &name, version, type, options, 0, &node, fname, &rdataset, &sigrdataset); } if (!quiet) { if (dbi != NULL) printf("\n"); print_result("", result); } found_as = ISC_FALSE; switch (result) { case ISC_R_SUCCESS: case DNS_R_GLUE: case DNS_R_CNAME: case DNS_R_ZONECUT: break; case DNS_R_DNAME: case DNS_R_DELEGATION: found_as = ISC_TRUE; break; case DNS_R_NXRRSET: if (dns_rdataset_isassociated(&rdataset)) break; if (dbi != NULL) { if (holdmode) { RUNTIME_CHECK(dbi->hold_count < MAXHOLD); dbi->hold_nodes[dbi->hold_count++] = node; node = NULL; } else dns_db_detachnode(db, &node); } else { dns_db_detachnode(db, &node); dns_db_detach(&db); } continue; case DNS_R_NXDOMAIN: if (dns_rdataset_isassociated(&rdataset)) break; /* FALLTHROUGH */ default: if (dbi == NULL) dns_db_detach(&db); if (quiet) print_result("", result); continue; } if (found_as && !quiet) { isc_buffer_init(&tb1, t1, sizeof(t1)); isc_buffer_init(&tb2, t2, sizeof(t2)); result = dns_name_totext(&name, ISC_FALSE, &tb1); if (result != ISC_R_SUCCESS) { print_result("", result); dns_db_detachnode(db, &node); if (dbi == NULL) dns_db_detach(&db); continue; } result = dns_name_totext(fname, ISC_FALSE, &tb2); if (result != ISC_R_SUCCESS) { print_result("", result); dns_db_detachnode(db, &node); if (dbi == NULL) dns_db_detach(&db); continue; } isc_buffer_usedregion(&tb1, &r1); isc_buffer_usedregion(&tb2, &r2); printf("found %.*s as %.*s\n", (int)r1.length, r1.base, (int)r2.length, r2.base); } if (printnode) dns_db_printnode(db, node, stdout); if (!found_as && type == dns_rdatatype_any) { rdsiter = NULL; result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); if (result == ISC_R_SUCCESS) { if (!quiet) print_rdatasets(fname, rdsiter); dns_rdatasetiter_destroy(&rdsiter); } else print_result("", result); } else { if (!quiet) print_rdataset(fname, &rdataset); if (dns_rdataset_isassociated(&sigrdataset)) { if (!quiet) print_rdataset(fname, &sigrdataset); dns_rdataset_disassociate(&sigrdataset); } if (dbi != NULL && addmode && !found_as) { rdataset.ttl++; rdataset.trust = trust; if (dns_db_iszone(db)) addopts = DNS_DBADD_MERGE; else addopts = 0; result = dns_db_addrdataset(db, node, version, 0, &rdataset, addopts, NULL); if (result != ISC_R_SUCCESS) print_result("", result); if (printnode) dns_db_printnode(db, node, stdout); } else if (dbi != NULL && delmode && !found_as) { result = dns_db_deleterdataset(db, node, version, type, 0); if (result != ISC_R_SUCCESS) print_result("", result); if (printnode) dns_db_printnode(db, node, stdout); } dns_rdataset_disassociate(&rdataset); } if (dbi != NULL) { if (holdmode) { RUNTIME_CHECK(dbi->hold_count < MAXHOLD); dbi->hold_nodes[dbi->hold_count++] = node; node = NULL; } else dns_db_detachnode(db, &node); } else { dns_db_detachnode(db, &node); dns_db_detach(&db); } } if (time_lookups) { isc_uint64_t usec; TIME_NOW(&finish); usec = isc_time_microdiff(&finish, &start); printf("elapsed time: %lu.%06lu seconds\n", (unsigned long)(usec / 1000000), (unsigned long)(usec % 1000000)); } unload_all(); dns_dbtable_detach(&dbtable); if (lctx != NULL) isc_log_destroy(&lctx); if (!quiet) isc_mem_stats(mctx, stdout); return (0); }
isc_result_t ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) { isc_result_t result; dns_tkeyctx_t *tctx = NULL; const char *s; isc_uint32_t n; dns_fixedname_t fname; dns_name_t *name; isc_buffer_t b; const cfg_obj_t *obj; int type; result = dns_tkeyctx_create(mctx, ectx, &tctx); if (result != ISC_R_SUCCESS) return (result); obj = NULL; result = cfg_map_get(options, "tkey-dhkey", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); isc_buffer_constinit(&b, s, strlen(s)); isc_buffer_add(&b, strlen(s)); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, type, NULL, mctx, &tctx->dhkey)); } obj = NULL; result = cfg_map_get(options, "tkey-domain", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); isc_buffer_constinit(&b, s, strlen(s)); isc_buffer_add(&b, strlen(s)); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); if (tctx->domain == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(tctx->domain, NULL); RETERR(dns_name_dup(name, mctx, tctx->domain)); } obj = NULL; result = cfg_map_get(options, "tkey-gssapi-credential", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); isc_buffer_constinit(&b, s, strlen(s)); isc_buffer_add(&b, strlen(s)); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred)); } obj = NULL; result = cfg_map_get(options, "tkey-gssapi-keytab", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); tctx->gssapi_keytab = isc_mem_strdup(mctx, s); if (tctx->gssapi_keytab == NULL) { result = ISC_R_NOMEMORY; goto failure; } } *tctxp = tctx; return (ISC_R_SUCCESS); failure: dns_tkeyctx_destroy(&tctx); return (result); }