1*7f2fe78bSCy Schubertfrom k5test import * 2*7f2fe78bSCy Schubertfrom base64 import b64encode 3*7f2fe78bSCy Schubertimport shutil 4*7f2fe78bSCy Schubert 5*7f2fe78bSCy Schubertrealm = K5Realm(create_host=False, get_creds=False) 6*7f2fe78bSCy Schubertusercache = 'FILE:' + os.path.join(realm.testdir, 'usercache') 7*7f2fe78bSCy Schubertstoragecache = 'FILE:' + os.path.join(realm.testdir, 'save') 8*7f2fe78bSCy Schubert 9*7f2fe78bSCy Schubert# Create two service principals with keys in the default keytab. 10*7f2fe78bSCy Schubertservice1 = 'service/1@%s' % realm.realm 11*7f2fe78bSCy Schubertrealm.addprinc(service1) 12*7f2fe78bSCy Schubertrealm.extract_keytab(service1, realm.keytab) 13*7f2fe78bSCy Schubertservice2 = 'service/2@%s' % realm.realm 14*7f2fe78bSCy Schubertrealm.addprinc(service2) 15*7f2fe78bSCy Schubertrealm.extract_keytab(service2, realm.keytab) 16*7f2fe78bSCy Schubert 17*7f2fe78bSCy Schubertpuser = 'p:' + realm.user_princ 18*7f2fe78bSCy Schubertpservice1 = 'p:' + service1 19*7f2fe78bSCy Schubertpservice2 = 'p:' + service2 20*7f2fe78bSCy Schubert 21*7f2fe78bSCy Schubert# Get forwardable creds for service1 in the default cache. 22*7f2fe78bSCy Schubertrealm.kinit(service1, None, ['-f', '-k']) 23*7f2fe78bSCy Schubert 24*7f2fe78bSCy Schubert# Try S4U2Self for user with a restricted password. 25*7f2fe78bSCy Schubertrealm.run([kadminl, 'modprinc', '+needchange', realm.user_princ]) 26*7f2fe78bSCy Schubertrealm.run(['./t_s4u', 'e:user', '-']) 27*7f2fe78bSCy Schubertrealm.run([kadminl, 'modprinc', '-needchange', 28*7f2fe78bSCy Schubert '-pwexpire', '1/1/2000', realm.user_princ]) 29*7f2fe78bSCy Schubertrealm.run(['./t_s4u', 'e:user', '-']) 30*7f2fe78bSCy Schubertrealm.run([kadminl, 'modprinc', '-pwexpire', 'never', realm.user_princ]) 31*7f2fe78bSCy Schubert 32*7f2fe78bSCy Schubert# Try krb5 -> S4U2Proxy with forwardable user creds. This should fail 33*7f2fe78bSCy Schubert# at the S4U2Proxy step since the DB2 back end currently has no 34*7f2fe78bSCy Schubert# support for allowing it. 35*7f2fe78bSCy Schubertrealm.kinit(realm.user_princ, password('user'), ['-f', '-c', usercache]) 36*7f2fe78bSCy Schubertoutput = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', 37*7f2fe78bSCy Schubert pservice1, pservice2], expected_code=1) 38*7f2fe78bSCy Schubertif ('auth1: ' + realm.user_princ not in output or 39*7f2fe78bSCy Schubert 'KDC can\'t fulfill requested option' not in output): 40*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy') 41*7f2fe78bSCy Schubert 42*7f2fe78bSCy Schubert# Again with SPNEGO. 43*7f2fe78bSCy Schubertoutput = realm.run(['./t_s4u2proxy_krb5', '--spnego', usercache, storagecache, 44*7f2fe78bSCy Schubert '-', pservice1, pservice2], 45*7f2fe78bSCy Schubert expected_code=1) 46*7f2fe78bSCy Schubertif ('auth1: ' + realm.user_princ not in output or 47*7f2fe78bSCy Schubert 'KDC can\'t fulfill requested option' not in output): 48*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy (SPNEGO)') 49*7f2fe78bSCy Schubert 50*7f2fe78bSCy Schubert# Try krb5 -> S4U2Proxy without forwardable user creds. 51*7f2fe78bSCy Schubertrealm.kinit(realm.user_princ, password('user'), ['-c', usercache]) 52*7f2fe78bSCy Schubertoutput = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, pservice1, 53*7f2fe78bSCy Schubert pservice1, pservice2], expected_code=1) 54*7f2fe78bSCy Schubertif ('auth1: ' + realm.user_princ not in output or 55*7f2fe78bSCy Schubert 'KDC can\'t fulfill requested option' not in output): 56*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy not-forwardable') 57*7f2fe78bSCy Schubert 58*7f2fe78bSCy Schubert# Try S4U2Self. Ask for an S4U2Proxy step; this won't succeed because 59*7f2fe78bSCy Schubert# service/1 isn't allowed to get a forwardable S4U2Self ticket. 60*7f2fe78bSCy Schubertrealm.run(['./t_s4u', puser, pservice2], expected_code=1, 61*7f2fe78bSCy Schubert expected_msg='KDC can\'t fulfill requested option') 62*7f2fe78bSCy Schubertrealm.run(['./t_s4u', '--spnego', puser, pservice2], expected_code=1, 63*7f2fe78bSCy Schubert expected_msg='KDC can\'t fulfill requested option') 64*7f2fe78bSCy Schubert 65*7f2fe78bSCy Schubert# Correct that problem and try again. As above, the S4U2Proxy step 66*7f2fe78bSCy Schubert# won't actually succeed since we don't support that in DB2. 67*7f2fe78bSCy Schubertrealm.run([kadminl, 'modprinc', '+ok_to_auth_as_delegate', service1]) 68*7f2fe78bSCy Schubertrealm.run(['./t_s4u', puser, pservice2], expected_code=1, 69*7f2fe78bSCy Schubert expected_msg='KDC can\'t fulfill requested option') 70*7f2fe78bSCy Schubert 71*7f2fe78bSCy Schubert# Again with SPNEGO. This uses SPNEGO for the initial authentication, 72*7f2fe78bSCy Schubert# but still uses krb5 for S4U2Proxy--the delegated cred is returned as 73*7f2fe78bSCy Schubert# a krb5 cred, not a SPNEGO cred, and t_s4u uses the delegated cred 74*7f2fe78bSCy Schubert# directly rather than saving and reacquiring it. 75*7f2fe78bSCy Schubertrealm.run(['./t_s4u', '--spnego', puser, pservice2], expected_code=1, 76*7f2fe78bSCy Schubert expected_msg='KDC can\'t fulfill requested option') 77*7f2fe78bSCy Schubert 78*7f2fe78bSCy Schubertrealm.stop() 79*7f2fe78bSCy Schubert 80*7f2fe78bSCy Schubert# Set up a realm using the test KDB module so that we can do 81*7f2fe78bSCy Schubert# successful S4U2Proxy delegations. 82*7f2fe78bSCy Schuberttestprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 83*7f2fe78bSCy Schubert 'user': {'keys': 'aes128-cts'}, 84*7f2fe78bSCy Schubert 'service/1': {'flags': '+ok-to-auth-as-delegate', 85*7f2fe78bSCy Schubert 'keys': 'aes128-cts'}, 86*7f2fe78bSCy Schubert 'service/2': {'keys': 'aes128-cts'}} 87*7f2fe78bSCy Schubertconf = {'realms': {'$realm': {'database_module': 'test'}}, 88*7f2fe78bSCy Schubert 'dbmodules': {'test': {'db_library': 'test', 89*7f2fe78bSCy Schubert 'princs': testprincs, 90*7f2fe78bSCy Schubert 'delegation': {'service/1': 'service/2'}}}} 91*7f2fe78bSCy Schubertrealm = K5Realm(create_kdb=False, kdc_conf=conf) 92*7f2fe78bSCy Schubertuserkeytab = 'FILE:' + os.path.join(realm.testdir, 'userkeytab') 93*7f2fe78bSCy Schubertrealm.extract_keytab(realm.user_princ, userkeytab) 94*7f2fe78bSCy Schubertrealm.extract_keytab(service1, realm.keytab) 95*7f2fe78bSCy Schubertrealm.extract_keytab(service2, realm.keytab) 96*7f2fe78bSCy Schubertrealm.start_kdc() 97*7f2fe78bSCy Schubert 98*7f2fe78bSCy Schubert# Get forwardable creds for service1 in the default cache. 99*7f2fe78bSCy Schubertrealm.kinit(service1, None, ['-f', '-k']) 100*7f2fe78bSCy Schubert 101*7f2fe78bSCy Schubert# Successful krb5 -> S4U2Proxy, with krb5 and SPNEGO mechs. 102*7f2fe78bSCy Schubertrealm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, 103*7f2fe78bSCy Schubert '-t', userkeytab]) 104*7f2fe78bSCy Schubertout = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', 105*7f2fe78bSCy Schubert pservice1, pservice2]) 106*7f2fe78bSCy Schubertif 'auth1: user@' not in out or 'auth2: user@' not in out: 107*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy') 108*7f2fe78bSCy Schubertout = realm.run(['./t_s4u2proxy_krb5', '--spnego', usercache, storagecache, 109*7f2fe78bSCy Schubert '-', pservice1, pservice2]) 110*7f2fe78bSCy Schubertif 'auth1: user@' not in out or 'auth2: user@' not in out: 111*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy') 112*7f2fe78bSCy Schubert 113*7f2fe78bSCy Schubert# Successful S4U2Self -> S4U2Proxy. 114*7f2fe78bSCy Schubertout = realm.run(['./t_s4u', puser, pservice2]) 115*7f2fe78bSCy Schubert 116*7f2fe78bSCy Schubert# Regression test for #8139: get a user ticket directly for service1 and 117*7f2fe78bSCy Schubert# try krb5 -> S4U2Proxy. 118*7f2fe78bSCy Schubertrealm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, 119*7f2fe78bSCy Schubert '-t', userkeytab, '-S', service1]) 120*7f2fe78bSCy Schubertout = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', 121*7f2fe78bSCy Schubert pservice1, pservice2]) 122*7f2fe78bSCy Schubertif 'auth1: user@' not in out or 'auth2: user@' not in out: 123*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy') 124*7f2fe78bSCy Schubert 125*7f2fe78bSCy Schubert# Simulate a krbtgt rollover and verify that the user ticket can still 126*7f2fe78bSCy Schubert# be validated. 127*7f2fe78bSCy Schubertrealm.stop_kdc() 128*7f2fe78bSCy Schubertnewtgt_keys = ['2 aes128-cts', '1 aes128-cts'] 129*7f2fe78bSCy Schubertnewtgt_princs = {'krbtgt/KRBTEST.COM': {'keys': newtgt_keys}} 130*7f2fe78bSCy Schubertnewtgt_conf = {'dbmodules': {'test': {'princs': newtgt_princs}}} 131*7f2fe78bSCy Schubertnewtgt_env = realm.special_env('newtgt', True, kdc_conf=newtgt_conf) 132*7f2fe78bSCy Schubertrealm.start_kdc(env=newtgt_env) 133*7f2fe78bSCy Schubertout = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', 134*7f2fe78bSCy Schubert pservice1, pservice2]) 135*7f2fe78bSCy Schubertif 'auth1: user@' not in out or 'auth2: user@' not in out: 136*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy') 137*7f2fe78bSCy Schubert 138*7f2fe78bSCy Schubert# Get a user ticket after the krbtgt rollover and verify that 139*7f2fe78bSCy Schubert# S4U2Proxy delegation works (also a #8139 regression test). 140*7f2fe78bSCy Schubertrealm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, 141*7f2fe78bSCy Schubert '-t', userkeytab]) 142*7f2fe78bSCy Schubertout = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', 143*7f2fe78bSCy Schubert pservice1, pservice2]) 144*7f2fe78bSCy Schubertif 'auth1: user@' not in out or 'auth2: user@' not in out: 145*7f2fe78bSCy Schubert fail('krb5 -> s4u2proxy') 146*7f2fe78bSCy Schubert 147*7f2fe78bSCy Schubertrealm.stop() 148*7f2fe78bSCy Schubert 149*7f2fe78bSCy Schubertmark('S4U2Self with various enctypes') 150*7f2fe78bSCy Schubertfor realm in multipass_realms(create_host=False, get_creds=False): 151*7f2fe78bSCy Schubert service1 = 'service/1@%s' % realm.realm 152*7f2fe78bSCy Schubert realm.addprinc(service1) 153*7f2fe78bSCy Schubert realm.extract_keytab(service1, realm.keytab) 154*7f2fe78bSCy Schubert realm.kinit(service1, None, ['-k']) 155*7f2fe78bSCy Schubert realm.run(['./t_s4u', 'e:user', '-']) 156*7f2fe78bSCy Schubert 157*7f2fe78bSCy Schubert# Test cross realm S4U2Self using server referrals. 158*7f2fe78bSCy Schubertmark('cross-realm S4U2Self') 159*7f2fe78bSCy Schuberttestprincs = {'krbtgt/SREALM': {'keys': 'aes128-cts'}, 160*7f2fe78bSCy Schubert 'krbtgt/UREALM': {'keys': 'aes128-cts'}, 161*7f2fe78bSCy Schubert 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 162*7f2fe78bSCy Schubert 'other': {'keys': 'aes128-cts'}} 163*7f2fe78bSCy Schubertkdcconf1 = {'realms': {'$realm': {'database_module': 'test'}}, 164*7f2fe78bSCy Schubert 'dbmodules': {'test': {'db_library': 'test', 165*7f2fe78bSCy Schubert 'princs': testprincs, 166*7f2fe78bSCy Schubert 'alias': {'enterprise@abc': '@UREALM', 167*7f2fe78bSCy Schubert 'user@UREALM': '@UREALM'}}}} 168*7f2fe78bSCy Schubertkdcconf2 = {'realms': {'$realm': {'database_module': 'test'}}, 169*7f2fe78bSCy Schubert 'dbmodules': {'test': {'db_library': 'test', 170*7f2fe78bSCy Schubert 'princs': testprincs, 171*7f2fe78bSCy Schubert 'alias': {'user@SREALM': '@SREALM', 172*7f2fe78bSCy Schubert 'user@UREALM': 'user', 173*7f2fe78bSCy Schubert 'enterprise@abc': 'user'}}}} 174*7f2fe78bSCy Schubertr1, r2 = cross_realms(2, xtgts=(), 175*7f2fe78bSCy Schubert args=({'realm': 'SREALM', 'kdc_conf': kdcconf1}, 176*7f2fe78bSCy Schubert {'realm': 'UREALM', 'kdc_conf': kdcconf2}), 177*7f2fe78bSCy Schubert create_kdb=False) 178*7f2fe78bSCy Schubert 179*7f2fe78bSCy Schubertr1.start_kdc() 180*7f2fe78bSCy Schubertr2.start_kdc() 181*7f2fe78bSCy Schubertr1.extract_keytab(r1.user_princ, r1.keytab) 182*7f2fe78bSCy Schubertr1.kinit(r1.user_princ, None, ['-k', '-t', r1.keytab]) 183*7f2fe78bSCy Schubertsavefile = r1.ccache + '.save' 184*7f2fe78bSCy Schubertshutil.copyfile(r1.ccache, savefile) 185*7f2fe78bSCy Schubert 186*7f2fe78bSCy Schubert# Include a regression test for #8741 by unsetting the default realm. 187*7f2fe78bSCy Schubertremove_default = {'libdefaults': {'default_realm': None}} 188*7f2fe78bSCy Schubertno_default = r1.special_env('no_default', False, krb5_conf=remove_default) 189*7f2fe78bSCy Schubertmsgs = ('Getting credentials user@UREALM -> user@SREALM', 190*7f2fe78bSCy Schubert '/Matching credential not found', 191*7f2fe78bSCy Schubert 'Getting credentials user@SREALM -> krbtgt/UREALM@SREALM', 192*7f2fe78bSCy Schubert 'Received creds for desired service krbtgt/UREALM@SREALM', 193*7f2fe78bSCy Schubert 'via TGT krbtgt/UREALM@SREALM after requesting user\\@SREALM@UREALM', 194*7f2fe78bSCy Schubert 'krbtgt/SREALM@UREALM differs from requested user\\@SREALM@UREALM', 195*7f2fe78bSCy Schubert 'via TGT krbtgt/SREALM@UREALM after requesting user@SREALM', 196*7f2fe78bSCy Schubert 'TGS reply is for user@UREALM -> user@SREALM') 197*7f2fe78bSCy Schubertr1.run(['./t_s4u', 'p:' + r2.user_princ, '-', r1.keytab], env=no_default, 198*7f2fe78bSCy Schubert expected_trace=msgs) 199*7f2fe78bSCy Schubert 200*7f2fe78bSCy Schubert# Test realm identification of enterprise principal names ([MS-SFU] 201*7f2fe78bSCy Schubert# 3.1.5.1.1.1). Attach a bogus realm to the enterprise name to verify 202*7f2fe78bSCy Schubert# that we start at the server realm. 203*7f2fe78bSCy Schubertmark('cross-realm S4U2Self with enterprise name') 204*7f2fe78bSCy Schubertmsgs = ('Getting initial credentials for enterprise\\@abc@SREALM', 205*7f2fe78bSCy Schubert 'Sending unauthenticated request', 206*7f2fe78bSCy Schubert '/Realm not local to KDC', 207*7f2fe78bSCy Schubert 'Following referral to realm UREALM', 208*7f2fe78bSCy Schubert 'Sending unauthenticated request', 209*7f2fe78bSCy Schubert '/Additional pre-authentication required', 210*7f2fe78bSCy Schubert 'Identified realm of client principal as UREALM', 211*7f2fe78bSCy Schubert 'Getting credentials enterprise\\@abc@UREALM -> user@SREALM', 212*7f2fe78bSCy Schubert 'TGS reply is for enterprise\\@abc@UREALM -> user@SREALM') 213*7f2fe78bSCy Schubertr1.run(['./t_s4u', 'e:enterprise@abc@NOREALM', '-', r1.keytab], 214*7f2fe78bSCy Schubert expected_trace=msgs) 215*7f2fe78bSCy Schubert 216*7f2fe78bSCy Schubertmark('S4U2Self using X509 certificate') 217*7f2fe78bSCy Schubert 218*7f2fe78bSCy Schubert# Encode name as a PEM certificate file (sort of) for use by kvno. 219*7f2fe78bSCy Schubertdef princ_cert(name): 220*7f2fe78bSCy Schubert enc = b64encode(name.encode('ascii')).decode('ascii') 221*7f2fe78bSCy Schubert return '-----BEGIN CERTIFICATE-----\n%s\n-----END y\n' % enc 222*7f2fe78bSCy Schubert 223*7f2fe78bSCy Schubertcert_path = os.path.join(r1.testdir, 'fake_cert') 224*7f2fe78bSCy Schubertwith open(cert_path, "w") as cert_file: 225*7f2fe78bSCy Schubert cert_file.write(princ_cert('other')) 226*7f2fe78bSCy Schubert 227*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 228*7f2fe78bSCy Schubertmsgs = ('Getting initial credentials for @SREALM', 229*7f2fe78bSCy Schubert 'Identified realm of client principal as SREALM', 230*7f2fe78bSCy Schubert 'TGS reply is for other@SREALM', 231*7f2fe78bSCy Schubert 'Getting credentials other@SREALM', 232*7f2fe78bSCy Schubert 'Storing other@SREALM') 233*7f2fe78bSCy Schubertr1.run([kvno, '-F', cert_path, r1.user_princ], expected_trace=msgs) 234*7f2fe78bSCy Schubert 235*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 236*7f2fe78bSCy Schubertmsgs = ('Getting credentials other@SREALM', 237*7f2fe78bSCy Schubert 'TGS reply is for other@SREALM', 238*7f2fe78bSCy Schubert 'Storing other@SREALM') 239*7f2fe78bSCy Schubertr1.run([kvno, '-I', 'other', '-F', cert_path, r1.user_princ], 240*7f2fe78bSCy Schubert expected_trace=msgs) 241*7f2fe78bSCy Schubert 242*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 243*7f2fe78bSCy Schubertmsgs = ('Getting initial credentials for other@SREALM', 244*7f2fe78bSCy Schubert 'Identified realm of client principal as SREALM', 245*7f2fe78bSCy Schubert 'Getting credentials other@SREALM', 246*7f2fe78bSCy Schubert 'TGS reply is for other@SREALM', 247*7f2fe78bSCy Schubert 'Storing other@SREALM') 248*7f2fe78bSCy Schubertr1.run([kvno, '-U', 'other', '-F', cert_path, r1.user_princ], 249*7f2fe78bSCy Schubert expected_trace=msgs) 250*7f2fe78bSCy Schubert 251*7f2fe78bSCy Schubertmark('cross-realm S4U2Self using X509 certificate') 252*7f2fe78bSCy Schubert 253*7f2fe78bSCy Schubertwith open(cert_path, "w") as cert_file: 254*7f2fe78bSCy Schubert cert_file.write(princ_cert('user@UREALM')) 255*7f2fe78bSCy Schubert 256*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 257*7f2fe78bSCy Schubertmsgs = ('Getting initial credentials for @SREALM', 258*7f2fe78bSCy Schubert 'Identified realm of client principal as UREALM', 259*7f2fe78bSCy Schubert 'TGS reply is for user@UREALM', 260*7f2fe78bSCy Schubert 'Getting credentials user@UREALM', 261*7f2fe78bSCy Schubert 'Storing user@UREALM') 262*7f2fe78bSCy Schubertr1.run([kvno, '-F', cert_path, r1.user_princ], expected_trace=msgs) 263*7f2fe78bSCy Schubert 264*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 265*7f2fe78bSCy Schubertmsgs = ('Getting credentials user@UREALM', 266*7f2fe78bSCy Schubert 'TGS reply is for user@UREALM', 267*7f2fe78bSCy Schubert 'Storing user@UREALM') 268*7f2fe78bSCy Schubertr1.run([kvno, '-I', 'user@UREALM', '-F', cert_path, r1.user_princ], 269*7f2fe78bSCy Schubert expected_trace=msgs) 270*7f2fe78bSCy Schubert 271*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 272*7f2fe78bSCy Schubertmsgs = ('Getting initial credentials for enterprise\\@abc@SREALM', 273*7f2fe78bSCy Schubert 'Identified realm of client principal as UREALM', 274*7f2fe78bSCy Schubert 'Getting credentials enterprise\\@abc@UREALM', 275*7f2fe78bSCy Schubert 'TGS reply is for enterprise\\@abc@UREALM', 276*7f2fe78bSCy Schubert 'Storing enterprise\\@abc@UREALM') 277*7f2fe78bSCy Schubertr1.run([kvno, '-U', 'enterprise@abc', '-F', cert_path, r1.user_princ], 278*7f2fe78bSCy Schubert expected_trace=msgs) 279*7f2fe78bSCy Schubert 280*7f2fe78bSCy Schubertshutil.copyfile(savefile, r1.ccache) 281*7f2fe78bSCy Schubert 282*7f2fe78bSCy Schubertmark('S4U2Self using X509 certificate (GSSAPI)') 283*7f2fe78bSCy Schubert 284*7f2fe78bSCy Schubertr1.run(['./t_s4u', 'c:other', '-', r1.keytab]) 285*7f2fe78bSCy Schubertr1.run(['./t_s4u', 'c:user@UREALM', '-', r1.keytab]) 286*7f2fe78bSCy Schubert 287*7f2fe78bSCy Schubertr1.run(['./t_s4u', '--spnego', 'c:other', '-', r1.keytab]) 288*7f2fe78bSCy Schubertr1.run(['./t_s4u', '--spnego', 'c:user@UREALM', '-', r1.keytab]) 289*7f2fe78bSCy Schubert 290*7f2fe78bSCy Schubertr1.stop() 291*7f2fe78bSCy Schubertr2.stop() 292*7f2fe78bSCy Schubert 293*7f2fe78bSCy Schubertmark('Resource-based constrained delegation') 294*7f2fe78bSCy Schubert 295*7f2fe78bSCy Schuberta_princs = {'krbtgt/A': {'keys': 'aes128-cts'}, 296*7f2fe78bSCy Schubert 'krbtgt/B': {'keys': 'aes128-cts'}, 297*7f2fe78bSCy Schubert 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 298*7f2fe78bSCy Schubert 'sensitive': {'keys': 'aes128-cts', 299*7f2fe78bSCy Schubert 'flags': '+disallow_forwardable'}, 300*7f2fe78bSCy Schubert 'impersonator': {'keys': 'aes128-cts'}, 301*7f2fe78bSCy Schubert 'service1': {'keys': 'aes128-cts'}, 302*7f2fe78bSCy Schubert 'rb2': {'keys': 'aes128-cts'}, 303*7f2fe78bSCy Schubert 'rb': {'keys': 'aes128-cts'}} 304*7f2fe78bSCy Schuberta_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 305*7f2fe78bSCy Schubert 'dbmodules': {'test': {'db_library': 'test', 306*7f2fe78bSCy Schubert 'princs': a_princs, 307*7f2fe78bSCy Schubert 'rbcd': {'rb@A': 'impersonator@A', 308*7f2fe78bSCy Schubert 'rb2@A': 'service1@A'}, 309*7f2fe78bSCy Schubert 'delegation': {'service1': 'rb2'}, 310*7f2fe78bSCy Schubert 'alias': {'rb@A': 'rb', 311*7f2fe78bSCy Schubert 'rb@B': '@B', 312*7f2fe78bSCy Schubert 'rb@C': '@B', 313*7f2fe78bSCy Schubert 'service/rb.a': 'rb', 314*7f2fe78bSCy Schubert 'service/rb.b': '@B', 315*7f2fe78bSCy Schubert 'service/rb.c': '@B' }}}} 316*7f2fe78bSCy Schubert 317*7f2fe78bSCy Schubertb_princs = {'krbtgt/B': {'keys': 'aes128-cts'}, 318*7f2fe78bSCy Schubert 'krbtgt/A': {'keys': 'aes128-cts'}, 319*7f2fe78bSCy Schubert 'krbtgt/C': {'keys': 'aes128-cts'}, 320*7f2fe78bSCy Schubert 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 321*7f2fe78bSCy Schubert 'rb': {'keys': 'aes128-cts'}} 322*7f2fe78bSCy Schubertb_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 323*7f2fe78bSCy Schubert 'dbmodules': {'test': {'db_library': 'test', 324*7f2fe78bSCy Schubert 'princs': b_princs, 325*7f2fe78bSCy Schubert 'rbcd': {'rb@B': 'impersonator@A'}, 326*7f2fe78bSCy Schubert 'alias': {'rb@B': 'rb', 327*7f2fe78bSCy Schubert 'service/rb.b': 'rb', 328*7f2fe78bSCy Schubert 'rb@C': '@C', 329*7f2fe78bSCy Schubert 'impersonator@A': '@A', 330*7f2fe78bSCy Schubert 'service/rb.c': '@C'}}}} 331*7f2fe78bSCy Schubert 332*7f2fe78bSCy Schubertc_princs = {'krbtgt/C': {'keys': 'aes128-cts'}, 333*7f2fe78bSCy Schubert 'krbtgt/B': {'keys': 'aes128-cts'}, 334*7f2fe78bSCy Schubert 'rb': {'keys': 'aes128-cts'}} 335*7f2fe78bSCy Schubertc_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 336*7f2fe78bSCy Schubert 'capaths': { 'A' : { 'C' : 'B' }}, 337*7f2fe78bSCy Schubert 'dbmodules': {'test': {'db_library': 'test', 338*7f2fe78bSCy Schubert 'princs': c_princs, 339*7f2fe78bSCy Schubert 'rbcd': {'rb@C': ['impersonator@A', 340*7f2fe78bSCy Schubert 'service1@A']}, 341*7f2fe78bSCy Schubert 'alias': {'rb@C': 'rb', 342*7f2fe78bSCy Schubert 'service/rb.c': 'rb' }}}} 343*7f2fe78bSCy Schubert 344*7f2fe78bSCy Schubertra, rb, rc = cross_realms(3, xtgts=(), 345*7f2fe78bSCy Schubert args=({'realm': 'A', 'kdc_conf': a_kconf}, 346*7f2fe78bSCy Schubert {'realm': 'B', 'kdc_conf': b_kconf}, 347*7f2fe78bSCy Schubert {'realm': 'C', 'kdc_conf': c_kconf}), 348*7f2fe78bSCy Schubert create_kdb=False) 349*7f2fe78bSCy Schubert 350*7f2fe78bSCy Schubertra.start_kdc() 351*7f2fe78bSCy Schubertrb.start_kdc() 352*7f2fe78bSCy Schubertrc.start_kdc() 353*7f2fe78bSCy Schubert 354*7f2fe78bSCy Schubertdomain_realm = {'domain_realm': {'.a':'A', '.b':'B', '.c':'C'}} 355*7f2fe78bSCy Schubertdomain_conf = ra.special_env('domain_conf', False, krb5_conf=domain_realm) 356*7f2fe78bSCy Schubert 357*7f2fe78bSCy Schubertra.extract_keytab('impersonator@A', ra.keytab) 358*7f2fe78bSCy Schubertra.kinit('impersonator@A', None, ['-f', '-k', '-t', ra.keytab]) 359*7f2fe78bSCy Schubert 360*7f2fe78bSCy Schubertmark('Local-realm RBCD') 361*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'p:rb']) 362*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb']) 363*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'p:rb@A']) 364*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@A']) 365*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@A@']) 366*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@A@A']) 367*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.a']) 368*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.a'], env=domain_conf) 369*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + 'sensitive@A', 'h:service@rb.a'], expected_code=1) 370*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + rb.user_princ, 'h:service@rb.a']) 371*7f2fe78bSCy Schubert 372*7f2fe78bSCy Schubertmark('Cross-realm RBCD') 373*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@B']) 374*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@B@']) 375*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@B@A']) 376*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.b']) 377*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.b'], env=domain_conf) 378*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + 'sensitive@A', 'h:service@rb.b'], expected_code=1) 379*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + rb.user_princ, 'h:service@rb.b']) 380*7f2fe78bSCy Schubert 381*7f2fe78bSCy Schubertmark('RBCD transitive trust') 382*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@C']) 383*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@C@']) 384*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@C@A']) 385*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.c']) 386*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.c'], env=domain_conf) 387*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + 'sensitive@A', 'h:service@rb.c'], expected_code=1) 388*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + rb.user_princ, 'h:service@rb.c']) 389*7f2fe78bSCy Schubert 390*7f2fe78bSCy Schubert# Although service1 has RBCD delegation privileges to rb2@A, it does 391*7f2fe78bSCy Schubert# not have ok-to-auth-as-delegate and does have traditional delegation 392*7f2fe78bSCy Schubert# privileges, so it cannot get a forwardable S4U2Self ticket. 393*7f2fe78bSCy Schubertmark('RBCD forwardable blocked by forward delegation privileges') 394*7f2fe78bSCy Schubertra.extract_keytab('service1@A', ra.keytab) 395*7f2fe78bSCy Schubertra.kinit('service1@A', None, ['-f', '-k', '-t', ra.keytab]) 396*7f2fe78bSCy Schubertra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb2@A'], expected_code=1, 397*7f2fe78bSCy Schubert expected_msg='KDC can\'t fulfill requested option') 398*7f2fe78bSCy Schubert 399*7f2fe78bSCy Schubertra.stop() 400*7f2fe78bSCy Schubertrb.stop() 401*7f2fe78bSCy Schubertrc.stop() 402*7f2fe78bSCy Schubert 403*7f2fe78bSCy Schubertsuccess('S4U test cases') 404