diff options
| author | Greg Hudson <ghudson@mit.edu> | 2012-06-22 12:48:26 -0400 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2012-07-02 02:24:14 -0400 |
| commit | 8651f3339ccc5a623172a8edfb9cf522883acacd (patch) | |
| tree | cdf246a41a1480d474d2fb09bfcefa9166d58641 /src/tests/gssapi | |
| parent | 68092d23093c646c03ccfefc07f8ae8984b32ba2 (diff) | |
| download | krb5-8651f3339ccc5a623172a8edfb9cf522883acacd.tar.gz krb5-8651f3339ccc5a623172a8edfb9cf522883acacd.tar.xz krb5-8651f3339ccc5a623172a8edfb9cf522883acacd.zip | |
Add client keytab initiation support
Support acquiring GSSAPI krb5 credentials by fetching initial
credentials using the client keytab. Credentials obtained this way
will be stored in the default ccache or collection, and will be
refreshed when they are halfway to expiring.
ticket: 7189 (new)
Diffstat (limited to 'src/tests/gssapi')
| -rw-r--r-- | src/tests/gssapi/Makefile.in | 8 | ||||
| -rw-r--r-- | src/tests/gssapi/ccinit.c | 72 | ||||
| -rw-r--r-- | src/tests/gssapi/ccrefresh.c | 80 | ||||
| -rw-r--r-- | src/tests/gssapi/t_ccselect.py | 2 | ||||
| -rw-r--r-- | src/tests/gssapi/t_client_keytab.py | 132 |
5 files changed, 292 insertions, 2 deletions
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in index 271921278..4ddd9c91d 100644 --- a/src/tests/gssapi/Makefile.in +++ b/src/tests/gssapi/Makefile.in @@ -14,11 +14,17 @@ OBJS= t_accname.o t_ccselect.o t_imp_cred.o t_imp_name.o t_s4u.o \ all:: t_accname t_ccselect t_imp_cred t_imp_name t_s4u t_s4u2proxy_krb5 \ t_namingexts t_gssexts t_spnego t_saslname -check-pytests:: t_accname t_ccselect t_imp_cred t_spnego t_s4u2proxy_krb5 t_s4u +check-pytests:: t_accname t_ccselect t_imp_cred t_spnego t_s4u2proxy_krb5 \ + t_s4u ccinit ccrefresh $(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_s4u.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS) +ccinit: ccinit.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o ccinit ccinit.o $(KRB5_BASE_LIBS) +ccrefresh: ccrefresh.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o ccrefresh ccrefresh.o $(KRB5_BASE_LIBS) t_accname: t_accname.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_accname t_accname.o $(GSS_LIBS) $(KRB5_BASE_LIBS) t_ccselect: t_ccselect.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) diff --git a/src/tests/gssapi/ccinit.c b/src/tests/gssapi/ccinit.c new file mode 100644 index 000000000..b06f04404 --- /dev/null +++ b/src/tests/gssapi/ccinit.c @@ -0,0 +1,72 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/gssapi/ccinit.c - Initialize an empty ccache */ +/* + * Copyright (C) 2012 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 program initializes a ccache without attempting to get credentials in + * it. It is used to test some finer points of gss_acquire_cred behavior. + */ + +#include "k5-int.h" + +static void +check(krb5_error_code code) +{ + if (code != 0) { + com_err("ccinit", code, NULL); + abort(); + } +} + +int +main(int argc, char **argv) +{ + const char *ccname, *princname; + krb5_context context; + krb5_principal princ; + krb5_ccache ccache; + + if (argc != 3) { + fprintf(stderr, "Usage: %s ccname princname\n", argv[0]); + return 1; + } + ccname = argv[1]; + princname = argv[2]; + + check(krb5_init_context(&context)); + check(krb5_parse_name(context, princname, &princ)); + check(krb5_cc_resolve(context, ccname, &ccache)); + check(krb5_cc_initialize(context, ccache, princ)); + krb5_cc_close(context, ccache); + krb5_free_principal(context, princ); + krb5_free_context(context); + return 0; +} diff --git a/src/tests/gssapi/ccrefresh.c b/src/tests/gssapi/ccrefresh.c new file mode 100644 index 000000000..bff299e46 --- /dev/null +++ b/src/tests/gssapi/ccrefresh.c @@ -0,0 +1,80 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/gssapi/ccrefresh.c - Get or set refresh time on a ccache */ +/* + * Copyright (C) 2012 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 program sets the refresh time of an existing ccache to 1, forcing a + * refresh. + */ + +#include "k5-int.h" + +static void +check(krb5_error_code code) +{ + if (code != 0) { + com_err("ccrefresh", code, NULL); + abort(); + } +} + +int +main(int argc, char **argv) +{ + const char *ccname, *value = NULL; + krb5_context context; + krb5_ccache ccache; + krb5_data d; + + if (argc != 2 && argc != 3) { + fprintf(stderr, "Usage: %s ccname [value]\n", argv[0]); + return 1; + } + ccname = argv[1]; + if (argc == 3) + value = argv[2]; + + check(krb5_init_context(&context)); + check(krb5_cc_resolve(context, ccname, &ccache)); + if (value != NULL) { + d = string2data((char *)value); + check(krb5_cc_set_config(context, ccache, NULL, KRB5_CONF_REFRESH_TIME, + &d)); + } else { + check(krb5_cc_get_config(context, ccache, NULL, KRB5_CONF_REFRESH_TIME, + &d)); + printf("%.*s\n", (int)d.length, d.data); + krb5_free_data_contents(context, &d); + } + krb5_cc_close(context, ccache); + krb5_free_context(context); + return 0; +} diff --git a/src/tests/gssapi/t_ccselect.py b/src/tests/gssapi/t_ccselect.py index 5350d9209..ce25dfb57 100644 --- a/src/tests/gssapi/t_ccselect.py +++ b/src/tests/gssapi/t_ccselect.py @@ -123,7 +123,7 @@ if output != (bob + '\n'): fail('bob not chosen via primary cache when no .k5identity line matches.') output = r1.run_as_client(['./t_ccselect', 'gss:bogus@' + hostname], expected_code=1) -if 'does not match desired' not in output: +if 'Can\'t find client principal noprinc' not in output: fail('Expected error not seen when k5identity selects bad principal.') success('GSSAPI credential selection tests') diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py new file mode 100644 index 000000000..71cb89e78 --- /dev/null +++ b/src/tests/gssapi/t_client_keytab.py @@ -0,0 +1,132 @@ +#!/usr/bin/python +from k5test import * + +# Set up a basic realm and a client keytab containing two user principals. +# Point HOME at realm.testdir for tests using .k5identity. +realm = K5Realm(get_creds=False) +bob = 'bob@' + realm.realm +gssserver = 'gss:host@' + hostname +realm.env_client['HOME'] = realm.testdir +realm.addprinc(bob, password('bob')) +realm.extract_keytab(realm.user_princ, realm.client_keytab) +realm.extract_keytab(bob, realm.client_keytab) + +# Test 1: no name/cache specified, pick first principal from client keytab +out = realm.run_as_client(['./t_ccselect', realm.host_princ]) +if realm.user_princ not in out: + fail('Authenticated as wrong principal') +realm.run_as_client([kdestroy]) + +# Test 2: no name/cache specified, pick principal from k5identity +k5idname = os.path.join(realm.testdir, '.k5identity') +k5id = open(k5idname, 'w') +k5id.write('%s service=host host=%s\n' % (bob, hostname)) +k5id.close() +out = realm.run_as_client(['./t_ccselect', gssserver]) +if bob not in out: + fail('Authenticated as wrong principal') +os.remove(k5idname) +realm.run_as_client([kdestroy]) + +# Test 3: no name/cache specified, default ccache has name but no creds +realm.run_as_client(['./ccinit', realm.ccache, bob]) +out = realm.run_as_client(['./t_ccselect', realm.host_princ]) +if bob not in out: + fail('Authenticated as wrong principal') +# Leave tickets for next test. + +# Test 4: name specified, non-collectable default cache doesn't match +out = realm.run_as_client(['./t_ccselect', realm.host_princ, realm.user_princ], + expected_code=1) +if 'Principal in credential cache does not match desired name' not in out: + fail('Expected error not seen') +realm.run_as_client([kdestroy]) + +# Test 5: name specified, nonexistent default cache +out = realm.run_as_client(['./t_ccselect', realm.host_princ, bob]) +if bob not in out: + fail('Authenticated as wrong principal') +# Leave tickets for next test. + +# Test 6: name specified, matches default cache, time to refresh +realm.run_as_client(['./ccrefresh', realm.ccache, '1']) +out = realm.run_as_client(['./t_ccselect', realm.host_princ, bob]) +if bob not in out: + fail('Authenticated as wrong principal') +out = realm.run_as_client(['./ccrefresh', realm.ccache]) +if int(out) < 1000: + fail('Credentials apparently not refreshed') +realm.run_as_client([kdestroy]) + +# Test 7: empty ccache specified, pick first principal from client keytab +realm.run_as_client(['./t_imp_cred', realm.host_princ]) +realm.klist(realm.user_princ) +realm.run_as_client([kdestroy]) + +# Test 8: ccache specified with name but no creds; name not in client keytab +realm.run_as_client(['./ccinit', realm.ccache, realm.host_princ]) +out = realm.run_as_client(['./t_imp_cred', realm.host_princ], expected_code=1) +if 'Credential cache is empty' not in out: + fail('Expected error not seen') +realm.run_as_client([kdestroy]) + +# Test 9: ccache specified with name but no creds; name in client keytab +realm.run_as_client(['./ccinit', realm.ccache, bob]) +realm.run_as_client(['./t_imp_cred', realm.host_princ]) +realm.klist(bob) +# Leave tickets for next test. + +# Test 10: ccache specified with creds, time to refresh +realm.run_as_client(['./ccrefresh', realm.ccache, '1']) +realm.run_as_client(['./t_imp_cred', realm.host_princ]) +realm.klist(bob) +out = realm.run_as_client(['./ccrefresh', realm.ccache]) +if int(out) < 1000: + fail('Credentials apparently not refreshed') +realm.run_as_client([kdestroy]) + +# Use a cache collection for the remaining tests. +ccdir = os.path.join(realm.testdir, 'cc') +ccname = 'DIR:' + ccdir +os.mkdir(ccdir) +realm.env_client['KRB5CCNAME'] = ccname + +# Test 11: name specified, matching cache in collection with no creds +bobcache = os.path.join(ccdir, 'tktbob') +realm.run_as_client(['./ccinit', bobcache, bob]) +out = realm.run_as_client(['./t_ccselect', realm.host_princ, bob]) +if bob not in out: + fail('Authenticated as wrong principal') +# Leave tickets for next test. + +# Test 12: name specified, matching cache in collection, time to refresh +realm.run_as_client(['./ccrefresh', bobcache, '1']) +out = realm.run_as_client(['./t_ccselect', realm.host_princ, bob]) +if bob not in out: + fail('Authenticated as wrong principal') +out = realm.run_as_client(['./ccrefresh', bobcache]) +if int(out) < 1000: + fail('Credentials apparently not refreshed') +realm.run_as_client([kdestroy, '-A']) + +# Test 13: name specified, collection has default for different principal +realm.kinit(realm.user_princ, password('user')) +out = realm.run_as_client(['./t_ccselect', realm.host_princ, bob]) +if bob not in out: + fail('Authenticated as wrong principal') +out = realm.run_as_client([klist]) +if 'Default principal: %s\n' % realm.user_princ not in out: + fail('Default cache overwritten by acquire_cred') +realm.run_as_client([kdestroy, '-A']) + +# Test 14: name specified, collection has no default cache +out = realm.run_as_client(['./t_ccselect', realm.host_princ, bob]) +if bob not in out: + fail('Authenticated as wrong principal') +# Make sure the tickets we acquired didn't become the default +out = realm.run_as_client([klist], expected_code=1) +if 'No credentials cache found' not in out: + fail('Expected error not seen') +realm.run_as_client([kdestroy, '-A']) + +success('Client keytab tests') |
