Path: blob/main/crypto/krb5/src/tests/gssapi/t_gssapi.py
34889 views
from k5test import *12# Test krb5 negotiation under SPNEGO for all enctype configurations. Also3# test IOV wrap/unwrap with and without SPNEGO.4for realm in multipass_realms():5realm.run(['./t_spnego','p:' + realm.host_princ, realm.keytab])6realm.run(['./t_iov', 'p:' + realm.host_princ])7realm.run(['./t_iov', '-s', 'p:' + realm.host_princ])8realm.run(['./t_pcontok', 'p:' + realm.host_princ])910realm = K5Realm()11realm.run([kadminl, 'modprinc', '+preauth', realm.user_princ])1213remove_default = {'libdefaults': {'default_realm': None}}14change_default = {'libdefaults': {'default_realm': 'WRONG.REALM'}}15no_default = realm.special_env('no_default', False, krb5_conf=remove_default)16wrong_default = realm.special_env('wrong_default', False,17krb5_conf=change_default)1819# Test IAKERB with credentials.20realm.run(['./t_iakerb', 'p:' + realm.user_princ, '-', 'h:host@' + hostname,21'h:host'])2223# Test IAKERB getting initial credentials.24realm.run(['./t_iakerb', 'p:' + realm.user_princ, password('user'),25'h:host@' + hostname, 'h:host'])2627# Test IAKERB realm discovery.28realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,29'h:host'])3031# Test IAKERB realm discovery without default_realm set. We get an32# error because the acceptor does not know the realm.33realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,34'h:host'], env=no_default, expected_code=1,35expected_msg='The IAKERB proxy could not determine its realm')3637# Test again, using a GSS_KRB5_NT_PRINCIPAL_NAME acceptor name so that38# gss_accept_sec_context() knows the realm.39realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,40'p:' + realm.host_princ], env=no_default)4142# Test IAKERB realm discovery with a non-useful default_realm set.43realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname,44'p:' + realm.host_princ], env=wrong_default)4546# Test gss_add_cred().47realm.run(['./t_add_cred'])4849### Test acceptor name behavior.5051# Create some host-based principals and put most of them into the52# keytab. Rename one principal so that the keytab name matches the53# key but not the client name.54realm.run([kadminl, 'addprinc', '-randkey', 'service1/abraham'])55realm.run([kadminl, 'addprinc', '-randkey', 'service1/barack'])56realm.run([kadminl, 'addprinc', '-randkey', 'service2/calvin'])57realm.run([kadminl, 'addprinc', '-randkey', 'service2/dwight'])58realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-'])59realm.run([kadminl, 'addprinc', '-randkey', 'http/localhost'])60realm.run([kadminl, 'xst', 'service1/abraham'])61realm.run([kadminl, 'xst', 'service1/barack'])62realm.run([kadminl, 'xst', 'service2/calvin'])63realm.run([kadminl, 'xst', 'http/localhost'])64realm.run([kadminl, 'renprinc', 'service1/abraham', 'service1/andrew'])6566# Test with no default realm and no dots in the server name.67realm.run(['./t_accname', 'h:http@localhost'], expected_msg='http/localhost')68realm.run(['./t_accname', 'h:http@localhost'], expected_msg='http/localhost',69env=no_default)7071# Test with no acceptor name, including client/keytab principal72# mismatch (non-fatal) and missing keytab entry (fatal).73realm.run(['./t_accname', 'p:service1/andrew'],74expected_msg='service1/abraham')75realm.run(['./t_accname', 'p:service1/barack'], expected_msg='service1/barack')76realm.run(['./t_accname', 'p:service2/calvin'], expected_msg='service2/calvin')77realm.run(['./t_accname', 'p:service2/dwight'], expected_code=1,78expected_msg=' not found in keytab')7980# Test with acceptor name containing service only, including81# client/keytab hostname mismatch (non-fatal) and service name82# mismatch (fatal).83realm.run(['./t_accname', 'p:service1/andrew', 'h:service1'],84expected_msg='service1/abraham')85realm.run(['./t_accname', 'p:service1/andrew', 'h:service2'], expected_code=1,86expected_msg=' not found in keytab')87realm.run(['./t_accname', 'p:service2/calvin', 'h:service2'],88expected_msg='service2/calvin')89realm.run(['./t_accname', 'p:service2/calvin', 'h:service1'], expected_code=1,90expected_msg=' found in keytab but does not match server principal')91# Regression test for #8892 (trailing @ in name).92realm.run(['./t_accname', 'p:service1/andrew', 'h:service1@'],93expected_msg='service1/abraham')9495# Test with acceptor name containing service and host. Use the96# client's un-canonicalized hostname as acceptor input to mirror what97# many servers do.98realm.run(['./t_accname', 'p:' + realm.host_princ,99'h:host@%s' % socket.gethostname()], expected_msg=realm.host_princ)100realm.run(['./t_accname', 'p:host/-nomatch-',101'h:host@%s' % socket.gethostname()], expected_code=1,102expected_msg=' not found in keytab')103104# If possible, test with an acceptor name requiring fallback to match105# against a keytab entry.106canonname = canonicalize_hostname(hostname)107if canonname != hostname:108os.rename(realm.keytab, realm.keytab + '.save')109canonprinc = 'host/' + canonname110realm.run([kadminl, 'addprinc', '-randkey', canonprinc])111realm.extract_keytab(canonprinc, realm.keytab)112# Use the canonical name for the initiator's target name, since113# host/hostname exists in the KDB (but not the keytab).114realm.run(['./t_accname', 'h:host@' + canonname, 'h:host@' + hostname])115os.rename(realm.keytab + '.save', realm.keytab)116else:117skipped('GSS acceptor name fallback test',118'%s does not canonicalize to a different name' % hostname)119120# Test krb5_gss_import_cred.121realm.run(['./t_imp_cred', 'p:service1/barack'])122realm.run(['./t_imp_cred', 'p:service1/barack', 'service1/barack'])123realm.run(['./t_imp_cred', 'p:service1/andrew', 'service1/abraham'])124realm.run(['./t_imp_cred', 'p:service2/dwight'], expected_code=1,125expected_msg=' not found in keytab')126127# Verify that we can't acquire acceptor creds without a keytab.128os.remove(realm.keytab)129out = realm.run(['./t_accname', 'p:abc'], expected_code=1)130if ('gss_acquire_cred: Keytab' not in out or131'nonexistent or empty' not in out):132fail('Expected error message not seen for nonexistent keytab')133134realm.stop()135136# Re-run the last acceptor name test with ignore_acceptor_hostname set137# and the principal for the mismatching hostname in the keytab.138ignore_conf = {'libdefaults': {'ignore_acceptor_hostname': 'true'}}139realm = K5Realm(krb5_conf=ignore_conf)140realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-'])141realm.run([kadminl, 'xst', 'host/-nomatch-'])142realm.run(['./t_accname', 'p:host/-nomatch-',143'h:host@%s' % socket.gethostname()], expected_msg='host/-nomatch-')144145realm.stop()146147# Make sure a GSSAPI acceptor can handle cross-realm tickets with a148# transited field. (Regression test for #7639.)149r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)),150create_user=False, create_host=False,151args=[{'realm': 'A.X', 'create_user': True},152{'realm': 'X'},153{'realm': 'B.X', 'create_host': True}])154os.rename(r3.keytab, r1.keytab)155r1.run(['./t_accname', 'p:' + r3.host_princ, 'h:host'])156r1.stop()157r2.stop()158r3.stop()159160### Test gss_inquire_cred behavior.161162realm = K5Realm()163164# Test deferred resolution of the default ccache for initiator creds.165realm.run(['./t_inq_cred'], expected_msg=realm.user_princ)166realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ)167realm.run(['./t_inq_cred', '-s'], expected_msg=realm.user_princ)168169# Test picking a name from the keytab for acceptor creds.170realm.run(['./t_inq_cred', '-a'], expected_msg=realm.host_princ)171realm.run(['./t_inq_cred', '-k', '-a'], expected_msg=realm.host_princ)172realm.run(['./t_inq_cred', '-s', '-a'], expected_msg=realm.host_princ)173174# Test client keytab initiation (non-deferred) with a specified name.175realm.extract_keytab(realm.user_princ, realm.client_keytab)176os.remove(realm.ccache)177realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ)178179# Test deferred client keytab initiation and GSS_C_BOTH cred usage.180os.remove(realm.client_keytab)181os.remove(realm.ccache)182shutil.copyfile(realm.keytab, realm.client_keytab)183realm.run(['./t_inq_cred', '-k', '-b'], expected_msg=realm.host_princ)184185# Test gss_export_name behavior.186realm.run(['./t_export_name', 'u:x'], expected_msg=\187'0401000B06092A864886F7120102020000000D78404B5242544553542E434F4D\n')188realm.run(['./t_export_name', '-s', 'u:xyz'],189expected_msg='0401000806062B06010505020000000378797A\n')190realm.run(['./t_export_name', 'p:a@b'],191expected_msg='0401000B06092A864886F71201020200000003614062\n')192realm.run(['./t_export_name', '-s', 'p:a@b'],193expected_msg='0401000806062B060105050200000003614062\n')194195# Test that composite-export tokens can be imported.196realm.run(['./t_export_name', '-c', 'p:a@b'], expected_msg=197'0402000B06092A864886F7120102020000000361406200000000\n')198199# Test gss_inquire_mechs_for_name behavior.200krb5_mech = '{ 1 2 840 113554 1 2 2 }'201spnego_mech = '{ 1 3 6 1 5 5 2 }'202out = realm.run(['./t_inq_mechs_name', 'p:a@b'])203if krb5_mech not in out:204fail('t_inq_mechs_name (principal)')205out = realm.run(['./t_inq_mechs_name', 'u:x'])206if krb5_mech not in out or spnego_mech not in out:207fail('t_inq_mecs_name (user)')208out = realm.run(['./t_inq_mechs_name', 'h:host'])209if krb5_mech not in out or spnego_mech not in out:210fail('t_inq_mecs_name (hostbased)')211212# Test that accept_sec_context can produce an error token and213# init_sec_context can interpret it.214realm.run(['./t_err', 'p:' + realm.host_princ])215realm.run(['./t_err', '--spnego', 'p:' + realm.host_princ])216217# Test the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option.218realm.run(['./t_ciflags', 'p:' + realm.host_princ])219220# Test that inquire_context works properly, even on incomplete221# contexts.222realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ])223224if runenv.sizeof_time_t <= 4:225skip_rest('y2038 GSSAPI tests', 'platform has 32-bit time_t')226227# Test lifetime results, using a realm with a large maximum lifetime228# so that we can test ticket end dates after y2038.229realm.stop()230conf = {'realms': {'$realm': {'max_life': '9000d'}}}231realm = K5Realm(kdc_conf=conf, get_creds=False)232233# Check a lifetime string result against an expected number value (or None).234# Allow some variance due to time elapsed during the tests.235def check_lifetime(msg, val, expected):236if expected is None and val != 'indefinite':237fail('%s: expected indefinite, got %s' % (msg, val))238if expected is not None and val == 'indefinite':239fail('%s: expected %d, got indefinite' % (msg, expected))240if expected is not None and abs(int(val) - expected) > 100:241fail('%s: expected %d, got %s' % (msg, expected, val))242243realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d'])244out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)])245ln = out.split('\n')246check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400)247check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400)248check_lifetime('acred gss_acquire_cred', ln[2], None)249check_lifetime('acred gss_inquire_cred', ln[3], None)250check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400)251check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400)252check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400)253check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300)254check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300)255check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300)256257success('GSSAPI tests')258259260