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