Fix autoconf 2.70 compatibility
[platform/upstream/krb5.git] / src / tests / t_keytab.py
1 from k5test import *
2
3 for realm in multipass_realms(create_user=False):
4     # Test kinit with a keytab.
5     realm.kinit(realm.host_princ, flags=['-k'])
6
7 realm = K5Realm(get_creds=False, start_kadmind=True)
8
9 # Test kinit with a partial keytab.
10 mark('partial keytab')
11 pkeytab = realm.keytab + '.partial'
12 realm.run([ktutil], input=('rkt %s\ndelent 1\nwkt %s\n' %
13                            (realm.keytab, pkeytab)))
14 realm.kinit(realm.host_princ, flags=['-k', '-t', pkeytab])
15
16 # Test kinit with no keys for client in keytab.
17 mark('no keys for client')
18 realm.kinit(realm.user_princ, flags=['-k'], expected_code=1,
19             expected_msg='no suitable keys')
20
21 # Test kinit and klist with client keytab defaults.
22 mark('client keytab')
23 realm.extract_keytab(realm.user_princ, realm.client_keytab);
24 realm.run([kinit, '-k', '-i'])
25 realm.klist(realm.user_princ)
26 realm.run([kdestroy])
27 realm.kinit(realm.user_princ, flags=['-k', '-i'])
28 realm.klist(realm.user_princ)
29 out = realm.run([klist, '-k', '-i'])
30 if realm.client_keytab not in out or realm.user_princ not in out:
31     fail('Expected output not seen from klist -k -i')
32
33 # Test implicit request for keytab (-i or -t without -k)
34 mark('implicit -k')
35 realm.run([kdestroy])
36 realm.kinit(realm.host_princ, flags=['-t', realm.keytab],
37             expected_msg='keytab specified, forcing -k')
38 realm.klist(realm.host_princ)
39 realm.run([kdestroy])
40 realm.kinit(realm.user_princ, flags=['-i'],
41             expected_msg='keytab specified, forcing -k')
42 realm.klist(realm.user_princ)
43
44 # Test extracting keys with multiple key versions present.
45 mark('multi-kvno extract')
46 os.remove(realm.keytab)
47 realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.host_princ])
48 out = realm.run([kadminl, 'ktadd', '-norandkey', realm.host_princ])
49 if 'with kvno 1,' not in out or 'with kvno 2,' not in out:
50     fail('Expected output not seen from kadmin.local ktadd -norandkey')
51 out = realm.run([klist, '-k', '-e'])
52 if ' 1 host/' not in out or ' 2 host/' not in out:
53     fail('Expected output not seen from klist -k -e')
54
55 # Test again using kadmin over the network.
56 mark('multi-kvno extract (via kadmin)')
57 realm.prep_kadmin()
58 os.remove(realm.keytab)
59 out = realm.run_kadmin(['ktadd', '-norandkey', realm.host_princ])
60 if 'with kvno 1,' not in out or 'with kvno 2,' not in out:
61     fail('Expected output not seen from kadmin.local ktadd -norandkey')
62 out = realm.run([klist, '-k', '-e'])
63 if ' 1 host/' not in out or ' 2 host/' not in out:
64     fail('Expected output not seen from klist -k -e')
65
66 # Test handling of kvno values beyond 255.  Use kadmin over the
67 # network since we used to have an 8-bit limit on kvno marshalling.
68
69 # Test one key rotation, verifying that the expected new kvno appears
70 # in the keytab and in the principal entry.
71 def test_key_rotate(realm, princ, expected_kvno):
72     realm.run_kadmin(['ktadd', '-k', realm.keytab, princ])
73     realm.run([kadminl, 'ktrem', princ, 'old'])
74     realm.kinit(princ, flags=['-k'])
75     msg = '%d %s' % (expected_kvno, princ)
76     out = realm.run([klist, '-k'], expected_msg=msg)
77     msg = 'Key: vno %d,' % expected_kvno
78     out = realm.run_kadmin(['getprinc', princ], expected_msg=msg)
79
80 mark('key rotation across boundaries')
81 princ = 'foo/bar@%s' % realm.realm
82 realm.addprinc(princ)
83 os.remove(realm.keytab)
84 realm.run([kadminl, 'modprinc', '-kvno', '253', princ])
85 test_key_rotate(realm, princ, 254)
86 test_key_rotate(realm, princ, 255)
87 test_key_rotate(realm, princ, 256)
88 test_key_rotate(realm, princ, 257)
89 realm.run([kadminl, 'modprinc', '-kvno', '32766', princ])
90 test_key_rotate(realm, princ, 32767)
91 test_key_rotate(realm, princ, 32768)
92 test_key_rotate(realm, princ, 32769)
93 realm.run([kadminl, 'modprinc', '-kvno', '65534', princ])
94 test_key_rotate(realm, princ, 65535)
95 test_key_rotate(realm, princ, 1)
96 test_key_rotate(realm, princ, 2)
97
98 mark('32-bit kvno')
99
100 # Test that klist -k can read a keytab entry without a 32-bit kvno and
101 # reports the 8-bit key version.
102 record = b'\x00\x01'             # principal component count
103 record += b'\x00\x0bKRBTEST.COM' # realm
104 record += b'\x00\x04user'        # principal component
105 record += b'\x00\x00\x00\x01'    # name type (NT-PRINCIPAL)
106 record += b'\x54\xf7\x4d\x35'    # timestamp
107 record += b'\x02'                # key version
108 record += b'\x00\x12'            # enctype
109 record += b'\x00\x20'            # key length
110 record += b'\x00' * 32           # key bytes
111 f = open(realm.keytab, 'wb')
112 f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record)]))
113 f.write(record)
114 f.close()
115 msg = '   2 %s' % realm.user_princ
116 out = realm.run([klist, '-k'], expected_msg=msg)
117
118 # Make sure zero-fill isn't treated as a 32-bit kvno.
119 f = open(realm.keytab, 'wb')
120 f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record) + 4]))
121 f.write(record)
122 f.write(b'\x00\x00\x00\x00')
123 f.close()
124 msg = '   2 %s' % realm.user_princ
125 out = realm.run([klist, '-k'], expected_msg=msg)
126
127 # Make sure a hand-crafted 32-bit kvno is recognized.
128 f = open(realm.keytab, 'wb')
129 f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record) + 4]))
130 f.write(record)
131 f.write(b'\x00\x00\x00\x03')
132 f.close()
133 msg = '   3 %s' % realm.user_princ
134 out = realm.run([klist, '-k'], expected_msg=msg)
135
136 # Test parameter expansion in profile variables
137 mark('parameter expansion')
138 realm.stop()
139 conf = {'libdefaults': {
140         'default_keytab_name': 'testdir/%{null}abc%{uid}',
141         'default_client_keytab_name': 'testdir/%{null}xyz%{uid}'}}
142 realm = K5Realm(krb5_conf=conf, create_kdb=False)
143 del realm.env['KRB5_KTNAME']
144 del realm.env['KRB5_CLIENT_KTNAME']
145 uidstr = str(os.getuid())
146 msg = 'FILE:testdir/abc%s' % uidstr
147 out = realm.run([klist, '-k'], expected_code=1, expected_msg=msg)
148 msg = 'FILE:testdir/xyz%s' % uidstr
149 out = realm.run([klist, '-ki'], expected_code=1, expected_msg=msg)
150
151 conf = {'libdefaults': {'allow_weak_crypto': 'true'}}
152 realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf)
153
154 realm.run([kadminl, 'ank', '-pw', 'pw', 'default'])
155 realm.run([kadminl, 'ank', '-e', 'aes256-cts:special', '-pw', 'pw', 'exp'])
156 realm.run([kadminl, 'ank', '-e', 'aes256-cts:special', '-pw', 'pw', '+preauth',
157            'pexp'])
158 realm.run([kadminl, 'ank', '-e', 'des-cbc-crc:afs3', '-pw', 'pw', 'afs'])
159 realm.run([kadminl, 'ank', '-e', 'des-cbc-crc:afs3', '-pw', 'pw', '+preauth',
160            'pafs'])
161
162 # Extract one of the explicit salt values from the database.
163 out = realm.run([kdb5_util, 'tabdump', 'keyinfo'])
164 salt_dict = {f[0]: f[5] for f in [l.split('\t') for l in out.splitlines()]}
165 exp_salt = bytes.fromhex(salt_dict['exp@KRBTEST.COM']).decode('ascii')
166
167 # Create a keytab using ktutil addent with the specified options and
168 # password "pw".  Test that we can use it to get initial tickets.
169 # Remove the keytab afterwards.
170 def test_addent(realm, princ, opts):
171     realm.run([ktutil], input=('addent -password -p %s -k 1 %s\npw\nwkt %s\n' %
172                                (princ, opts, realm.keytab)))
173     realm.kinit(princ, flags=['-k'])
174     os.remove(realm.keytab)
175
176 mark('ktutil addent')
177
178 # Test with default salt.
179 test_addent(realm, 'default', '-e aes128-cts')
180 test_addent(realm, 'default', '-e aes256-cts')
181
182 # Test with a salt specified to ktutil addent.
183 test_addent(realm, 'exp', '-e aes256-cts -s %s' % exp_salt)
184
185 # Test etype-info fetching.
186 test_addent(realm, 'default', '-f')
187 test_addent(realm, 'default', '-f -e aes128-cts')
188 test_addent(realm, 'exp', '-f')
189 test_addent(realm, 'pexp', '-f')
190 test_addent(realm, 'afs', '-f')
191 test_addent(realm, 'pafs', '-f')
192
193 success('Keytab-related tests')
194 success('Keytab-related tests')