From 4e455365bf2f8d5eeb185f3b7141ba2519fbbc93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 18 Mar 2026 00:28:19 +0100 Subject: [PATCH 1/3] Implement RFC 3645 Section 3.1.1 ret_flags check in GSS-API client After gss_init_sec_context() completes, verify that both MUTUAL and INTEG flags are set in ret_flags. RFC 3645 Section 3.1.1 requires the client to abandon the algorithm if either flag is missing, as the security context would not provide mutual authentication or message integrity. Also fix uninitialized gss_name_t variable in dst_gssapi_initctx() that could cause undefined behavior if gss_import_name() fails and the cleanup path calls gss_release_name() on the uninitialized value. --- lib/dns/gssapictx.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index a2d55de3e0..ea86c4b43b 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -296,7 +296,7 @@ dst_gssapi_initctx(const dns_name_t *name, isc_buffer_t *intoken, isc_mem_t *mctx, char **err_message) { isc_region_t r; isc_buffer_t namebuf; - gss_name_t gname; + gss_name_t gname = NULL; OM_uint32 gret, minor, ret_flags, flags; gss_buffer_desc gintoken, *gintokenp, gouttoken = GSS_C_EMPTY_BUFFER; isc_result_t result; @@ -356,9 +356,20 @@ dst_gssapi_initctx(const dns_name_t *name, isc_buffer_t *intoken, } /* - * XXXSRA Not handled yet: RFC 3645 3.1.1: check ret_flags - * MUTUAL and INTEG flags, fail if either not set. + * RFC 3645 Section 3.1.1: verify that mutual authentication + * and integrity are supported. If either is missing, the + * security context does not meet the protocol requirements. */ + if (gret == GSS_S_COMPLETE && + (ret_flags & (GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG)) != + (GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG)) + { + gss_log(3, + "GSS-API context lacks required MUTUAL or " + "INTEG flags (ret_flags=0x%x)", + (unsigned int)ret_flags); + CLEANUP(ISC_R_FAILURE); + } /* * RFC 2744 states the a valid output token has a non-zero length. @@ -372,7 +383,9 @@ cleanup: if (gouttoken.length != 0U) { (void)gss_release_buffer(&minor, &gouttoken); } - (void)gss_release_name(&minor, &gname); + if (gname != NULL) { + (void)gss_release_name(&minor, &gname); + } return result; } From 45c93af5c0f9bcc2ff864f7f122fdfe5a2e9382c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 18 Mar 2026 01:02:24 +0100 Subject: [PATCH 2/3] Verify integrity flag on server-side GSS-API context After gss_accept_sec_context() completes, verify that the INTEG flag is set in ret_flags. Without integrity protection, GSS-TSIG message authentication cannot function correctly. The server side was previously passing NULL for ret_flags, meaning it never verified the negotiated security properties. The client side was fixed in the previous commit; this fixes the server side. --- lib/dns/gssapictx.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index ea86c4b43b..8f4c1c56c9 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -442,15 +442,30 @@ dst_gssapi_acceptctx(const char *gssapi_keytab, isc_region_t *intoken, #endif } + OM_uint32 ret_flags = 0; + gret = gss_accept_sec_context(&minor, &context, GSS_C_NO_CREDENTIAL, &gintoken, GSS_C_NO_CHANNEL_BINDINGS, - &gname, NULL, &gouttoken, NULL, NULL, - NULL); + &gname, NULL, &gouttoken, &ret_flags, + NULL, NULL); result = ISC_R_FAILURE; switch (gret) { case GSS_S_COMPLETE: + /* + * RFC 2743 Section 1.2.2: verify that the negotiated + * context provides integrity protection. + */ + if ((ret_flags & GSS_C_INTEG_FLAG) == 0) { + gss_log(3, + "GSS-API context lacks required INTEG " + "flag (ret_flags=0x%x)", + (unsigned int)ret_flags); + (void)gss_delete_sec_context(&minor, &context, NULL); + result = DNS_R_INVALIDTKEY; + goto cleanup; + } break; /* * RFC 3645 4.1.3: we don't handle GSS_S_CONTINUE_NEEDED From 2b0f5aeb8148fd70ea881798b82f2774c57e8901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 7 Apr 2026 15:58:31 +0200 Subject: [PATCH 3/3] Check GSS_C_REPLAY_FLAG in client-side ret_flags validation RFC 3645 Section 3.1.1 mandates that the client MUST abandon the algorithm if replay_det_state is FALSE after GSS_Init_sec_context completes. The previous commit checked MUTUAL and INTEG but missed REPLAY, even though it was already requested in the input flags. Add GSS_C_REPLAY_FLAG to the ret_flags bitmask check so all three required properties (replay detection, mutual authentication, and integrity) are verified. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/dns/gssapictx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index 8f4c1c56c9..9e025b1a3b 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -356,17 +356,19 @@ dst_gssapi_initctx(const dns_name_t *name, isc_buffer_t *intoken, } /* - * RFC 3645 Section 3.1.1: verify that mutual authentication - * and integrity are supported. If either is missing, the - * security context does not meet the protocol requirements. + * RFC 3645 Section 3.1.1: verify that replay detection, mutual + * authentication and integrity are supported. The RFC mandates + * checking replay_det_state and mutual_state; integ_avail is + * also verified because GSS-TSIG cannot function without it. */ if (gret == GSS_S_COMPLETE && - (ret_flags & (GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG)) != - (GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG)) + (ret_flags & + (GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG)) != + (GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG)) { gss_log(3, - "GSS-API context lacks required MUTUAL or " - "INTEG flags (ret_flags=0x%x)", + "GSS-API context lacks required REPLAY, MUTUAL, " + "or INTEG flags (ret_flags=0x%x)", (unsigned int)ret_flags); CLEANUP(ISC_R_FAILURE); }