Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/t_authdata.py
34878 views
1
from k5test import *
2
3
# Load the sample KDC authdata module. Allow renewable tickets.
4
greet_path = os.path.join(buildtop, 'plugins', 'authdata', 'greet_server',
5
'greet_server.so')
6
conf = {'realms': {'$realm': {'max_life': '20h', 'max_renewable_life': '20h'}},
7
'plugins': {'kdcauthdata': {'module': 'greet:' + greet_path}}}
8
realm = K5Realm(krb5_conf=conf)
9
10
# With no requested authdata, we expect to see PAC (128) in an
11
# if-relevant container and the greet authdata in a kdc-issued
12
# container.
13
mark('baseline authdata')
14
out = realm.run(['./adata', realm.host_princ])
15
if '?128: [6, 7, 10, 16, 19]' not in out or '^-42: Hello' not in out:
16
fail('expected authdata not seen for basic request')
17
18
# Requested authdata is copied into the ticket, with KDC-only types
19
# filtered out. (128 is win2k-pac, which should be filtered.)
20
mark('request authdata')
21
out = realm.run(['./adata', realm.host_princ, '-5', 'test1', '?-6', 'test2',
22
'128', 'fakepac', '?128', 'ifrelfakepac',
23
'^-8', 'fakekdcissued', '?^-8', 'ifrelfakekdcissued'])
24
if ' -5: test1' not in out or '?-6: test2' not in out:
25
fail('expected authdata not seen for request with authdata')
26
if 'fake' in out:
27
fail('KDC-only authdata not filtered for request with authdata')
28
29
mark('AD-MANDATORY-FOR-KDC')
30
realm.run(['./adata', realm.host_princ, '!-1', 'mandatoryforkdc'],
31
expected_code=1, expected_msg='KDC policy rejects request')
32
33
# The no_auth_data_required server flag should suppress the PAC, but
34
# not module or request authdata.
35
mark('no_auth_data_required server flag')
36
realm.run([kadminl, 'ank', '-randkey', '+no_auth_data_required', 'noauth'])
37
realm.extract_keytab('noauth', realm.keytab)
38
out = realm.run(['./adata', 'noauth', '-2', 'test'])
39
if '^-42: Hello' not in out or ' -2: test' not in out:
40
fail('expected authdata not seen for no_auth_data_required request')
41
if '128: ' in out:
42
fail('PAC authdata seen for no_auth_data_required request')
43
44
# Cross-realm TGT requests should not suppress PAC or request
45
# authdata.
46
mark('cross-realm')
47
realm.addprinc('krbtgt/XREALM')
48
realm.extract_keytab('krbtgt/XREALM', realm.keytab)
49
out = realm.run(['./adata', 'krbtgt/XREALM', '-3', 'test'])
50
if '128:' not in out or '^-42: Hello' not in out or ' -3: test' not in out:
51
fail('expected authdata not seen for cross-realm TGT request')
52
53
mark('pac_privsvr_enctype')
54
# Change the privsvr enctype and make sure we can still verify the PAC
55
# on a service ticket in a TGS request.
56
realm.run([kadminl, 'setstr', realm.host_princ,
57
'pac_privsvr_enctype', 'aes128-sha1'])
58
realm.kinit(realm.user_princ, password('user'),
59
['-S', realm.host_princ, '-r', '1h'])
60
realm.kinit(realm.user_princ, None, ['-S', realm.host_princ, '-R'])
61
# Remove the attribute and make sure the previously-issued service
62
# ticket PAC no longer verifies.
63
realm.run([kadminl, 'delstr', realm.host_princ, 'pac_privsvr_enctype'])
64
realm.kinit(realm.user_princ, None, ['-S', realm.host_princ, '-R'],
65
expected_code=1, expected_msg='Message stream modified')
66
67
realm.stop()
68
69
if not pkinit_enabled:
70
skipped('anonymous ticket authdata tests', 'PKINIT not built')
71
else:
72
# Set up a realm with PKINIT support and get anonymous tickets.
73
realm = K5Realm(krb5_conf=conf, get_creds=False, pkinit=True)
74
realm.addprinc('WELLKNOWN/ANONYMOUS')
75
realm.kinit('@%s' % realm.realm, flags=['-n'])
76
77
# PAC and module authdata should be suppressed for anonymous
78
# tickets, but not request authdata.
79
mark('anonymous')
80
out = realm.run(['./adata', realm.host_princ, '-4', 'test'])
81
if ' -4: test' not in out:
82
fail('expected authdata not seen for anonymous request')
83
if '128: ' in out or '-42: ' in out:
84
fail('PAC or greet authdata seen for anonymous request')
85
86
realm.stop()
87
88
# Test authentication indicators. Load the test preauth module so we
89
# can control the indicators asserted.
90
testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so')
91
krb5conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth},
92
'clpreauth': {'module': 'test:' + testpreauth}}}
93
realm, realm2 = cross_realms(2, args=({'realm': 'LOCAL'},
94
{'realm': 'FOREIGN'}),
95
krb5_conf=krb5conf, get_creds=False)
96
realm.run([kadminl, 'modprinc', '+requires_preauth', '-maxrenewlife', '2 days',
97
realm.user_princ])
98
realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.host_princ])
99
realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.krbtgt_princ])
100
realm.extract_keytab(realm.krbtgt_princ, realm.keytab)
101
realm.extract_keytab(realm.host_princ, realm.keytab)
102
realm.extract_keytab('krbtgt/FOREIGN', realm.keytab)
103
realm2.extract_keytab(realm2.krbtgt_princ, realm.keytab)
104
realm2.extract_keytab(realm2.host_princ, realm.keytab)
105
realm2.extract_keytab('krbtgt/LOCAL', realm.keytab)
106
107
# AS request to local-realm service
108
mark('AS-REQ to local service auth indicator')
109
realm.kinit(realm.user_princ, password('user'),
110
['-X', 'indicators=indcl', '-r', '2d', '-S', realm.host_princ])
111
realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]')
112
113
# Ticket modification request
114
mark('ticket modification auth indicator')
115
realm.kinit(realm.user_princ, None, ['-R', '-S', realm.host_princ])
116
realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]')
117
118
# AS request to cross TGT
119
mark('AS-REQ to cross TGT auth indicator')
120
realm.kinit(realm.user_princ, password('user'),
121
['-X', 'indicators=indcl', '-S', 'krbtgt/FOREIGN'])
122
realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]')
123
124
# Multiple indicators
125
mark('AS multiple indicators')
126
realm.kinit(realm.user_princ, password('user'),
127
['-X', 'indicators=indcl indcl2 indcl3'])
128
realm.run(['./adata', realm.krbtgt_princ],
129
expected_msg='+97: [indcl, indcl2, indcl3]')
130
131
# AS request to local TGT (resulting creds are used for TGS tests)
132
mark('AS-REQ to local TGT auth indicator')
133
realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl'])
134
realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl]')
135
136
# Local TGS request for local realm service
137
mark('TGS-REQ to local service auth indicator')
138
realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]')
139
140
# Local TGS request for cross TGT service
141
mark('TGS-REQ to cross TGT auth indicator')
142
realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]')
143
144
# We don't yet have support for passing auth indicators across realms,
145
# so just verify that indicators don't survive cross-realm requests.
146
mark('TGS-REQ to foreign service auth indicator')
147
out = realm.run(['./adata', realm2.krbtgt_princ])
148
if '97:' in out:
149
fail('auth-indicator seen in cross TGT request to local TGT')
150
out = realm.run(['./adata', 'krbtgt/LOCAL@FOREIGN'])
151
if '97:' in out:
152
fail('auth-indicator seen in cross TGT request to cross TGT')
153
out = realm.run(['./adata', realm2.host_princ])
154
if '97:' in out:
155
fail('auth-indicator seen in cross TGT request to service')
156
157
# Test that the CAMMAC signature still works during a krbtgt rollover.
158
mark('CAMMAC signature across krbtgt rollover')
159
realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.krbtgt_princ])
160
realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]')
161
162
# Test indicator enforcement.
163
mark('auth indicator enforcement')
164
realm.addprinc('restricted')
165
realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'superstrong'])
166
realm.kinit(realm.user_princ, password('user'), ['-S', 'restricted'],
167
expected_code=1, expected_msg='KDC policy rejects request')
168
realm.run([kvno, 'restricted'], expected_code=1,
169
expected_msg='KDC policy rejects request')
170
realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'indcl'])
171
realm.run([kvno, 'restricted'])
172
realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=ind1 ind2'])
173
realm.run([kvno, 'restricted'], expected_code=1)
174
realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'a b c ind2'])
175
realm.run([kvno, 'restricted'])
176
177
# Regression test for one manifestation of #8139: ensure that
178
# forwarded TGTs obtained across a TGT re-key still work when the
179
# preferred krbtgt enctype changes.
180
mark('#8139 regression test')
181
realm.kinit(realm.user_princ, password('user'), ['-f'])
182
realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'des3-cbc-sha1',
183
realm.krbtgt_princ])
184
realm.run(['./forward'])
185
realm.run([kvno, realm.host_princ])
186
187
# Repeat the above test using a renewed TGT.
188
mark('#8139 regression test (renewed TGT)')
189
realm.kinit(realm.user_princ, password('user'), ['-r', '2d'])
190
realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes128-cts',
191
realm.krbtgt_princ])
192
realm.kinit(realm.user_princ, None, ['-R'])
193
realm.run([kvno, realm.host_princ])
194
195
realm.stop()
196
realm2.stop()
197
198
# Load the test KDB module to allow successful S4U2Proxy
199
# auth-indicator requests and to detect whether replaced_reply_key is
200
# set.
201
testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
202
'krbtgt/FOREIGN': {'keys': 'aes128-cts'},
203
'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
204
'user2': {'keys': 'aes128-cts', 'flags': '+preauth'},
205
'rservice': {'keys': 'aes128-cts',
206
'strings': 'require_auth:strong'},
207
'service/1': {'keys': 'aes128-cts',
208
'flags': '+ok_to_auth_as_delegate'},
209
'service/2': {'keys': 'aes128-cts'},
210
'noauthdata': {'keys': 'aes128-cts',
211
'flags': '+no_auth_data_required'}}
212
kdcconf = {'realms': {'$realm': {'database_module': 'test'}},
213
'dbmodules': {'test': {'db_library': 'test',
214
'princs': testprincs,
215
'delegation': {'service/1': 'service/2'}}}}
216
realm = K5Realm(krb5_conf=krb5conf, kdc_conf=kdcconf, create_kdb=False,
217
pkinit=True)
218
usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache')
219
realm.extract_keytab(realm.krbtgt_princ, realm.keytab)
220
realm.extract_keytab('krbtgt/FOREIGN', realm.keytab)
221
realm.extract_keytab(realm.user_princ, realm.keytab)
222
realm.extract_keytab('ruser', realm.keytab)
223
realm.extract_keytab('service/1', realm.keytab)
224
realm.extract_keytab('service/2', realm.keytab)
225
realm.extract_keytab('noauthdata', realm.keytab)
226
realm.start_kdc()
227
228
if not pkinit_enabled:
229
skipped('replaced_reply_key test', 'PKINIT not built')
230
else:
231
# Check that replaced_reply_key is set in issue_pac() when PKINIT
232
# is used. The test KDB module will indicate this by including a
233
# fake PAC_CREDENTIAL_INFO(2) buffer in the PAC.
234
mark('PKINIT (replaced_reply_key set)')
235
realm.pkinit(realm.user_princ)
236
realm.run(['./adata', realm.krbtgt_princ],
237
expected_msg='?128: [1, 2, 6, 7, 10]')
238
239
# S4U2Self (should have no indicators since client did not authenticate)
240
mark('S4U2Self (no auth indicators expected)')
241
realm.kinit('service/1', None, ['-k', '-f', '-X', 'indicators=inds1'])
242
realm.run([kvno, '-U', 'user', 'service/1'])
243
out = realm.run(['./adata', '-p', realm.user_princ, 'service/1'])
244
if '97:' in out:
245
fail('auth-indicator present in S4U2Self response')
246
247
# Get another S4U2Self ticket with requested authdata.
248
realm.run(['./s4u2self', 'user', 'service/1', '-', '-2', 'self_ad'])
249
realm.run(['./adata', '-p', realm.user_princ, 'service/1', '-2', 'self_ad'],
250
expected_msg=' -2: self_ad')
251
252
# S4U2Proxy (indicators should come from evidence ticket, not TGT)
253
mark('S4U2Proxy (auth indicators from evidence ticket expected)')
254
realm.kinit(realm.user_princ, None, ['-k', '-f', '-X', 'indicators=indcl',
255
'-S', 'service/1', '-c', usercache])
256
realm.run(['./s4u2proxy', usercache, 'service/2'])
257
out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
258
if '+97: [indcl]' not in out or '[inds1]' in out:
259
fail('correct auth-indicator not seen for S4U2Proxy req')
260
# Make sure a PAC with an S4U_DELEGATION_INFO(11) buffer is included.
261
if '?128: [1, 6, 7, 10, 11, 16, 19]' not in out:
262
fail('PAC with delegation info not seen for S4U2Proxy req')
263
264
# Get another S4U2Proxy ticket including request-authdata.
265
realm.run(['./s4u2proxy', usercache, 'service/2', '-2', 'proxy_ad'])
266
realm.run(['./adata', '-p', realm.user_princ, 'service/2', '-2', 'proxy_ad'],
267
expected_msg=' -2: proxy_ad')
268
269
# Get an S4U2Proxy ticket using an evidence ticket obtained by S4U2Self,
270
# with request authdata in both steps.
271
realm.run(['./s4u2self', 'user2', 'service/1', usercache, '-2', 'self_ad'])
272
realm.run(['./s4u2proxy', usercache, 'service/2', '-2', 'proxy_ad'])
273
out = realm.run(['./adata', '-p', 'user2', 'service/2', '-2', 'proxy_ad'])
274
if ' -2: self_ad' not in out or ' -2: proxy_ad' not in out:
275
fail('expected authdata not seen in S4U2Proxy ticket')
276
277
# Test alteration of auth indicators by KDB module (AS and TGS).
278
realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=dummy dbincr1'])
279
realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [dbincr2]')
280
realm.run(['./adata', 'service/1'], expected_msg='+97: [dbincr3]')
281
realm.kinit(realm.user_princ, None,
282
['-k', '-X', 'indicators=strong', '-S', 'rservice'])
283
# Test enforcement of altered indicators during AS request.
284
realm.kinit(realm.user_princ, None,
285
['-k', '-X', 'indicators=strong dbincr1', '-S', 'rservice'],
286
expected_code=1)
287
288
# Test that the PAC is suppressed in an AS request by a negative PAC
289
# request.
290
mark('AS-REQ PAC client supression')
291
realm.kinit(realm.user_princ, None, ['-k', '--no-request-pac'])
292
out = realm.run(['./adata', realm.krbtgt_princ])
293
if '128:' in out:
294
fail('PAC not suppressed by --no-request-pac')
295
296
mark('S4U2Proxy with a foreign client')
297
298
a_princs = {'krbtgt/A': {'keys': 'aes128-cts'},
299
'krbtgt/B': {'keys': 'aes128-cts'},
300
'impersonator': {'keys': 'aes128-cts'},
301
'impersonator2': {'keys': 'aes128-cts'},
302
'resource': {'keys': 'aes128-cts'}}
303
a_kconf = {'realms': {'$realm': {'database_module': 'test'}},
304
'dbmodules': {'test': {'db_library': 'test',
305
'delegation': {'impersonator' : 'resource'},
306
'princs': a_princs,
307
'alias': {'service/rb.b': '@B'}}}}
308
309
b_princs = {'krbtgt/B': {'keys': 'aes128-cts'},
310
'krbtgt/A': {'keys': 'aes128-cts'},
311
'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
312
'rb': {'keys': 'aes128-cts'}}
313
b_kconf = {'realms': {'$realm': {'database_module': 'test'}},
314
'dbmodules': {'test': {'db_library': 'test',
315
'princs': b_princs,
316
'rbcd': {'rb@B': 'impersonator2@A'},
317
'alias': {'service/rb.b': 'rb',
318
'impersonator2@A': '@A'}}}}
319
320
ra, rb = cross_realms(2, xtgts=(),
321
args=({'realm': 'A', 'kdc_conf': a_kconf},
322
{'realm': 'B', 'kdc_conf': b_kconf}),
323
create_kdb=False)
324
325
ra.start_kdc()
326
rb.start_kdc()
327
328
ra.extract_keytab('impersonator@A', ra.keytab)
329
ra.extract_keytab('impersonator2@A', ra.keytab)
330
rb.extract_keytab('user@B', rb.keytab)
331
332
usercache = 'FILE:' + os.path.join(rb.testdir, 'usercache')
333
rb.kinit(rb.user_princ, None, ['-k', '-f', '-c', usercache])
334
rb.run([kvno, '-C', 'impersonator@A', '-c', usercache])
335
336
ra.kinit('impersonator@A', None, ['-f', '-k', '-t', ra.keytab])
337
ra.run(['./s4u2proxy', usercache, 'resource@A'])
338
339
mark('Cross realm S4U authdata tests')
340
341
ra.kinit('impersonator2@A', None, ['-f', '-k', '-t', ra.keytab])
342
ra.run(['./s4u2self', rb.user_princ, 'impersonator2@A', usercache, '-2',
343
'cross_s4u_self_ad'])
344
out = ra.run(['./adata', '-c', usercache, '-p', rb.user_princ,
345
'impersonator2@A', '-2', 'cross_s4u_self_ad'])
346
if out.count(' -2: cross_s4u_self_ad') != 1:
347
fail('expected one cross_s4u_self_ad, got: %s' % count)
348
349
ra.run(['./s4u2proxy', usercache, 'service/rb.b', '-2',
350
'cross_s4u_proxy_ad'])
351
rb.extract_keytab('service/rb.b', ra.keytab)
352
out = ra.run(['./adata', '-p', rb.user_princ, 'service/rb.b', '-2',
353
'cross_s4u_proxy_ad'])
354
if out.count(' -2: cross_s4u_self_ad') != 1:
355
fail('expected one cross_s4u_self_ad, got: %s' % count)
356
if out.count(' -2: cross_s4u_proxy_ad') != 1:
357
fail('expected one cross_s4u_proxy_ad, got: %s' % count)
358
359
ra.stop()
360
rb.stop()
361
362
success('Authorization data tests')
363
364