From 6211396239897a3a9c207690ea2d6dc9ec580bc2 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Mon, 9 Dec 2013 00:45:08 -0500 Subject: Add tests for krb5_sname_to_principal --- src/tests/Makefile.in | 12 ++++-- src/tests/deps | 2 + src/tests/s2p.c | 81 +++++++++++++++++++++++++++++++++++++ src/tests/t_sn2princ.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 src/tests/s2p.c create mode 100644 src/tests/t_sn2princ.py (limited to 'src') diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index b9358fa133..0543d415b1 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -6,9 +6,9 @@ SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \ RUN_SETUP = @KRB5_RUN_ENV@ KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf OBJS= gcred.o hist.o kdbtest.o plugorder.o t_init_creds.o \ - t_localauth.o responder.o + t_localauth.o responder.o s2p.o EXTRADEPSRCS= gcred.c hist.c kdbtest.c plugorder.c t_init_creds.c \ - t_localauth.c responder.c + t_localauth.c responder.c s2p.c TEST_DB = ./testdb TEST_REALM = FOO.TEST.REALM @@ -39,6 +39,9 @@ plugorder: plugorder.o $(KRB5_BASE_DEPLIBS) responder: responder.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ responder.o $(KRB5_BASE_LIBS) +s2p: s2p.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ s2p.o $(KRB5_BASE_LIBS) + t_init_creds: t_init_creds.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_init_creds.o $(KRB5_BASE_LIBS) @@ -87,7 +90,7 @@ kdb_check: kdc.conf krb5.conf $(RUN_SETUP) $(VALGRIND) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f $(RM) $(TEST_DB)* stash_file -check-pytests:: gcred hist hrealm kdbtest plugorder responder +check-pytests:: gcred hist hrealm kdbtest plugorder responder s2p check-pytests:: t_init_creds t_localauth $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_dump.py $(PYTESTFLAGS) @@ -115,6 +118,7 @@ check-pytests:: t_init_creds t_localauth $(RUNPYTEST) $(srcdir)/t_kdb.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keydata.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_mkey.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_sn2princ.py $(PYTESTFLAGS) $(OFFLINE) $(RUNPYTEST) $(srcdir)/t_cve-2012-1014.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS) @@ -126,7 +130,7 @@ check-pytests:: t_init_creds t_localauth $(RUNPYTEST) $(srcdir)/t_salt.py $(PYTESTFLAGS) clean:: - $(RM) gcred hist hrealm kdbtest plugorder responder + $(RM) gcred hist hrealm kdbtest plugorder responder s2p $(RM) t_init_creds t_localauth krb5.conf kdc.conf $(RM) -rf kdc_realm/sandbox ldap $(RM) au.log diff --git a/src/tests/deps b/src/tests/deps index b2b4b19153..862abcce76 100644 --- a/src/tests/deps +++ b/src/tests/deps @@ -67,3 +67,5 @@ $(OUTPRE)responder.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-json.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/krb5.h responder.c +$(OUTPRE)s2p.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ + $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h s2p.c diff --git a/src/tests/s2p.c b/src/tests/s2p.c new file mode 100644 index 0000000000..8fb2a94d6a --- /dev/null +++ b/src/tests/s2p.c @@ -0,0 +1,81 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/s2p.c - krb5_name_to_principal test harness */ +/* + * Copyright (C) 2013 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. + */ + +#include +#include +#include +#include + +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) +{ + krb5_principal princ; + krb5_int32 type; + const char *service, *hostname; + char *name; + + /* Parse arguments. */ + assert(argc == 4); + hostname = argv[1]; + service = argv[2]; + if (strcmp(argv[3], "unknown") == 0) + type = KRB5_NT_UNKNOWN; + else if (strcmp(argv[3], "srv-hst") == 0) + type = KRB5_NT_SRV_HST; + else + abort(); + + check(krb5_init_context(&ctx)); + check(krb5_sname_to_principal(ctx, hostname, service, type, &princ)); + check(krb5_unparse_name(ctx, princ, &name)); + printf("%s\n", name); + + krb5_free_unparsed_name(ctx, name); + krb5_free_principal(ctx, princ); + krb5_free_context(ctx); + return 0; +} diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py new file mode 100644 index 0000000000..de6bb0e6a1 --- /dev/null +++ b/src/tests/t_sn2princ.py @@ -0,0 +1,105 @@ +#!/usr/bin/python +from k5test import * + +offline = (len(args) > 0 and args[0] != "no") + +conf = {'domain_realm': {'kerberos.org': 'R1', + 'example.com': 'R2', + 'mit.edu': 'R3'}} +no_rdns_conf = {'libdefaults': {'rdns': 'false'}} +no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}} + +realm = K5Realm(create_kdb=False, krb5_conf=conf) +no_rdns = realm.special_env('no_rdns', False, krb5_conf=no_rdns_conf) +no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) + +def testbase(host, nametype, princhost, princrealm, env=None): + # Run the sn2princ harness with a specified host and name type and + # the fixed service string 'svc', and compare the result to the + # expected hostname and realm part. + out = realm.run(['./s2p', host, 'SVC', nametype], env=env).rstrip() + expected = 'SVC/%s@%s' % (princhost, princrealm) + if out != expected: + fail('Expected %s, got %s' % (expected, out)) + +def test(host, princhost, princrealm): + # Test with the host-based name type in the default environment. + testbase(host, 'srv-hst', princhost, princrealm) + +def testnc(host, princhost, princrealm): + # Test with the host-based name type with canonicalization disabled. + testbase(host, 'srv-hst', princhost, princrealm, env=no_canon) + +def testnr(host, princhost, princrealm): + # Test with the host-based name type with reverse lookup disabled. + testbase(host, 'srv-hst', princhost, princrealm, env=no_rdns) + +def testu(host, princhost, princrealm): + # Test with the unknown name type. + testbase(host, 'unknown', princhost, princrealm) + +# With the unknown principal type, we do not canonicalize or downcase, +# but we do remove a trailing period and look up the realm. +testu('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') +testu('Example.COM', 'Example.COM', 'R2') +testu('abcde', 'abcde', '') + +# A ':port' or ':instance' trailer should be ignored for hostname +# adjustment and realm lookup. If there is more than one colon in the +# name, we assume it's an IPv6 address and don't treat it as having a +# trailer. +testu('example.com.:123', 'example.com:123', 'R2') +testu('Example.COM:xyZ', 'Example.COM:xyZ', 'R2') +testu('example.com.::123', 'example.com.::123', '') + +# With dns_canonicalize_hostname=false, we downcase and remove +# trailing dots but do not canonicalize the hostname. Trailers do not +# get downcased. +testnc('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') +testnc('Example.COM', 'example.com', 'R2') +testnc('abcde', 'abcde', '') +testnc('example.com.:123', 'example.com:123', 'R2') +testnc('Example.COM:xyZ', 'example.com:xyZ', 'R2') +testnc('example.com.::123', 'example.com.::123', '') + +def skip_rest(msg): + success('Warning: skipping online krb5_sname_to_principal tests: %s' % msg) + sys.exit(0) + +if offline: + skip_rest('offline mode requested') + +# For the online tests, we rely on ptr-mismatch.kerberos.org forward +# and reverse resolving to these names. +oname = 'ptr-mismatch.kerberos.org' +fname = 'www.kerberos.org' +rname = 'kerberos-org.mit.edu' + +# Verify forward resolution before testing for it. +try: + ai = socket.getaddrinfo(oname, None, 0, 0, 0, socket.AI_CANONNAME) +except socket.gaierror: + skip_rest('cannot forward resolve %s' % oname) +(family, socktype, proto, canonname, sockaddr) = ai[0] +if canonname.lower() != fname: + skip_rest('%s forward resolves to %s, not %s' % (oname, canonname, fname)) + +# Test forward-only canonicalization (rdns=false). +testnr(oname, fname, 'R1') +testnr(oname + ':123', fname + ':123', 'R1') +testnr(oname + ':xyZ', fname + ':xyZ', 'R1') + +# Verify reverse resolution before testing for it. +try: + names = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD) +except socket.gaierror: + skip_rest('cannot reverse resolve %s' % oname) +if names[0].lower() != rname: + skip_rest('%s reverse resolves to %s, not %s' % (oname, names[0], rname)) + +# Test default canonicalization (forward and reverse lookup). +test(oname, rname, 'R3') +test(oname + ':123', rname + ':123', 'R3') +test(oname + ':xyZ', rname + ':xyZ', 'R3') + +success('krb5_sname_to_principal tests') -- cgit