summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2014-02-03 20:59:54 -0500
committerGreg Hudson <ghudson@mit.edu>2014-02-05 00:40:20 -0500
commit53cfb8327c452bd72a8e915338fb5ec838079cd3 (patch)
treec5e6e98f93a527b36d9275f44734394e35bd9c30
parent8255613476d4c1583a5e810b50444f188fde871f (diff)
downloadkrb5-53cfb8327c452bd72a8e915338fb5ec838079cd3.zip
krb5-53cfb8327c452bd72a8e915338fb5ec838079cd3.tar.gz
krb5-53cfb8327c452bd72a8e915338fb5ec838079cd3.tar.xz
Test SPNEGO acceptor response to MS krb5 mech OID
In t_spnego.c, add code to make a SPNEGO request with the erroneous Microsoft OID value and examine the response to make sure that it uses the same OID value as the request did. The token and tmp variables were unused, so rename them to itok and atok for the purpose of the new test code. ticket: 7858 target_version: 1.12.2 tags: pullup
-rw-r--r--src/tests/gssapi/t_spnego.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/src/tests/gssapi/t_spnego.c b/src/tests/gssapi/t_spnego.c
index cbf720b..ca05848 100644
--- a/src/tests/gssapi/t_spnego.c
+++ b/src/tests/gssapi/t_spnego.c
@@ -27,9 +27,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "common.h"
+static gss_OID_desc mech_krb5_wrong = {
+ 9, "\052\206\110\202\367\022\001\002\002"
+};
+gss_OID_set_desc mechset_krb5_wrong = { 1, &mech_krb5_wrong };
+
/*
* Test program for SPNEGO and gss_set_neg_mechs
*
@@ -44,11 +50,13 @@ main(int argc, char *argv[])
{
OM_uint32 minor, major, flags;
gss_cred_id_t verifier_cred_handle = GSS_C_NO_CREDENTIAL;
+ gss_cred_id_t initiator_cred_handle = GSS_C_NO_CREDENTIAL;
gss_OID_set actual_mechs = GSS_C_NO_OID_SET;
- gss_buffer_desc token = GSS_C_EMPTY_BUFFER, tmp = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER;
gss_ctx_id_t initiator_context, acceptor_context;
gss_name_t target_name, source_name = GSS_C_NO_NAME;
gss_OID mech = GSS_C_NO_OID;
+ const unsigned char *atok_oid;
if (argc < 2 || argc > 3) {
fprintf(stderr, "Usage: %s target_name [keytab]\n", argv[0]);
@@ -83,10 +91,58 @@ main(int argc, char *argv[])
(void)gss_delete_sec_context(&minor, &initiator_context, NULL);
(void)gss_delete_sec_context(&minor, &acceptor_context, NULL);
(void)gss_release_name(&minor, &source_name);
- (void)gss_release_name(&minor, &target_name);
- (void)gss_release_buffer(&minor, &token);
- (void)gss_release_buffer(&minor, &tmp);
(void)gss_release_cred(&minor, &verifier_cred_handle);
(void)gss_release_oid_set(&minor, &actual_mechs);
+
+ /*
+ * Test that the SPNEGO acceptor code properly reflects back the erroneous
+ * Microsoft mech OID in the supportedMech field of the NegTokenResp
+ * message. Our initiator code doesn't care (it treats all variants of the
+ * krb5 mech as equivalent when comparing the supportedMech response to its
+ * first-choice mech), so we have to look directly at the DER encoding of
+ * the response token. If we don't request mutual authentication, the
+ * SPNEGO reply will contain no underlying mech token, so the encoding of
+ * the correct NegotiationToken response is completely predictable:
+ *
+ * A1 14 (choice 1, length 20, meaning negTokenResp)
+ * 30 12 (sequence, length 18)
+ * A0 03 (context tag 0, length 3)
+ * 0A 01 00 (enumerated value 0, meaning accept-completed)
+ * A1 0B (context tag 1, length 11)
+ * 06 09 (object identifier, length 9)
+ * 2A 86 48 82 F7 12 01 02 02 (the erroneous krb5 OID)
+ *
+ * So we can just compare the length to 22 and the nine bytes at offset 13
+ * to the expected OID.
+ */
+ 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(2)", major, minor);
+ major = gss_set_neg_mechs(&minor, initiator_cred_handle,
+ &mechset_krb5_wrong);
+ check_gsserr("gss_set_neg_mechs(2)", major, minor);
+ major = gss_init_sec_context(&minor, initiator_cred_handle,
+ &initiator_context, target_name, &mech_spnego,
+ flags, GSS_C_INDEFINITE,
+ GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok,
+ NULL, NULL);
+ check_gsserr("gss_init_sec_context", major, minor);
+ assert(major == GSS_S_CONTINUE_NEEDED);
+ major = gss_accept_sec_context(&minor, &acceptor_context,
+ GSS_C_NO_CREDENTIAL, &itok,
+ GSS_C_NO_CHANNEL_BINDINGS, NULL,
+ NULL, &atok, NULL, NULL, NULL);
+ assert(atok.length == 22);
+ atok_oid = (unsigned char *)atok.value + 13;
+ assert(memcmp(atok_oid, mech_krb5_wrong.elements, 9) == 0);
+ check_gsserr("gss_accept_sec_context", major, minor);
+
+ (void)gss_delete_sec_context(&minor, &initiator_context, NULL);
+ (void)gss_delete_sec_context(&minor, &acceptor_context, NULL);
+ (void)gss_release_cred(&minor, &initiator_cred_handle);
+ (void)gss_release_name(&minor, &target_name);
+ (void)gss_release_buffer(&minor, &itok);
+ (void)gss_release_buffer(&minor, &atok);
return 0;
}