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