krb5 commit: Fix SPNEGO mechListMIC parsing

ghudson at mit.edu ghudson at mit.edu
Mon Sep 8 17:20:16 EDT 2025


https://github.com/krb5/krb5/commit/942c5036e14066a1f4badfdf67716c47f2e33a39
commit 942c5036e14066a1f4badfdf67716c47f2e33a39
Author: dovsyannikov <Dmitry.Ovsyannikov at dell.com>
Date:   Wed Sep 3 13:52:57 2025 +0000

    Fix SPNEGO mechListMIC parsing
    
    Commit fdceb225f881e2b1337eebcb9a9443fa4a9be3fd erroneously altered
    get_negTokenResp() to look for mechListMIC with tag 0xA4 instead of
    0xA3.  Fix it.
    
    Restore the t_spnego.c reselection test by constructing a
    two-mechanism SPNEGO initiator credential using the internal
    structures.
    
    [ghudson at mit.edu: added test case; rewrote commit message]
    
    ticket: 9183 (new)
    tags: pullup
    target_version: 1.21-next
    target_version: 1.22-next

 src/lib/gssapi/spnego/spnego_mech.c |  2 +-
 src/tests/gssapi/Makefile.in        |  2 +-
 src/tests/gssapi/deps               | 19 ++++++++++--
 src/tests/gssapi/t_spnego.c         | 60 +++++++++++++++++++++++++++++--------
 4 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 43ba63ab2..4a7783643 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -3515,7 +3515,7 @@ get_negTokenResp(OM_uint32 *minor_status, struct k5input *in,
 			return GSS_S_DEFECTIVE_TOKEN;
 	}
 
-	if (k5_der_get_value(&seq, CONTEXT | 0x04, &field)) {
+	if (k5_der_get_value(&seq, CONTEXT | 0x03, &field)) {
 		*mechListMIC = get_octet_string(&field);
 
                 /* Handle Windows 2000 duplicate response token */
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
index 97a6ac3f3..5f57173cd 100644
--- a/src/tests/gssapi/Makefile.in
+++ b/src/tests/gssapi/Makefile.in
@@ -4,7 +4,7 @@ DEFINES = -DUSE_AUTOCONF_H
 
 # For t_prf.c
 LOCALINCLUDES = -I$(srcdir)/../../lib/gssapi/mechglue \
-	-I$(srcdir)/../../lib/gssapi/krb5 \
+	-I$(srcdir)/../../lib/gssapi/krb5 -I$(srcdir)/../../lib/gssapi/spnego \
 	-I$(srcdir)/../../lib/gssapi/generic -I../../lib/gssapi/krb5 \
 	-I../../lib/gssapi/generic
 
diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps
index 2c55fa517..e93250af7 100644
--- a/src/tests/gssapi/deps
+++ b/src/tests/gssapi/deps
@@ -187,9 +187,24 @@ $(OUTPRE)t_saslname.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
   $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
   $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
   common.h t_saslname.c
-$(OUTPRE)t_spnego.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
+$(OUTPRE)t_spnego.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
   $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
-  $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \
+  $(COM_ERR_DEPS) $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \
+  $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \
+  $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \
+  $(srcdir)/../../lib/gssapi/spnego/gssapiP_negoex.h \
+  $(srcdir)/../../lib/gssapi/spnego/gssapiP_spnego.h \
+  $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-queue.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
   common.h t_spnego.c
 $(OUTPRE)t_srcattrs.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
   $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
diff --git a/src/tests/gssapi/t_spnego.c b/src/tests/gssapi/t_spnego.c
index 4091739f8..3b5309718 100644
--- a/src/tests/gssapi/t_spnego.c
+++ b/src/tests/gssapi/t_spnego.c
@@ -29,6 +29,11 @@
 #include <string.h>
 #include <assert.h>
 
+/* See create_reselection_cred(). */
+#include "k5-int.h"
+#include <mglueP.h>
+#include <gssapiP_spnego.h>
+
 #include "common.h"
 
 static gss_OID_desc mech_krb5_wrong = {
@@ -228,6 +233,47 @@ test_neghints(void)
     (void)gss_delete_sec_context(&minor, &actx, NULL);
 }
 
+/*
+ * There is currently no API to create a SPNEGO credential supporting multiple
+ * mechanisms unless a third-party mechanism is configured in the mechs file;
+ * the default credential contains only krb5 (after tickets #8021 and #8217)
+ * and a SPNEGO cred cannot be created from an existing union cred.  Using
+ * internal structures, create a two-mechanism initiator cred so that we can
+ * test reselection.
+ */
+static gss_cred_id_t
+create_reselection_cred(void)
+{
+    OM_uint32 major, minor;
+    gss_OID_desc mlist[2] = { mech_krb5, mech_iakerb };
+    gss_OID_set_desc mechs = { 2, mlist };
+    gss_cred_id_t cred;
+    spnego_gss_cred_id_t scred;
+    gss_union_cred_t ucred;
+
+    major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE,
+                             &mechs, GSS_C_INITIATE, &cred, NULL, NULL);
+    check_gsserr("gss_acquire_cred(reslection)", major, minor);
+
+    scred = calloc(1, sizeof(*scred));
+    assert(scred != NULL);
+    scred->mcred = cred;
+
+    ucred = calloc(1, sizeof(*ucred));
+    assert(ucred != NULL);
+    ucred->loopback = ucred;
+    ucred->count = 1;
+    ucred->mechs_array = calloc(1, sizeof(*ucred->mechs_array));
+    ucred->cred_array = calloc(1, sizeof(*ucred->cred_array));
+    assert(ucred->mechs_array != NULL && ucred->cred_array != NULL);
+    ucred->mechs_array[0].elements = malloc(mech_spnego.length);
+    assert(ucred->mechs_array[0].elements != NULL);
+    g_OID_copy(&ucred->mechs_array[0], &mech_spnego);
+    ucred->cred_array[0] = (gss_cred_id_t)scred;
+
+    return (gss_cred_id_t)ucred;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -254,19 +300,7 @@ main(int argc, char *argv[])
     }
 
     /* Get default initiator cred. */
-    major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE,
-                             &mechset_spnego, GSS_C_INITIATE,
-                             &initiator_cred_handle, NULL, NULL);
-    check_gsserr("gss_acquire_cred(initiator)", major, minor);
-
-    /*
-     * The following test is designed to exercise SPNEGO reselection on the
-     * client and server.  Unfortunately, it no longer does so after tickets
-     * #8217 and #8021, since SPNEGO now only acquires a single krb5 cred and
-     * there is no way to expand the underlying creds with gss_set_neg_mechs().
-     * To fix this we need gss_acquire_cred_with_cred() or some other way to
-     * turn a cred with a specifically requested mech set into a SPNEGO cred.
-     */
+    initiator_cred_handle = create_reselection_cred();
 
     /* Make the initiator prefer IAKERB and offer krb5 as an alternative. */
     pref_oids[0] = mech_iakerb;


More information about the cvs-krb5 mailing list