From 8fde93e3fb519bbd08b5d19d6ba54fcb9e4983f6 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Thu, 20 Oct 2011 17:45:44 -0500 Subject: [PATCH] Initial name canon rules tests (just kgetcred) --- lib/krb5/Makefile.am | 7 +- lib/krb5/test_canon.c | 177 +++++++++++++++++++++++++++++++++++ tests/bin/setup-env.in | 1 + tests/kdc/Makefile.am | 17 ++++ tests/kdc/check-canon.in | 167 +++++++++++++++++++++++++++++++++ tests/kdc/krb5-canon.conf.in | 95 +++++++++++++++++++ 6 files changed, 461 insertions(+), 3 deletions(-) create mode 100755 lib/krb5/test_canon.c create mode 100644 tests/kdc/check-canon.in create mode 100644 tests/kdc/krb5-canon.conf.in diff --git a/lib/krb5/Makefile.am b/lib/krb5/Makefile.am index ebf773e64..2b401e25b 100644 --- a/lib/krb5/Makefile.am +++ b/lib/krb5/Makefile.am @@ -8,14 +8,15 @@ bin_PROGRAMS = verify_krb5_conf noinst_PROGRAMS = \ krbhst-test \ - test_gic \ test_alname \ + test_canon \ test_crypto \ - test_rfc3961 \ + test_forward \ test_get_addrs \ + test_gic \ test_kuserok \ test_renew \ - test_forward + test_rfc3961 noinst_LTLIBRARIES = \ librfc3961.la diff --git a/lib/krb5/test_canon.c b/lib/krb5/test_canon.c new file mode 100755 index 000000000..8389c02c6 --- /dev/null +++ b/lib/krb5/test_canon.c @@ -0,0 +1,177 @@ +/* + * 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 retval; + krb5_context context; + krb5_principal princ = NULL; + krb5_principal me = NULL; + krb5_principal cmp_to_princ = NULL; + krb5_ccache cc = NULL; + krb5_creds *out_creds = NULL; + krb5_keytab kt = NULL; + krb5_keytab_entry ktent; + krb5_creds in_creds; + char *hostname = NULL; + char *unparsed = NULL; + char *unparsed_canon = NULL; + char *during; + char *cmp_to = NULL;; + int do_kt = 0; + int do_get_creds = 0; + int opt; + int ret = 1; + + memset(&ktent, 0, sizeof(ktent)); + + while ((opt = getopt(argc, argv, "hgkc:")) != -1) { + switch (opt) { + case 'g': + do_get_creds++; + break; + case 'k': + do_kt++; + break; + case 'c': + cmp_to = optarg; + break; + case 'h': + default: + fprintf(stderr, "Usage: %s [-g] [-k] [-c compare-to-principal] " + "[principal]\n", argv[0]); + return 1; + } + } + + if (!do_get_creds && !do_kt && !cmp_to) + do_get_creds++; + + if (optind < argc) + hostname = argv[optind]; + + during = "init_context"; + retval = krb5_init_context(&context); + if (retval) goto err; + + during = "sn2p"; + retval = krb5_sname_to_principal(context, hostname, "host", KRB5_NT_SRV_HST, &princ); + if (retval) goto err; + + during = "unparse of sname2princ"; + retval = krb5_unparse_name(context, princ, &unparsed); + if (retval) goto err; + printf("krb5_sname_to_principal() output: %s\n", unparsed); + + if (cmp_to) { + krb5_boolean eq; + + during = "parsing principal name for comparison compare"; + retval = krb5_parse_name(context, cmp_to, &cmp_to_princ); + if (retval) goto err; + + eq = krb5_principal_compare(context, princ, cmp_to_princ); + printf("%s %s %s\n", unparsed, eq ? "==" : "!=", cmp_to); + } + + if (do_get_creds) { + during = "ccdefault"; + retval = krb5_cc_default(context, &cc); + if (retval) goto err; + + during = "ccprinc"; + retval = krb5_cc_get_principal(context, cc, &me); + if (retval) goto err; + + memset(&in_creds, 0, sizeof(in_creds)); + in_creds.client = me; + in_creds.server = princ; + + during = "getcreds"; + retval = krb5_get_credentials(context, 0, cc, &in_creds, &out_creds); + if (retval) goto err; + + during = "unparsing principal name canonicalized by krb5_get_credentials()"; + retval = krb5_unparse_name(context, in_creds.server, &unparsed_canon); + if (retval) goto err; + printf("Principal name as canonicalized by krb5_get_credentials() is %s\n", unparsed_canon); + } + + if (do_kt) { + during = "getting keytab"; + retval = krb5_kt_default(context, &kt); + if (retval) goto err; + + during = "getting keytab ktent"; + retval = krb5_kt_get_entry(context, kt, princ, 0, 0, &ktent); + if (retval) goto err; + + during = "unparsing principal name canonicalized by krb5_kt_get_entry()"; + retval = krb5_unparse_name(context, ktent.principal, &unparsed_canon); + if (retval) goto err; + printf("Principal name as canonicalized by krb5_kt_get_entry() is %s\n", unparsed_canon); + } + + ret = 0; + +err: + krb5_free_principal(context, princ); + krb5_free_principal(context, me); + krb5_free_principal(context, cmp_to_princ); + krb5_xfree(unparsed); + krb5_xfree(unparsed_canon); + if (do_get_creds) { + krb5_free_creds(context, out_creds); + (void) krb5_cc_close(context, cc); + } + krb5_kt_free_entry(context, &ktent); + if (kt) + krb5_kt_close(context, kt); + krb5_free_context(context); + if (ret) + fprintf(stderr, "Failed while doing %s (%d)\n", during, retval); + return (ret); +} + diff --git a/tests/bin/setup-env.in b/tests/bin/setup-env.in index 8e5691c54..e51851fa1 100644 --- a/tests/bin/setup-env.in +++ b/tests/bin/setup-env.in @@ -33,6 +33,7 @@ gsstool="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/gsstool" # regression test tools test_ap_req="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_ap-req" +test_canon="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_canon" test_gic="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_gic" test_renew="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_renew" test_ntlm="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/test_ntlm" diff --git a/tests/kdc/Makefile.am b/tests/kdc/Makefile.am index 398cb6391..9bd674b8f 100644 --- a/tests/kdc/Makefile.am +++ b/tests/kdc/Makefile.am @@ -2,6 +2,7 @@ include $(top_srcdir)/Makefile.am.common noinst_DATA = \ krb5.conf \ + krb5-canon.conf \ krb5-hdb-mitdb.conf.in \ krb5-weak.conf \ krb5-pkinit.conf \ @@ -11,6 +12,7 @@ noinst_DATA = \ check_SCRIPTS = $(SCRIPT_TESTS) SCRIPT_TESTS = \ + check-canon \ check-cc \ check-delegation \ check-des \ @@ -50,6 +52,11 @@ do_subst = sed $(do_dlopen) \ LDADD = ../../lib/krb5/libkrb5.la $(LIB_roken) +check-canon: check-canon.in Makefile krb5-canon.conf + $(do_subst) < $(srcdir)/check-canon.in > check-canon.tmp + chmod +x check-canon.tmp + mv check-canon.tmp check-canon + check-cc: check-cc.in Makefile $(do_subst) < $(srcdir)/check-cc.in > check-cc.tmp chmod +x check-cc.tmp @@ -127,6 +134,13 @@ krb5.conf: krb5.conf.in Makefile -e 's,[@]kdc[@],,g' < $(srcdir)/krb5.conf.in > krb5.conf.tmp mv krb5.conf.tmp krb5.conf +krb5-canon.conf: krb5-canon.conf.in Makefile + $(do_subst) \ + -e 's,[@]WEAK[@],false,g' \ + -e 's,[@]dk[@],,g' \ + -e 's,[@]kdc[@],,g' < $(srcdir)/krb5-canon.conf.in > krb5-canon.conf.tmp + mv krb5-canon.conf.tmp krb5-canon.conf + krb5-hdb-mitdb.conf: krb5-hdb-mitdb.conf.in Makefile $(do_subst) \ -e 's,[@]WEAK[@],false,g' \ @@ -170,6 +184,7 @@ CLEANFILES= \ digest-reply \ foopassword \ krb5.conf \ + krb5-canon.conf \ krb5-weak.conf \ krb5.conf.keys \ krb5-cc.conf \ @@ -204,6 +219,7 @@ CLEANFILES= \ EXTRA_DIST = \ NTMakefile \ + check-canon.in \ check-cc.in \ check-delegation.in \ check-des.in \ @@ -223,6 +239,7 @@ EXTRA_DIST = \ iprop-acl \ krb5-pkinit.conf.in \ krb5.conf.in \ + krb5-canon.conf.in \ krb5.conf.keys.in \ ntlm-user-file.txt \ leaks-kill.sh \ diff --git a/tests/kdc/check-canon.in b/tests/kdc/check-canon.in new file mode 100644 index 000000000..8665242e6 --- /dev/null +++ b/tests/kdc/check-canon.in @@ -0,0 +1,167 @@ +#!/bin/sh +# +# 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. + +env_setup="@env_setup@" +objdir="@objdir@" + +. ${env_setup} + +# If there is no useful db support compile in, disable test +# (krb5_kt_get_entry() is tested in another test) +${have_db} || exit 77 + +R1=TEST.H5L.SE +R2=TEST2.H5L.SE +R3=TEST3.H5L.SE + +port=@port@ + +kadmin="${kadmin} -l -r ${R1}" +kdc="${kdc} --addresses=localhost -P $port" + +cache="FILE:${objdir}/cache.krb5" + +kinit="${kinit} -c $cache ${afs_no_afslog}" +klist="${klist} -c $cache" +kgetcred="${kgetcred} -c $cache" +kdestroy="${kdestroy} -c $cache ${afs_no_unlog}" + +KRB5_CONFIG="${objdir}/krb5-canon.conf" +export KRB5_CONFIG + +testfailed="echo test failed; ${klist} -v ; exit 1" + +rm -f ${keytabfile} +rm -f current-db* +rm -f out-* +rm -f mkey.file* + +> messages.log + +echo "Creating database" +initflags="init --realm-max-ticket-life=1day --realm-max-renewable-life=1month" + +${kadmin} ${initflags} ${R1} || exit 1 +${kadmin} ${initflags} ${R2} || exit 1 +${kadmin} ${initflags} ${R3} || exit 1 + +${kadmin} add -p foo --use-defaults foo@${R1} || exit 1 + +${kadmin} add -p cross1 --use-defaults krbtgt/${R1}@${R2} || exit 1 +${kadmin} add -p cross2 --use-defaults krbtgt/${R2}@${R1} || exit 1 +${kadmin} add -p cross3 --use-defaults krbtgt/${R3}@${R1} || exit 1 +${kadmin} add -p cross4 --use-defaults krbtgt/${R1}@${R3} || exit 1 +${kadmin} add -p cross5 --use-defaults krbtgt/${R3}@${R2} || exit 1 +${kadmin} add -p cross6 --use-defaults krbtgt/${R2}@${R3} || exit 1 + +${kadmin} add -p foo --use-defaults host/t1@${R1} || exit 1 +${kadmin} add -p foo --use-defaults host/t2@${R2} || exit 1 +${kadmin} add -p foo --use-defaults host/t3@${R3} || exit 1 +${kadmin} add -p foo --use-defaults host/t11.test1.h5l.se@${R1} || exit 1 +${kadmin} add -p foo --use-defaults host/t12.test1.h5l.se@${R2} || exit 1 +${kadmin} add -p foo --use-defaults host/t22.test2.h5l.se@${R2} || exit 1 +${kadmin} add -p foo --use-defaults host/t23.test2.h5l.se@${R3} || exit 1 +${kadmin} add -p foo --use-defaults host/t33.test2.h5l.se@${R3} || exit 1 + + +echo "Doing database check" +${kadmin} check ${R1} || exit 1 +${kadmin} check ${R2} || exit 1 +${kadmin} check ${R3} || exit 1 + +echo foo > ${objdir}/foopassword + +echo "Starting kdc" +${kdc} & +kdcpid=$! + +sh ${wait_kdc} +if [ "$?" != 0 ] ; then + kill -9 ${kdcpid} + exit 1 +fi + +trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT + +ec=0 + +echo "Getting client initial tickets"; +${kinit} --password-file=${objdir}/foopassword foo@${R1} || \ + { ec=1 ; eval "${testfailed}"; } + +echo "get service tickets" +${kgetcred} --name-type=SRV_HST host t1 || { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t2 || { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t3 || { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t11 || { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t12 || { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t22 || { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t23 && { ec=1 ; eval "${testfailed}"; } +${kgetcred} --name-type=SRV_HST host t33 || { ec=1 ; eval "${testfailed}"; } + +echo "check result" +${klist} | grep 'host/t1@$' > /dev/null || + { ec=1 ; echo "t1 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t1@${R1}" > /dev/null || + { ec=1 ; echo "canonicalized t1 entry not present"; eval "${testfailed}"; } +${klist} | grep 'host/t2@$' > /dev/null || + { ec=1 ; echo "t2 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t2@${R2}" > /dev/null || + { ec=1 ; echo "canonicalized t2 entry not present"; eval "${testfailed}"; } +${klist} | grep 'host/t3@$' > /dev/null || + { ec=1 ; echo "t3 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t3@${R3}" > /dev/null || + { ec=1 ; echo "canonicalized t3 entry not present"; eval "${testfailed}"; } +${klist} | grep 'host/t11@$' > /dev/null || + { ec=1 ; echo "t11 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t11.test1.h5l.se@${R2}" > /dev/null || + { ec=1 ; echo "canonicalized t11 entry not present"; eval "${testfailed}"; } +${klist} | grep 'host/t12@$' > /dev/null || + { ec=1 ; echo "t12 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t12.test1.h5l.se@${R2}" > /dev/null || + { ec=1 ; echo "canonicalized t12 entry not present"; eval "${testfailed}"; } +${klist} | grep 'host/t22@$' > /dev/null || + { ec=1 ; echo "t22 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t22.test2.h5l.se@${R2}" > /dev/null || + { ec=1 ; echo "canonicalized t22 entry not present"; eval "${testfailed}"; } +${klist} | grep 'host/t33@$' > /dev/null || + { ec=1 ; echo "t33 referral entry not present"; eval "${testfailed}"; } +${klist} | grep "host/t33.test2.h5l.se@${R2}" > /dev/null || + { ec=1 ; echo "canonicalized t33 entry not present"; eval "${testfailed}"; } + + +${kdestroy} + +echo "killing kdc (${kdcpid})" +sh ${leaks_kill} kdc $kdcpid || exit 1 + +trap "" EXIT + +exit $ec diff --git a/tests/kdc/krb5-canon.conf.in b/tests/kdc/krb5-canon.conf.in new file mode 100644 index 000000000..b2989bf05 --- /dev/null +++ b/tests/kdc/krb5-canon.conf.in @@ -0,0 +1,95 @@ +[libdefaults] + default_realm = TEST.H5L.SE TEST2.H5L.SE + no-addresses = TRUE + name_canon_rules = as-is:realm=TEST.H5L.SE + name_canon_rules = as-is:realm=TEST2.H5L.SE + name_canon_rules = as-is:realm=TEST3.H5L.SE + name_canon_rules = qualify:domain=test1.h5l.se:realm=TEST.H5L.SE + name_canon_rules = qualify:domain=test1.h5l.se:realm=TEST2.H5L.SE + name_canon_rules = qualify:domain=test2.h5l.se:realm=TEST2.H5L.SE + name_canon_rules = qualify:domain=test2.h5l.se:realm=TEST2.H5L.SE + +[appdefaults] + pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt + reconnect-min = 2s + reconnect-backoff = 2s + reconnect-max = 10s + +[realms] + TEST.H5L.SE = { + kdc = localhost:@port@ + admin_server = localhost:@admport@ + kpasswd_server = localhost:@pwport@ + } + TEST2.H5L.SE = { + kdc = localhost:@port@ + kpasswd_server = localhost:@pwport@ + } + TEST3.H5L.SE = { + kdc = localhost:@port@ + } + +[domain_realm] + .test1.h5l.se = TEST.H5L.SE + .test2.h5l.se = TEST2.H5L.SE + .test3.h5l.se = TEST3.H5L.SE + localhost = TEST.H5L.SE + + +[kdc] + enable-digest = true + allow-anonymous = true + digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2 + + enable-http = true + + enable-pkinit = true + pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key + pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt + pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt +# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl + pkinit_mappings_file = @srcdir@/pki-mapping + pkinit_allow_proxy_certificate = true + + database = { + label = { + dbname = @objdir@/current-db@kdc@ + realm = TEST.H5L.SE + mkey_file = @objdir@/mkey.file + acl_file = @srcdir@/heimdal.acl + log_file = @objdir@/current@kdc@.log + } + label2 = { + dbname = @objdir@/current-db@kdc@ + realm = TEST2.H5L.SE + mkey_file = @objdir@/mkey.file + acl_file = @srcdir@/heimdal.acl + log_file = @objdir@/current@kdc@.log + } + } + + signal_socket = @objdir@/signal + iprop-stats = @objdir@/iprop-stats + iprop-acl = @srcdir@/iprop-acl + +[logging] + kdc = 0-/FILE:@objdir@/messages.log + default = 0-/FILE:@objdir@/messages.log + +[kadmin] + save-password = true + @dk@ + +[capaths] + TEST.H5L.SE = { + TEST3.H5L.SE = . + TEST2.H5L.SE = . + } + TEST2.H5L.SE = { + TEST.H5L.SE = . + TEST3.H5L.SE = . + } + TEST3.H5L.SE = { + TEST.H5L.SE = . + TEST2.H5L.SE = . + }