1# Copyright (C) 2011 by the Massachusetts Institute of Technology. 2# All rights reserved. 3 4# Export of this software from the United States of America may 5# require a specific license from the United States Government. 6# It is the responsibility of any person or organization contemplating 7# export to obtain such a license before exporting. 8# 9# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 10# distribute this software and its documentation for any purpose and 11# without fee is hereby granted, provided that the above copyright 12# notice appear in all copies and that both that copyright notice and 13# this permission notice appear in supporting documentation, and that 14# the name of M.I.T. not be used in advertising or publicity pertaining 15# to distribution of the software without specific, written prior 16# permission. Furthermore if you modify this software you must label 17# your software as modified software and not distribute it in such a 18# fashion that it might be confused with the original M.I.T. software. 19# M.I.T. makes no representations about the suitability of 20# this software for any purpose. It is provided "as is" without express 21# or implied warranty. 22 23from k5test import * 24 25# Create two independent realms (no cross-realm TGTs). For the 26# fallback realm tests we need to control the precise server hostname, 27# so turn off DNS canonicalization and shortname qualification. 28conf = {'libdefaults': {'dns_canonicalize_hostname': 'false', 29 'qualify_shortname': ''}} 30r1 = K5Realm(create_user=False, krb5_conf=conf) 31r2 = K5Realm(create_user=False, krb5_conf=conf, realm='KRBTEST2.COM', 32 portbase=62000, testdir=os.path.join(r1.testdir, 'r2')) 33 34host1 = 'p:' + r1.host_princ 35host2 = 'p:' + r2.host_princ 36foo = 'foo.krbtest.com' 37foo2 = 'foo.krbtest2.com' 38foobar = "foo.bar.krbtest.com" 39 40# These strings specify the target as a GSS name. The resulting 41# principal will have the host-based type, with the referral realm 42# (since k5test realms have no domain-realm mapping by default). 43# krb5_cc_select() will use the fallback realm, which is either the 44# uppercased parent domain, or the default realm if the hostname is a 45# single component. 46gssserver = 'h:host@' + foo 47gssserver2 = 'h:host@' + foo2 48gssserver_bar = 'h:host@' + foobar 49gsslocal = 'h:host@localhost' 50 51# refserver specifies the target as a principal in the referral realm. 52# The principal won't be treated as a host principal by the 53# .k5identity rules since it has unknown type. 54refserver = 'p:host/' + hostname + '@' 55 56# Verify that we can't get initiator creds with no credentials in the 57# collection. 58r1.run(['./t_ccselect', host1, '-'], expected_code=1, 59 expected_msg='No Kerberos credentials available') 60 61# Make a directory collection and use it for client commands in both realms. 62ccdir = os.path.join(r1.testdir, 'cc') 63ccname = 'DIR:' + ccdir 64r1.env['KRB5CCNAME'] = ccname 65r2.env['KRB5CCNAME'] = ccname 66 67# Use .k5identity from testdir and not from the tester's homedir. 68r1.env['HOME'] = r1.testdir 69r2.env['HOME'] = r1.testdir 70 71# Create two users in r1 and one in r2. 72alice='alice@KRBTEST.COM' 73bob='bob@KRBTEST.COM' 74zaphod='zaphod@KRBTEST2.COM' 75r1.addprinc(alice, password('alice')) 76r1.addprinc(bob, password('bob')) 77r2.addprinc(zaphod, password('zaphod')) 78 79# Create host principals and keytabs for fallback realm tests. 80if hostname != 'localhost': 81 r1.addprinc('host/localhost') 82 r2.addprinc('host/localhost') 83r1.addprinc('host/' + foo) 84r2.addprinc('host/' + foo2) 85r1.addprinc('host/' + foobar) 86r1.extract_keytab('host/localhost', r1.keytab) 87r2.extract_keytab('host/localhost', r2.keytab) 88r1.extract_keytab('host/' + foo, r1.keytab) 89r2.extract_keytab('host/' + foo2, r2.keytab) 90r1.extract_keytab('host/' + foobar, r1.keytab) 91 92# Get tickets for one user in each realm (zaphod will be primary). 93r1.kinit(alice, password('alice')) 94r2.kinit(zaphod, password('zaphod')) 95 96# Check that we can find a cache for a specified client principal. 97output = r1.run(['./t_ccselect', host1, 'p:' + alice]) 98if output != (alice + '\n'): 99 fail('alice not chosen when specified') 100output = r2.run(['./t_ccselect', host2, 'p:' + zaphod]) 101if output != (zaphod + '\n'): 102 fail('zaphod not chosen when specified') 103 104# Check that we can guess a cache based on the service realm. 105output = r1.run(['./t_ccselect', host1]) 106if output != (alice + '\n'): 107 fail('alice not chosen as default initiator cred for server in r1') 108output = r1.run(['./t_ccselect', host1, '-']) 109if output != (alice + '\n'): 110 fail('alice not chosen as default initiator name for server in r1') 111output = r2.run(['./t_ccselect', host2]) 112if output != (zaphod + '\n'): 113 fail('zaphod not chosen as default initiator cred for server in r1') 114output = r2.run(['./t_ccselect', host2, '-']) 115if output != (zaphod + '\n'): 116 fail('zaphod not chosen as default initiator name for server in r1') 117 118# Check that primary cache is used if server realm is unknown. 119output = r2.run(['./t_ccselect', refserver]) 120if output != (zaphod + '\n'): 121 fail('zaphod not chosen via primary cache for unknown server realm') 122r1.run(['./t_ccselect', gssserver2], expected_code=1) 123# Check ccache selection using a fallback realm. 124output = r1.run(['./t_ccselect', gssserver]) 125if output != (alice + '\n'): 126 fail('alice not chosen via parent domain fallback') 127output = r2.run(['./t_ccselect', gssserver2]) 128if output != (zaphod + '\n'): 129 fail('zaphod not chosen via parent domain fallback') 130# Check ccache selection using a fallback realm (default realm). 131output = r1.run(['./t_ccselect', gsslocal]) 132if output != (alice + '\n'): 133 fail('alice not chosen via default realm fallback') 134output = r2.run(['./t_ccselect', gsslocal]) 135if output != (zaphod + '\n'): 136 fail('zaphod not chosen via default realm fallback') 137 138# Check that realm ccselect fallback works correctly 139r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice) 140r2.kinit(zaphod, password('zaphod')) 141r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice) 142 143# Get a second cred in r1 (bob will be primary). 144r1.kinit(bob, password('bob')) 145 146# Try some cache selections using .k5identity. 147k5id = open(os.path.join(r1.testdir, '.k5identity'), 'w') 148k5id.write('%s realm=%s\n' % (alice, r1.realm)) 149k5id.write('%s service=ho*t host=localhost\n' % zaphod) 150k5id.write('noprinc service=bogus') 151k5id.close() 152output = r1.run(['./t_ccselect', host1]) 153if output != (alice + '\n'): 154 fail('alice not chosen via .k5identity realm line.') 155output = r2.run(['./t_ccselect', gsslocal]) 156if output != (zaphod + '\n'): 157 fail('zaphod not chosen via .k5identity service/host line.') 158output = r1.run(['./t_ccselect', refserver]) 159if output != (bob + '\n'): 160 fail('bob not chosen via primary cache when no .k5identity line matches.') 161r1.run(['./t_ccselect', 'h:bogus@' + foo2], expected_code=1, 162 expected_msg="Can't find client principal noprinc") 163 164success('GSSAPI credential selection tests') 165