]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix SPNEGO mechListMIC parsing 1451/head
authordovsyannikov <Dmitry.Ovsyannikov@dell.com>
Wed, 3 Sep 2025 13:52:57 +0000 (13:52 +0000)
committerGreg Hudson <ghudson@mit.edu>
Mon, 8 Sep 2025 20:31:44 +0000 (16:31 -0400)
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@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
src/tests/gssapi/Makefile.in
src/tests/gssapi/deps
src/tests/gssapi/t_spnego.c

index 43ba63ab2a7b0954c1b8753350bbc7059d6a1ebd..4a778364336ebac5e646b0475dd7b38de979fdf1 100644 (file)
@@ -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 */
index 97a6ac3f3f78db8c2d3b262333c7e4d940a00e07..5f57173cd8afc05bbe2ec4c4bddabaefcc2e91da 100644 (file)
@@ -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
 
index 2c55fa51799f5dd1ec30c4e2d0cabe562d2aa4b6..e93250af77705a1c50a886e6610c2b6f8f8f6242 100644 (file)
@@ -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 \
index 4091739f835b471ea7ae459c42ed503122780f08..3b53097182dd9e1760d89622e7fca8012802bdb9 100644 (file)
 #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;