diff --git a/lib/krb5/Makefile.am b/lib/krb5/Makefile.am index 07d56715d..2df7d5b36 100644 --- a/lib/krb5/Makefile.am +++ b/lib/krb5/Makefile.am @@ -47,7 +47,7 @@ TESTS = \ check_DATA = test_config_strings.out -check_PROGRAMS = $(TESTS) test_hostname test_ap-req test_canon +check_PROGRAMS = $(TESTS) test_hostname test_ap-req test_canon test_set_kvno0 LDADD = libkrb5.la \ $(LIB_hcrypto) \ diff --git a/lib/krb5/test_set_kvno0.c b/lib/krb5/test_set_kvno0.c new file mode 100644 index 000000000..526c240f1 --- /dev/null +++ b/lib/krb5/test_set_kvno0.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2011, Secure Endpoints Inc. + * 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. + * + */ + +#include "krb5_locl.h" +#include +#include + +#if 0 +#include +#include +#include +#include +#include +#include +#endif + +int +main(int argc, char **argv) +{ + krb5_error_code ret; + krb5_context context; + krb5_ccache src_cc = NULL; + krb5_ccache dst_cc = NULL; + krb5_cc_cursor cursor; + krb5_principal me = NULL; + krb5_creds cred; + const char *during; + Ticket t; + size_t len; + int make_kvno_absent = 0; + int opt; + + memset(&cred, 0, sizeof (cred)); + during = "init_context"; + ret = krb5_init_context(&context); + if (ret) goto err; + + while ((opt = getopt(argc, argv, "c:n")) != -1) { + switch (opt) { + case 'c': + during = "cc_resolve of source ccache"; + ret = krb5_cc_resolve(context, optarg, &src_cc); + if (ret) goto err; + break; + case 'n': + make_kvno_absent++; + break; + case 'h': + default: + fprintf(stderr, "Usage: %s [-n] [-c ccache]\n" + "\tThis utility edits a ccache, setting all ticket\n" + "\tenc_part kvnos to zero or absent (if -n is set).\n", + argv[0]); + return 1; + } + } + + if (!src_cc) { + during = "cc_default"; + ret = krb5_cc_default(context, &src_cc); + if (ret) goto err; + } + + during = "cc_get_principal"; + ret = krb5_cc_get_principal(context, src_cc, &me); + if (ret) goto err; + + if (optind != argc) { + fprintf(stderr, "Usage: %s [-n] [-c ccache]\n" + "\tThis utility edits a ccache, setting all ticket\n" + "\tenc_part kvnos to zero or absent (if -n is set).\n", + argv[0]); + return 1; + } + + during = "cc_new_unique of temporary ccache"; + ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, src_cc), + NULL, &dst_cc); + + during = "cc_initialize of temporary ccache"; + ret = krb5_cc_initialize(context, dst_cc, me); + if (ret) goto err; + + during = "cc_start_seq_get"; + ret = krb5_cc_start_seq_get(context, src_cc, &cursor); + if (ret) goto err; + + while ((ret = krb5_cc_next_cred(context, src_cc, &cursor, &cred)) == 0) { + krb5_data data; + + during = "decode_Ticket"; + memset(&t, 0, sizeof (t)); + ret = decode_Ticket(cred.ticket.data, cred.ticket.length, &t, &len); + if (ret == ASN1_MISSING_FIELD) + continue; + if (ret) goto err; + if (t.enc_part.kvno) { + *t.enc_part.kvno = 0; + if (make_kvno_absent) { + free(t.enc_part.kvno); + t.enc_part.kvno = NULL; + } + /* + * The new Ticket has to need less or same space as before, so + * we reuse cred->icket.data. + */ + during = "encode_Ticket"; + ASN1_MALLOC_ENCODE(Ticket, data.data, data.length, &t, &len, ret); + if (ret) { + free_Ticket(&t); + goto err; + } + krb5_data_free(&cred.ticket); + cred.ticket = data; + } + free_Ticket(&t); + during = "cc_store_cred"; + ret = krb5_cc_store_cred(context, dst_cc, &cred); + if (ret) goto err; + krb5_free_cred_contents(context, &cred); + memset(&cred, 0, sizeof (cred)); + } + during = "cc_next_cred"; + if (ret != KRB5_CC_END) goto err; + + during = "cc_end_seq_get"; + ret = krb5_cc_end_seq_get(context, src_cc, &cursor); + if (ret) goto err; + + during = "cc_move"; + ret = krb5_cc_move(context, dst_cc, src_cc); + if (ret) goto err; + dst_cc = NULL; + + during = "cc_switch"; + ret = krb5_cc_switch(context, src_cc); + if (ret) goto err; + +err: + (void) krb5_free_principal(context, me); + if (src_cc) + (void) krb5_cc_close(context, src_cc); + if (dst_cc) + (void) krb5_cc_destroy(context, dst_cc); + if (ret) { + fprintf(stderr, "Failed while doing %s (%d)\n", during, ret); + ret = 1; + } + return (ret); +} + diff --git a/tests/bin/setup-env.in b/tests/bin/setup-env.in index e51851fa1..700b64363 100644 --- a/tests/bin/setup-env.in +++ b/tests/bin/setup-env.in @@ -30,6 +30,7 @@ kpasswdd="${TESTS_ENVIRONMENT} ${top_builddir}/kpasswd/kpasswdd" kswitch="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/kcc kswitch" ktutil="${TESTS_ENVIRONMENT} ${top_builddir}/admin/ktutil" gsstool="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/gsstool" +test_set_kvno0="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_set_kvno0" # regression test tools test_ap_req="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_ap-req" diff --git a/tests/kdc/check-kdc.in b/tests/kdc/check-kdc.in index 8522c65d6..181907b40 100644 --- a/tests/kdc/check-kdc.in +++ b/tests/kdc/check-kdc.in @@ -77,6 +77,7 @@ kgetcred="${kgetcred} -c $cache" kgetcred_imp="${kgetcred} -c $cache --out-cache=${ocache}" kdestroy="${kdestroy} -c $cache ${afs_no_unlog}" kimpersonate="${kimpersonate} -k ${keytab} --ccache=${ocache}" +test_set_kvno0="${test_set_kvno0} -c $cache -n" rm -f ${keytabfile} rm -f current-db* @@ -244,6 +245,33 @@ for a in $enctypes; do done ${kdestroy} +echo "Trying x-realm TGT with kvno 0 case"; +${kinit} --password-file=${objdir}/foopassword foo@$R || + { ec=1 ; eval "${testfailed}"; } +${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; } +echo "Getting cross realm tickets"; > messages.log +${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; } +${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; } +echo "Getting service ticket"; > messages.log +${kgetcred} ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; } +${klist} -v +${kdestroy} + +echo "Trying x-realm TGT with kvno 0 case with key rollover"; +${kinit} --password-file=${objdir}/foopassword foo@$R || + { ec=1 ; eval "${testfailed}"; } +${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; } +echo "Getting cross realm tickets"; > messages.log +${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; } +echo "Rolling over cross realm keys"; > messages.log +${kadmin} cpw -r --keepold krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; } +${kadmin} cpw -r --keepold krbtgt/${R}@${R2} || { ec=1 ; eval "${testfailed}"; } +${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; } +echo "Getting service ticket"; > messages.log +${kgetcred} ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; } +${klist} -v +${kdestroy} + echo "try all permutations"; > messages.log for a in $enctypes; do echo "Getting client initial tickets ($a)"; > messages.log