Merge branch '4012-remove-win2k-hacks' into 'main'

remove win2k gss-tsig hacks

Closes #4012

See merge request isc-projects/bind9!7843
This commit is contained in:
Evan Hunt
2023-05-31 08:29:20 +00:00
9 changed files with 42 additions and 117 deletions

View File

@@ -1,3 +1,10 @@
6184. [func] Special-case code that was added to allow GSS-TSIG
to work around bugs in the Windows 2000 version of
Active Directory has been removed. The 'nsupdate -o'
option and 'oldgsstsig' command have been
deprecated, and are now treated as synonyms for
'nsupdate -g' and 'gsstsig' respectively. [GL #4012]
6183. [bug] Fix a serve-stale bug where a delegation from cache
could be returned to the client. [GL #3950]

View File

@@ -119,8 +119,6 @@ static bool is_dst_up = false;
static bool use_tls = false;
static bool usevc = false;
static bool usegsstsig = false;
static bool use_win2k_gsstsig = false;
static bool tried_other_gsstsig = false;
static bool local_only = false;
static isc_nm_t *netmgr = NULL;
static isc_loopmgr_t *loopmgr = NULL;
@@ -376,7 +374,6 @@ reset_system(void) {
if (gssring != NULL) {
dns_tsigkeyring_detach(&gssring);
}
tried_other_gsstsig = false;
}
}
@@ -1196,11 +1193,9 @@ parse_args(int argc, char **argv) {
break;
case 'g':
usegsstsig = true;
use_win2k_gsstsig = false;
break;
case 'o':
usegsstsig = true;
use_win2k_gsstsig = true;
break;
case 'O':
use_tls = true;
@@ -2303,7 +2298,6 @@ do_next_command(char *cmdline) {
if (strcasecmp(word, "gsstsig") == 0) {
#if HAVE_GSSAPI
usegsstsig = true;
use_win2k_gsstsig = false;
#else /* HAVE_GSSAPI */
fprintf(stderr, "gsstsig not supported\n");
#endif /* HAVE_GSSAPI */
@@ -2312,7 +2306,6 @@ do_next_command(char *cmdline) {
if (strcasecmp(word, "oldgsstsig") == 0) {
#if HAVE_GSSAPI
usegsstsig = true;
use_win2k_gsstsig = true;
#else /* HAVE_GSSAPI */
fprintf(stderr, "gsstsig not supported\n");
#endif /* HAVE_GSSAPI */
@@ -2338,8 +2331,6 @@ do_next_command(char *cmdline) {
"the request)\n"
"gsstsig (use GSS_TSIG to "
"sign the request)\n"
"oldgsstsig (use Microsoft's "
"GSS_TSIG to sign the request)\n"
"zone name (set the zone to be "
"updated)\n"
"class CLASS (set the zone's DNS "
@@ -3108,8 +3099,7 @@ start_gssrequest(dns_name_t *primary) {
/* Build first request. */
context = GSS_C_NO_CONTEXT;
result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
&context, use_win2k_gsstsig, gmctx,
&err_message);
&context, gmctx, &err_message);
if (result == ISC_R_FAILURE) {
fprintf(stderr, "tkey query failed: %s\n",
err_message != NULL ? err_message : "unknown error");
@@ -3234,19 +3224,6 @@ recvgss(void *arg) {
fatal("invalid OPCODE in response to GSS-TSIG query");
}
if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) {
ddebug("recvgss trying %s GSS-TSIG",
use_win2k_gsstsig ? "Standard" : "Win2k");
if (use_win2k_gsstsig) {
use_win2k_gsstsig = false;
} else {
use_win2k_gsstsig = true;
}
tried_other_gsstsig = true;
start_gssrequest(&restart_primary);
goto done;
}
if (rcvmsg->rcode != dns_rcode_noerror &&
rcvmsg->rcode != dns_rcode_nxdomain)
{
@@ -3261,8 +3238,7 @@ recvgss(void *arg) {
tsigkey = NULL;
result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname, &context,
&tsigkey, gssring, use_win2k_gsstsig,
&err_message);
&tsigkey, gssring, &err_message);
switch (result) {
case DNS_R_CONTINUE:
dns_message_detach(&rcvmsg);
@@ -3310,7 +3286,6 @@ recvgss(void *arg) {
err_message != NULL ? err_message : "");
}
done:
dns_request_destroy(&request);
dns_message_detach(&tsigquery);

View File

@@ -149,8 +149,10 @@ Options
.. option:: -o
This option enables a non-standards-compliant variant of GSS-TSIG
used by Windows 2000.
This option is deprecated. Previously, it enabled a
non-standards-compliant variant of GSS-TSIG that was used by Windows
2000. Since that OS is now long past its end of life, this option is
now treated as a synonym for :option:`-g`.
.. option:: -O
@@ -300,8 +302,9 @@ The command formats and their meanings are as follows:
:option:`-g` on the command line.
``oldgsstsig``
This command uses the Windows 2000 version of GSS-TSIG to sign the updates. This is
equivalent to specifying :option:`-o` on the command line.
This command is deprecated and will be removed in a future release.
Previously, it caused ``nsupdate`` to use the Windows 2000 version of
GSS-TSIG to sign updates. It is now treated as a synonym for ``gsstsig``.
``realm [realm_name]``
When using GSS-TSIG, this command specifies the use of ``realm_name`` rather than the default realm

View File

@@ -37,7 +37,12 @@ New Features
Removed Features
~~~~~~~~~~~~~~~~
- None.
- Special-case code that was originally added to allow GSS-TSIG to work
around bugs in the Windows 2000 version of Active Directory has now
been removed since Windows 2000 is long past end-of-life.
The ``nsupdate -o`` option and the ``oldgsstsig`` command to ``nsupdate``
have been deprecated, and are now treated as synonyms for ``nsupdate -g``
and ``gsstsig`` respectively. :gl:`#4012`
Feature Changes
~~~~~~~~~~~~~~~

View File

@@ -90,7 +90,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
isc_result_t
dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
const dns_name_t *gname, isc_buffer_t *intoken,
uint32_t lifetime, dns_gss_ctx_id_t *context, bool win2k,
uint32_t lifetime, dns_gss_ctx_id_t *context,
isc_mem_t *mctx, char **err_message);
/*%<
* Builds a query containing a TKEY that will generate a GSSAPI context.
@@ -102,8 +102,6 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
*\li 'gname' is a valid name
*\li 'context' is a pointer to a valid gss_ctx_id_t
* (which may have the value GSS_C_NO_CONTEXT)
*\li 'win2k' when true says to turn on some hacks to work
* with the non-standard GSS-TSIG of Windows 2000
*
* Returns:
*\li ISC_R_SUCCESS msg was successfully updated to include the
@@ -116,9 +114,8 @@ 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,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
bool win2k, char **err_message);
/*
char **err_message);
/*%<
* Client side negotiation of GSS-TSIG. Process the response
* to a TKEY, and establish a TSIG key if negotiation was successful.
* Build a response to the input TKEY message. Can take multiple
@@ -134,8 +131,6 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
* if non-NULL must point to NULL
* 'ring' is the keyring in which to establish the key,
* or NULL
* 'win2k' when true says to turn on some hacks to work
* with the non-standard GSS-TSIG of Windows 2000
*
* Returns:
* ISC_R_SUCCESS context was successfully established
@@ -144,5 +139,4 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
* DNS_R_CONTINUE additional context negotiation is required;
* send the new qmsg to the server
*/
ISC_LANG_ENDDECLS

View File

@@ -35,8 +35,6 @@ extern const dns_name_t *dns_tsig_hmacmd5_name;
#define DNS_TSIG_HMACMD5_NAME dns_tsig_hmacmd5_name
extern const dns_name_t *dns_tsig_gssapi_name;
#define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name
extern const dns_name_t *dns_tsig_gssapims_name;
#define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name
extern const dns_name_t *dns_tsig_hmacsha1_name;
#define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name
extern const dns_name_t *dns_tsig_hmacsha224_name;

View File

@@ -197,12 +197,9 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
return (ISC_R_NOPERM);
}
if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) &&
!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME))
{
if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME)) {
tkeyout->error = dns_tsigerror_badalg;
tkey_log("process_gsstkey(): dns_tsigerror_badalg"); /* XXXSRA
*/
tkey_log("process_gsstkey(): dns_tsigerror_badalg");
return (ISC_R_SUCCESS);
}
@@ -403,20 +400,10 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname,
dns_rdatatype_tkey, 0, &name, &tkeyset);
if (result != ISC_R_SUCCESS) {
/*
* Try the answer section, since that's where Win2000
* puts it.
*/
name = NULL;
if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname,
dns_rdatatype_tkey, 0, &name,
&tkeyset) != ISC_R_SUCCESS)
{
result = DNS_R_FORMERR;
tkey_log("dns_tkey_processquery: couldn't find a TKEY "
"matching the question");
goto failure;
}
result = DNS_R_FORMERR;
tkey_log("dns_tkey_processquery: couldn't find a TKEY "
"matching the question");
goto failure;
}
result = dns_rdataset_first(tkeyset);
if (result != ISC_R_SUCCESS) {
@@ -614,8 +601,7 @@ failure:
}
static isc_result_t
buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey,
bool win2k) {
buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey) {
dns_name_t *qname = NULL, *aname = NULL;
dns_rdataset_t *question = NULL, *tkeyset = NULL;
dns_rdatalist_t *tkeylist = NULL;
@@ -662,16 +648,7 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey,
ISC_LIST_APPEND(aname->list, tkeyset, link);
dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
/*
* Windows 2000 needs this in the answer section, not the additional
* section where the RFC specifies.
*/
if (win2k) {
dns_message_addname(msg, aname, DNS_SECTION_ANSWER);
} else {
dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
}
dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
return (ISC_R_SUCCESS);
}
@@ -679,7 +656,7 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey,
isc_result_t
dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
const dns_name_t *gname, isc_buffer_t *intoken,
uint32_t lifetime, dns_gss_ctx_id_t *context, bool win2k,
uint32_t lifetime, dns_gss_ctx_id_t *context,
isc_mem_t *mctx, char **err_message) {
dns_rdata_tkey_t tkey;
isc_result_t result;
@@ -707,13 +684,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
ISC_LINK_INIT(&tkey.common, link);
tkey.mctx = NULL;
dns_name_init(&tkey.algorithm, NULL);
if (win2k) {
dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm);
} else {
dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm);
}
dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm);
tkey.inception = now;
tkey.expire = now + lifetime;
tkey.mode = DNS_TKEYMODE_GSSAPI;
@@ -723,7 +694,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
tkey.other = NULL;
tkey.otherlen = 0;
return (buildquery(msg, name, &tkey, win2k));
return (buildquery(msg, name, &tkey));
}
static isc_result_t
@@ -759,7 +730,7 @@ 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,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
bool win2k, char **err_message) {
char **err_message) {
dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname;
dns_rdata_tkey_t rtkey, qtkey, tkey;
@@ -784,14 +755,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
freertkey = true;
if (win2k) {
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ANSWER));
} else {
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ADDITIONAL));
}
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata, DNS_SECTION_ADDITIONAL));
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
if (rtkey.error != dns_rcode_noerror ||
@@ -825,12 +789,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
ISC_LINK_INIT(&tkey.common, link);
tkey.mctx = NULL;
dns_name_init(&tkey.algorithm, NULL);
if (win2k) {
dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm);
} else {
dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm);
}
dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm);
tkey.inception = qtkey.inception;
tkey.expire = qtkey.expire;
@@ -842,7 +801,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
tkey.otherlen = 0;
dns_message_reset(qmsg, DNS_MESSAGE_INTENTRENDER);
RETERR(buildquery(qmsg, tkeyname, &tkey, win2k));
RETERR(buildquery(qmsg, tkeyname, &tkey));
return (DNS_R_CONTINUE);
}
@@ -856,10 +815,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
*/
RETERR(dns_tsigkey_createfromkey(
tkeyname,
(win2k ? DNS_TSIG_GSSAPIMS_NAME : DNS_TSIG_GSSAPI_NAME), dstkey,
true, false, NULL, rtkey.inception, rtkey.expire, ring->mctx,
ring, outkey));
tkeyname, DNS_TSIG_GSSAPI_NAME, dstkey, true, false, NULL,
rtkey.inception, rtkey.expire, ring->mctx, ring, outkey));
dst_key_free(&dstkey);
dns_rdata_freestruct(&rtkey);
return (result);

View File

@@ -63,16 +63,6 @@ static dns_name_t const gsstsig = DNS_NAME_INITABSOLUTE(gsstsig_ndata,
gsstsig_offsets);
const dns_name_t *dns_tsig_gssapi_name = &gsstsig;
/*
* Since Microsoft doesn't follow its own standard, we will use this
* alternate name as a second guess.
*/
static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com";
static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 };
static dns_name_t const gsstsigms = DNS_NAME_INITABSOLUTE(gsstsigms_ndata,
gsstsigms_offsets);
const dns_name_t *dns_tsig_gssapims_name = &gsstsigms;
static unsigned char hmacsha1_ndata[] = "\011hmac-sha1";
static unsigned char hmacsha1_offsets[] = { 0, 10 };
static dns_name_t const hmacsha1 = DNS_NAME_INITABSOLUTE(hmacsha1_ndata,
@@ -108,7 +98,6 @@ static const struct {
unsigned int dstalg;
} known_algs[] = { { &hmacmd5, DST_ALG_HMACMD5 },
{ &gsstsig, DST_ALG_GSSAPI },
{ &gsstsigms, DST_ALG_GSSAPI },
{ &hmacsha1, DST_ALG_HMACSHA1 },
{ &hmacsha224, DST_ALG_HMACSHA224 },
{ &hmacsha256, DST_ALG_HMACSHA256 },

View File

@@ -503,8 +503,6 @@ ISC_RUN_TEST_IMPL(algfromname) {
assert_int_equal(dns__tsig_algfromname(DNS_TSIG_GSSAPI_NAME),
DST_ALG_GSSAPI);
assert_int_equal(dns__tsig_algfromname(DNS_TSIG_GSSAPIMS_NAME),
DST_ALG_GSSAPI);
assert_int_equal(dns__tsig_algfromname(dns_rootname), 0);
}
@@ -538,7 +536,6 @@ ISC_RUN_TEST_IMPL(algnamefromname) {
test_name("hmac-sha512", DNS_TSIG_HMACSHA512_NAME);
test_name("gss-tsig", DNS_TSIG_GSSAPI_NAME);
test_name("gss.microsoft.com", DNS_TSIG_GSSAPIMS_NAME);
/* try another name that isn't a standard algorithm name */
assert_null(dns__tsig_algnamefromname(dns_rootname));