From 996c0089cf2e3240e1b331555897e5bf83b023e7 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Wed, 4 Jan 2017 18:31:15 -0500 Subject: [PATCH] Add tests for per-request preauth data scoping Add a test harness which interleaves calls for multiple initial creds contexts using the same library context. Add a test case to t_preauth.py using the new harness and the test preauth module to verify that modreq pointers are correctly tracked. ticket: 7877 (cherry picked from commit c0b25fe282355d4f329418956b9c6295780af633) [rharwood@redhat.com: drop .gitignore] --- src/tests/Makefile.in | 23 +++++--- src/tests/icinterleave.c | 124 +++++++++++++++++++++++++++++++++++++++ src/tests/t_preauth.py | 13 ++++ 3 files changed, 151 insertions(+), 9 deletions(-) create mode 100644 src/tests/icinterleave.c diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index a2093108b..bd1b21346 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -6,12 +6,12 @@ SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \ RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \ LC_ALL=C $(VALGRIND) -OBJS= adata.o etinfo.o forward.o gcred.o hist.o hooks.o hrealm.o icred.o \ - kdbtest.o localauth.o plugorder.o rdreq.o responder.o s2p.o \ - s4u2proxy.o unlockiter.o +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 \ + responder.o s2p.o s4u2proxy.o unlockiter.o EXTRADEPSRCS= adata.c etinfo.c forward.c gcred.c hist.c hooks.c hrealm.c \ - icred.c kdbtest.c localauth.c plugorder.c rdreq.o responder.c s2p.c \ - s4u2proxy.c unlockiter.c + icinterleave.c icred.c kdbtest.c localauth.c plugorder.c rdreq.o \ + responder.c s2p.c s4u2proxy.c unlockiter.c TEST_DB = ./testdb TEST_REALM = FOO.TEST.REALM @@ -44,6 +44,9 @@ hooks: hooks.o $(KRB5_BASE_DEPLIBS) hrealm: hrealm.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hrealm.o $(KRB5_BASE_LIBS) +icinterleave: icinterleave.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ icinterleave.o $(KRB5_BASE_LIBS) + icred: icred.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ icred.o $(KRB5_BASE_LIBS) @@ -115,8 +118,9 @@ kdb_check: kdc.conf krb5.conf $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f $(RM) $(TEST_DB)* stash_file -check-pytests: adata etinfo forward gcred hist hooks hrealm icred kdbtest -check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter +check-pytests: adata etinfo forward gcred hist hooks hrealm icinterleave icred +check-pytests: kdbtest localauth plugorder rdreq responder s2p s4u2proxy +check-pytests: unlockiter $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_hooks.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_dump.py $(PYTESTFLAGS) @@ -172,8 +176,9 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS) clean: - $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest - $(RM) localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RM) adata etinfo forward gcred hist hooks hrealm icinterleave icred + $(RM) kdbtest localauth plugorder rdreq responder s2p s4u2proxy + $(RM) unlockiter $(RM) krb5.conf kdc.conf $(RM) -rf kdc_realm/sandbox ldap $(RM) au.log diff --git a/src/tests/icinterleave.c b/src/tests/icinterleave.c new file mode 100644 index 000000000..d76ecf361 --- /dev/null +++ b/src/tests/icinterleave.c @@ -0,0 +1,124 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/icinterleave.c - interleaved init_creds_step test harness */ +/* + * Copyright (C) 2017 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. + */ + +/* + * This test harness performs multiple initial creds operations using + * krb5_init_creds_step(), interleaving the operations to test the scoping of + * the preauth state. All principals must have the same password (or not + * require a password). + */ + +#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); + } +} + +int +main(int argc, char **argv) +{ + const char *password; + char **princstrs; + krb5_principal client; + krb5_init_creds_context *iccs; + krb5_data req, *reps, realm; + krb5_boolean any_left; + int i, nclients, master; + unsigned int flags; + + if (argc < 3) { + fprintf(stderr, "Usage: icinterleave password princ1 princ2 ...\n"); + exit(1); + } + password = argv[1]; + princstrs = argv + 2; + nclients = argc - 2; + + check(krb5_init_context(&ctx)); + + /* Create an initial creds context for each client principal. */ + iccs = calloc(nclients, sizeof(*iccs)); + assert(iccs != NULL); + for (i = 0; i < nclients; i++) { + check(krb5_parse_name(ctx, princstrs[i], &client)); + check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, + &iccs[i])); + check(krb5_init_creds_set_password(ctx, iccs[i], password)); + krb5_free_principal(ctx, client); + } + + reps = calloc(nclients, sizeof(*reps)); + assert(reps != NULL); + + any_left = TRUE; + while (any_left) { + any_left = FALSE; + for (i = 0; i < nclients; i++) { + if (iccs[i] == NULL) + continue; + any_left = TRUE; + + printf("step %d\n", i + 1); + + req = empty_data(); + realm = empty_data(); + check(krb5_init_creds_step(ctx, iccs[i], &reps[i], &req, &realm, + &flags)); + if (!(flags & KRB5_INIT_CREDS_STEP_FLAG_CONTINUE)) { + printf("finish %d\n", i + 1); + krb5_init_creds_free(ctx, iccs[i]); + iccs[i] = NULL; + continue; + } + + master = 0; + krb5_free_data_contents(ctx, &reps[i]); + check(krb5_sendto_kdc(ctx, &req, &realm, &reps[i], &master, 0)); + krb5_free_data_contents(ctx, &req); + krb5_free_data_contents(ctx, &realm); + } + } + + krb5_free_context(ctx); + return 0; +} diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py index 0ef8bbca4..9b6da5a96 100644 --- a/src/tests/t_preauth.py +++ b/src/tests/t_preauth.py @@ -24,4 +24,17 @@ out = realm.run([kinit, realm.user_princ], input=password('user')+'\n') if '2rt: secondtrip' not in out: fail('multi round-trip cookie test') +# Test that multiple stepwise initial creds operations can be +# performed with the same krb5_context, with proper tracking of +# clpreauth module request handles. +realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1']) +realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2']) +realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3']) +realm.run([kadminl, 'setstr', 'u2', '2rt', 'extra']) +out = realm.run(['./icinterleave', 'pw', 'u1', 'u2', 'u3']) +if out != ('step 1\nstep 2\nstep 3\nstep 1\nfinish 1\nstep 2\nno attr\n' + 'step 3\nno attr\nstep 2\n2rt: extra\nstep 3\nfinish 3\nstep 2\n' + 'finish 2\n'): + fail('unexpected output from icinterleave') + success('Pre-authentication framework tests')