summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-09-13 02:52:23 +0000
committerGreg Hudson <ghudson@mit.edu>2009-09-13 02:52:23 +0000
commit0e39f8a3ad915eeb0131fb4a87b0fef304101cfd (patch)
tree6c6d7fd4b23f4724156300b5505433b13cfe9fb6 /src/tests
parentf89b62fe9fd7b0cb10d7e2ff542fb18c1b56d35d (diff)
downloadkrb5-0e39f8a3ad915eeb0131fb4a87b0fef304101cfd.tar.gz
krb5-0e39f8a3ad915eeb0131fb4a87b0fef304101cfd.tar.xz
krb5-0e39f8a3ad915eeb0131fb4a87b0fef304101cfd.zip
Implement s4u extensions
Merge Luke's users/lhoward/s4u branch to trunk. Implements S4U2Self and S4U2Proxy extensions. ticket: 6563 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22736 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/asn.1/krb5_decode_leak.c11
-rw-r--r--src/tests/asn.1/krb5_decode_test.c8
-rw-r--r--src/tests/asn.1/krb5_encode_test.c12
-rw-r--r--src/tests/asn.1/ktest.c25
-rw-r--r--src/tests/asn.1/ktest.h3
-rw-r--r--src/tests/asn.1/ktest_equal.c14
-rw-r--r--src/tests/asn.1/ktest_equal.h4
-rw-r--r--src/tests/asn.1/reference_encode.out1
-rw-r--r--src/tests/asn.1/trval_reference.out17
-rw-r--r--src/tests/gssapi/Makefile.in11
-rw-r--r--src/tests/gssapi/t_s4u.c418
11 files changed, 518 insertions, 6 deletions
diff --git a/src/tests/asn.1/krb5_decode_leak.c b/src/tests/asn.1/krb5_decode_leak.c
index 41045b5a8..be0a536e9 100644
--- a/src/tests/asn.1/krb5_decode_leak.c
+++ b/src/tests/asn.1/krb5_decode_leak.c
@@ -658,7 +658,18 @@ main(int argc, char **argv)
krb5_free_enc_sam_response_enc_2);
ktest_empty_enc_sam_response_enc_2(&sam_ch2);
}
+ /****************************************************************/
+ /* encode_krb5_pa_s4u_x509_user */
+ {
+ krb5_pa_s4u_x509_user s4u, *tmp;
+ setup(s4u, "pa_s4u_x509_user",
+ ktest_make_sample_pa_s4u_x509_user);
+ leak_test(s4u, encode_krb5_pa_s4u_x509_user,
+ decode_krb5_pa_s4u_x509_user,
+ krb5_free_pa_s4u_x509_user);
+ ktest_empty_pa_s4u_x509_user(&s4u);
+ }
krb5_free_context(test_context);
return 0;
}
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
index 7136669ac..2d2000422 100644
--- a/src/tests/asn.1/krb5_decode_test.c
+++ b/src/tests/asn.1/krb5_decode_test.c
@@ -890,7 +890,13 @@ int main(argc, argv)
ktest_empty_sam_response(&ref);
}
-
+
+ {
+ setup(krb5_pa_s4u_x509_user,"krb5_pa_s4u_x509_user",ktest_make_sample_pa_s4u_x509_user);
+ decode_run("pa_s4u_x509_user","","30 68 A0 55 30 53 A0 06 02 04 00 CA 14 9A A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 12 04 10 70 61 5F 73 34 75 5F 78 35 30 39 5F 75 73 65 72 A4 07 03 05 00 80 00 00 00 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_pa_s4u_x509_user,ktest_equal_pa_s4u_x509_user,krb5_free_pa_s4u_x509_user);
+ ktest_empty_pa_s4u_x509_user(&ref);
+ }
+
#ifdef ENABLE_LDAP
/* ldap sequence_of_keys */
{
diff --git a/src/tests/asn.1/krb5_encode_test.c b/src/tests/asn.1/krb5_encode_test.c
index 2da5c1e7f..7ae32ec75 100644
--- a/src/tests/asn.1/krb5_encode_test.c
+++ b/src/tests/asn.1/krb5_encode_test.c
@@ -695,6 +695,18 @@ main(argc, argv)
acc.encode_krb5_enc_sam_response_enc_2);
ktest_empty_enc_sam_response_enc_2(&sam_ch2);
}
+ /****************************************************************/
+ /* encode_krb5_pa_s4u_x509_user */
+ {
+ krb5_pa_s4u_x509_user s4u;
+ setup(s4u,krb5_pa_s4u_x509_user,"pa_s4u_x509_user",
+ ktest_make_sample_pa_s4u_x509_user);
+ encode_run(s4u,krb5_pa_s4u_x509_user,
+ "pa_s4u_x509_user","",
+ encode_krb5_pa_s4u_x509_user);
+ ktest_empty_pa_s4u_x509_user(&s4u);
+ }
+
#ifdef ENABLE_LDAP
{
ldap_seqof_key_data skd;
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
index 5951b6c7e..8b6367918 100644
--- a/src/tests/asn.1/ktest.c
+++ b/src/tests/asn.1/ktest.c
@@ -825,6 +825,23 @@ krb5_error_code ktest_make_sample_enc_sam_response_enc_2(p)
return 0;
}
+krb5_error_code ktest_make_sample_pa_s4u_x509_user(p)
+ krb5_pa_s4u_x509_user *p;
+{
+ krb5_error_code retval;
+ krb5_s4u_userid *u = &p->user_id;
+ u->nonce = 13243546;
+ retval = ktest_make_sample_principal(&u->user);
+ if (retval) return retval;
+ u->subject_cert.data = strdup("pa_s4u_x509_user");
+ if (u->subject_cert.data == NULL) return ENOMEM;
+ u->subject_cert.length = strlen(u->subject_cert.data);
+ u->options = 0x80000000;
+ retval = ktest_make_sample_checksum(&p->cksum);
+ if (retval) return retval;
+ return 0;
+}
+
#ifdef ENABLE_LDAP
static krb5_error_code ktest_make_sample_key_data(krb5_key_data *p, int i)
{
@@ -1420,6 +1437,14 @@ void ktest_empty_enc_sam_response_enc_2(p)
ktest_empty_data(&p->sam_sad);
}
+void ktest_empty_pa_s4u_x509_user(p)
+ krb5_pa_s4u_x509_user *p;
+{
+ ktest_destroy_principal(&p->user_id.user);
+ ktest_empty_data(&p->user_id.subject_cert);
+ if (p->cksum.contents) free(p->cksum.contents);
+}
+
#ifdef ENABLE_LDAP
void ktest_empty_ldap_seqof_key_data(ctx, p)
krb5_context ctx;
diff --git a/src/tests/asn.1/ktest.h b/src/tests/asn.1/ktest.h
index af7c9acc8..a2951d26f 100644
--- a/src/tests/asn.1/ktest.h
+++ b/src/tests/asn.1/ktest.h
@@ -105,7 +105,7 @@ krb5_error_code ktest_make_sample_enc_sam_response_enc
(krb5_enc_sam_response_enc *p);
krb5_error_code ktest_make_sample_predicted_sam_response(krb5_predicted_sam_response *p);
krb5_error_code ktest_make_sample_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p);
-
+krb5_error_code ktest_make_sample_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p);
#ifdef ENABLE_LDAP
krb5_error_code ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data * p);
@@ -214,6 +214,7 @@ void ktest_empty_enc_sam_response_enc(krb5_enc_sam_response_enc *p);
void ktest_empty_predicted_sam_response(krb5_predicted_sam_response *p);
void ktest_empty_sam_response_2(krb5_sam_response_2 *p);
void ktest_empty_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p);
+void ktest_empty_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p);
#ifdef ENABLE_LDAP
void ktest_empty_ldap_seqof_key_data(krb5_context, ldap_seqof_key_data *p);
diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c
index 5ec0a01dc..da0324973 100644
--- a/src/tests/asn.1/ktest_equal.c
+++ b/src/tests/asn.1/ktest_equal.c
@@ -542,6 +542,20 @@ int ktest_equal_sam_response(ref, var)
return p;
}
+int ktest_equal_pa_s4u_x509_user(ref, var)
+ krb5_pa_s4u_x509_user *ref;
+ krb5_pa_s4u_x509_user *var;
+{
+ int p = TRUE;
+ if (ref == var) return TRUE;
+ else if (ref == NULL || var == NULL) return FALSE;
+ p=p&&scalar_equal(user_id.nonce);
+ p=p&&ptr_equal(user_id.user,ktest_equal_principal_data);
+ p=p&&struct_equal(user_id.subject_cert,ktest_equal_data);
+ p=p&&scalar_equal(user_id.options);
+ p=p&&struct_equal(cksum,ktest_equal_checksum);
+ return p;
+}
#ifdef ENABLE_LDAP
static int equal_key_data(ref, var)
krb5_key_data *ref;
diff --git a/src/tests/asn.1/ktest_equal.h b/src/tests/asn.1/ktest_equal.h
index 217272378..8a0641de5 100644
--- a/src/tests/asn.1/ktest_equal.h
+++ b/src/tests/asn.1/ktest_equal.h
@@ -91,6 +91,10 @@ int ktest_equal_krb5_etype_info_entry
(krb5_etype_info_entry * ref,
krb5_etype_info_entry * var);
+int ktest_equal_pa_s4u_x509_user
+ (krb5_pa_s4u_x509_user *ref,
+ krb5_pa_s4u_x509_user *var);
+
int ktest_equal_ldap_sequence_of_keys(ldap_seqof_key_data *ref,
ldap_seqof_key_data *var);
#endif
diff --git a/src/tests/asn.1/reference_encode.out b/src/tests/asn.1/reference_encode.out
index b6ac7fb2d..0d913cdb2 100644
--- a/src/tests/asn.1/reference_encode.out
+++ b/src/tests/asn.1/reference_encode.out
@@ -56,3 +56,4 @@ encode_krb5_enc_sam_response_enc: 30 38 A0 05 02 03 01 33 2A A1 11 18 0F 31 39 3
encode_krb5_predicted_sam_response: 30 6D A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 07 03 05 00 00 00 00 09 A2 11 18 0F 31 39 37 30 30 31 30 31 30 30 30 30 31 37 5A A3 03 02 01 12 A4 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A6 07 04 05 68 65 6C 6C 6F
encode_krb5_sam_response_2: 30 42 A0 03 02 01 2B A1 07 03 05 00 80 00 00 00 A2 0C 04 0A 74 72 61 63 6B 20 64 61 74 61 A3 1D 30 1B A0 03 02 01 01 A1 04 02 02 0D 36 A2 0E 04 0C 6E 6F 6E 63 65 20 6F 72 20 73 61 64 A4 05 02 03 54 32 10
encode_krb5_enc_sam_response_enc_2: 30 1F A0 03 02 01 58 A1 18 04 16 65 6E 63 5F 73 61 6D 5F 72 65 73 70 6F 6E 73 65 5F 65 6E 63 5F 32
+encode_krb5_pa_s4u_x509_user: 30 68 A0 55 30 53 A0 06 02 04 00 CA 14 9A A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 12 04 10 70 61 5F 73 34 75 5F 78 35 30 39 5F 75 73 65 72 A4 07 03 05 00 80 00 00 00 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34
diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out
index 9c5f8cc1e..c8aa48e3f 100644
--- a/src/tests/asn.1/trval_reference.out
+++ b/src/tests/asn.1/trval_reference.out
@@ -1246,3 +1246,20 @@ encode_krb5_enc_sam_response_enc_2:
. [0] [Integer] 88
. [1] [Octet String] "enc_sam_response_enc_2"
+encode_krb5_pa_s4u_x509_user:
+
+[Sequence/Sequence Of]
+. [0] [Sequence/Sequence Of]
+. . [0] [Integer] 13243546
+. . [1] [Sequence/Sequence Of]
+. . . [0] [Integer] 1
+. . . [1] [Sequence/Sequence Of]
+. . . . [General string] "hftsai"
+. . . . [General string] "extra"
+. . [2] [General string] "ATHENA.MIT.EDU"
+. . [3] [Octet String] "pa_s4u_x509_user"
+. . [4] [Bit String] 0x80000000
+. [1] [Sequence/Sequence Of]
+. . [0] [Integer] 1
+. . [1] [Octet String] "1234"
+
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
index d0ea1e137..e385c68f6 100644
--- a/src/tests/gssapi/Makefile.in
+++ b/src/tests/gssapi/Makefile.in
@@ -6,15 +6,18 @@ DEFINES = -DUSE_AUTOCONF_H
PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
-SRCS= $(srcdir)/t_imp_name.c
+SRCS= $(srcdir)/t_imp_name.c $(srcdir)/t_s4u.c
-OBJS= t_imp_name.o
+OBJS= t_imp_name.o t_s4u.o
-all:: t_imp_name
+all:: t_imp_name t_s4u
t_imp_name: t_imp_name.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o t_imp_name t_imp_name.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
+t_s4u: t_s4u.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
+ $(CC_LINK) -o t_s4u t_s4u.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
+
clean::
- $(RM) t_imp_name
+ $(RM) t_imp_name t_s4u
diff --git a/src/tests/gssapi/t_s4u.c b/src/tests/gssapi/t_s4u.c
new file mode 100644
index 000000000..264e60a60
--- /dev/null
+++ b/src/tests/gssapi/t_s4u.c
@@ -0,0 +1,418 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gssapi/gssapi_krb5.h>
+
+/*
+ * Test program for protocol transition (S4U2Self) and constrained delegation
+ * (S4U2Proxy)
+ *
+ * Note: because of name canonicalization, the following tips may help
+ * when configuring with Active Directory:
+ *
+ * - Create a computer account FOO$
+ * - Set the UPN to host/foo.domain (no suffix); this is necessary to
+ * be able to send an AS-REQ as this principal, otherwise you would
+ * need to use the canonical name (FOO$), which will cause principal
+ * comparison errors in gss_accept_sec_context().
+ * - Add a SPN of host/foo.domain
+ * - Configure the computer account to support constrained delegation with
+ * protocol transition (Trust this computer for delegation to specified
+ * services only / Use any authentication protocol)
+ * - Add host/foo.domain to the keytab (possibly easiest to do this
+ * with ktadd)
+ *
+ * For S4U2Proxy to work the TGT must be forwardable too.
+ *
+ * Usage eg:
+ *
+ * kinit -k -t test.keytab -f 'host/test.win.mit.edu@WIN.MIT.EDU'
+ * ./t_s4u delegtest@WIN.MIT.EDU HOST/WIN-EQ7E4AA2WR8.win.mit.edu@WIN.MIT.EDU test.keytab
+ */
+
+static gss_OID_desc spnego_mech = { 6, "\053\006\001\005\005\002" };
+
+int use_spnego = 0;
+
+static void displayStatus_1(m, code, type)
+ char *m;
+ OM_uint32 code;
+ int type;
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc msg;
+ OM_uint32 msg_ctx;
+
+ msg_ctx = 0;
+ while (1) {
+ maj_stat = gss_display_status(&min_stat, code,
+ type, GSS_C_NULL_OID,
+ &msg_ctx, &msg);
+ fprintf(stderr, "%s: %s\n", m, (char *)msg.value);
+ (void) gss_release_buffer(&min_stat, &msg);
+
+ if (!msg_ctx)
+ break;
+ }
+}
+
+static void displayStatus(msg, maj_stat, min_stat)
+ char *msg;
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+{
+ displayStatus_1(msg, maj_stat, GSS_C_GSS_CODE);
+ displayStatus_1(msg, min_stat, GSS_C_MECH_CODE);
+}
+
+static OM_uint32
+displayCanonName(OM_uint32 *minor, gss_name_t name, char *tag)
+{
+ gss_name_t canon;
+ OM_uint32 major, tmp_minor;
+ gss_buffer_desc buf;
+
+ major = gss_canonicalize_name(minor, name,
+ (gss_OID)gss_mech_krb5, &canon);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_canonicalize_name", major, *minor);
+ return major;
+ }
+
+ major = gss_display_name(minor, canon, &buf, NULL);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_display_name", major, *minor);
+ gss_release_name(&tmp_minor, &canon);
+ return major;
+ }
+
+ printf("%s:\t%s\n", tag, (char *)buf.value);
+
+ gss_release_buffer(&tmp_minor, &buf);
+ gss_release_name(&tmp_minor, &canon);
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+displayOID(OM_uint32 *minor, gss_OID oid, char *tag)
+{
+ OM_uint32 major, tmp_minor;
+ gss_buffer_desc buf;
+
+ major = gss_oid_to_str(minor, oid, &buf);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_oid_to_str", major, *minor);
+ return major;
+ }
+
+ printf("%s:\t%s\n", tag, (char *)buf.value);
+
+ gss_release_buffer(&tmp_minor, &buf);
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+initAcceptSecContext(OM_uint32 *minor,
+ gss_cred_id_t claimant_cred_handle,
+ gss_cred_id_t verifier_cred_handle,
+ gss_cred_id_t *deleg_cred_handle)
+{
+ OM_uint32 major, tmp_minor;
+ gss_buffer_desc token, tmp;
+ gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT;
+ gss_ctx_id_t acceptor_context = GSS_C_NO_CONTEXT;
+ gss_name_t source_name = GSS_C_NO_NAME;
+ gss_name_t target_name = GSS_C_NO_NAME;
+ OM_uint32 time_rec;
+ gss_OID mech = GSS_C_NO_OID;
+
+ token.value = NULL;
+ token.length = 0;
+
+ tmp.value = NULL;
+ tmp.length = 0;
+
+ *deleg_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ major = gss_inquire_cred(minor, verifier_cred_handle,
+ &target_name, NULL, NULL, NULL);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_inquire_cred", major, *minor);
+ return major;
+ }
+
+ displayCanonName(minor, target_name, "Target name");
+
+ mech = use_spnego ? (gss_OID)&spnego_mech : (gss_OID)gss_mech_krb5;
+ displayOID(minor, mech, "Target mech");
+
+ major = gss_init_sec_context(minor,
+ claimant_cred_handle,
+ &initiator_context,
+ target_name,
+ mech,
+ GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ GSS_C_NO_BUFFER,
+ NULL,
+ &token,
+ NULL,
+ &time_rec);
+
+ if (target_name != GSS_C_NO_NAME)
+ (void) gss_release_name(&tmp_minor, &target_name);
+
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_init_sec_context", major, *minor);
+ return major;
+ }
+
+ (void) gss_delete_sec_context(minor, &initiator_context, NULL);
+ mech = GSS_C_NO_OID;
+
+ major = gss_accept_sec_context(minor,
+ &acceptor_context,
+ verifier_cred_handle,
+ &token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &source_name,
+ &mech,
+ &tmp,
+ NULL,
+ &time_rec,
+ deleg_cred_handle);
+
+ if (GSS_ERROR(major))
+ displayStatus("gss_accept_sec_context", major, *minor);
+ else {
+ displayCanonName(minor, source_name, "Source name");
+ displayOID(minor, mech, "Source mech");
+ }
+
+ (void) gss_release_name(&tmp_minor, &source_name);
+ (void) gss_delete_sec_context(&tmp_minor, &acceptor_context, NULL);
+ (void) gss_release_buffer(&tmp_minor, &token);
+ (void) gss_release_buffer(&tmp_minor, &tmp);
+ (void) gss_release_oid(&tmp_minor, &mech);
+
+ return major;
+}
+
+static OM_uint32
+constrainedDelegate(OM_uint32 *minor,
+ gss_OID_set desired_mechs,
+ gss_name_t target,
+ gss_cred_id_t delegated_cred_handle,
+ gss_cred_id_t verifier_cred_handle)
+{
+ OM_uint32 major, tmp_minor;
+ gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT;
+ gss_name_t cred_name = GSS_C_NO_NAME;
+ OM_uint32 time_rec, lifetime;
+ gss_cred_usage_t usage;
+ gss_buffer_desc token;
+ gss_OID_set mechs;
+
+ printf("Constrained delegation tests follow\n");
+ printf("-----------------------------------\n\n");
+
+ if (gss_inquire_cred(minor, verifier_cred_handle, &cred_name,
+ &lifetime, &usage, NULL) == GSS_S_COMPLETE) {
+ displayCanonName(minor, cred_name, "Proxy name");
+ gss_release_name(&tmp_minor, &cred_name);
+ }
+ displayCanonName(minor, target, "Target name");
+ if (gss_inquire_cred(minor, delegated_cred_handle, &cred_name,
+ &lifetime, &usage, &mechs) == GSS_S_COMPLETE) {
+ displayCanonName(minor, cred_name, "Delegated name");
+ displayOID(minor, &mechs->elements[0], "Delegated mech");
+ gss_release_name(&tmp_minor, &cred_name);
+ }
+
+ printf("\n");
+
+ major = gss_init_sec_context(minor,
+ delegated_cred_handle,
+ &initiator_context,
+ target,
+ mechs ? &mechs->elements[0] :
+ (gss_OID)gss_mech_krb5,
+ GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ GSS_C_NO_BUFFER,
+ NULL,
+ &token,
+ NULL,
+ &time_rec);
+ if (GSS_ERROR(major))
+ displayStatus("gss_init_sec_context", major, *minor);
+
+ (void) gss_release_buffer(&tmp_minor, &token);
+ (void) gss_delete_sec_context(&tmp_minor, &initiator_context, NULL);
+ (void) gss_release_oid_set(&tmp_minor, &mechs);
+
+ return major;
+}
+
+int main(int argc, char *argv[])
+{
+ OM_uint32 minor, major;
+ gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL;
+ gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL;
+ gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+ gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME;
+ gss_OID_set_desc mechs;
+ gss_OID_set actual_mechs = GSS_C_NO_OID_SET;
+ gss_buffer_desc buf;
+
+ if (argc < 2 || argc > 5) {
+ fprintf(stderr, "Usage: %s [--spnego] [user] "
+ "[proxy-target] [keytab]\n", argv[0]);
+ fprintf(stderr, " proxy-target and keytab are optional\n");
+ exit(1);
+ }
+
+ if (strcmp(argv[1], "--spnego") == 0) {
+ use_spnego++;
+ argc--;
+ argv++;
+ }
+
+ buf.value = argv[1];
+ buf.length = strlen((char *)buf.value);
+
+ major = gss_import_name(&minor, &buf,
+ (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME,
+ &user);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_import_name(user)", major, minor);
+ goto out;
+ }
+
+ if (argc > 2 && strcmp(argv[2], "-")) {
+ buf.value = argv[2];
+ buf.length = strlen((char *)buf.value);
+
+ major = gss_import_name(&minor, &buf,
+ (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME,
+ &target);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_import_name(target)", major, minor);
+ goto out;
+ }
+ } else {
+ target = GSS_C_NO_NAME;
+ }
+
+ if (argc > 3) {
+ major = krb5_gss_register_acceptor_identity(argv[3]);
+ if (GSS_ERROR(major)) {
+ displayStatus("krb5_gss_register_acceptor_identity",
+ major, minor);
+ goto out;
+ }
+ }
+
+ mechs.elements = use_spnego ? (gss_OID)&spnego_mech :
+ (gss_OID)gss_mech_krb5;
+ mechs.count = 1;
+
+ /* get default cred */
+ major = gss_acquire_cred(&minor,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ &mechs,
+ GSS_C_BOTH,
+ &impersonator_cred_handle,
+ &actual_mechs,
+ NULL);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_acquire_cred", major, minor);
+ goto out;
+ }
+
+ (void) gss_release_oid_set(&minor, &actual_mechs);
+
+ printf("Protocol transition tests follow\n");
+ printf("-----------------------------------\n\n");
+
+ /* get S4U2Self cred */
+ major = gss_acquire_cred_impersonate_name(&minor,
+ impersonator_cred_handle,
+ user,
+ GSS_C_INDEFINITE,
+ &mechs,
+ GSS_C_INITIATE,
+ &user_cred_handle,
+ &actual_mechs,
+ NULL);
+ if (GSS_ERROR(major)) {
+ displayStatus("gss_acquire_cred_impersonate_name", major, minor);
+ goto out;
+ }
+
+ major = initAcceptSecContext(&minor,
+ user_cred_handle,
+ impersonator_cred_handle,
+ &delegated_cred_handle);
+ if (GSS_ERROR(major))
+ goto out;
+
+ printf("\n");
+
+ if (target != GSS_C_NO_NAME &&
+ delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
+ major = constrainedDelegate(&minor, &mechs, target,
+ delegated_cred_handle,
+ impersonator_cred_handle);
+ } else if (target != GSS_C_NO_NAME) {
+ fprintf(stderr, "Warning: no delegated credentials handle returned\n\n");
+ fprintf(stderr, "Verify:\n\n");
+ fprintf(stderr, " - The TGT for the impersonating service is forwardable\n");
+ fprintf(stderr, " - The T2A4D flag set on the impersonating service's UAC\n");
+ fprintf(stderr, " - The user is not marked sensitive and cannot be delegated\n");
+ fprintf(stderr, "\n");
+ }
+
+out:
+ (void) gss_release_name(&minor, &user);
+ (void) gss_release_name(&minor, &target);
+ (void) gss_release_cred(&minor, &delegated_cred_handle);
+ (void) gss_release_cred(&minor, &impersonator_cred_handle);
+ (void) gss_release_cred(&minor, &user_cred_handle);
+ (void) gss_release_oid_set(&minor, &actual_mechs);
+
+ return GSS_ERROR(major) ? 1 : 0;
+}
+