33525022ba84f8179c4302fa5b4f7be4920c9ada
[platform/upstream/krb5.git] / src / tests / t_authdata.py
1 #!/usr/bin/python
2 from k5test import *
3
4 # Load the sample KDC authdata module.
5 greet_path = os.path.join(buildtop, 'plugins', 'authdata', 'greet_server',
6                           'greet_server.so')
7 conf = {'plugins': {'kdcauthdata': {'module': 'greet:' + greet_path}}}
8 realm = K5Realm(krb5_conf=conf)
9
10 # With no requested authdata, we expect to see SIGNTICKET (512) in an
11 # if-relevant container and the greet authdata in a kdc-issued
12 # container.
13 out = realm.run(['./adata', realm.host_princ])
14 if '?512: ' not in out or '^-42: Hello' not in out:
15     fail('expected authdata not seen for basic request')
16
17 # Requested authdata is copied into the ticket, with KDC-only types
18 # filtered out.  (128 is win2k-pac, which should be filtered.)
19 out = realm.run(['./adata', realm.host_princ, '-5', 'test1', '?-6', 'test2',
20                  '128', 'fakepac', '?128', 'ifrelfakepac',
21                  '^-8', 'fakekdcissued', '?^-8', 'ifrelfakekdcissued'])
22 if ' -5: test1' not in out or '?-6: test2' not in out:
23     fail('expected authdata not seen for request with authdata')
24 if 'fake' in out:
25     fail('KDC-only authdata not filtered for request with authdata')
26
27 out = realm.run(['./adata', realm.host_princ, '!-1', 'mandatoryforkdc'],
28                 expected_code=1)
29 if 'KDC policy rejects request' not in out:
30     fail('Wrong error seen for mandatory-for-kdc failure')
31
32 # The no_auth_data_required server flag should suppress SIGNTICKET,
33 # but not module or request authdata.
34 realm.run([kadminl, 'ank', '-randkey', '+no_auth_data_required', 'noauth'])
35 realm.extract_keytab('noauth', realm.keytab)
36 out = realm.run(['./adata', 'noauth', '-2', 'test'])
37 if '^-42: Hello' not in out or ' -2: test' not in out:
38     fail('expected authdata not seen for no_auth_data_required request')
39 if '512: ' in out:
40     fail('SIGNTICKET authdata seen for no_auth_data_required request')
41
42 # Cross-realm TGT requests should also suppress SIGNTICKET, but not
43 # module or request authdata.
44 realm.addprinc('krbtgt/XREALM')
45 realm.extract_keytab('krbtgt/XREALM', realm.keytab)
46 out = realm.run(['./adata', 'krbtgt/XREALM', '-3', 'test'])
47 if '^-42: Hello' not in out or ' -3: test' not in out:
48     fail('expected authdata not seen for cross-realm TGT request')
49 if '512: ' in out:
50     fail('SIGNTICKET authdata seen in cross-realm TGT')
51
52 realm.stop()
53
54 if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
55     skipped('anonymous ticket authdata tests', 'PKINIT not built')
56 else:
57     # Set up a realm with PKINIT support and get anonymous tickets.
58     certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs')
59     ca_pem = os.path.join(certs, 'ca.pem')
60     kdc_pem = os.path.join(certs, 'kdc.pem')
61     privkey_pem = os.path.join(certs, 'privkey.pem')
62     pkinit_conf = {'realms': {'$realm': {
63                 'pkinit_anchors': 'FILE:%s' % ca_pem,
64                 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem)}}}
65     conf.update(pkinit_conf)
66     realm = K5Realm(krb5_conf=conf, get_creds=False)
67     realm.addprinc('WELLKNOWN/ANONYMOUS')
68     realm.kinit('@%s' % realm.realm, flags=['-n'])
69
70     # SIGNTICKET and module authdata should be suppressed for
71     # anonymous tickets, but not request authdata.
72     out = realm.run(['./adata', realm.host_princ, '-4', 'test'])
73     if ' -4: test' not in out:
74         fail('expected authdata not seen for anonymous request')
75     if '512: ' in out or '-42: ' in out:
76         fail('SIGNTICKET or greet authdata seen for anonymous request')
77
78 realm.stop()
79
80 # Test authentication indicators.  Load the test preauth module so we
81 # can control the indicators asserted.
82 testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so')
83 krb5conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth},
84                         'clpreauth': {'module': 'test:' + testpreauth}}}
85 realm, realm2 = cross_realms(2, args=({'realm': 'LOCAL'},
86                                       {'realm': 'FOREIGN'}),
87                              krb5_conf=krb5conf, get_creds=False)
88 realm.run([kadminl, 'modprinc', '+requires_preauth', '-maxrenewlife', '2 days',
89            realm.user_princ])
90 realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.host_princ])
91 realm.extract_keytab(realm.krbtgt_princ, realm.keytab)
92 realm.extract_keytab(realm.host_princ, realm.keytab)
93 realm.extract_keytab('krbtgt/FOREIGN', realm.keytab)
94 realm2.extract_keytab(realm2.krbtgt_princ, realm.keytab)
95 realm2.extract_keytab(realm2.host_princ, realm.keytab)
96 realm2.extract_keytab('krbtgt/LOCAL', realm.keytab)
97
98 # AS request to local-realm service
99 realm.kinit(realm.user_princ, password('user'),
100             ['-X', 'indicators=indcl', '-r', '2d', '-S', realm.host_princ])
101 out = realm.run(['./adata', realm.host_princ])
102 if '+97: [indcl]' not in out:
103     fail('auth-indicator not seen for AS req to service')
104
105 # Ticket modification request
106 realm.kinit(realm.user_princ, None, ['-R', '-S', realm.host_princ])
107 out = realm.run(['./adata', realm.host_princ])
108 if '+97: [indcl]' not in out:
109     fail('auth-indicator not seen for ticket modification request')
110
111 # AS request to cross TGT
112 realm.kinit(realm.user_princ, password('user'),
113             ['-X', 'indicators=indcl', '-S', 'krbtgt/FOREIGN'])
114 out = realm.run(['./adata', 'krbtgt/FOREIGN'])
115 if '+97: [indcl]' not in out:
116     fail('auth-indicator not seen for AS req to cross-realm TGT')
117
118 # Multiple indicators
119 realm.kinit(realm.user_princ, password('user'),
120             ['-X', 'indicators=indcl indcl2 indcl3'])
121 out = realm.run(['./adata', realm.krbtgt_princ])
122 if '+97: [indcl, indcl2, indcl3]' not in out:
123     fail('multiple auth-indicators not seen for normal AS req')
124
125 # AS request to local TGT (resulting creds are used for TGS tests)
126 realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl'])
127 out = realm.run(['./adata', realm.krbtgt_princ])
128 if '+97: [indcl]' not in out:
129     fail('auth-indicator not seen for normal AS req')
130
131 # Local TGS request for local realm service
132 out = realm.run(['./adata', realm.host_princ])
133 if '+97: [indcl]' not in out:
134     fail('auth-indicator not seen for local TGS req')
135
136 # Local TGS request for cross TGT service
137 out = realm.run(['./adata', 'krbtgt/FOREIGN'])
138 if '+97: [indcl]' not in out:
139     fail('auth-indicator not seen for TGS req to cross-realm TGT')
140
141 # We don't yet have support for passing auth indicators across realms,
142 # so just verify that indicators don't survive cross-realm requests.
143 out = realm.run(['./adata', realm2.krbtgt_princ])
144 if '97:' in out:
145     fail('auth-indicator seen in cross TGT request to local TGT')
146 out = realm.run(['./adata', 'krbtgt/LOCAL@FOREIGN'])
147 if '97:' in out:
148     fail('auth-indicator seen in cross TGT request to cross TGT')
149 out = realm.run(['./adata', realm2.host_princ])
150 if '97:' in out:
151     fail('auth-indicator seen in cross TGT request to service')
152
153 # Test that the CAMMAC signature still works during a krbtgt rollover.
154 realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.krbtgt_princ])
155 out = realm.run(['./adata', realm.host_princ])
156 if '+97: [indcl]' not in out:
157     fail('auth-indicator not seen for local TGS req after krbtgt rotation')
158
159 # Test indicator enforcement.
160 realm.addprinc('restricted')
161 realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'superstrong'])
162 out = realm.run([kvno, 'restricted'], expected_code=1)
163 if 'KDC policy rejects request' not in out:
164     fail('expected error not seen for auth indicator enforcement')
165 realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'indcl'])
166 realm.run([kvno, 'restricted'])
167 realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=ind1 ind2'])
168 realm.run([kvno, 'restricted'], expected_code=1)
169 realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'a b c ind2'])
170 realm.run([kvno, 'restricted'])
171
172 # Regression test for one manifestation of #8139: ensure that
173 # forwarded TGTs obtained across a TGT re-key still work when the
174 # preferred krbtgt enctype changes.
175 realm.kinit(realm.user_princ, password('user'), ['-f'])
176 realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'des3-cbc-sha1',
177            realm.krbtgt_princ])
178 realm.run(['./forward'])
179 realm.run([kvno, realm.host_princ])
180
181 realm.stop()
182 realm2.stop()
183
184 # Load the test KDB module to allow successful S4U2Proxy
185 # auth-indicator requests.
186 testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
187               'krbtgt/FOREIGN': {'keys': 'aes128-cts'},
188               'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
189               'service/1': {'keys': 'aes128-cts', 'flags': '+preauth'},
190               'service/2': {'keys': 'aes128-cts'},
191               'noauthdata': {'keys': 'aes128-cts',
192                              'flags': '+no_auth_data_required'}}
193 kdcconf = {'realms': {'$realm': {'database_module': 'test'}},
194            'dbmodules': {'test': {'db_library': 'test',
195                                   'princs': testprincs,
196                                   'delegation': {'service/1': 'service/2'}}}}
197 realm = K5Realm(krb5_conf=krb5conf, kdc_conf=kdcconf, create_kdb=False)
198 usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache')
199 realm.extract_keytab(realm.krbtgt_princ, realm.keytab)
200 realm.extract_keytab('krbtgt/FOREIGN', realm.keytab)
201 realm.extract_keytab(realm.user_princ, realm.keytab)
202 realm.extract_keytab('service/1', realm.keytab)
203 realm.extract_keytab('service/2', realm.keytab)
204 realm.extract_keytab('noauthdata', realm.keytab)
205 realm.start_kdc()
206
207 # S4U2Self (should have no indicators since client did not authenticate)
208 realm.kinit('service/1', None, ['-k', '-f', '-X', 'indicators=inds1'])
209 realm.run([kvno, '-U', 'user', 'service/1'])
210 out = realm.run(['./adata', '-p', realm.user_princ, 'service/1'])
211 if '97:' in out:
212     fail('auth-indicator present in S4U2Self response')
213
214 # S4U2Proxy (indicators should come from evidence ticket, not TGT)
215 realm.kinit(realm.user_princ, None, ['-k', '-f', '-X', 'indicators=indcl',
216                                      '-S', 'service/1', '-c', usercache])
217 realm.run(['./s4u2proxy', usercache, 'service/2'])
218 out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
219 if '+97: [indcl]' not in out or '[inds1]' in out:
220     fail('correct auth-indicator not seen for S4U2Proxy req')
221
222 # Test that KDB module authdata is included in an AS request, by
223 # default or with an explicit PAC request.
224 realm.kinit(realm.user_princ, None, ['-k'])
225 out = realm.run(['./adata', realm.krbtgt_princ])
226 if '-456: db-authdata-test' not in out:
227     fail('DB authdata not seen in default AS request')
228 realm.kinit(realm.user_princ, None, ['-k', '--request-pac'])
229 out = realm.run(['./adata', realm.krbtgt_princ])
230 if '-456: db-authdata-test' not in out:
231     fail('DB authdata not seen with --request-pac')
232
233 # Test that KDB module authdata is suppressed in an AS request by a
234 # negative PAC request.
235 realm.kinit(realm.user_princ, None, ['-k', '--no-request-pac'])
236 out = realm.run(['./adata', realm.krbtgt_princ])
237 if '-456: db-authdata-test' in out:
238     fail('DB authdata not suppressed by --no-request-pac')
239
240 # Test that KDB authdata is included in a TGS request by default.
241 out = realm.run(['./adata', 'service/1'])
242 if '-456: db-authdata-test' not in out:
243     fail('DB authdata not seen in TGS request')
244
245 # Test that KDB authdata is suppressed in a TGS request by the
246 # +no_auth_data_required flag.
247 out = realm.run(['./adata', 'noauthdata'])
248 if '-456: db-authdata-test' in out:
249     fail('DB authdata not suppressed by +no_auth_data_required')
250
251 # Additional KDB module authdata behavior we don't currently test:
252 # * KDB module authdata is suppressed in TGS requests if the TGT
253 #   contains no authdata and the request is not cross-realm or S4U.
254 # * KDB module authdata is suppressed for anonymous tickets.
255
256 success('Authorization data tests')