xref: /freebsd/crypto/krb5/src/tests/t_preauth.py (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1from k5test import *
2
3# Test that the kdcpreauth client_keyblock() callback matches the key
4# indicated by the etype info, and returns NULL if no key was selected.
5testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so')
6conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth},
7                    'clpreauth': {'module': 'test:' + testpreauth}}}
8realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
9realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ])
10realm.run([kadminl, 'setstr', realm.user_princ, 'teststring', 'testval'])
11realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser'])
12realm.kinit(realm.user_princ, password('user'), expected_msg='testval')
13realm.kinit('nokeyuser', password('user'), expected_code=1,
14            expected_msg='no key')
15
16# Preauth type -123 is the test preauth module type; 133 is FAST
17# PA-FX-COOKIE; 2 is encrypted timestamp.
18
19# Test normal preauth flow.
20mark('normal')
21msgs = ('Sending unauthenticated request',
22        '/Additional pre-authentication required',
23        'Preauthenticating using KDC method data',
24        'Processing preauth types:',
25        'Preauth module test (-123) (real) returned: 0/Success',
26        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
27        'Decrypted AS reply')
28realm.run(['./icred', realm.user_princ, password('user')],
29          expected_msg='testval', expected_trace=msgs)
30
31# Test successful optimistic preauth.
32mark('optimistic')
33expected_trace = ('Attempting optimistic preauth',
34                  'Processing preauth types: -123',
35                  'Preauth module test (-123) (real) returned: 0/Success',
36                  'Produced preauth for next request: -123',
37                  'Decrypted AS reply')
38realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')],
39          expected_trace=expected_trace)
40
41# Test optimistic preauth failing on client, falling back to encrypted
42# timestamp.
43mark('optimistic (client failure)')
44msgs = ('Attempting optimistic preauth',
45        'Processing preauth types: -123',
46        '/induced optimistic fail',
47        'Sending unauthenticated request',
48        '/Additional pre-authentication required',
49        'Preauthenticating using KDC method data',
50        'Processing preauth types:',
51        'Encrypted timestamp (for ',
52        'module encrypted_timestamp (2) (real) returned: 0/Success',
53        'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
54        'Decrypted AS reply')
55realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ,
56           password('user')], expected_trace=msgs)
57
58# Test optimistic preauth failing on KDC, falling back to encrypted
59# timestamp.
60mark('optimistic (KDC failure)')
61realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes'])
62msgs = ('Attempting optimistic preauth',
63        'Processing preauth types: -123',
64        'Preauth module test (-123) (real) returned: 0/Success',
65        'Produced preauth for next request: -123',
66        '/Preauthentication failed',
67        'Preauthenticating using KDC method data',
68        'Processing preauth types:',
69        'Encrypted timestamp (for ',
70        'module encrypted_timestamp (2) (real) returned: 0/Success',
71        'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
72        'Decrypted AS reply')
73realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')],
74          expected_trace=msgs)
75# Leave failopt set for the next test.
76
77# Test optimistic preauth failing on KDC, stopping because the test
78# module disabled fallback.
79mark('optimistic (KDC failure, no fallback)')
80msgs = ('Attempting optimistic preauth',
81        'Processing preauth types: -123',
82        'Preauth module test (-123) (real) returned: 0/Success',
83        'Produced preauth for next request: -123',
84        '/Preauthentication failed')
85realm.run(['./icred', '-X', 'disable_fallback', '-o', '-123', realm.user_princ,
86           password('user')], expected_code=1,
87          expected_msg='Preauthentication failed', expected_trace=msgs)
88realm.run([kadminl, 'delstr', realm.user_princ, 'failopt'])
89
90# Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies.
91mark('second round-trip')
92realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip'])
93msgs = ('Sending unauthenticated request',
94        '/Additional pre-authentication required',
95        'Preauthenticating using KDC method data',
96        'Processing preauth types:',
97        'Preauth module test (-123) (real) returned: 0/Success',
98        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
99        '/More preauthentication data is required',
100        'Continuing preauth mech -123',
101        'Processing preauth types: -123, PA-FX-COOKIE (133)',
102        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
103        'Decrypted AS reply')
104realm.run(['./icred', realm.user_princ, password('user')],
105          expected_msg='2rt: secondtrip', expected_trace=msgs)
106
107# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
108# falling back to encrypted timestamp.
109mark('second round-trip (client failure)')
110msgs = ('Sending unauthenticated request',
111        '/Additional pre-authentication required',
112        'Preauthenticating using KDC method data',
113        'Processing preauth types:',
114        'Preauth module test (-123) (real) returned: 0/Success',
115        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
116        '/More preauthentication data is required',
117        'Continuing preauth mech -123',
118        'Processing preauth types: -123, PA-FX-COOKIE (133)',
119        '/induced 2rt fail',
120        'Preauthenticating using KDC method data',
121        'Processing preauth types:',
122        'Encrypted timestamp (for ',
123        'module encrypted_timestamp (2) (real) returned: 0/Success',
124        'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
125        'Decrypted AS reply')
126realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')],
127          expected_msg='2rt: secondtrip', expected_trace=msgs)
128
129# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
130# stopping because the test module disabled fallback.
131mark('second round-trip (client failure, no fallback)')
132msgs = ('Sending unauthenticated request',
133        '/Additional pre-authentication required',
134        'Preauthenticating using KDC method data',
135        'Processing preauth types:',
136        'Preauth module test (-123) (real) returned: 0/Success',
137        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
138        '/More preauthentication data is required',
139        'Continuing preauth mech -123',
140        'Processing preauth types: -123, PA-FX-COOKIE (133)',
141        '/induced 2rt fail')
142realm.run(['./icred', '-X', 'fail_2rt', '-X', 'disable_fallback',
143           realm.user_princ, password('user')], expected_code=1,
144          expected_msg='Pre-authentication failed: induced 2rt fail',
145          expected_trace=msgs)
146
147# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
148# falling back to encrypted timestamp.
149mark('second round-trip (KDC failure)')
150realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes'])
151msgs = ('Sending unauthenticated request',
152        '/Additional pre-authentication required',
153        'Preauthenticating using KDC method data',
154        'Processing preauth types:',
155        'Preauth module test (-123) (real) returned: 0/Success',
156        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
157        '/More preauthentication data is required',
158        'Continuing preauth mech -123',
159        'Processing preauth types: -123, PA-FX-COOKIE (133)',
160        'Preauth module test (-123) (real) returned: 0/Success',
161        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
162        '/Preauthentication failed',
163        'Preauthenticating using KDC method data',
164        'Processing preauth types:',
165        'Encrypted timestamp (for ',
166        'module encrypted_timestamp (2) (real) returned: 0/Success',
167        'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
168        'Decrypted AS reply')
169realm.run(['./icred', realm.user_princ, password('user')],
170          expected_msg='2rt: secondtrip', expected_trace=msgs)
171# Leave fail2rt set for the next test.
172
173# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
174# stopping because the test module disabled fallback.
175mark('second round-trip (KDC failure, no fallback)')
176msgs = ('Sending unauthenticated request',
177        '/Additional pre-authentication required',
178        'Preauthenticating using KDC method data',
179        'Processing preauth types:',
180        'Preauth module test (-123) (real) returned: 0/Success',
181        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
182        '/More preauthentication data is required',
183        'Continuing preauth mech -123',
184        'Processing preauth types: -123, PA-FX-COOKIE (133)',
185        'Preauth module test (-123) (real) returned: 0/Success',
186        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
187        '/Preauthentication failed')
188realm.run(['./icred', '-X', 'disable_fallback',
189           realm.user_princ, password('user')], expected_code=1,
190          expected_msg='Preauthentication failed', expected_trace=msgs)
191realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt'])
192
193# Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC.
194mark('tryagain')
195realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain'])
196msgs = ('Sending unauthenticated request',
197        '/Additional pre-authentication required',
198        'Preauthenticating using KDC method data',
199        'Processing preauth types:',
200        'Preauth module test (-123) (real) returned: 0/Success',
201        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
202        '/KDC has no support for encryption type',
203        'Recovering from KDC error 14 using preauth mech -123',
204        'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)',
205        'Preauth module test (-123) tryagain returned: 0/Success',
206        'Followup preauth for next request: -123, PA-FX-COOKIE (133)',
207        'Decrypted AS reply')
208realm.run(['./icred', realm.user_princ, password('user')],
209          expected_msg='tryagain: testagain', expected_trace=msgs)
210
211# Test a client-side tryagain failure, falling back to encrypted
212# timestamp.
213mark('tryagain (client failure)')
214msgs = ('Sending unauthenticated request',
215        '/Additional pre-authentication required',
216        'Preauthenticating using KDC method data',
217        'Processing preauth types:',
218        'Preauth module test (-123) (real) returned: 0/Success',
219        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
220        '/KDC has no support for encryption type',
221        'Recovering from KDC error 14 using preauth mech -123',
222        'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)',
223        '/induced tryagain fail',
224        'Preauthenticating using KDC method data',
225        'Processing preauth types:',
226        'Encrypted timestamp (for ',
227        'module encrypted_timestamp (2) (real) returned: 0/Success',
228        'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
229        'Decrypted AS reply')
230realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ,
231           password('user')], expected_trace=msgs)
232
233# Test a client-side tryagain failure, stopping because the test
234# module disabled fallback.
235mark('tryagain (client failure, no fallback)')
236msgs = ('Sending unauthenticated request',
237        '/Additional pre-authentication required',
238        'Preauthenticating using KDC method data',
239        'Processing preauth types:',
240        'Preauth module test (-123) (real) returned: 0/Success',
241        'Produced preauth for next request: PA-FX-COOKIE (133), -123',
242        '/KDC has no support for encryption type',
243        'Recovering from KDC error 14 using preauth mech -123',
244        'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)',
245        '/induced tryagain fail')
246realm.run(['./icred', '-X', 'fail_tryagain', '-X', 'disable_fallback',
247           realm.user_princ, password('user')], expected_code=1,
248          expected_msg='KDC has no support for encryption type',
249          expected_trace=msgs)
250
251# Test that multiple stepwise initial creds operations can be
252# performed with the same krb5_context, with proper tracking of
253# clpreauth module request handles.
254mark('interleaved')
255realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1'])
256realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2'])
257realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3'])
258realm.run([kadminl, 'setstr', 'u2', '2rt', 'extra'])
259out = realm.run(['./icinterleave', 'pw', 'u1', 'u2', 'u3'])
260if out != ('step 1\nstep 2\nstep 3\nstep 1\nfinish 1\nstep 2\nno attr\n'
261           'step 3\nno attr\nstep 2\n2rt: extra\nstep 3\nfinish 3\nstep 2\n'
262           'finish 2\n'):
263    fail('unexpected output from icinterleave')
264
265success('Pre-authentication framework tests')
266