]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Some thoughts on a solution
authorMatthijs Mekking <matthijs@isc.org>
Tue, 29 Jan 2019 17:10:27 +0000 (18:10 +0100)
committerEvan Hunt <each@isc.org>
Wed, 30 Jan 2019 19:45:30 +0000 (11:45 -0800)
lib/dns/tkey.c

index 87d1b4835327bcab688537de597d97955e167441..4bade507ccef0e2a89c9122c2a71384ef4138b16 100644 (file)
@@ -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))