2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 18:19:42 +00:00

further cleanup after removing diffie-hellman TKEY mode

without diffie-hellman TKEY negotiation, some other code is
now effectively dead or unnecessary, and can be cleaned up:

- the rndc tsig-list and tsig-delete commands.
- a nonoperational command-line option to dnssec-keygen that
  was documented as being specific to DH.
- the section of the ARM that discussed TKEY/DH.
- the functions dns_tkey_builddeletequery(), processdeleteresponse(),
  and tkey_processgssresponse(), which are unused.
This commit is contained in:
Evan Hunt 2023-02-28 15:28:29 -08:00 committed by Ondřej Surý
parent bd4576b3ce
commit f030831481
16 changed files with 4 additions and 568 deletions

View File

@ -56,7 +56,7 @@ usage(void) {
fprintf(stderr, " name: owner of the key\n");
fprintf(stderr, "Other options:\n");
fprintf(stderr, " -a algorithm: \n"
" DH | RSASHA1 |\n"
" RSASHA1 |\n"
" NSEC3RSASHA1 |\n"
" RSASHA256 | RSASHA512 |\n"
" ECDSAP256SHA256 | ECDSAP384SHA384 |\n"

View File

@ -851,7 +851,7 @@ main(int argc, char **argv) {
* Process memory debugging argument first.
*/
#define CMDLINE_FLAGS \
"3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:k:L:l:m:n:P:p:qR:r:S:s:" \
"3A:a:b:Cc:D:d:E:Ff:GhI:i:K:k:L:l:m:n:P:p:qR:r:S:s:" \
"T:t:v:V"
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
@ -907,10 +907,6 @@ main(int argc, char **argv) {
case 'E':
engine = isc_commandline_argument;
break;
case 'e':
fprintf(stderr, "phased-out option -e "
"(was 'use (RSA) large exponent')\n");
break;
case 'f':
c = (unsigned char)(isc_commandline_argument[0]);
if (toupper(c) == 'K') {
@ -922,11 +918,6 @@ main(int argc, char **argv) {
isc_commandline_argument);
}
break;
case 'g':
fprintf(stderr,
"phased-out option -e "
"(was 'use specified generator (DH only)')\n");
break;
case 'K':
ctx.directory = isc_commandline_argument;
ret = try_dir(ctx.directory);

View File

@ -21,7 +21,7 @@ dnssec-keygen: DNSSEC key generation tool
Synopsis
~~~~~~~~
:program:`dnssec-keygen` [**-3**] [**-A** date/offset] [**-a** algorithm] [**-b** keysize] [**-C**] [**-c** class] [**-D** date/offset] [**-d** bits] [**-D** sync date/offset] [**-E** engine] [**-f** flag] [**-G**] [**-g** generator] [**-h**] [**-I** date/offset] [**-i** interval] [**-K** directory] [**-k** policy] [**-L** ttl] [**-l** file] [**-n** nametype] [**-P** date/offset] [**-P** sync date/offset] [**-p** protocol] [**-q**] [**-R** date/offset] [**-S** key] [**-s** strength] [**-T** rrtype] [**-t** type] [**-V**] [**-v** level] {name}
:program:`dnssec-keygen` [**-3**] [**-A** date/offset] [**-a** algorithm] [**-b** keysize] [**-C**] [**-c** class] [**-D** date/offset] [**-d** bits] [**-D** sync date/offset] [**-E** engine] [**-f** flag] [**-G**] [**-h**] [**-I** date/offset] [**-i** interval] [**-K** directory] [**-k** policy] [**-L** ttl] [**-l** file] [**-n** nametype] [**-P** date/offset] [**-P** sync date/offset] [**-p** protocol] [**-q**] [**-R** date/offset] [**-S** key] [**-s** strength] [**-T** rrtype] [**-t** type] [**-V**] [**-v** level] {name}
Description
~~~~~~~~~~~
@ -114,12 +114,6 @@ Options
This option generates a key, but does not publish it or sign with it. This option is
incompatible with :option:`-P` and :option:`-A`.
.. option:: -g generator
This option indicates the generator to use if generating a Diffie-Hellman key. Allowed
values are 2 and 5. If no generator is specified, a known prime from
:rfc:`2539` is used if possible; otherwise the default is 2.
.. option:: -h
This option prints a short summary of the options and arguments to

View File

@ -276,10 +276,6 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly,
result = named_server_freeze(named_g_server, false, lex, text);
} else if (command_compare(command, NAMED_COMMAND_TRACE)) {
result = named_server_setdebuglevel(named_g_server, lex);
} else if (command_compare(command, NAMED_COMMAND_TSIGDELETE)) {
result = named_server_tsigdelete(named_g_server, lex, text);
} else if (command_compare(command, NAMED_COMMAND_TSIGLIST)) {
result = named_server_tsiglist(named_g_server, text);
} else if (command_compare(command, NAMED_COMMAND_VALIDATION)) {
result = named_server_validation(named_g_server, lex, text);
} else if (command_compare(command, NAMED_COMMAND_ZONESTATUS)) {

View File

@ -43,8 +43,6 @@
#define NAMED_COMMAND_FLUSHNAME "flushname"
#define NAMED_COMMAND_FLUSHTREE "flushtree"
#define NAMED_COMMAND_STATUS "status"
#define NAMED_COMMAND_TSIGLIST "tsig-list"
#define NAMED_COMMAND_TSIGDELETE "tsig-delete"
#define NAMED_COMMAND_FREEZE "freeze"
#define NAMED_COMMAND_UNFREEZE "unfreeze"
#define NAMED_COMMAND_THAW "thaw"

View File

@ -250,19 +250,6 @@ named_server_flushnode(named_server_t *server, isc_lex_t *lex, bool tree);
isc_result_t
named_server_status(named_server_t *server, isc_buffer_t **text);
/*%
* Report a list of dynamic and static tsig keys, per view.
*/
isc_result_t
named_server_tsiglist(named_server_t *server, isc_buffer_t **text);
/*%
* Delete a specific key (with optional view).
*/
isc_result_t
named_server_tsigdelete(named_server_t *server, isc_lex_t *lex,
isc_buffer_t **text);
/*%
* Enable or disable updates for a zone.
*/

View File

@ -12317,235 +12317,6 @@ cleanup:
return (result);
}
static isc_result_t
delete_keynames(dns_tsig_keyring_t *ring, char *target,
unsigned int *foundkeys) {
char namestr[DNS_NAME_FORMATSIZE];
isc_result_t result;
dns_rbtnodechain_t chain;
dns_name_t foundname;
dns_fixedname_t fixedorigin;
dns_name_t *origin;
dns_rbtnode_t *node;
dns_tsigkey_t *tkey;
dns_name_init(&foundname, NULL);
origin = dns_fixedname_initname(&fixedorigin);
again:
dns_rbtnodechain_init(&chain);
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin);
if (result == ISC_R_NOTFOUND) {
dns_rbtnodechain_invalidate(&chain);
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
for (;;) {
node = NULL;
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data;
if (tkey != NULL) {
if (!tkey->generated) {
goto nextkey;
}
dns_name_format(&tkey->name, namestr, sizeof(namestr));
if (strcmp(namestr, target) == 0) {
(*foundkeys)++;
dns_rbtnodechain_invalidate(&chain);
(void)dns_rbt_deletename(ring->keys,
&tkey->name, false);
goto again;
}
}
nextkey:
result = dns_rbtnodechain_next(&chain, &foundname, origin);
if (result == ISC_R_NOMORE) {
break;
}
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
}
return (ISC_R_SUCCESS);
}
isc_result_t
named_server_tsigdelete(named_server_t *server, isc_lex_t *lex,
isc_buffer_t **text) {
isc_result_t result;
dns_view_t *view;
unsigned int foundkeys = 0;
char *ptr, *viewname;
char target[DNS_NAME_FORMATSIZE];
char fbuf[16];
REQUIRE(text != NULL);
(void)next_token(lex, text); /* skip command name */
ptr = next_token(lex, text);
if (ptr == NULL) {
return (ISC_R_UNEXPECTEDEND);
}
strlcpy(target, ptr, DNS_NAME_FORMATSIZE);
viewname = next_token(lex, text);
isc_loopmgr_pause(named_g_loopmgr);
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
view = ISC_LIST_NEXT(view, link))
{
if (viewname == NULL || strcmp(view->name, viewname) == 0) {
RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_write);
result = delete_keynames(view->dynamickeys, target,
&foundkeys);
RWUNLOCK(&view->dynamickeys->lock,
isc_rwlocktype_write);
if (result != ISC_R_SUCCESS) {
isc_loopmgr_resume(named_g_loopmgr);
return (result);
}
}
}
isc_loopmgr_resume(named_g_loopmgr);
snprintf(fbuf, sizeof(fbuf), "%u", foundkeys);
CHECK(putstr(text, fbuf));
CHECK(putstr(text, " tsig keys deleted."));
CHECK(putnull(text));
cleanup:
return (result);
}
static isc_result_t
list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t **text,
unsigned int *foundkeys) {
char namestr[DNS_NAME_FORMATSIZE];
char creatorstr[DNS_NAME_FORMATSIZE];
isc_result_t result;
dns_rbtnodechain_t chain;
dns_name_t foundname;
dns_fixedname_t fixedorigin;
dns_name_t *origin;
dns_rbtnode_t *node;
dns_tsigkey_t *tkey;
const char *viewname;
if (view != NULL) {
viewname = view->name;
} else {
viewname = "(global)";
}
dns_name_init(&foundname, NULL);
origin = dns_fixedname_initname(&fixedorigin);
dns_rbtnodechain_init(&chain);
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin);
if (result == ISC_R_NOTFOUND) {
dns_rbtnodechain_invalidate(&chain);
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
for (;;) {
node = NULL;
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data;
if (tkey != NULL) {
dns_name_format(&tkey->name, namestr, sizeof(namestr));
if (tkey->generated) {
dns_name_format(tkey->creator, creatorstr,
sizeof(creatorstr));
if (*foundkeys != 0) {
CHECK(putstr(text, "\n"));
}
CHECK(putstr(text, "view \""));
CHECK(putstr(text, viewname));
CHECK(putstr(text, "\"; type \"dynamic\"; key "
"\""));
CHECK(putstr(text, namestr));
CHECK(putstr(text, "\"; creator \""));
CHECK(putstr(text, creatorstr));
CHECK(putstr(text, "\";"));
} else {
if (*foundkeys != 0) {
CHECK(putstr(text, "\n"));
}
CHECK(putstr(text, "view \""));
CHECK(putstr(text, viewname));
CHECK(putstr(text, "\"; type \"static\"; key "
"\""));
CHECK(putstr(text, namestr));
CHECK(putstr(text, "\";"));
}
(*foundkeys)++;
}
result = dns_rbtnodechain_next(&chain, &foundname, origin);
if (result == ISC_R_NOMORE || result == DNS_R_NEWORIGIN) {
break;
}
}
return (ISC_R_SUCCESS);
cleanup:
dns_rbtnodechain_invalidate(&chain);
return (result);
}
isc_result_t
named_server_tsiglist(named_server_t *server, isc_buffer_t **text) {
isc_result_t result = ISC_R_SUCCESS;
dns_view_t *view;
unsigned int foundkeys = 0;
REQUIRE(text != NULL);
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
view = ISC_LIST_NEXT(view, link))
{
RWLOCK(&view->statickeys->lock, isc_rwlocktype_read);
result = list_keynames(view, view->statickeys, text,
&foundkeys);
RWUNLOCK(&view->statickeys->lock, isc_rwlocktype_read);
if (result != ISC_R_SUCCESS) {
return (result);
}
RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_read);
result = list_keynames(view, view->dynamickeys, text,
&foundkeys);
RWUNLOCK(&view->dynamickeys->lock, isc_rwlocktype_read);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
if (foundkeys == 0) {
CHECK(putstr(text, "no tsig keys found."));
}
if (isc_buffer_usedlength(*text) > 0) {
CHECK(putnull(text));
}
cleanup:
return (result);
}
/*
* Act on a "sign" or "loadkeys" command from the command channel.
*/

View File

@ -217,10 +217,6 @@ command is one of the following:\n\
Enable updates to a frozen dynamic zone and reload it.\n\
trace Increment debugging level by one.\n\
trace level Change the debugging level.\n\
tsig-delete keyname [view]\n\
Delete a TKEY-negotiated TSIG key.\n\
tsig-list List all currently active TSIG keys, including both statically\n\
configured and TKEY-negotiated keys.\n\
validation [ on | off | status ] [view]\n\
Enable / disable DNSSEC validation.\n\
zonestatus zone [class [view]]\n\

View File

@ -616,17 +616,6 @@ Currently supported commands are:
.. program:: rndc
.. option:: tsig-delete keyname [view]
This command deletes a given TKEY-negotiated key from the server. This does not
apply to statically configured TSIG keys.
.. option:: tsig-list
This command lists the names of all TSIG keys currently configured for use by
:iscman:`named` in each view. The list includes both statically configured keys and
dynamic TKEY-negotiated keys.
.. option:: validation (on | off | status) [view ...]
This command enables, disables, or checks the current status of DNSSEC validation. By

View File

@ -57,7 +57,6 @@ EXTRA_DIST = \
rpz.inc.rst \
security.inc.rst \
sig0.inc.rst \
tkey.inc.rst \
troubleshooting.inc.rst \
tsig.inc.rst \
zones.inc.rst \

View File

@ -11,5 +11,4 @@
.. include:: security.inc.rst
.. include:: tsig.inc.rst
.. include:: tkey.inc.rst
.. include:: sig0.inc.rst

View File

@ -1,40 +0,0 @@
.. Copyright (C) Internet Systems Consortium, Inc. ("ISC")
..
.. SPDX-License-Identifier: MPL-2.0
..
.. This Source Code Form is subject to the terms of the Mozilla Public
.. License, v. 2.0. If a copy of the MPL was not distributed with this
.. file, you can obtain one at https://mozilla.org/MPL/2.0/.
..
.. See the COPYRIGHT file distributed with this work for additional
.. information regarding copyright ownership.
TKEY
----
TKEY (Transaction KEY) is a mechanism for automatically negotiating a
shared secret between two hosts, originally specified in :rfc:`2930`.
There are several TKEY "modes" that specify how a key is to be generated
or assigned. BIND 9 implements only one of these modes: Diffie-Hellman
key exchange. Both hosts are required to have a KEY record with
algorithm DH (though this record is not required to be present in a
zone).
The TKEY process is initiated by a client or server by sending a query
of type TKEY to a TKEY-aware server. The query must include an
appropriate KEY record in the additional section, and must be signed
using either TSIG or SIG(0) with a previously established key. The
server's response, if successful, contains a TKEY record in its
answer section. After this transaction, both participants have
enough information to calculate a shared secret using Diffie-Hellman key
exchange. The shared secret can then be used to sign subsequent
transactions between the two servers.
TSIG keys known by the server, including TKEY-negotiated keys, can be
listed using :option:`rndc tsig-list`.
TKEY-negotiated keys can be deleted from a server using
:option:`rndc tsig-delete`. This can also be done via the TKEY protocol
itself, by sending an authenticated TKEY query specifying the "key
deletion" mode.

View File

@ -87,9 +87,6 @@ server receives a message signed by the key, it is able to verify
the signature. If the signature is valid, the response is signed
using the same key.
TSIG keys that are known to a server can be listed using the command
:option:`rndc tsig-list`.
Instructing the Server to Use a Key
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -112,50 +112,6 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
*\li *err_message optional error message
*/
isc_result_t
dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key);
/*%<
* Builds a query containing a TKEY record that will delete the
* specified shared secret from the server.
*
* Requires:
*\li 'msg' is a valid message
*\li 'key' is a valid TSIG key
*
* Returns:
*\li #ISC_R_SUCCESS msg was successfully updated to include the
* query to be sent
*\li other an error occurred while building the message
*/
isc_result_t
dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
const dns_name_t *gname, dns_gss_ctx_id_t *context,
isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
dns_tsig_keyring_t *ring, char **err_message);
/*%<
* XXX
*/
isc_result_t
dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dns_tsig_keyring_t *ring);
/*%<
* Processes a response to a query containing a TKEY that was
* designed to delete a shared secret. If the query was successful,
* the shared key is deleted from the list of shared keys.
*
* Requires:
*\li 'qmsg' is a valid message (the query)
*\li 'rmsg' is a valid message (the response)
*\li 'ring' is not NULL
*
* Returns:
*\li #ISC_R_SUCCESS the shared key was successfully deleted
*\li #ISC_R_NOTFOUND an error occurred while looking for a
* component of the query or response
*/
isc_result_t
dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
const dns_name_t *server, dns_gss_ctx_id_t *context,

View File

@ -631,10 +631,6 @@ dst_key_generate(const dns_name_t *name, unsigned int alg, unsigned int bits,
* RSA: exponent
* 0 use exponent 3
* !0 use Fermat4 (2^16 + 1)
* DH: generator
* 0 default - use well known prime if bits == 768 or 1024,
* otherwise use 2 as the generator.
* !0 use this value as the generator.
* DSA: unused
* HMACMD5: entropy
* 0 default - require good entropy

View File

@ -73,40 +73,6 @@ tkey_log(const char *fmt, ...) {
va_end(ap);
}
static void
dumpmessage(dns_message_t *msg) {
isc_buffer_t outbuf;
unsigned char *output;
int len = TEMP_BUFFER_SZ;
isc_result_t result;
for (;;) {
output = isc_mem_get(msg->mctx, len);
isc_buffer_init(&outbuf, output, len);
result = dns_message_totext(msg, &dns_master_style_debug, 0,
&outbuf);
if (result == ISC_R_NOSPACE) {
isc_mem_put(msg->mctx, output, len);
len *= 2;
continue;
}
if (result == ISC_R_SUCCESS) {
tkey_log("%.*s", (int)isc_buffer_usedlength(&outbuf),
(char *)isc_buffer_base(&outbuf));
} else {
tkey_log("Warning: dns_message_totext: %s",
isc_result_totext(result));
}
break;
}
if (output != NULL) {
isc_mem_put(msg->mctx, output, len);
}
}
isc_result_t
dns_tkeyctx_create(isc_mem_t *mctx, dns_tkeyctx_t **tctxp) {
REQUIRE(mctx != NULL);
@ -763,28 +729,6 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
return (buildquery(msg, name, &tkey, win2k));
}
isc_result_t
dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) {
dns_rdata_tkey_t tkey;
REQUIRE(msg != NULL);
REQUIRE(key != NULL);
tkey.common.rdclass = dns_rdataclass_any;
tkey.common.rdtype = dns_rdatatype_tkey;
ISC_LINK_INIT(&tkey.common, link);
tkey.mctx = msg->mctx;
dns_name_init(&tkey.algorithm, NULL);
dns_name_clone(key->algorithm, &tkey.algorithm);
tkey.inception = tkey.expire = 0;
tkey.mode = DNS_TKEYMODE_DELETE;
tkey.error = 0;
tkey.keylen = tkey.otherlen = 0;
tkey.key = tkey.other = NULL;
return (buildquery(msg, &key->name, &tkey, false));
}
static isc_result_t
find_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata,
int section) {
@ -814,143 +758,6 @@ find_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata,
return (result);
}
isc_result_t
dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
const dns_name_t *gname, dns_gss_ctx_id_t *context,
isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
dns_tsig_keyring_t *ring, char **err_message) {
dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname;
dns_rdata_tkey_t rtkey, qtkey;
dst_key_t *dstkey = NULL;
isc_buffer_t intoken;
isc_result_t result;
unsigned char array[TEMP_BUFFER_SZ];
REQUIRE(outtoken != NULL);
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
REQUIRE(gname != NULL);
REQUIRE(ring != NULL);
if (outkey != NULL) {
REQUIRE(*outkey == NULL);
}
if (rmsg->rcode != dns_rcode_noerror) {
return (dns_result_fromrcode(rmsg->rcode));
}
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
/*
* Win2k puts the item in the ANSWER section, while the RFC
* specifies it should be in the ADDITIONAL section. Check first
* where it should be, and then where it may be.
*/
result = find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ADDITIONAL);
if (result == ISC_R_NOTFOUND) {
result = find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ANSWER);
}
if (result != ISC_R_SUCCESS) {
goto failure;
}
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
if (rtkey.error != dns_rcode_noerror ||
rtkey.mode != DNS_TKEYMODE_GSSAPI ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm))
{
tkey_log("dns_tkey_processgssresponse: tkey mode invalid "
"or error set(2) %d",
rtkey.error);
dumpmessage(qmsg);
dumpmessage(rmsg);
result = DNS_R_INVALIDTKEY;
goto failure;
}
isc_buffer_init(outtoken, array, sizeof(array));
isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context,
ring->mctx, err_message));
RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx, &dstkey,
NULL));
RETERR(dns_tsigkey_createfromkey(
tkeyname, DNS_TSIG_GSSAPI_NAME, dstkey, false, NULL,
rtkey.inception, rtkey.expire, ring->mctx, ring, outkey));
dst_key_free(&dstkey);
dns_rdata_freestruct(&rtkey);
return (result);
failure:
/*
* XXXSRA This probably leaks memory from rtkey and qtkey.
*/
if (dstkey != NULL) {
dst_key_free(&dstkey);
}
return (result);
}
isc_result_t
dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dns_tsig_keyring_t *ring) {
dns_rdata_t qtkeyrdata = DNS_RDATA_INIT, rtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname, *tempname;
dns_rdata_tkey_t qtkey, rtkey;
dns_tsigkey_t *tsigkey = NULL;
isc_result_t result;
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
if (rmsg->rcode != dns_rcode_noerror) {
return (dns_result_fromrcode(rmsg->rcode));
}
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata, DNS_SECTION_ADDITIONAL));
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
if (rtkey.error != dns_rcode_noerror ||
rtkey.mode != DNS_TKEYMODE_DELETE || rtkey.mode != qtkey.mode ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
rmsg->rcode != dns_rcode_noerror)
{
tkey_log("dns_tkey_processdeleteresponse: tkey mode invalid "
"or error set(3)");
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&qtkey);
dns_rdata_freestruct(&rtkey);
goto failure;
}
dns_rdata_freestruct(&qtkey);
RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm, ring));
dns_rdata_freestruct(&rtkey);
/*
* Mark the key as deleted.
*/
dns_tsigkey_setdeleted(tsigkey);
/*
* Release the reference.
*/
dns_tsigkey_detach(&tsigkey);
failure:
return (result);
}
isc_result_t
dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
const dns_name_t *server, dns_gss_ctx_id_t *context,