diff options
| author | Greg Hudson <ghudson@mit.edu> | 2009-10-09 18:29:34 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2009-10-09 18:29:34 +0000 |
| commit | 17ffdd0e93271072369e479f440ddf85e020580a (patch) | |
| tree | cdaf4944a478128a1d53d854063a7d809b7c6aae /src/tests | |
| parent | 6ad74ac369b09df7d29ca8e09b0af946b4819523 (diff) | |
Implement GSS naming extensions and authdata verification
Merge Luke's users/lhoward/authdata branch to trunk. Implements GSS naming
extensions and verification of authorization data.
ticket: 6572
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22875 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/asn.1/krb5_decode_leak.c | 12 | ||||
| -rw-r--r-- | src/tests/asn.1/krb5_decode_test.c | 10 | ||||
| -rw-r--r-- | src/tests/asn.1/krb5_encode_test.c | 12 | ||||
| -rw-r--r-- | src/tests/asn.1/ktest.c | 21 | ||||
| -rw-r--r-- | src/tests/asn.1/ktest.h | 2 | ||||
| -rw-r--r-- | src/tests/asn.1/ktest_equal.c | 14 | ||||
| -rw-r--r-- | src/tests/asn.1/ktest_equal.h | 4 | ||||
| -rw-r--r-- | src/tests/asn.1/reference_encode.out | 1 | ||||
| -rw-r--r-- | src/tests/asn.1/trval_reference.out | 20 | ||||
| -rw-r--r-- | src/tests/gssapi/Makefile.in | 11 | ||||
| -rw-r--r-- | src/tests/gssapi/t_namingexts.c | 488 | ||||
| -rw-r--r-- | src/tests/gssapi/t_s4u.c | 135 |
12 files changed, 722 insertions, 8 deletions
diff --git a/src/tests/asn.1/krb5_decode_leak.c b/src/tests/asn.1/krb5_decode_leak.c index be0a536e9..3eb6f3c66 100644 --- a/src/tests/asn.1/krb5_decode_leak.c +++ b/src/tests/asn.1/krb5_decode_leak.c @@ -662,7 +662,6 @@ main(int argc, char **argv) /* 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, @@ -670,6 +669,17 @@ main(int argc, char **argv) krb5_free_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&s4u); } + /****************************************************************/ + /* encode_krb5_ad_kdcissued */ + { + krb5_ad_kdcissued kdci, *tmp; + setup(kdci, "ad_kdcissued", + ktest_make_sample_ad_kdcissued); + leak_test(kdci, encode_krb5_ad_kdcissued, + decode_krb5_ad_kdcissued, + krb5_free_ad_kdcissued); + ktest_empty_ad_kdcissued(&kdci); + } 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 2d2000422..401b26240 100644 --- a/src/tests/asn.1/krb5_decode_test.c +++ b/src/tests/asn.1/krb5_decode_test.c @@ -891,12 +891,22 @@ int main(argc, argv) ktest_empty_sam_response(&ref); } + /****************************************************************/ + /* decode_pa_s4u_x509_user */ { 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); } + /****************************************************************/ + /* decode_ad_kdcissued */ + { + setup(krb5_ad_kdcissued,"krb5_ad_kdcissued",ktest_make_sample_ad_kdcissued); + decode_run("ad_kdcissued","","30 65 A0 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 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 A3 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_ad_kdcissued,ktest_equal_ad_kdcissued,krb5_free_ad_kdcissued); + ktest_empty_ad_kdcissued(&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 7ae32ec75..c010af9ab 100644 --- a/src/tests/asn.1/krb5_encode_test.c +++ b/src/tests/asn.1/krb5_encode_test.c @@ -706,7 +706,17 @@ main(argc, argv) encode_krb5_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&s4u); } - + /****************************************************************/ + /* encode_krb5_ad_kdcissued */ + { + krb5_ad_kdcissued kdci; + setup(kdci,krb5_ad_kdcissued,"ad_kdcissued", + ktest_make_sample_ad_kdcissued); + encode_run(kdci,krb5_ad_kdcissued, + "ad_kdcissued","", + encode_krb5_ad_kdcissued); + ktest_empty_ad_kdcissued(&kdci); + } #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 8b6367918..f41347c0f 100644 --- a/src/tests/asn.1/ktest.c +++ b/src/tests/asn.1/ktest.c @@ -842,6 +842,19 @@ krb5_error_code ktest_make_sample_pa_s4u_x509_user(p) return 0; } +krb5_error_code ktest_make_sample_ad_kdcissued(p) + krb5_ad_kdcissued *p; +{ + krb5_error_code retval; + retval = ktest_make_sample_checksum(&p->ad_checksum); + if (retval) return retval; + retval = ktest_make_sample_principal(&p->i_principal); + if (retval) return retval; + retval = ktest_make_sample_authorization_data(&p->elements); + if (retval) return retval; + return retval; +} + #ifdef ENABLE_LDAP static krb5_error_code ktest_make_sample_key_data(krb5_key_data *p, int i) { @@ -1445,6 +1458,14 @@ void ktest_empty_pa_s4u_x509_user(p) if (p->cksum.contents) free(p->cksum.contents); } +void ktest_empty_ad_kdcissued(p) + krb5_ad_kdcissued *p; +{ + if (p->ad_checksum.contents) free(p->ad_checksum.contents); + ktest_destroy_principal(&p->i_principal); + ktest_destroy_authorization_data(&p->elements); +} + #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 a2951d26f..fa33ceffd 100644 --- a/src/tests/asn.1/ktest.h +++ b/src/tests/asn.1/ktest.h @@ -106,6 +106,7 @@ krb5_error_code ktest_make_sample_enc_sam_response_enc 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); +krb5_error_code ktest_make_sample_ad_kdcissued(krb5_ad_kdcissued *p); #ifdef ENABLE_LDAP krb5_error_code ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data * p); @@ -215,6 +216,7 @@ 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); +void ktest_empty_ad_kdcissued(krb5_ad_kdcissued *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 da0324973..5479f8047 100644 --- a/src/tests/asn.1/ktest_equal.c +++ b/src/tests/asn.1/ktest_equal.c @@ -556,6 +556,20 @@ int ktest_equal_pa_s4u_x509_user(ref, var) p=p&&struct_equal(cksum,ktest_equal_checksum); return p; } + +int ktest_equal_ad_kdcissued(ref, var) + krb5_ad_kdcissued *ref; + krb5_ad_kdcissued *var; +{ + int p = TRUE; + if (ref == var) return TRUE; + else if (ref == NULL || var == NULL) return FALSE; + p=p&&struct_equal(ad_checksum,ktest_equal_checksum); + p=p&&ptr_equal(i_principal,ktest_equal_principal_data); + p=p&&ptr_equal(elements,ktest_equal_authorization_data); + 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 8a0641de5..1464ebb50 100644 --- a/src/tests/asn.1/ktest_equal.h +++ b/src/tests/asn.1/ktest_equal.h @@ -95,6 +95,10 @@ int ktest_equal_pa_s4u_x509_user (krb5_pa_s4u_x509_user *ref, krb5_pa_s4u_x509_user *var); +int ktest_equal_ad_kdcissued + (krb5_ad_kdcissued *ref, + krb5_ad_kdcissued *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 0d913cdb2..952e69c77 100644 --- a/src/tests/asn.1/reference_encode.out +++ b/src/tests/asn.1/reference_encode.out @@ -57,3 +57,4 @@ encode_krb5_predicted_sam_response: 30 6D A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 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 +encode_krb5_ad_kdcissued: 30 65 A0 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 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 A3 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out index c8aa48e3f..b19ca747e 100644 --- a/src/tests/asn.1/trval_reference.out +++ b/src/tests/asn.1/trval_reference.out @@ -1263,3 +1263,23 @@ encode_krb5_pa_s4u_x509_user: . . [0] [Integer] 1 . . [1] [Octet String] "1234" +encode_krb5_ad_kdcissued: + +[Sequence/Sequence Of] +. [0] [Sequence/Sequence Of] +. . [0] [Integer] 1 +. . [1] [Octet String] "1234" +. [1] [General string] "ATHENA.MIT.EDU" +. [2] [Sequence/Sequence Of] +. . [0] [Integer] 1 +. . [1] [Sequence/Sequence Of] +. . . [General string] "hftsai" +. . . [General string] "extra" +. [3] [Sequence/Sequence Of] +. . [Sequence/Sequence Of] +. . . [0] [Integer] 1 +. . . [1] [Octet String] "foobar" +. . [Sequence/Sequence Of] +. . . [0] [Integer] 1 +. . . [1] [Octet String] "foobar" + diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in index e385c68f6..fd7b7db5b 100644 --- a/src/tests/gssapi/Makefile.in +++ b/src/tests/gssapi/Makefile.in @@ -6,18 +6,19 @@ DEFINES = -DUSE_AUTOCONF_H PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) -SRCS= $(srcdir)/t_imp_name.c $(srcdir)/t_s4u.c +SRCS= $(srcdir)/t_imp_name.c $(srcdir)/t_s4u.c $(srcdir)/t_namingexts.c -OBJS= t_imp_name.o t_s4u.o +OBJS= t_imp_name.o t_s4u.o t_namingexts.o -all:: t_imp_name t_s4u +all:: t_imp_name t_s4u t_namingexts 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_namingexts: t_namingexts.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o t_namingexts t_namingexts.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 t_s4u + $(RM) t_imp_name t_s4u t_namingexts diff --git a/src/tests/gssapi/t_namingexts.c b/src/tests/gssapi/t_namingexts.c new file mode 100644 index 000000000..3d7e4e349 --- /dev/null +++ b/src/tests/gssapi/t_namingexts.c @@ -0,0 +1,488 @@ +/* -*- 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> +#include <gssapi/gssapi_generic.h> + +static gss_OID_desc spnego_mech = { 6, "\053\006\001\005\005\002" }; + +static 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; + 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)) { + gss_release_name(&tmp, &canon); + displayStatus("gss_display_name", major, *minor); + return major; + } + + printf("%s:\t%s\n", tag, (char *)buf.value); + + gss_release_name(&tmp, &canon); + gss_release_buffer(&tmp, &buf); + + return GSS_S_COMPLETE; +} + +static void +dumpAttribute(OM_uint32 *minor, + gss_name_t name, + gss_buffer_t attribute, + int noisy) +{ + OM_uint32 major, tmp; + gss_buffer_desc value; + gss_buffer_desc display_value; + int authenticated = 0; + int complete = 0; + int more = -1; + unsigned int i; + + while (more != 0) { + value.value = NULL; + display_value.value = NULL; + + major = gss_get_name_attribute(minor, + name, + attribute, + &authenticated, + &complete, + &value, + &display_value, + &more); + if (GSS_ERROR(major)) { + displayStatus("gss_get_name_attribute", major, *minor); + break; + } + + printf("Attribute %.*s %s %s\n\n%.*s\n", + (int)attribute->length, (char *)attribute->value, + authenticated ? "Authenticated" : "", + complete ? "Complete" : "", + (int)display_value.length, (char *)display_value.value); + + if (noisy) { + for (i = 0; i < value.length; i++) { + if ((i % 32) == 0) + printf("\n"); + printf("%02x", ((char *)value.value)[i] & 0xFF); + } + printf("\n\n"); + } + + gss_release_buffer(&tmp, &value); + gss_release_buffer(&tmp, &display_value); + } +} + +static OM_uint32 +enumerateAttributes(OM_uint32 *minor, + gss_name_t name, + int noisy) +{ + OM_uint32 major, tmp; + int name_is_MN; + gss_OID mech = GSS_C_NO_OID; + gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET; + unsigned int i; + + major = gss_inquire_name(minor, + name, + &name_is_MN, + &mech, + &attrs); + if (GSS_ERROR(major)) { + displayStatus("gss_inquire_name", major, *minor); + return major; + } + + if (attrs != GSS_C_NO_BUFFER_SET) { + for (i = 0; i < attrs->count; i++) + dumpAttribute(minor, name, &attrs->elements[i], noisy); + } + + gss_release_oid(&tmp, &mech); + gss_release_buffer_set(&tmp, &attrs); + + return major; +} + +static OM_uint32 +testExportImportName(OM_uint32 *minor, + gss_name_t name) +{ + OM_uint32 major, tmp; + gss_buffer_desc exported_name; + gss_name_t imported_name = GSS_C_NO_NAME; + unsigned int i; + + exported_name.value = NULL; + + major = gss_export_name_composite(minor, + name, + &exported_name); + if (GSS_ERROR(major)) { + displayStatus("gss_export_name_composite", major, *minor); + return major; + } + + printf("Exported name:\n"); + + for (i = 0; i < exported_name.length; i++) { + if ((i % 32) == 0) + printf("\n"); + printf("%02x", ((char *)exported_name.value)[i] & 0xFF); + } + + printf("\n"); + + major = gss_import_name(minor, &exported_name, gss_nt_exported_name, + &imported_name); + if (GSS_ERROR(major)) { + displayStatus("gss_import_name", major, *minor); + gss_release_buffer(&tmp, &exported_name); + return major; + } + + gss_release_buffer(&tmp, &exported_name); + + printf("\n"); + displayCanonName(minor, imported_name, "Re-imported name"); + printf("Re-imported attributes:\n\n"); + major = enumerateAttributes(minor, imported_name, 0); + + gss_release_name(&tmp, &imported_name); + + return major; +} + +static OM_uint32 +testGreetAuthzData(OM_uint32 *minor, + gss_name_t name) +{ + OM_uint32 major; + gss_buffer_desc attr; + gss_buffer_desc value; + + attr.value = "greet:greeting"; + attr.length = strlen((char *)attr.value); + + major = gss_delete_name_attribute(minor, + name, + &attr); + if (major == GSS_S_UNAVAILABLE) { + fprintf(stderr, "Warning: greet_client plugin not installed\n"); + return GSS_S_COMPLETE; + } else if (GSS_ERROR(major)) { + displayStatus("gss_delete_name_attribute", major, *minor); + return major; + } + + value.value = "Hello, acceptor world!"; + value.length = strlen((char *)value.value); + + major = gss_set_name_attribute(minor, + name, + 1, + &attr, + &value); + if (major == GSS_S_UNAVAILABLE) + return GSS_S_COMPLETE; + else if (GSS_ERROR(major)) + displayStatus("gss_set_name_attribute", major, *minor); + + return major; +} + +static OM_uint32 +testMapNameToAny(OM_uint32 *minor, + gss_name_t name) +{ + OM_uint32 major; + OM_uint32 tmp_minor; + gss_buffer_desc type_id; + krb5_pac pac; + krb5_context context; + krb5_error_code code; + size_t len; + krb5_ui_4 *types; + + type_id.value = "mspac"; + type_id.length = strlen((char *)type_id.value); + + major = gss_map_name_to_any(minor, + name, + 1, /* authenticated */ + &type_id, + (gss_any_t *)&pac); + if (major == GSS_S_UNAVAILABLE) + return GSS_S_COMPLETE; + else if (GSS_ERROR(major)) + displayStatus("gss_map_name_to_any", major, &minor); + + code = krb5_init_context(&context); + if (code != 0) { + gss_release_any_name_mapping(&tmp_minor, name, + &type_id, (gss_any_t *)&pac); + *minor = code; + return GSS_S_FAILURE; + } + + code = krb5_pac_get_types(context, pac, &len, &types); + if (code == 0) { + size_t i; + + printf("PAC buffer types:"); + for (i = 0; i < len; i++) + printf(" %d", types[i]); + printf("\n"); + free(types); + } + + gss_release_any_name_mapping(&tmp_minor, name, + &type_id, (gss_any_t *)&pac); + + return GSS_S_COMPLETE; +} + +static OM_uint32 +initAcceptSecContext(OM_uint32 *minor, + gss_cred_id_t verifier_cred_handle) +{ + OM_uint32 major; + 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; + + token.value = NULL; + token.length = 0; + + tmp.value = NULL; + tmp.length = 0; + + 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"); + + major = gss_init_sec_context(minor, + verifier_cred_handle, + &initiator_context, + target_name, + use_spnego ? + (gss_OID)&spnego_mech : + (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 (target_name != GSS_C_NO_NAME) + (void) gss_release_name(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); + + major = gss_accept_sec_context(minor, + &acceptor_context, + verifier_cred_handle, + &token, + GSS_C_NO_CHANNEL_BINDINGS, + &source_name, + NULL, + &tmp, + NULL, + &time_rec, + NULL); + + if (GSS_ERROR(major)) + displayStatus("gss_accept_sec_context", major, *minor); + else { + displayCanonName(minor, source_name, "Source name"); + enumerateAttributes(minor, source_name, 1); + testExportImportName(minor, source_name); + testMapNameToAny(minor, source_name); + } + + (void) gss_release_name(minor, &source_name); + (void) gss_delete_sec_context(minor, &acceptor_context, NULL); + (void) gss_release_buffer(minor, &token); + (void) gss_release_buffer(minor, &tmp); + + return major; +} + +int main(int argc, char *argv[]) +{ + OM_uint32 minor, major, tmp; + gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; + gss_OID_set_desc mechs; + gss_OID_set actual_mechs = GSS_C_NO_OID_SET; + gss_name_t name = GSS_C_NO_NAME; + + if (argc > 1 && strcmp(argv[1], "--spnego") == 0) { + use_spnego++; + argc--; + argv++; + } + + if (argc > 1) { + gss_buffer_desc name_buf; + gss_name_t tmp_name; + + name_buf.value = argv[1]; + name_buf.length = strlen(argv[1]); + + major = gss_import_name(&minor, &name_buf, + (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &tmp_name); + if (GSS_ERROR(major)) { + displayStatus("gss_import_name", major, minor); + goto out; + } + + major = gss_canonicalize_name(&minor, tmp_name, + (gss_OID)gss_mech_krb5, &name); + if (GSS_ERROR(major)) { + gss_release_name(&tmp, &tmp_name); + displayStatus("gss_canonicalze_name", major, minor); + goto out; + } + + gss_release_name(&tmp, &tmp_name); + + major = testGreetAuthzData(&minor, name); + if (GSS_ERROR(major)) + goto out; + } else { + fprintf(stderr, "Usage: %s [--spnego] [principal] [keytab]\n", argv[0]); + exit(1); + } + + if (argc > 2) { + major = krb5_gss_register_acceptor_identity(argv[2]); + 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, + name, + GSS_C_INDEFINITE, + &mechs, + GSS_C_BOTH, + &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); + + major = initAcceptSecContext(&minor, cred_handle); + if (GSS_ERROR(major)) + goto out; + + printf("\n"); + +out: + (void) gss_release_cred(&tmp, &cred_handle); + (void) gss_release_oid_set(&tmp, &actual_mechs); + (void) gss_release_name(&tmp, &name); + + return GSS_ERROR(major) ? 1 : 0; +} + diff --git a/src/tests/gssapi/t_s4u.c b/src/tests/gssapi/t_s4u.c index 264e60a60..394313a68 100644 --- a/src/tests/gssapi/t_s4u.c +++ b/src/tests/gssapi/t_s4u.c @@ -59,7 +59,7 @@ static gss_OID_desc spnego_mech = { 6, "\053\006\001\005\005\002" }; -int use_spnego = 0; +static int use_spnego = 0; static void displayStatus_1(m, code, type) char *m; @@ -140,6 +140,134 @@ displayOID(OM_uint32 *minor, gss_OID oid, char *tag) return GSS_S_COMPLETE; } +static void +dumpAttribute(OM_uint32 *minor, + gss_name_t name, + gss_buffer_t attribute, + int noisy) +{ + OM_uint32 major, tmp_minor; + gss_buffer_desc value; + gss_buffer_desc display_value; + int authenticated = 0; + int complete = 0; + int more = -1; + unsigned int i; + + while (more != 0) { + value.value = NULL; + display_value.value = NULL; + + major = gss_get_name_attribute(minor, + name, + attribute, + &authenticated, + &complete, + &value, + &display_value, + &more); + if (GSS_ERROR(major)) { + displayStatus("gss_get_name_attribute", major, *minor); + break; + } + + printf("Attribute %.*s %s %s\n\n%.*s\n", + (int)attribute->length, (char *)attribute->value, + authenticated ? "Authenticated" : "", + complete ? "Complete" : "", + (int)display_value.length, (char *)display_value.value); + + if (noisy) { + for (i = 0; i < value.length; i++) { + if ((i % 32) == 0) + printf("\n"); + printf("%02x", ((char *)value.value)[i] & 0xFF); + } + printf("\n\n"); + } + + gss_release_buffer(&tmp_minor, &value); + gss_release_buffer(&tmp_minor, &display_value); + } +} + +static OM_uint32 +enumerateAttributes(OM_uint32 *minor, + gss_name_t name, + int noisy) +{ + OM_uint32 major, tmp_minor; + int name_is_MN; + gss_OID mech = GSS_C_NO_OID; + gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET; + unsigned int i; + + major = gss_inquire_name(minor, + name, + &name_is_MN, + &mech, + &attrs); + if (GSS_ERROR(major)) { + displayStatus("gss_inquire_name", major, *minor); + return major; + } + + if (attrs != GSS_C_NO_BUFFER_SET) { + for (i = 0; i < attrs->count; i++) + dumpAttribute(minor, name, &attrs->elements[i], noisy); + } + + gss_release_oid(&tmp_minor, &mech); + gss_release_buffer_set(&tmp_minor, &attrs); + + return major; +} + +static OM_uint32 +testGreetAuthzData(OM_uint32 *minor, + gss_name_t *name) +{ + OM_uint32 major, tmp_minor; + gss_buffer_desc attr; + gss_buffer_desc value; + gss_name_t canon; + + major = gss_canonicalize_name(minor, + *name, + (gss_OID)gss_mech_krb5, + &canon); + if (GSS_ERROR(major)) { + displayStatus("gss_canonicalize_name", major, *minor); + return major; + } + + attr.value = "greet:greeting"; + attr.length = strlen((char *)attr.value); + + value.value = "Hello, acceptor world!"; + value.length = strlen((char *)value.value); + + major = gss_set_name_attribute(minor, + canon, + 1, + &attr, + &value); + if (major == GSS_S_UNAVAILABLE) + major = GSS_S_COMPLETE; + else if (GSS_ERROR(major)) + displayStatus("gss_set_name_attribute", major, *minor); + else { + gss_release_name(&tmp_minor, name); + *name = canon; + canon = GSS_C_NO_NAME; + } + + if (canon != GSS_C_NO_NAME) + gss_release_name(&tmp_minor, &canon); + + return GSS_S_COMPLETE; +} + static OM_uint32 initAcceptSecContext(OM_uint32 *minor, gss_cred_id_t claimant_cred_handle, @@ -217,6 +345,7 @@ initAcceptSecContext(OM_uint32 *minor, else { displayCanonName(minor, source_name, "Source name"); displayOID(minor, mech, "Source mech"); + enumerateAttributes(minor, source_name, 1); } (void) gss_release_name(&tmp_minor, &source_name); @@ -367,6 +496,10 @@ int main(int argc, char *argv[]) printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); + major = testGreetAuthzData(&minor, &user); + if (GSS_ERROR(major)) + goto out; + /* get S4U2Self cred */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, |
