aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Boukris <iboukris@gmail.com>2019-12-12 03:20:44 +0100
committerGreg Hudson <ghudson@mit.edu>2020-01-24 21:59:07 -0500
commit8642b06696fd7fca68aae475bd4113be5a1658cb (patch)
tree627f352db6c898678edfacf3c108b9388e7d48dc
parentcad856e8a51c0b22ec2c41db02c6a56c433e5b20 (diff)
downloadkrb5-8642b06696fd7fca68aae475bd4113be5a1658cb.zip
krb5-8642b06696fd7fca68aae475bd4113be5a1658cb.tar.gz
krb5-8642b06696fd7fca68aae475bd4113be5a1658cb.tar.bz2
Add tests for S4U request-authdata handling
In adata.c, look up the server in the keytab by ticket->server (which has the canonicalized realm), to allow testing of cross-realm RBCD (although unused for now). In s4u2proxy.c, set KRB5_GC_CANONICALIZE to support RBCD, and add an authdata request option. Add an s4u2self test harness with authdata request option. [ghudson@mit.edu: minor code simplifications; edited commit message] (cherry picked from commit 2d039a2b4c3ba6d71da8fcf76658dc63bc659f0c) ticket: 8866 version_fixed: 1.18
-rw-r--r--.gitignore1
-rw-r--r--src/tests/Makefile.in11
-rw-r--r--src/tests/adata.c4
-rw-r--r--src/tests/s4u2proxy.c37
-rw-r--r--src/tests/s4u2self.c128
-rw-r--r--src/tests/t_authdata.py22
6 files changed, 195 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index adf6615..ae1c262 100644
--- a/.gitignore
+++ b/.gitignore
@@ -444,6 +444,7 @@ local.properties
/src/tests/responder
/src/tests/s2p
/src/tests/s4u2proxy
+/src/tests/s4u2self
/src/tests/unlockiter
/src/tests/asn.1/expected_encode.out
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 81ca4cb..3f88f17 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -8,10 +8,10 @@ RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \
OBJS= adata.o etinfo.o forward.o gcred.o hist.o hooks.o hrealm.o \
icinterleave.o icred.o kdbtest.o localauth.o plugorder.o rdreq.o \
- replay.o responder.o s2p.o s4u2proxy.o unlockiter.o
+ replay.o responder.o s2p.o s4u2self.o s4u2proxy.o unlockiter.o
EXTRADEPSRCS= adata.c etinfo.c forward.c gcred.c hist.c hooks.c hrealm.c \
icinterleave.c icred.c kdbtest.c localauth.c plugorder.c rdreq.c \
- replay.c responder.c s2p.c s4u2proxy.c unlockiter.c
+ replay.c responder.c s2p.c s4u2self.c s4u2proxy.c unlockiter.c
TEST_DB = ./testdb
TEST_REALM = FOO.TEST.REALM
@@ -72,6 +72,9 @@ responder: responder.o $(KRB5_BASE_DEPLIBS)
s2p: s2p.o $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o $@ s2p.o $(KRB5_BASE_LIBS)
+s4u2self: s4u2self.o $(KRB5_BASE_DEPLIBS)
+ $(CC_LINK) -o $@ s4u2self.o $(KRB5_BASE_LIBS)
+
s4u2proxy: s4u2proxy.o $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o $@ s4u2proxy.o $(KRB5_BASE_LIBS)
@@ -117,7 +120,7 @@ kdb_check: kdc.conf krb5.conf
check-pytests: adata etinfo forward gcred hist hooks hrealm icinterleave icred
check-pytests: kdbtest localauth plugorder rdreq replay responder s2p s4u2proxy
-check-pytests: unlockiter
+check-pytests: unlockiter s4u2self
$(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_hooks.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_dump.py $(PYTESTFLAGS)
@@ -180,7 +183,7 @@ check-pytests: unlockiter
clean:
$(RM) adata etinfo forward gcred hist hooks hrealm icinterleave icred
$(RM) kdbtest localauth plugorder rdreq replay responder s2p s4u2proxy
- $(RM) unlockiter
+ $(RM) unlockiter s4u2self
$(RM) krb5.conf kdc.conf
$(RM) -rf kdc_realm/sandbox ldap
$(RM) au.log
diff --git a/src/tests/adata.c b/src/tests/adata.c
index df77c80..d3bd08e 100644
--- a/src/tests/adata.c
+++ b/src/tests/adata.c
@@ -303,9 +303,11 @@ main(int argc, char **argv)
check(krb5_get_credentials(ctx, KRB5_GC_NO_STORE, ccache, &in_creds,
&creds));
+ assert(in_creds.authdata == NULL || creds->authdata != NULL);
+
check(krb5_decode_ticket(&creds->ticket, &ticket));
check(krb5_kt_default(ctx, &keytab));
- check(krb5_kt_get_entry(ctx, keytab, server, ticket->enc_part.kvno,
+ check(krb5_kt_get_entry(ctx, keytab, ticket->server, ticket->enc_part.kvno,
ticket->enc_part.enctype, &ktent));
check(krb5_decrypt_tkt_part(ctx, &ktent.key, ticket));
diff --git a/src/tests/s4u2proxy.c b/src/tests/s4u2proxy.c
index 28bff61..4adf6ac 100644
--- a/src/tests/s4u2proxy.c
+++ b/src/tests/s4u2proxy.c
@@ -31,7 +31,7 @@
*/
/*
- * Usage: s4u2proxy evccname targetname
+ * Usage: s4u2proxy evccname targetname [ad-type ad-contents]
*
* evccname contains an evidence ticket. The default ccache contains a TGT for
* the intermediate service. The default keytab contains a key for the
@@ -57,6 +57,28 @@ check(krb5_error_code code)
}
}
+static krb5_authdata **
+make_request_authdata(int type, const char *contents)
+{
+ krb5_authdata *ad;
+ krb5_authdata **req_authdata;
+
+ ad = malloc(sizeof(*ad));
+ assert(ad != NULL);
+ ad->magic = KV5M_AUTHDATA;
+ ad->ad_type = type;
+ ad->length = strlen(contents);
+ ad->contents = (unsigned char *)strdup(contents);
+ assert(ad->contents != NULL);
+
+ req_authdata = malloc(2 * sizeof(*req_authdata));
+ assert(req_authdata != NULL);
+ req_authdata[0] = ad;
+ req_authdata[1] = NULL;
+
+ return req_authdata;
+}
+
int
main(int argc, char **argv)
{
@@ -66,6 +88,12 @@ main(int argc, char **argv)
krb5_keytab defkt;
krb5_creds mcred, ev_cred, *new_cred;
krb5_ticket *ev_ticket;
+ krb5_authdata **req_authdata = NULL;
+
+ if (argc == 5) {
+ req_authdata = make_request_authdata(atoi(argv[3]), argv[4]);
+ argc -= 2;
+ }
assert(argc == 3);
check(krb5_init_context(&context));
@@ -91,12 +119,16 @@ main(int argc, char **argv)
/* Make an S4U2Proxy request for the target service. */
mcred.client = client_name;
mcred.server = target_name;
- check(krb5_get_credentials_for_proxy(context, KRB5_GC_NO_STORE, defcc,
+ mcred.authdata = req_authdata;
+ check(krb5_get_credentials_for_proxy(context, KRB5_GC_NO_STORE |
+ KRB5_GC_CANONICALIZE, defcc,
&mcred, ev_ticket, &new_cred));
/* Store the new cred in the default ccache. */
check(krb5_cc_store_cred(context, defcc, new_cred));
+ assert(req_authdata == NULL || new_cred->authdata != NULL);
+
krb5_cc_close(context, defcc);
krb5_cc_close(context, evcc);
krb5_kt_close(context, defkt);
@@ -106,6 +138,7 @@ main(int argc, char **argv)
krb5_free_cred_contents(context, &ev_cred);
krb5_free_ticket(context, ev_ticket);
krb5_free_creds(context, new_cred);
+ krb5_free_authdata(context, req_authdata);
krb5_free_context(context);
return 0;
}
diff --git a/src/tests/s4u2self.c b/src/tests/s4u2self.c
new file mode 100644
index 0000000..c8e4822
--- /dev/null
+++ b/src/tests/s4u2self.c
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2019 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Usage: s4u2self user self out_cache [ad-type ad-contents]
+ *
+ * The default ccache contains a TGT for the intermediate service self. An
+ * S4U2Self request is made to self. The resulting cred is stored in
+ * out_cache.
+ */
+
+#include <k5-int.h>
+
+static krb5_context ctx;
+
+static void
+check(krb5_error_code code)
+{
+ const char *errmsg;
+
+ if (code) {
+ errmsg = krb5_get_error_message(ctx, code);
+ fprintf(stderr, "%s\n", errmsg);
+ krb5_free_error_message(ctx, errmsg);
+ exit(1);
+ }
+}
+
+static krb5_authdata **
+make_request_authdata(int type, const char *contents)
+{
+ krb5_authdata *ad;
+ krb5_authdata **req_authdata;
+
+ ad = malloc(sizeof(*ad));
+ assert(ad != NULL);
+ ad->magic = KV5M_AUTHDATA;
+ ad->ad_type = type;
+ ad->length = strlen(contents);
+ ad->contents = (unsigned char *)strdup(contents);
+ assert(ad->contents != NULL);
+
+ req_authdata = malloc(2 * sizeof(*req_authdata));
+ assert(req_authdata != NULL);
+ req_authdata[0] = ad;
+ req_authdata[1] = NULL;
+
+ return req_authdata;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_ccache defcc, ocache;
+ krb5_principal client, self;
+ krb5_creds mcred, *new_cred;
+ krb5_authdata **req_authdata = NULL;
+
+ if (argc == 6) {
+ req_authdata = make_request_authdata(atoi(argv[4]), argv[5]);
+ argc -= 2;
+ }
+
+ assert(argc == 4);
+ check(krb5_init_context(&context));
+
+ /* Open the default ccache. */
+ check(krb5_cc_default(context, &defcc));
+
+ check(krb5_parse_name(context, argv[1], &client));
+ check(krb5_parse_name(context, argv[2], &self));
+
+ memset(&mcred, 0, sizeof(mcred));
+ mcred.client = client;
+ mcred.server = self;
+ mcred.authdata = req_authdata;
+ check(krb5_get_credentials_for_user(context, KRB5_GC_NO_STORE |
+ KRB5_GC_CANONICALIZE, defcc,
+ &mcred, NULL, &new_cred));
+
+ if (strcmp(argv[3], "-") == 0) {
+ check(krb5_cc_store_cred(context, defcc, new_cred));
+ } else {
+ check(krb5_cc_resolve(context, argv[3], &ocache));
+ check(krb5_cc_initialize(context, ocache, new_cred->client));
+ check(krb5_cc_store_cred(context, ocache, new_cred));
+ krb5_cc_close(context, ocache);
+ }
+
+ assert(req_authdata == NULL || new_cred->authdata != NULL);
+
+ krb5_cc_close(context, defcc);
+ krb5_free_principal(context, client);
+ krb5_free_principal(context, self);
+ krb5_free_creds(context, new_cred);
+ krb5_free_authdata(context, req_authdata);
+ krb5_free_context(context);
+ return 0;
+}
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
index 9b41bc0..44965dd 100644
--- a/src/tests/t_authdata.py
+++ b/src/tests/t_authdata.py
@@ -193,7 +193,9 @@ realm2.stop()
testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
'krbtgt/FOREIGN': {'keys': 'aes128-cts'},
'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
- 'service/1': {'keys': 'aes128-cts', 'flags': '+preauth'},
+ 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'},
+ 'service/1': {'keys': 'aes128-cts',
+ 'flags': '+ok_to_auth_as_delegate'},
'service/2': {'keys': 'aes128-cts'},
'noauthdata': {'keys': 'aes128-cts',
'flags': '+no_auth_data_required'}}
@@ -219,6 +221,11 @@ out = realm.run(['./adata', '-p', realm.user_princ, 'service/1'])
if '97:' in out:
fail('auth-indicator present in S4U2Self response')
+# Get another S4U2Self ticket with requested authdata.
+realm.run(['./s4u2self', 'user', 'service/1', '-', '-2', 'self_ad'])
+realm.run(['./adata', '-p', realm.user_princ, 'service/1', '-2', 'self_ad'],
+ expected_msg=' -2: self_ad')
+
# S4U2Proxy (indicators should come from evidence ticket, not TGT)
mark('S4U2Proxy (auth indicators from evidence ticket expected)')
realm.kinit(realm.user_princ, None, ['-k', '-f', '-X', 'indicators=indcl',
@@ -228,6 +235,19 @@ out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
if '+97: [indcl]' not in out or '[inds1]' in out:
fail('correct auth-indicator not seen for S4U2Proxy req')
+# Get another S4U2Proxy ticket including request-authdata.
+realm.run(['./s4u2proxy', usercache, 'service/2', '-2', 'proxy_ad'])
+realm.run(['./adata', '-p', realm.user_princ, 'service/2', '-2', 'proxy_ad'],
+ expected_msg=' -2: proxy_ad')
+
+# Get an S4U2Proxy ticket using an evidence ticket obtained by S4U2Self,
+# with request authdata in both steps.
+realm.run(['./s4u2self', 'user2', 'service/1', usercache, '-2', 'self_ad'])
+realm.run(['./s4u2proxy', usercache, 'service/2', '-2', 'proxy_ad'])
+out = realm.run(['./adata', '-p', 'user2', 'service/2', '-2', 'proxy_ad'])
+if ' -2: self_ad' not in out or ' -2: proxy_ad' not in out:
+ fail('expected authdata not seen in S4U2Proxy ticket')
+
# Test alteration of auth indicators by KDB module (AS and TGS).
realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=dummy dbincr1'])
realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [dbincr2]')