Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/gssapi/t_gssapi.py
34889 views
1
from k5test import *
2
3
# Test krb5 negotiation under SPNEGO for all enctype configurations. Also
4
# test IOV wrap/unwrap with and without SPNEGO.
5
for realm in multipass_realms():
6
realm.run(['./t_spnego','p:' + realm.host_princ, realm.keytab])
7
realm.run(['./t_iov', 'p:' + realm.host_princ])
8
realm.run(['./t_iov', '-s', 'p:' + realm.host_princ])
9
realm.run(['./t_pcontok', 'p:' + realm.host_princ])
10
11
realm = K5Realm()
12
realm.run([kadminl, 'modprinc', '+preauth', realm.user_princ])
13
14
remove_default = {'libdefaults': {'default_realm': None}}
15
change_default = {'libdefaults': {'default_realm': 'WRONG.REALM'}}
16
no_default = realm.special_env('no_default', False, krb5_conf=remove_default)
17
wrong_default = realm.special_env('wrong_default', False,
18
krb5_conf=change_default)
19
20
# Test IAKERB with credentials.
21
realm.run(['./t_iakerb', 'p:' + realm.user_princ, '-', 'h:host@' + hostname,
22
'h:host'])
23
24
# Test IAKERB getting initial credentials.
25
realm.run(['./t_iakerb', 'p:' + realm.user_princ, password('user'),
26
'h:host@' + hostname, 'h:host'])
27
28
# Test IAKERB realm discovery.
29
realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,
30
'h:host'])
31
32
# Test IAKERB realm discovery without default_realm set. We get an
33
# error because the acceptor does not know the realm.
34
realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,
35
'h:host'], env=no_default, expected_code=1,
36
expected_msg='The IAKERB proxy could not determine its realm')
37
38
# Test again, using a GSS_KRB5_NT_PRINCIPAL_NAME acceptor name so that
39
# gss_accept_sec_context() knows the realm.
40
realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,
41
'p:' + realm.host_princ], env=no_default)
42
43
# Test IAKERB realm discovery with a non-useful default_realm set.
44
realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,
45
'p:' + realm.host_princ], env=wrong_default)
46
47
# Test gss_add_cred().
48
realm.run(['./t_add_cred'])
49
50
### Test acceptor name behavior.
51
52
# Create some host-based principals and put most of them into the
53
# keytab. Rename one principal so that the keytab name matches the
54
# key but not the client name.
55
realm.run([kadminl, 'addprinc', '-randkey', 'service1/abraham'])
56
realm.run([kadminl, 'addprinc', '-randkey', 'service1/barack'])
57
realm.run([kadminl, 'addprinc', '-randkey', 'service2/calvin'])
58
realm.run([kadminl, 'addprinc', '-randkey', 'service2/dwight'])
59
realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-'])
60
realm.run([kadminl, 'addprinc', '-randkey', 'http/localhost'])
61
realm.run([kadminl, 'xst', 'service1/abraham'])
62
realm.run([kadminl, 'xst', 'service1/barack'])
63
realm.run([kadminl, 'xst', 'service2/calvin'])
64
realm.run([kadminl, 'xst', 'http/localhost'])
65
realm.run([kadminl, 'renprinc', 'service1/abraham', 'service1/andrew'])
66
67
# Test with no default realm and no dots in the server name.
68
realm.run(['./t_accname', 'h:http@localhost'], expected_msg='http/localhost')
69
realm.run(['./t_accname', 'h:http@localhost'], expected_msg='http/localhost',
70
env=no_default)
71
72
# Test with no acceptor name, including client/keytab principal
73
# mismatch (non-fatal) and missing keytab entry (fatal).
74
realm.run(['./t_accname', 'p:service1/andrew'],
75
expected_msg='service1/abraham')
76
realm.run(['./t_accname', 'p:service1/barack'], expected_msg='service1/barack')
77
realm.run(['./t_accname', 'p:service2/calvin'], expected_msg='service2/calvin')
78
realm.run(['./t_accname', 'p:service2/dwight'], expected_code=1,
79
expected_msg=' not found in keytab')
80
81
# Test with acceptor name containing service only, including
82
# client/keytab hostname mismatch (non-fatal) and service name
83
# mismatch (fatal).
84
realm.run(['./t_accname', 'p:service1/andrew', 'h:service1'],
85
expected_msg='service1/abraham')
86
realm.run(['./t_accname', 'p:service1/andrew', 'h:service2'], expected_code=1,
87
expected_msg=' not found in keytab')
88
realm.run(['./t_accname', 'p:service2/calvin', 'h:service2'],
89
expected_msg='service2/calvin')
90
realm.run(['./t_accname', 'p:service2/calvin', 'h:service1'], expected_code=1,
91
expected_msg=' found in keytab but does not match server principal')
92
# Regression test for #8892 (trailing @ in name).
93
realm.run(['./t_accname', 'p:service1/andrew', 'h:service1@'],
94
expected_msg='service1/abraham')
95
96
# Test with acceptor name containing service and host. Use the
97
# client's un-canonicalized hostname as acceptor input to mirror what
98
# many servers do.
99
realm.run(['./t_accname', 'p:' + realm.host_princ,
100
'h:host@%s' % socket.gethostname()], expected_msg=realm.host_princ)
101
realm.run(['./t_accname', 'p:host/-nomatch-',
102
'h:host@%s' % socket.gethostname()], expected_code=1,
103
expected_msg=' not found in keytab')
104
105
# If possible, test with an acceptor name requiring fallback to match
106
# against a keytab entry.
107
canonname = canonicalize_hostname(hostname)
108
if canonname != hostname:
109
os.rename(realm.keytab, realm.keytab + '.save')
110
canonprinc = 'host/' + canonname
111
realm.run([kadminl, 'addprinc', '-randkey', canonprinc])
112
realm.extract_keytab(canonprinc, realm.keytab)
113
# Use the canonical name for the initiator's target name, since
114
# host/hostname exists in the KDB (but not the keytab).
115
realm.run(['./t_accname', 'h:host@' + canonname, 'h:host@' + hostname])
116
os.rename(realm.keytab + '.save', realm.keytab)
117
else:
118
skipped('GSS acceptor name fallback test',
119
'%s does not canonicalize to a different name' % hostname)
120
121
# Test krb5_gss_import_cred.
122
realm.run(['./t_imp_cred', 'p:service1/barack'])
123
realm.run(['./t_imp_cred', 'p:service1/barack', 'service1/barack'])
124
realm.run(['./t_imp_cred', 'p:service1/andrew', 'service1/abraham'])
125
realm.run(['./t_imp_cred', 'p:service2/dwight'], expected_code=1,
126
expected_msg=' not found in keytab')
127
128
# Verify that we can't acquire acceptor creds without a keytab.
129
os.remove(realm.keytab)
130
out = realm.run(['./t_accname', 'p:abc'], expected_code=1)
131
if ('gss_acquire_cred: Keytab' not in out or
132
'nonexistent or empty' not in out):
133
fail('Expected error message not seen for nonexistent keytab')
134
135
realm.stop()
136
137
# Re-run the last acceptor name test with ignore_acceptor_hostname set
138
# and the principal for the mismatching hostname in the keytab.
139
ignore_conf = {'libdefaults': {'ignore_acceptor_hostname': 'true'}}
140
realm = K5Realm(krb5_conf=ignore_conf)
141
realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-'])
142
realm.run([kadminl, 'xst', 'host/-nomatch-'])
143
realm.run(['./t_accname', 'p:host/-nomatch-',
144
'h:host@%s' % socket.gethostname()], expected_msg='host/-nomatch-')
145
146
realm.stop()
147
148
# Make sure a GSSAPI acceptor can handle cross-realm tickets with a
149
# transited field. (Regression test for #7639.)
150
r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)),
151
create_user=False, create_host=False,
152
args=[{'realm': 'A.X', 'create_user': True},
153
{'realm': 'X'},
154
{'realm': 'B.X', 'create_host': True}])
155
os.rename(r3.keytab, r1.keytab)
156
r1.run(['./t_accname', 'p:' + r3.host_princ, 'h:host'])
157
r1.stop()
158
r2.stop()
159
r3.stop()
160
161
### Test gss_inquire_cred behavior.
162
163
realm = K5Realm()
164
165
# Test deferred resolution of the default ccache for initiator creds.
166
realm.run(['./t_inq_cred'], expected_msg=realm.user_princ)
167
realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ)
168
realm.run(['./t_inq_cred', '-s'], expected_msg=realm.user_princ)
169
170
# Test picking a name from the keytab for acceptor creds.
171
realm.run(['./t_inq_cred', '-a'], expected_msg=realm.host_princ)
172
realm.run(['./t_inq_cred', '-k', '-a'], expected_msg=realm.host_princ)
173
realm.run(['./t_inq_cred', '-s', '-a'], expected_msg=realm.host_princ)
174
175
# Test client keytab initiation (non-deferred) with a specified name.
176
realm.extract_keytab(realm.user_princ, realm.client_keytab)
177
os.remove(realm.ccache)
178
realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ)
179
180
# Test deferred client keytab initiation and GSS_C_BOTH cred usage.
181
os.remove(realm.client_keytab)
182
os.remove(realm.ccache)
183
shutil.copyfile(realm.keytab, realm.client_keytab)
184
realm.run(['./t_inq_cred', '-k', '-b'], expected_msg=realm.host_princ)
185
186
# Test gss_export_name behavior.
187
realm.run(['./t_export_name', 'u:x'], expected_msg=\
188
'0401000B06092A864886F7120102020000000D78404B5242544553542E434F4D\n')
189
realm.run(['./t_export_name', '-s', 'u:xyz'],
190
expected_msg='0401000806062B06010505020000000378797A\n')
191
realm.run(['./t_export_name', 'p:a@b'],
192
expected_msg='0401000B06092A864886F71201020200000003614062\n')
193
realm.run(['./t_export_name', '-s', 'p:a@b'],
194
expected_msg='0401000806062B060105050200000003614062\n')
195
196
# Test that composite-export tokens can be imported.
197
realm.run(['./t_export_name', '-c', 'p:a@b'], expected_msg=
198
'0402000B06092A864886F7120102020000000361406200000000\n')
199
200
# Test gss_inquire_mechs_for_name behavior.
201
krb5_mech = '{ 1 2 840 113554 1 2 2 }'
202
spnego_mech = '{ 1 3 6 1 5 5 2 }'
203
out = realm.run(['./t_inq_mechs_name', 'p:a@b'])
204
if krb5_mech not in out:
205
fail('t_inq_mechs_name (principal)')
206
out = realm.run(['./t_inq_mechs_name', 'u:x'])
207
if krb5_mech not in out or spnego_mech not in out:
208
fail('t_inq_mecs_name (user)')
209
out = realm.run(['./t_inq_mechs_name', 'h:host'])
210
if krb5_mech not in out or spnego_mech not in out:
211
fail('t_inq_mecs_name (hostbased)')
212
213
# Test that accept_sec_context can produce an error token and
214
# init_sec_context can interpret it.
215
realm.run(['./t_err', 'p:' + realm.host_princ])
216
realm.run(['./t_err', '--spnego', 'p:' + realm.host_princ])
217
218
# Test the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option.
219
realm.run(['./t_ciflags', 'p:' + realm.host_princ])
220
221
# Test that inquire_context works properly, even on incomplete
222
# contexts.
223
realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ])
224
225
if runenv.sizeof_time_t <= 4:
226
skip_rest('y2038 GSSAPI tests', 'platform has 32-bit time_t')
227
228
# Test lifetime results, using a realm with a large maximum lifetime
229
# so that we can test ticket end dates after y2038.
230
realm.stop()
231
conf = {'realms': {'$realm': {'max_life': '9000d'}}}
232
realm = K5Realm(kdc_conf=conf, get_creds=False)
233
234
# Check a lifetime string result against an expected number value (or None).
235
# Allow some variance due to time elapsed during the tests.
236
def check_lifetime(msg, val, expected):
237
if expected is None and val != 'indefinite':
238
fail('%s: expected indefinite, got %s' % (msg, val))
239
if expected is not None and val == 'indefinite':
240
fail('%s: expected %d, got indefinite' % (msg, expected))
241
if expected is not None and abs(int(val) - expected) > 100:
242
fail('%s: expected %d, got %s' % (msg, expected, val))
243
244
realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d'])
245
out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)])
246
ln = out.split('\n')
247
check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400)
248
check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400)
249
check_lifetime('acred gss_acquire_cred', ln[2], None)
250
check_lifetime('acred gss_inquire_cred', ln[3], None)
251
check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400)
252
check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400)
253
check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400)
254
check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300)
255
check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300)
256
check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300)
257
258
success('GSSAPI tests')
259
260