diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 29eac06c9d..2b8c01973c 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -165,7 +165,7 @@ struct dns_message { dns_name_t *cursors[DNS_SECTION_MAX]; dns_rdataset_t *opt; dns_rdataset_t *sig0; - dns_rdataset_t *tsigset; + dns_rdataset_t *tsig; int state; unsigned int from_to_wire : 2; @@ -199,7 +199,7 @@ struct dns_message { dns_rcode_t tsigstatus; dns_rcode_t querytsigstatus; dns_name_t *tsigname; - dns_rdataset_t *querytsigset; + dns_rdataset_t *querytsig; dns_tsigkey_t *tsigkey; void *tsigctx; int sigstart; diff --git a/lib/dns/message.c b/lib/dns/message.c index 2f6bc73566..4185c6e963 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -322,7 +322,7 @@ msginitprivate(dns_message_t *m) { m->opt = NULL; m->sig0 = NULL; m->sig0name = NULL; - m->tsigset = NULL; + m->tsig = NULL; m->tsigname = NULL; m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */ m->opt_reserved = 0; @@ -343,7 +343,7 @@ msginittsig(dns_message_t *m) { m->sig0status = dns_rcode_noerror; m->query = NULL; m->saved = NULL; - m->querytsigset = NULL; + m->querytsig = NULL; } /* @@ -414,23 +414,22 @@ msgresetsigs(dns_message_t *msg, isc_boolean_t replying) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; } - if (msg->tsigset != NULL) { - INSIST(dns_rdataset_isassociated(msg->tsigset)); + if (msg->tsig != NULL) { + INSIST(dns_rdataset_isassociated(msg->tsig)); INSIST(msg->namepool != NULL); if (replying) { - INSIST(msg->querytsigset == NULL); - msg->querytsigset = msg->tsigset; + INSIST(msg->querytsig == NULL); + msg->querytsig = msg->tsig; } else { - dns_rdataset_disassociate(msg->tsigset); - isc_mempool_put(msg->rdspool, msg->tsigset); - if (msg->querytsigset != NULL) { - dns_rdataset_disassociate(msg->querytsigset); - isc_mempool_put(msg->rdspool, - msg->querytsigset); + dns_rdataset_disassociate(msg->tsig); + isc_mempool_put(msg->rdspool, msg->tsig); + if (msg->querytsig != NULL) { + dns_rdataset_disassociate(msg->querytsig); + isc_mempool_put(msg->rdspool, msg->querytsig); } } isc_mempool_put(msg->namepool, msg->tsigname); - msg->tsigset = NULL; + msg->tsig = NULL; msg->tsigname = NULL; } if (msg->sig0 != NULL) { @@ -1136,7 +1135,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, result = DNS_R_FORMERR; goto cleanup; } - if (msg->tsigset != NULL) { + if (msg->tsig != NULL) { result = DNS_R_FORMERR; goto cleanup; } @@ -1395,7 +1394,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, free_name = ISC_FALSE; } else if (rdtype == dns_rdatatype_tsig) { - msg->tsigset = rdataset; + msg->tsig = rdataset; msg->tsigname = name; rdataset = NULL; free_rdataset = ISC_FALSE; @@ -1484,8 +1483,7 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, if (r.length != 0) return (DNS_R_FORMERR); - if (msg->tsigset != NULL || msg->tsigkey != NULL || - msg->sig0 != NULL) { + if (msg->tsig != NULL || msg->tsigkey != NULL || msg->sig0 != NULL) { msg->saved = isc_mem_get(msg->mctx, sizeof(isc_region_t)); if (msg->saved == NULL) return (ISC_R_NOMEMORY); @@ -1817,6 +1815,32 @@ dns_message_renderend(dns_message_t *msg) { return (result); } + /* + * If we're adding a TSIG or SIG(0) to a truncated message, + * clear all rdatasets from the message except for the question + * before adding the TSIG or SIG(0). + */ + if ((msg->tsigkey != NULL || msg->sig0key != NULL) && + (msg->flags & DNS_MESSAGEFLAG_TC) != 0) + { + isc_buffer_t *buf; + + msgresetnames(msg, DNS_SECTION_ANSWER); + buf = msg->buffer; + dns_message_renderreset(msg); + msg->buffer = buf; + isc_buffer_clear(msg->buffer); + isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN); + dns_compress_rollback(&msg->cctx, 0); + result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, + 0); + if (result != ISC_R_SUCCESS) + return (result); + } + + /* + * If we're adding a TSIG record, generate and render it. + */ if (msg->tsigkey != NULL) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; @@ -1824,12 +1848,17 @@ dns_message_renderend(dns_message_t *msg) { if (result != ISC_R_SUCCESS) return (result); count = 0; - result = dns_rdataset_towire(msg->tsigset, msg->tsigname, + result = dns_rdataset_towire(msg->tsig, msg->tsigname, &msg->cctx, msg->buffer, &count); msg->counts[DNS_SECTION_ADDITIONAL] += count; if (result != ISC_R_SUCCESS) return (result); - } else if (msg->sig0key != NULL) { + } + + /* + * If we're adding a SIG(0) record, generate and render it. + */ + if (msg->sig0key != NULL) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; result = dns_dnssec_signmessage(msg, msg->sig0key); @@ -2179,7 +2208,7 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) { * This saves the query TSIG status, if the query was signed, and * reserves space in the reply for the TSIG. */ - if (msg->querytsigset != NULL) { + if (msg->querytsig != NULL) { unsigned int otherlen = 0; msg->querytsigstatus = msg->tsigstatus; msg->tsigstatus = dns_rcode_noerror; @@ -2270,7 +2299,7 @@ dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) { REQUIRE(owner != NULL && *owner == NULL); *owner = msg->tsigname; - return (msg->tsigset); + return (msg->tsig); } isc_result_t @@ -2322,7 +2351,7 @@ dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) { isc_result_t result; REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(msg->querytsigset == NULL); + REQUIRE(msg->querytsig == NULL); if (querytsig == NULL) return (ISC_R_SUCCESS); @@ -2353,7 +2382,7 @@ dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) { if (result != ISC_R_SUCCESS) goto cleanup; - msg->querytsigset = set; + msg->querytsig = set; return (result); @@ -2378,13 +2407,13 @@ dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, REQUIRE(mctx != NULL); REQUIRE(querytsig != NULL && *querytsig == NULL); - if (msg->tsigset == NULL) + if (msg->tsig == NULL) return (ISC_R_SUCCESS); - result = dns_rdataset_first(msg->tsigset); + result = dns_rdataset_first(msg->tsig); if (result != ISC_R_SUCCESS) return (result); - dns_rdataset_current(msg->tsigset, &rdata); + dns_rdataset_current(msg->tsig, &rdata); dns_rdata_toregion(&rdata, &r); result = isc_buffer_allocate(mctx, querytsig, r.length); @@ -2505,7 +2534,7 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) { REQUIRE(signer != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); - if (msg->tsigset == NULL && msg->sig0 == NULL) + if (msg->tsig == NULL && msg->sig0 == NULL) return (ISC_R_NOTFOUND); if (msg->verify_attempted == 0) @@ -2543,9 +2572,9 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) { dns_name_t *identity; dns_rdata_any_tsig_t tsig; - result = dns_rdataset_first(msg->tsigset); + result = dns_rdataset_first(msg->tsig); INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(msg->tsigset, &rdata); + dns_rdataset_current(msg->tsig, &rdata); result = dns_rdata_tostruct(&rdata, &tsig, NULL); if (msg->tsigstatus != dns_rcode_noerror) @@ -2575,12 +2604,12 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(view != NULL); - if (msg->tsigkey == NULL && msg->tsigset == NULL && msg->sig0 == NULL) + if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL) return (ISC_R_SUCCESS); INSIST(msg->saved != NULL); isc_buffer_init(&msgb, msg->saved->base, msg->saved->length); isc_buffer_add(&msgb, msg->saved->length); - if (msg->tsigkey != NULL || msg->tsigset != NULL) + if (msg->tsigkey != NULL || msg->tsig != NULL) return (dns_view_checksig(view, &msgb, msg)); else { dns_rdata_t rdata; diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 5f4a2e3bbc..25077ebeca 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -16,7 +16,7 @@ */ /* - * $Id: tsig.c,v 1.66 2000/05/30 23:14:54 bwelling Exp $ + * $Id: tsig.c,v 1.67 2000/05/31 23:58:34 bwelling Exp $ * Principal Author: Brian Wellington */ @@ -260,7 +260,7 @@ dns_tsig_sign(dns_message_t *msg) { /* * If this is a response, there should be a query tsig. */ - if (is_response(msg) && msg->querytsigset == NULL) + if (is_response(msg) && msg->querytsig == NULL) return (DNS_R_EXPECTEDTSIG); dynbuf = NULL; @@ -324,11 +324,10 @@ dns_tsig_sign(dns_message_t *msg) { if (is_response(msg)) { dns_rdata_t querytsigrdata; - ret = dns_rdataset_first(msg->querytsigset); + ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) goto cleanup_other; - dns_rdataset_current(msg->querytsigset, - &querytsigrdata); + dns_rdataset_current(msg->querytsig, &querytsigrdata); ret = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) @@ -525,7 +524,7 @@ dns_tsig_sign(dns_message_t *msg) { goto cleanup_dynbuf; dns_rdataset_init(dataset); dns_rdatalist_tordataset(datalist, dataset); - msg->tsigset = dataset; + msg->tsig = dataset; msg->tsigname = owner; return (ISC_R_SUCCESS); @@ -575,7 +574,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, /* * There should be a TSIG record... */ - if (msg->tsigset == NULL) + if (msg->tsig == NULL) return (DNS_R_EXPECTEDTSIG); /* @@ -583,7 +582,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, * shouldn't be one on the response. */ if (is_response(msg) && - (tsigkey == NULL || msg->querytsigset == NULL)) + (tsigkey == NULL || msg->querytsig == NULL)) return (DNS_R_UNEXPECTEDTSIG); mctx = msg->mctx; @@ -594,18 +593,18 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, */ keyname = msg->tsigname; - ret = dns_rdataset_first(msg->tsigset); + ret = dns_rdataset_first(msg->tsig); if (ret != ISC_R_SUCCESS) return (ret); - dns_rdataset_current(msg->tsigset, &rdata); + dns_rdataset_current(msg->tsig, &rdata); ret = dns_rdata_tostruct(&rdata, &tsig, NULL); if (ret != ISC_R_SUCCESS) return (ret); if (is_response(msg)) { - ret = dns_rdataset_first(msg->querytsigset); + ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) return (ret); - dns_rdataset_current(msg->querytsigset, &rdata); + dns_rdataset_current(msg->querytsig, &rdata); ret = dns_rdata_tostruct(&rdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) return (ret); @@ -742,7 +741,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, isc_buffer_init(&databuf, data, sizeof(data)); isc_buffer_putuint16(&databuf, tsig.common.rdclass); - isc_buffer_putuint32(&databuf, msg->tsigset->ttl); + isc_buffer_putuint32(&databuf, msg->tsig->ttl); isc_buffer_usedregion(&databuf, &r); ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r, &sig_r); @@ -839,27 +838,27 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { REQUIRE(dns_message_gettsigkey(msg) != NULL); REQUIRE(msg->tcp_continuation == 1); REQUIRE(is_response(msg)); - REQUIRE(msg->querytsigset != NULL); + REQUIRE(msg->querytsig != NULL); mctx = msg->mctx; tsigkey = dns_message_gettsigkey(msg); - if (msg->tsigset != NULL) { + if (msg->tsig != NULL) { has_tsig = ISC_TRUE; keyname = msg->tsigname; - ret = dns_rdataset_first(msg->tsigset); + ret = dns_rdataset_first(msg->tsig); if (ret != ISC_R_SUCCESS) return (ret); - dns_rdataset_current(msg->tsigset, &rdata); + dns_rdataset_current(msg->tsig, &rdata); ret = dns_rdata_tostruct(&rdata, &tsig, NULL); if (ret != ISC_R_SUCCESS) return (ret); - ret = dns_rdataset_first(msg->querytsigset); + ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) return (ret); - dns_rdataset_current(msg->querytsigset, &rdata); + dns_rdataset_current(msg->querytsig, &rdata); ret = dns_rdata_tostruct(&rdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) return (ret);