From: Matthijs Mekking Date: Tue, 29 Jan 2019 17:10:27 +0000 (+0100) Subject: Some thoughts on a solution X-Git-Tag: v9.13.6~22^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1302dea18434c72b083f164e56fb0e15621d3049;p=thirdparty%2Fbind9.git Some thoughts on a solution --- diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index 87d1b483532..4bade507cce 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -497,7 +497,7 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name, } static isc_result_t -process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin, +process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx, dns_rdata_tkey_t *tkeyout, dns_tsig_keyring_t *ring) { @@ -515,7 +515,7 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin, * You have to define either a gss credential (principal) to * accept with tkey-gssapi-credential, or you have to * configure a specific keytab (with tkey-gssapi-keytab) in - * order to use gsstkey + * order to use gsstkey. */ if (tctx->gsscred == NULL && tctx->gssapi_keytab == NULL) { tkey_log("process_gsstkey(): no tkey-gssapi-credential " @@ -589,7 +589,7 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin, RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm, dstkey, true, principal, now, expire, ring->mctx, ring, - NULL)); + &tsigkey)); dst_key_free(&dstkey); tkeyout->inception = now; tkeyout->expire = expire; @@ -624,6 +624,29 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin, tkey_log("process_gsstkey(): dns_tsigerror_noerror"); /* XXXSRA */ + /* + * [#821] WMM: So we found a TKEY to respond with. We don't know if + * the request is TSIG signed, but if it is not we need to make an + * effort so that the response is signed, as described in the except + * case in RFC 2845 Section 2.2: + * + * The server MUST not generate a signed response to an unsigned + * request, except in case of response to client's unsigned TKEY + * query if secret key is established on server side after server + * processed client's query. Signing responses to unsigned TKEY + * queries MUST be explicitly specified in the description of an + * individual secret key establishment algorithm. + * + * In dns_message_reply() it is checked whether to TSIG sign the + * response by checking if msg->tsigkey is non-NULL. A first naive + * attempt to set the tsigkey here with: + * + * RETERR(dns_message_settsigkey(msg, tsigkey)); + * + * is not the right approach, but captures the idea of what needs + * to be done: signal that the msg needs to be TSIG signed. + */ + return (ISC_R_SUCCESS); failure: @@ -757,9 +780,9 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, result = dns_message_signer(msg, &tsigner); if (result != ISC_R_SUCCESS) { if (tkeyin.mode == DNS_TKEYMODE_GSSAPI && - result == ISC_R_NOTFOUND) - signer = NULL; - else { + result == ISC_R_NOTFOUND) { + signer = NULL; + } else { tkey_log("dns_tkey_processquery: query was not " "properly signed - rejecting"); result = DNS_R_FORMERR; @@ -862,7 +885,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, break; case DNS_TKEYMODE_GSSAPI: tkeyout.error = dns_rcode_noerror; - RETERR(process_gsstkey(keyname, &tkeyin, tctx, + RETERR(process_gsstkey(msg, keyname, &tkeyin, tctx, &tkeyout, ring)); break; case DNS_TKEYMODE_DELETE: @@ -879,6 +902,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, } failure_with_tkey: + dns_rdata_init(&rdata); isc_buffer_init(&tkeyoutbuf, tkeyoutdata, sizeof(tkeyoutdata)); result = dns_rdata_fromstruct(&rdata, tkeyout.common.rdclass, @@ -912,6 +936,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, return (ISC_R_SUCCESS); failure: + if (freetkeyin) dns_rdata_freestruct(&tkeyin); if (!ISC_LIST_EMPTY(namelist))