xref: /freebsd/crypto/krb5/src/tests/gssapi/t_s4u.py (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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