From: Greg Hudson Date: Wed, 18 Apr 2018 23:21:56 +0000 (-0400) Subject: Add marks to longer Python test scripts X-Git-Tag: krb5-1.17-beta1~139 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0879b7d506c0a1bb77c85d7499a55d91743ad9a8;p=thirdparty%2Fkrb5.git Add marks to longer Python test scripts --- diff --git a/src/appl/gss-sample/t_gss_sample.py b/src/appl/gss-sample/t_gss_sample.py index 0299e45904..c053b27808 100755 --- a/src/appl/gss-sample/t_gss_sample.py +++ b/src/appl/gss-sample/t_gss_sample.py @@ -95,22 +95,26 @@ def kt_test(realm, options, server_options=[]): for realm in multipass_realms(): ccache_save(realm) + mark('TGS') tgs_test(realm, ['-krb5']) tgs_test(realm, ['-spnego']) tgs_test(realm, ['-iakerb'], ['-iakerb']) # test default (i.e., krb5) mechanism with GSS_C_DCE_STYLE tgs_test(realm, ['-dce']) + mark('pw') pw_test(realm, ['-krb5']) pw_test(realm, ['-spnego']) pw_test(realm, ['-iakerb'], ['-iakerb']) pw_test(realm, ['-dce']) + mark('wrong pw') wrong_pw_test(realm, ['-krb5']) wrong_pw_test(realm, ['-spnego']) wrong_pw_test(realm, ['-iakerb'], ['-iakerb'], True) wrong_pw_test(realm, ['-dce']) + mark('client keytab') realm.extract_keytab(realm.user_princ, realm.client_keytab) kt_test(realm, ['-krb5']) kt_test(realm, ['-spnego']) diff --git a/src/lib/krb5/ccache/t_cccol.py b/src/lib/krb5/ccache/t_cccol.py index f7f1785647..0d78b5cfe7 100755 --- a/src/lib/krb5/ccache/t_cccol.py +++ b/src/lib/krb5/ccache/t_cccol.py @@ -81,20 +81,24 @@ def cursor_test(testname, args, expected): 'Expected output:\n\n' + '\n'.join(expected) + '\n\n' + 'Actual output:\n\n' + '\n'.join(outlines)) +mark('FILE cursor') fccname = 'FILE:%s' % realm.ccache cursor_test('file-default', [], [fccname]) cursor_test('file-default2', [realm.ccache], [fccname]) cursor_test('file-default3', [fccname], [fccname]) +mark('DIR cursor') cursor_test('dir', [dccname], [duser, dalice, dbob]) cursor_test('dir-subsidiary', [duser], [duser]) cursor_test('dir-nofile', [dnoent], []) if test_keyring: + mark('KEYRING cursor') cursor_test('keyring', [krccname], [kruser, kralice, krbob]) cursor_test('keyring-subsidiary', [kruser], [kruser]) cursor_test('keyring-noent', [krnoent], []) +mark('MEMORY cursor') mfoo = 'MEMORY:foo' mbar = 'MEMORY:bar' cursor_test('filemem', [fccname, mfoo, mbar], [fccname, mfoo, mbar]) @@ -103,6 +107,7 @@ if test_keyring: cursor_test('keyringmem', [krccname, mfoo], [kruser, kralice, krbob, mfoo]) # Test krb5_cccol_have_content. +mark('krb5_cccol_have_content') realm.run(['./t_cccursor', dccname, 'CONTENT']) realm.run(['./t_cccursor', fccname, 'CONTENT']) realm.run(['./t_cccursor', realm.ccache, 'CONTENT']) @@ -112,6 +117,7 @@ if test_keyring: cleanup_keyring('@s', col_ringname) # Make sure FILE doesn't yield a nonexistent default cache. +mark('FILE nonexistent') realm.run([kdestroy]) cursor_test('noexist', [], []) realm.run(['./t_cccursor', fccname, 'CONTENT'], expected_code=1) diff --git a/src/lib/krb5/krb/t_vfy_increds.py b/src/lib/krb5/krb/t_vfy_increds.py index c820cc690d..1e8e262247 100755 --- a/src/lib/krb5/krb/t_vfy_increds.py +++ b/src/lib/krb5/krb/t_vfy_increds.py @@ -27,17 +27,20 @@ from k5test import * realm = K5Realm() # Verify the default test realm credentials with the default keytab. +mark('default keytab') realm.run(['./t_vfy_increds']) realm.run(['./t_vfy_increds', '-n']) # Verify after updating the keytab (so the keytab contains an outdated # version 1 key followed by an up-to-date version 2 key). +mark('updated keytab') realm.run([kadminl, 'ktadd', realm.host_princ]) realm.run(['./t_vfy_increds']) realm.run(['./t_vfy_increds', '-n']) # Bump the host key without updating the keytab and make sure that # verification fails as we expect it to. +mark('outdated keytab') realm.run([kadminl, 'change_password', '-randkey', realm.host_princ]) realm.run(['./t_vfy_increds'], expected_code=1) realm.run(['./t_vfy_increds', '-n'], expected_code=1) @@ -47,6 +50,7 @@ realm.run(['./t_vfy_increds', '-n'], expected_code=1) # matches. Verify after updating the keytab with a host service # principal that has hostname that doesn't match the host running the # test. Verify should succeed, with or without nofail. +mark('hostname mismatch') realm.run([kadminl, 'addprinc', '-randkey', 'host/wrong.hostname']) realm.run([kadminl, 'ktadd', 'host/wrong.hostname']) realm.run(['./t_vfy_increds']) @@ -54,6 +58,7 @@ realm.run(['./t_vfy_increds', '-n']) # Remove the keytab and verify again. This should succeed if nofail # is not set, and fail if it is set. +mark('no keytab') os.remove(realm.keytab) realm.run(['./t_vfy_increds']) realm.run(['./t_vfy_increds', '-n'], expected_code=1) @@ -65,6 +70,7 @@ realm.run(['./t_vfy_increds', '-n'], expected_code=1) # set. (An empty keytab file appears as corrupt to keytab calls, # causing a KRB5_KEYTAB_BADVNO error, so any tightening of the # krb5_verify_init_creds semantics needs to take this into account.) +mark('empty keytab') open(realm.keytab, 'w').close() realm.run(['./t_vfy_increds']) realm.run(['./t_vfy_increds', '-n'], expected_code=1) @@ -73,6 +79,7 @@ os.remove(realm.keytab) # Add an NFS service principal to keytab. Verify should ignore it by # default (succeeding unless nofail is set), but should verify with it # when it is specifically requested. +mark('keytab with NFS principal') realm.run([kadminl, 'addprinc', '-randkey', realm.nfs_princ]) realm.run([kadminl, 'ktadd', realm.nfs_princ]) realm.run(['./t_vfy_increds']) @@ -83,6 +90,7 @@ realm.run(['./t_vfy_increds', '-n', realm.nfs_princ]) # Invalidating the NFS keys in the keytab. We should get the same # results with the default principal argument, but verification should # now fail if we request it specifically. +mark('keytab with outdated NFS principal') realm.run([kadminl, 'change_password', '-randkey', realm.nfs_princ]) realm.run(['./t_vfy_increds']) realm.run(['./t_vfy_increds', '-n'], expected_code=1) @@ -91,6 +99,7 @@ realm.run(['./t_vfy_increds', '-n', realm.nfs_princ], expected_code=1) # Spot-check that verify_ap_req_nofail works equivalently to the # programmatic nofail option. +mark('verify_ap_req_nofail') realm.stop() conf = {'libdefaults': {'verify_ap_req_nofail': 'true'}} realm = K5Realm(krb5_conf=conf) diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py index 8a577b4b18..eef701ad43 100644 --- a/src/tests/t_authdata.py +++ b/src/tests/t_authdata.py @@ -10,12 +10,14 @@ realm = K5Realm(krb5_conf=conf) # With no requested authdata, we expect to see SIGNTICKET (512) in an # if-relevant container and the greet authdata in a kdc-issued # container. +mark('baseline authdata') out = realm.run(['./adata', realm.host_princ]) if '?512: ' not in out or '^-42: Hello' not in out: fail('expected authdata not seen for basic request') # Requested authdata is copied into the ticket, with KDC-only types # filtered out. (128 is win2k-pac, which should be filtered.) +mark('request authdata') out = realm.run(['./adata', realm.host_princ, '-5', 'test1', '?-6', 'test2', '128', 'fakepac', '?128', 'ifrelfakepac', '^-8', 'fakekdcissued', '?^-8', 'ifrelfakekdcissued']) @@ -24,11 +26,13 @@ if ' -5: test1' not in out or '?-6: test2' not in out: if 'fake' in out: fail('KDC-only authdata not filtered for request with authdata') +mark('AD-MANDATORY-FOR-KDC') realm.run(['./adata', realm.host_princ, '!-1', 'mandatoryforkdc'], expected_code=1, expected_msg='KDC policy rejects request') # The no_auth_data_required server flag should suppress SIGNTICKET, # but not module or request authdata. +mark('no_auth_data_required server flag') realm.run([kadminl, 'ank', '-randkey', '+no_auth_data_required', 'noauth']) realm.extract_keytab('noauth', realm.keytab) out = realm.run(['./adata', 'noauth', '-2', 'test']) @@ -39,6 +43,7 @@ if '512: ' in out: # Cross-realm TGT requests should also suppress SIGNTICKET, but not # module or request authdata. +mark('cross-realm') realm.addprinc('krbtgt/XREALM') realm.extract_keytab('krbtgt/XREALM', realm.keytab) out = realm.run(['./adata', 'krbtgt/XREALM', '-3', 'test']) @@ -67,6 +72,7 @@ else: # SIGNTICKET and module authdata should be suppressed for # anonymous tickets, but not request authdata. + mark('anonymous') out = realm.run(['./adata', realm.host_princ, '-4', 'test']) if ' -4: test' not in out: fail('expected authdata not seen for anonymous request') @@ -95,37 +101,45 @@ realm2.extract_keytab(realm2.host_princ, realm.keytab) realm2.extract_keytab('krbtgt/LOCAL', realm.keytab) # AS request to local-realm service +mark('AS-REQ to local service auth indicator') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl', '-r', '2d', '-S', realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Ticket modification request +mark('ticket modification auth indicator') realm.kinit(realm.user_princ, None, ['-R', '-S', realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # AS request to cross TGT +mark('AS-REQ to cross TGT auth indicator') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl', '-S', 'krbtgt/FOREIGN']) realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]') # Multiple indicators +mark('AS multiple indicators') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl indcl2 indcl3']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl, indcl2, indcl3]') # AS request to local TGT (resulting creds are used for TGS tests) +mark('AS-REQ to local TGT auth indicator') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl]') # Local TGS request for local realm service +mark('TGS-REQ to local service auth indicator') realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Local TGS request for cross TGT service +mark('TGS-REQ to cross TGT auth indicator') realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]') # We don't yet have support for passing auth indicators across realms, # so just verify that indicators don't survive cross-realm requests. +mark('TGS-REQ to foreign service auth indicator') out = realm.run(['./adata', realm2.krbtgt_princ]) if '97:' in out: fail('auth-indicator seen in cross TGT request to local TGT') @@ -137,10 +151,12 @@ if '97:' in out: fail('auth-indicator seen in cross TGT request to service') # Test that the CAMMAC signature still works during a krbtgt rollover. +mark('CAMMAC signature across krbtgt rollover') realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.krbtgt_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Test indicator enforcement. +mark('auth indicator enforcement') realm.addprinc('restricted') realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'superstrong']) realm.run([kvno, 'restricted'], expected_code=1, @@ -155,6 +171,7 @@ realm.run([kvno, 'restricted']) # Regression test for one manifestation of #8139: ensure that # forwarded TGTs obtained across a TGT re-key still work when the # preferred krbtgt enctype changes. +mark('#8139 regression test') realm.kinit(realm.user_princ, password('user'), ['-f']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'des3-cbc-sha1', realm.krbtgt_princ]) @@ -162,6 +179,7 @@ realm.run(['./forward']) realm.run([kvno, realm.host_princ]) # Repeat the above test using a renewed TGT. +mark('#8139 regression test (renewed TGT)') realm.kinit(realm.user_princ, password('user'), ['-r', '2d']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes128-cts', realm.krbtgt_princ]) @@ -195,6 +213,7 @@ realm.extract_keytab('noauthdata', realm.keytab) realm.start_kdc() # S4U2Self (should have no indicators since client did not authenticate) +mark('S4U2Self (no auth indicators expected)') realm.kinit('service/1', None, ['-k', '-f', '-X', 'indicators=inds1']) realm.run([kvno, '-U', 'user', 'service/1']) out = realm.run(['./adata', '-p', realm.user_princ, 'service/1']) @@ -202,6 +221,7 @@ if '97:' in out: fail('auth-indicator present in S4U2Self response') # S4U2Proxy (indicators should come from evidence ticket, not TGT) +mark('S4U2Proxy (auth indicators from evidence ticket expected)') realm.kinit(realm.user_princ, None, ['-k', '-f', '-X', 'indicators=indcl', '-S', 'service/1', '-c', usercache]) realm.run(['./s4u2proxy', usercache, 'service/2']) @@ -211,6 +231,7 @@ if '+97: [indcl]' not in out or '[inds1]' in out: # Test that KDB module authdata is included in an AS request, by # default or with an explicit PAC request. +mark('AS-REQ KDB module authdata') realm.kinit(realm.user_princ, None, ['-k']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='-456: db-authdata-test') @@ -220,16 +241,19 @@ realm.run(['./adata', realm.krbtgt_princ], # Test that KDB module authdata is suppressed in an AS request by a # negative PAC request. +mark('AS-REQ KDB module authdata client supression') realm.kinit(realm.user_princ, None, ['-k', '--no-request-pac']) out = realm.run(['./adata', realm.krbtgt_princ]) if '-456: db-authdata-test' in out: fail('DB authdata not suppressed by --no-request-pac') # Test that KDB authdata is included in a TGS request by default. +mark('TGS-REQ KDB authdata') realm.run(['./adata', 'service/1'], expected_msg='-456: db-authdata-test') # Test that KDB authdata is suppressed in a TGS request by the # +no_auth_data_required flag. +mark('TGS-REQ KDB authdata service suppression') out = realm.run(['./adata', 'noauthdata']) if '-456: db-authdata-test' in out: fail('DB authdata not suppressed by +no_auth_data_required') diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py index 61d549b7b6..4ddb83a2f0 100755 --- a/src/tests/t_ccache.py +++ b/src/tests/t_ccache.py @@ -34,14 +34,17 @@ if not test_keyring: skipped('keyring ccache tests', 'keyring support not built') # Test kdestroy and klist of a non-existent ccache. +mark('no ccache') realm.run([kdestroy]) realm.run([klist], expected_code=1, expected_msg='No credentials cache found') # Test kinit with an inaccessible ccache. +mark('inaccessible ccache') realm.kinit(realm.user_princ, password('user'), flags=['-c', 'testdir/xx/yy'], expected_code=1, expected_msg='Failed to store credentials') # Test klist -s with a single ccache. +mark('klist -s single ccache') realm.run([klist, '-s'], expected_code=1) realm.kinit(realm.user_princ, password('user')) realm.run([klist, '-s']) @@ -57,9 +60,11 @@ realm.addprinc('bob', password('bob')) realm.addprinc('carol', password('carol')) def collection_test(realm, ccname): + cctype = ccname.partition(':')[0] oldccname = realm.env['KRB5CCNAME'] realm.env['KRB5CCNAME'] = ccname + mark('%s collection, single cache' % cctype) realm.run([klist, '-A', '-s'], expected_code=1) realm.kinit('alice', password('alice')) realm.run([klist], expected_msg='Default principal: alice@') @@ -73,6 +78,7 @@ def collection_test(realm, ccname): fail('Initial kdestroy failed to empty cache collection.') realm.run([klist, '-A', '-s'], expected_code=1) + mark('%s collection, multiple caches' % cctype) realm.kinit('alice', password('alice')) realm.kinit('carol', password('carol')) output = realm.run([klist, '-l']) @@ -96,6 +102,7 @@ def collection_test(realm, ccname): # (only works with klist/kdestroy for now, not kinit/kswitch). realm.env['KRB5CCNAME'] = oldccname + mark('%s collection, command-line specifier' % cctype) realm.run([kdestroy, '-c', ccname]) output = realm.run([klist, '-l', ccname]) if 'carol@' in output or 'bob@' not in output or output.count('\n') != 4: @@ -127,6 +134,7 @@ if test_keyring: cleanup_keyring('@s', col_ringname) # Test legacy keyring cache linkage. + mark('legacy keyring cache linkage') realm.env['KRB5CCNAME'] = 'KEYRING:' + cname realm.run([kdestroy, '-A']) realm.kinit(realm.user_princ, password('user')) @@ -150,6 +158,7 @@ if test_keyring: cleanup_keyring('@s', col_ringname) # Test parameter expansion in default_ccache_name +mark('default_ccache_name parameter expansion') realm.stop() conf = {'libdefaults': {'default_ccache_name': 'testdir/%{null}abc%{uid}'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) diff --git a/src/tests/t_crossrealm.py b/src/tests/t_crossrealm.py index 4d595dca63..cd7f4aaca1 100755 --- a/src/tests/t_crossrealm.py +++ b/src/tests/t_crossrealm.py @@ -61,6 +61,7 @@ def tgt(r1, r2): # Basic two-realm test with cross TGTs in both directions. +mark('two realms') r1, r2 = cross_realms(2) test_kvno(r1, r2.host_princ, 'basic r1->r2') check_klist(r1, (tgt(r1, r1), tgt(r2, r1), r2.host_princ)) @@ -72,6 +73,7 @@ stop(r1, r2) # client in A.X will ask for a cross TGT to B.X, but A.X's KDC only # has a TGT for the intermediate realm X, so it will return that # instead. The client will use that to get a TGT for B.X. +mark('hierarchical realms') r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A.X'}, {'realm': 'X'}, {'realm': 'B.X'})) @@ -84,6 +86,7 @@ stop(r1, r2, r3) # The client will walk its A->D capaths to get TGTs for B, then C, # then D. The KDCs for C and D need capaths settings to avoid failing # transited checks, including a capaths for A->C. +mark('client capaths') capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A'}, @@ -99,6 +102,7 @@ stop(r1, r2, r3, r4) # Test KDC capaths. The KDCs for A and B have appropriate capaths # settings to determine intermediate TGTs to return, but the client # has no idea. +mark('kdc capaths') capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}, 'B': {'D': 'C'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A', 'krb5_conf': capaths}, @@ -111,6 +115,7 @@ stop(r1, r2, r3, r4) # A capaths value of '.' should enforce direct cross-realm, with no # intermediate. +mark('direct cross-realm enforcement') capaths = {'capaths': {'A.X': {'B.X': '.'}}} r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A.X', 'krb5_conf': capaths}, @@ -122,6 +127,7 @@ stop(r1, r2, r3) # Test transited error. The KDC for C does not recognize B as an # intermediate realm for A->C, so it refuses to issue a service # ticket. +mark('transited error (three realms)') capaths = {'capaths': {'A': {'C': 'B'}}} r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A', 'krb5_conf': capaths}, @@ -134,6 +140,7 @@ stop(r1, r2, r3) # Test a different kind of transited error. The KDC for D does not # recognize B as an intermediate realm for A->C, so it refuses to # verify the krbtgt/C@B ticket in the TGS AP-REQ. +mark('transited error (four realms)') capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}, 'B': {'D': 'C'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A', 'krb5_conf': capaths}, diff --git a/src/tests/t_dump.py b/src/tests/t_dump.py index 8a9462bd8e..2a424d9493 100755 --- a/src/tests/t_dump.py +++ b/src/tests/t_dump.py @@ -25,6 +25,7 @@ f.close() # Destroy and load the database; check that the policies exist. # Spot-check principal and policy fields. +mark('reload after dump') realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load', dumpfile]) out = realm.run([kadminl, 'getprincs']) @@ -42,6 +43,7 @@ realm.run([kadminl, 'getpol', 'barney'], expected_msg='Number of old keys kept: 1') # Dump/load again, and make sure everything is still there. +mark('second reload') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile]) out = realm.run([kadminl, 'getprincs']) @@ -64,6 +66,7 @@ realm.run([kdb5_util, 'load', srcdump]) realm.run([kdb5_util, 'stash', '-P', 'master']) def dump_compare(realm, opt, srcfile): + mark('dump comparison against %s' % os.path.basename(srcfile)) realm.run([kdb5_util, 'dump'] + opt + [dumpfile]) if not cmp(srcfile, dumpfile, False): fail('Dump output does not match %s' % srcfile) @@ -77,6 +80,7 @@ dump_compare(realm, ['-b7'], srcdump_b7) dump_compare(realm, ['-ov'], srcdump_ov) def load_dump_check_compare(realm, opt, srcfile): + mark('load check from %s' % os.path.basename(srcfile)) realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load'] + opt + [srcfile]) realm.run([kadminl, 'getprincs'], expected_msg='user@') diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py index b2eb0f7aff..00113aaa52 100644 --- a/src/tests/t_etype_info.py +++ b/src/tests/t_etype_info.py @@ -16,6 +16,7 @@ realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser']) # Run the test harness for the given principal and request enctype # list. Compare the output to the expected lines, ignoring order. def test_etinfo(princ, enctypes, expected_lines): + mark('etinfo test: %s %s' % (princ.partition('@')[0], enctypes)) lines = realm.run(['./etinfo', princ, enctypes]).splitlines() if sorted(lines) != sorted(expected_lines): fail('Unexpected output for princ %s, etypes %s' % (princ, enctypes)) @@ -75,6 +76,7 @@ test_etinfo('nokeyuser', 'des3', []) # Verify that etype-info2 is included in a MORE_PREAUTH_DATA_REQUIRED # error if the client does optimistic preauth. +mark('MORE_PREAUTH_DATA_REQUIRED test') realm.stop() testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, diff --git a/src/tests/t_general.py b/src/tests/t_general.py index 91ad0cb8a0..3490d28bba 100755 --- a/src/tests/t_general.py +++ b/src/tests/t_general.py @@ -3,15 +3,18 @@ from k5test import * for realm in multipass_realms(create_host=False): # Check that kinit fails appropriately with the wrong password. + mark('kinit wrong password failure') msg = 'Password incorrect while getting initial credentials' realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg=msg) # Check that we can kinit as a different principal. + mark('kinit with specified principal') realm.kinit(realm.admin_princ, password('admin')) realm.klist(realm.admin_princ) # Test FAST kinit. + mark('FAST kinit') fastpw = password('fast') realm.run([kadminl, 'ank', '-pw', fastpw, '+requires_preauth', 'user/fast']) @@ -25,6 +28,7 @@ for realm in multipass_realms(create_host=False): # Test that we can get initial creds with an empty password via the # API. We have to disable the "empty" pwqual module to create a # principal with an empty password. (Regression test for #7642.) +mark('initial creds with empty password') conf={'plugins': {'pwqual': {'disable': 'empty'}}} realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf) realm.run([kadminl, 'addprinc', '-pw', '', 'user']) @@ -36,16 +40,19 @@ realm = K5Realm(create_host=False) # Regression test for #8454 (responder callback isn't used when # preauth is not required). +mark('#8454 regression test') realm.run(['./responder', '-r', 'password=%s' % password('user'), realm.user_princ]) # Test that WRONG_REALM responses aren't treated as referrals unless # they contain a crealm field pointing to a different realm. # (Regression test for #8060.) +mark('#8060 regression test') realm.run([kinit, '-C', 'notfoundprinc'], expected_code=1, expected_msg='not found in Kerberos database') # Spot-check KRB5_TRACE output +mark('KRB5_TRACE spot check') expected_trace = ('Sending initial UDP request', 'Received answer', 'Selected etype info', diff --git a/src/tests/t_hostrealm.py b/src/tests/t_hostrealm.py index 224c067ef4..c14c9267e0 100755 --- a/src/tests/t_hostrealm.py +++ b/src/tests/t_hostrealm.py @@ -42,6 +42,7 @@ def testd_error(realm, expected_error, msg, env=None): # The test2 module returns a fatal error on hosts beginning with 'z', # and an answer on hosts begining with 'a'. +mark('test2 module') testh_error(realm, 'zoo', 'service not available', 'host_realm test2 z') testh(realm, 'abacus', ['a'], 'host_realm test2 a') @@ -49,6 +50,7 @@ testh(realm, 'abacus', ['a'], 'host_realm test2 a') # 'X', due to [domain_realms]. There is also an entry for hostnames # ending in '1', but hostnames which appear to be IP or IPv6 addresses # should instead fall through to test1. +mark('profile module') testh(realm, 'x', ['MATCH'], 'host_realm profile x') testh(realm, '.x', ['DOTMATCH'], 'host_realm profile .x') testh(realm, 'b.x', ['DOTMATCH'], 'host_realm profile b.x') @@ -60,9 +62,11 @@ testh(realm, 'b:c.x', ['b:c', 'x'], 'host_realm profile b:c.x') testh(realm, 'X.', ['MATCH'], 'host_realm profile X.') # The test1 module returns a list of the hostname components. +mark('test1 module') testh(realm, 'b.c.d', ['b', 'c', 'd'], 'host_realm test1') # If no module returns a result, we should get the referral realm. +mark('no result') testh(realm, '', [''], 'host_realm referral realm') ### @@ -76,10 +80,12 @@ def try_env(realm, testname, n): # The domain module will answer with the uppercased parent domain, # with no special configuration. +mark('fallback: domain module') testf(realm, 'a.b.c', ['B.C'], 'fallback_realm domain a.b.c') # With realm_try_domains = 0, the hostname itself will be looked up as # a realm and returned if found. +mark('fallback: realm_try_domains = 0') try0 = try_env(realm, 'try0', 0) testf(realm, 'krbtest.com', ['KRBTEST.COM'], 'fallback_realm try0', env=try0) testf(realm, 'a.b.krbtest.com', ['B.KRBTEST.COM'], @@ -88,6 +94,7 @@ testf(realm, 'a.b.c', ['B.C'], 'fallback_realm try0 nomatch', env=try0) # With realm_try_domains = 2, the parent and grandparent will be # checked as well, but it stops there. +mark('fallback: realm_try_domains = 2') try2 = try_env(realm, 'try2', 2) testf(realm, 'krbtest.com', ['KRBTEST.COM'], 'fallback_realm try2', env=try2) testf(realm, 'a.b.krbtest.com', ['KRBTEST.COM'], @@ -97,10 +104,12 @@ testf(realm, 'a.b.c.krbtest.com', ['B.C.KRBTEST.COM'], # The test1 module answers with a list of components. Use an IPv4 # address to bypass the domain module. +mark('fallback: test1 module') testf(realm, '1.2.3.4', ['1', '2', '3', '4'], 'fallback_realm test1') # If no module answers, the default realm is returned. The test2 # module returns an error when we try to look that up. +mark('fallback: default realm') testf_error(realm, '', 'service not available', 'fallback_realm default') ### @@ -108,10 +117,12 @@ testf_error(realm, '', 'service not available', 'fallback_realm default') ### # The test2 module returns an error. +mark('default_realm: test2 module') testd_error(realm, 'service not available', 'default_realm test2') # The profile module returns the default realm from the profile. # Disable test2 to expose this behavior. +mark('default_realm: profile module') disable_conf = {'plugins': {'hostrealm': {'disable': 'test2'}}} notest2 = realm.special_env('notest2', False, krb5_conf=disable_conf) testd(realm, 'KRBTEST.COM', 'default_realm profile', env=notest2) @@ -119,6 +130,7 @@ testd(realm, 'KRBTEST.COM', 'default_realm profile', env=notest2) # The test1 module returns a list of two realms, of which we can only # see the first. Remove the profile default_realm setting to expose # this behavior. +mark('default_realm: test1 module') remove_default = {'libdefaults': {'default_realm': None}} nodefault_conf = dict(disable_conf.items() + remove_default.items()) nodefault = realm.special_env('nodefault', False, krb5_conf=nodefault_conf) diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py index 8e23cd5de9..13ef1cab02 100755 --- a/src/tests/t_iprop.py +++ b/src/tests/t_iprop.py @@ -201,6 +201,7 @@ realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) check_ulog(6, 1, 6, [None, pr1, pr3, pr2, pr2, pr2]) # Start kpropd for slave1 and get a full dump from master. +mark('propagate M->1 full') kpropd1 = realm.start_kpropd(slave1, ['-d']) wait_for_prop(kpropd1, True, 1, 6) out = realm.run([kadminl, 'listprincs'], env=slave1) @@ -209,6 +210,7 @@ if pr1 not in out or pr2 not in out or pr3 not in out: check_ulog(1, 6, 6, [None], slave1) # Make a change and check that it propagates incrementally. +mark('propagate M->1 incremental') realm.run([kadminl, 'modprinc', '-allow_tix', pr2]) check_ulog(7, 1, 7, [None, pr1, pr3, pr2, pr2, pr2, pr2]) kpropd1.send_signal(signal.SIGUSR1) @@ -227,6 +229,7 @@ realm.start_server([kadmind, '-r', realm.realm, '-nofork', '-proponly', '-W', '-F', slave1_out_dump_path], 'starting...', slave1m) # Test similar default_realm and domain_realm map settings with -r realm. +mark('propagate 1->3 full') slave3_in_dump_path = os.path.join(realm.testdir, 'dump.slave3.in') kpropd3 = realm.start_server([kpropd, '-d', '-D', '-r', realm.realm, '-P', slave2_kprop_port, '-f', slave3_in_dump_path, @@ -239,6 +242,7 @@ if pr1 not in out or pr2 not in out or pr3 not in out: check_ulog(1, 7, 7, [None], env=slave3) # Test an incremental propagation for the kpropd -r case. +mark('propagate M->1->3 incremental') realm.run([kadminl, 'modprinc', '-maxlife', '20 minutes', pr1]) check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1]) kpropd1.send_signal(signal.SIGUSR1) @@ -254,6 +258,7 @@ realm.run([kadminl, '-r', realm.realm, 'getprinc', pr1], env=slave3, stop_daemon(kpropd3) # Test dissimilar default_realm and domain_realm map settings (no -r realm). +mark('propagate 1->4 full') slave4_in_dump_path = os.path.join(realm.testdir, 'dump.slave4.in') kpropd4 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port, '-f', slave4_in_dump_path, '-p', kdb5_util, @@ -268,6 +273,7 @@ stop_daemon(kpropd4) # talking to the same host as master (we specify it anyway to exercise # the code), but slave2 defines iprop_port to $port8 so it will talk # to slave1. Get a full dump from slave1. +mark('propagate 1->2 full') kpropd2 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port, '-f', slave2_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', slave2) @@ -279,6 +285,7 @@ if pr1 not in out or pr2 not in out or pr3 not in out: # Make another change and check that it propagates incrementally to # both slaves. +mark('propagate M->1->2 incremental') realm.run([kadminl, 'modprinc', '-maxrenewlife', '22 hours', pr1]) check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1]) kpropd1.send_signal(signal.SIGUSR1) @@ -296,6 +303,7 @@ realm.run([kadminl, 'getprinc', pr1], env=slave2, # resync will use the old dump file and then propagate changes. # slave2 should still be in sync with slave1 after the resync, so make # sure it doesn't take a full resync. +mark('propagate M->1->2 full') realm.run([kproplog, '-R'], slave1) check_ulog(1, 1, 1, [None], slave1) kpropd1.send_signal(signal.SIGUSR1) @@ -307,6 +315,7 @@ check_ulog(3, 7, 9, [None, pr1, pr1], slave2) # Make another change and check that it propagates incrementally to # both slaves. +mark('propagate M->1->2 incremental (after reset)') realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) check_ulog(10, 1, 10, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1, pr2]) kpropd1.send_signal(signal.SIGUSR1) @@ -319,6 +328,7 @@ check_ulog(4, 7, 10, [None, pr1, pr1, pr2], slave2) realm.run([kadminl, 'getprinc', pr2], env=slave2, expected_msg='Attributes:\n') # Create a policy and check that it propagates via full resync. +mark('propagate M->1->2 full (new policy)') realm.run([kadminl, 'addpol', '-minclasses', '2', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) @@ -333,6 +343,7 @@ realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_msg='Minimum number of password character classes: 2') # Modify the policy and test that it also propagates via full resync. +mark('propagate M->1->2 full (policy change)') realm.run([kadminl, 'modpol', '-minlength', '17', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) @@ -347,6 +358,7 @@ realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_msg='Minimum password length: 17') # Delete the policy and test that it propagates via full resync. +mark('propgate M->1->2 full (policy delete)') realm.run([kadminl, 'delpol', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) @@ -361,6 +373,7 @@ realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_code=1, expected_msg='Policy does not exist') # Modify a principal on the master and test that it propagates incrementally. +mark('propagate M->1->2 incremental (after policy changes)') realm.run([kadminl, 'modprinc', '-maxlife', '10 minutes', pr1]) check_ulog(2, 1, 2, [None, pr1]) kpropd1.send_signal(signal.SIGUSR1) @@ -375,6 +388,7 @@ realm.run([kadminl, 'getprinc', pr1], env=slave2, expected_msg='Maximum ticket life: 0 days 00:10:00') # Delete a principal and test that it propagates incrementally. +mark('propagate M->1->2 incremental (princ delete)') realm.run([kadminl, 'delprinc', pr3]) check_ulog(3, 1, 3, [None, pr1, pr3]) kpropd1.send_signal(signal.SIGUSR1) @@ -389,6 +403,7 @@ realm.run([kadminl, 'getprinc', pr3], env=slave2, expected_code=1, expected_msg='Principal does not exist') # Rename a principal and test that it propagates incrementally. +mark('propagate M->1->2 incremental (princ rename)') renpr = "quacked@" + realm.realm realm.run([kadminl, 'renprinc', pr1, renpr]) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr]) @@ -408,6 +423,7 @@ realm.run([kadminl, 'getprinc', renpr], env=slave2) pr1 = renpr # Reset the ulog on the master to force a full resync. +mark('propagate M->1->2 full (ulog reset)') realm.run([kproplog, '-R']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) @@ -420,6 +436,7 @@ check_ulog(1, 1, 1, [None], slave2) # Stop the kprop daemons so we can test kpropd -t. stop_daemon(kpropd1) stop_daemon(kpropd2) +mark('kpropd -t') # Test the case where no updates are needed. out = realm.run_kpropd_once(slave1, ['-d']) diff --git a/src/tests/t_kadmin_acl.py b/src/tests/t_kadmin_acl.py index 42bdf423c3..d5a1326392 100755 --- a/src/tests/t_kadmin_acl.py +++ b/src/tests/t_kadmin_acl.py @@ -84,6 +84,7 @@ realm.addprinc('selected', 'oldpw') realm.addprinc('unselected', 'oldpw') for pw in (['-pw', 'newpw'], ['-randkey']): for ks in ([], ['-e', 'aes256-cts']): + mark('cpw: %s %s' % (repr(pw), repr(ks))) args = pw + ks kadmin_as(all_changepw, ['cpw'] + args + ['unselected']) kadmin_as(some_changepw, ['cpw'] + args + ['selected']) @@ -101,6 +102,7 @@ for pw in (['-pw', 'newpw'], ['-randkey']): realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) +mark('addpol') kadmin_as(all_add, ['addpol', 'policy']) realm.run([kadminl, 'delpol', 'policy']) kadmin_as(none, ['addpol', 'policy'], expected_code=1, @@ -108,6 +110,7 @@ kadmin_as(none, ['addpol', 'policy'], expected_code=1, # addprinc can generate two different RPC calls depending on options. for ks in ([], ['-e', 'aes256-cts']): + mark('addprinc: %s' % repr(ks)) args = ['-pw', 'pw'] + ks kadmin_as(all_add, ['addprinc'] + args + ['unselected']) realm.run([kadminl, 'delprinc', 'unselected']) @@ -122,6 +125,7 @@ for ks in ([], ['-e', 'aes256-cts']): kadmin_as(some_add, ['addprinc'] + args + ['unselected'], expected_code=1, expected_msg="Operation requires ``add'' privilege") +mark('delprinc') realm.addprinc('unselected', 'pw') kadmin_as(all_delete, ['delprinc', 'unselected']) realm.addprinc('selected', 'pw') @@ -133,6 +137,7 @@ kadmin_as(some_delete, ['delprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") realm.run([kadminl, 'delprinc', 'unselected']) +mark('getpol') kadmin_as(all_inquire, ['getpol', 'minlife'], expected_msg='Policy: minlife') kadmin_as(none, ['getpol', 'minlife'], expected_code=1, expected_msg="Operation requires ``get'' privilege") @@ -140,6 +145,7 @@ realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) kadmin_as(none, ['getpol', 'minlife'], expected_msg='Policy: minlife') realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) +mark('getprinc') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_inquire, ['getprinc', 'unselected'], @@ -155,10 +161,12 @@ kadmin_as(none, ['getprinc', 'none'], realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) +mark('listprincs') kadmin_as(all_list, ['listprincs'], expected_msg='K/M@KRBTEST.COM') kadmin_as(none, ['listprincs'], expected_code=1, expected_msg="Operation requires ``list'' privilege") +mark('getstrs') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') realm.run([kadminl, 'setstr', 'selected', 'key', 'value']) @@ -173,6 +181,7 @@ kadmin_as(none, ['getstrs', 'none'], expected_msg='(No string attributes.)') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) +mark('modpol') out = kadmin_as(all_modify, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1) if 'Operation requires' in out: @@ -180,6 +189,7 @@ if 'Operation requires' in out: kadmin_as(none, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") +mark('modprinc') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) @@ -195,6 +205,7 @@ kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'unselected'], realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) +mark('purgekeys') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['purgekeys', 'unselected']) @@ -207,6 +218,7 @@ kadmin_as(none, ['purgekeys', 'none']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) +mark('renprinc') realm.addprinc('from', 'pw') kadmin_as(all_rename, ['renprinc', 'from', 'to']) realm.run([kadminl, 'renprinc', 'to', 'from']) @@ -225,6 +237,7 @@ kadmin_as(restricted_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") realm.run([kadminl, 'delprinc', 'notfrom']) +mark('setstr') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['setstr', 'unselected', 'key', 'value']) @@ -236,6 +249,7 @@ kadmin_as(some_modify, ['setstr', 'unselected', 'key', 'value'], realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) +mark('addprinc/delprinc (wildcard)') kadmin_as(admin, ['addprinc', '-pw', 'pw', 'anytarget']) realm.run([kadminl, 'delprinc', 'anytarget']) kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card']) @@ -249,6 +263,7 @@ kadmin_as(admin, ['delprinc', 'none'], expected_code=1, realm.addprinc('four/one/three', 'pw') kadmin_as(onetwothreefour, ['delprinc', 'four/one/three']) +mark('addprinc (restrictions)') kadmin_as(restrictions, ['addprinc', '-pw', 'pw', 'type1']) realm.run([kadminl, 'getprinc', 'type1'], expected_msg='Policy: minlife') realm.run([kadminl, 'delprinc', 'type1']) @@ -268,6 +283,7 @@ kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxrenewlife', '1 day', realm.run([kadminl, 'getprinc', 'type3'], expected_msg='Maximum renewable life: 0 days 02:00:00') +mark('extract') realm.run([kadminl, 'addprinc', '-pw', 'pw', 'extractkeys']) kadmin_as(all_wildcard, ['ktadd', '-norandkey', 'extractkeys'], expected_code=1, @@ -276,6 +292,7 @@ kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) realm.kinit('extractkeys', flags=['-k']) os.remove(realm.keytab) +mark('lockdown_keys') kadmin_as(all_modify, ['modprinc', '+lockdown_keys', 'extractkeys']) kadmin_as(all_changepw, ['cpw', '-pw', 'newpw', 'extractkeys'], expected_code=1, @@ -297,6 +314,7 @@ realm.kinit('extractkeys', flags=['-k']) os.remove(realm.keytab) # Verify that self-service key changes require an initial ticket. +mark('self-service initial ticket') realm.run([kadminl, 'cpw', '-pw', password('none'), 'none']) realm.run([kadminl, 'modprinc', '+allow_tgs_req', 'kadmin/admin']) realm.kinit('none', password('none')) diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py index 6e563b1032..8438a45aa5 100755 --- a/src/tests/t_kdb.py +++ b/src/tests/t_kdb.py @@ -201,6 +201,7 @@ if out != 'KRBTEST.COM\n': # because we're sticking a krbPrincipalAux objectclass onto a subtree # krbContainer, but it works and it avoids having to load core.schema # in the test LDAP server. +mark('LDAP specified dn') realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=krb5', 'princ1'], expected_code=1, expected_msg='DN is out of the realm subtree') # Check that the DN container check is a hierarchy test, not a simple @@ -218,6 +219,7 @@ realm.run([kadminl, 'modprinc', '-x', 'linkdn=cn=t1,cn=krb5', 'princ1'], expected_code=1, expected_msg='link information can not be set') # Create a principal with a specified linkdn. +mark('LDAP specified linkdn') realm.run([kadminl, 'ank', '-randkey', '-x', 'linkdn=cn=krb5', 'princ2'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'linkdn=cn=t1,cn=krb5', 'princ2']) @@ -226,6 +228,7 @@ realm.run([kadminl, 'modprinc', '-x', 'linkdn=cn=t2,cn=krb5', 'princ2'], expected_code=1, expected_msg='kerberos principal is already linked') # Create a principal with a specified containerdn. +mark('LDAP specified containerdn') realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=krb5', 'princ3'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=t1,cn=krb5', @@ -238,6 +241,8 @@ realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=krb5', '-x', 'linkdn=cn=t2,cn=krb5', 'princ4'], expected_code=1, expected_msg='DN is out of the realm subtree') +mark('LDAP ticket policy') + # Create and modify a ticket policy. kldaputil(['create_policy', '-maxtktlife', '3hour', '-maxrenewlife', '6hour', '-allow_forwardable', 'tktpol']) @@ -304,6 +309,7 @@ realm.run([kadminl, '-q', 'modprinc -policy tktpol2 princ4'], # Do some basic tests with a KDC against the LDAP module, exercising the # db_args processing code. +mark('LDAP KDC operation') realm.start_kdc(['-x', 'nconns=3', '-x', 'host=' + ldap_uri, '-x', 'binddn=' + admin_dn, '-x', 'bindpwd=' + admin_pw]) realm.addprinc(realm.user_princ, password('user')) @@ -313,6 +319,8 @@ realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.klist(realm.user_princ, realm.host_princ) +mark('LDAP auth indicator') + # Test auth indicator support realm.addprinc('authind', password('authind')) realm.run([kadminl, 'setstr', 'authind', 'require_auth', 'otp radius']) @@ -326,6 +334,8 @@ if 'krbPrincipalAuthInd: radius' not in out: realm.run([kadminl, 'getstrs', 'authind'], expected_msg='require_auth: otp radius') +mark('LDAP service principal aliases') + # Test service principal aliases. realm.addprinc('canon', password('canon')) ldap_modify('dn: krbPrincipalName=canon@KRBTEST.COM,cn=t1,cn=krb5\n' @@ -381,6 +391,8 @@ realm.run([kadminl, 'modprinc', '+requires_preauth', 'canon']) realm.kinit('canon', password('canon')) realm.kinit('alias', password('canon'), ['-C']) +mark('LDAP password history') + # Test password history. def test_pwhist(nhist): def cpw(n, **kwargs): @@ -420,6 +432,7 @@ def get_princ(princ): out = realm.run([kadminl, 'getprinc', princ]) return dict(map(str.strip, x.split(":", 1)) for x in out.splitlines()) +mark('LDAP principal renaming') realm.addprinc("rename", password('rename')) renameprinc = get_princ("rename") realm.run([kadminl, '-p', 'fake@KRBTEST.COM', 'renprinc', 'rename', 'renamed']) @@ -428,6 +441,7 @@ if renameprinc['Last modified'] == renamedprinc['Last modified']: fail('Last modified data not updated when principal was renamed') # Regression test for #7980 (fencepost when dividing keys up by kvno). +mark('#7980 regression test') realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', @@ -438,6 +452,7 @@ realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', realm.run([kadminl, 'getprinc', 'kvnoprinc'], expected_msg='Number of keys: 6') # Regression test for #8041 (NULL dereference on keyless principals). +mark('#8041 regression test') realm.run([kadminl, 'addprinc', '-nokey', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 0') @@ -452,6 +467,7 @@ realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 0') # Test for 8354 (old password history entries when -keepold is used) +mark('#8354 regression test') realm.run([kadminl, 'addpol', '-history', '2', 'keepoldpasspol']) realm.run([kadminl, 'addprinc', '-policy', 'keepoldpasspol', '-pw', 'aaaa', 'keepoldpassprinc']) @@ -468,6 +484,7 @@ else: realm.stop() # Briefly test dump and load. +mark('LDAP dump and load') dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], expected_code=1, @@ -488,6 +505,7 @@ if runenv.have_sasl != 'yes': # Test SASL EXTERNAL auth. Remove the DNs and service password file # from the DB module config. +mark('LDAP SASL EXTERNAL auth') os.remove(ldap_pwfile) dbmod = conf['dbmodules']['ldap'] dbmod['ldap_kdc_sasl_mech'] = dbmod['ldap_kadmind_sasl_mech'] = 'EXTERNAL' @@ -504,6 +522,7 @@ realm.run([kdb5_ldap_util, 'destroy', '-f']) # Test SASL DIGEST-MD5 auth. We need to set a clear-text password for # the admin DN, so create a person entry (requires the core schema). # Restore the service password file in the config and set authcids. +mark('LDAP SASL DIGEST-MD5 auth') ldap_add('cn=admin,cn=krb5', 'person', ['sn: dummy', 'userPassword: admin']) dbmod['ldap_kdc_sasl_mech'] = dbmod['ldap_kadmind_sasl_mech'] = 'DIGEST-MD5' diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py index a48740ba53..91fd23d3c8 100755 --- a/src/tests/t_keytab.py +++ b/src/tests/t_keytab.py @@ -8,16 +8,19 @@ for realm in multipass_realms(create_user=False): realm = K5Realm(get_creds=False, start_kadmind=True) # Test kinit with a partial keytab. +mark('partial keytab') pkeytab = realm.keytab + '.partial' realm.run([ktutil], input=('rkt %s\ndelent 1\nwkt %s\n' % (realm.keytab, pkeytab))) realm.kinit(realm.host_princ, flags=['-k', '-t', pkeytab]) # Test kinit with no keys for client in keytab. +mark('no keys for client') realm.kinit(realm.user_princ, flags=['-k'], expected_code=1, expected_msg='no suitable keys') # Test kinit and klist with client keytab defaults. +mark('client keytab') realm.extract_keytab(realm.user_princ, realm.client_keytab); realm.run([kinit, '-k', '-i']) realm.klist(realm.user_princ) @@ -29,6 +32,7 @@ if realm.client_keytab not in out or realm.user_princ not in out: fail('Expected output not seen from klist -k -i') # Test implicit request for keytab (-i or -t without -k) +mark('implicit -k') realm.run([kdestroy]) realm.kinit(realm.host_princ, flags=['-t', realm.keytab], expected_msg='keytab specified, forcing -k') @@ -39,6 +43,7 @@ realm.kinit(realm.user_princ, flags=['-i'], realm.klist(realm.user_princ) # Test extracting keys with multiple key versions present. +mark('multi-kvno extract') os.remove(realm.keytab) realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.host_princ]) out = realm.run([kadminl, 'ktadd', '-norandkey', realm.host_princ]) @@ -49,6 +54,7 @@ if ' 1 host/' not in out or ' 2 host/' not in out: fail('Expected output not seen from klist -k -e') # Test again using kadmin over the network. +mark('multi-kvno extract (via kadmin)') realm.prep_kadmin() os.remove(realm.keytab) out = realm.run_kadmin(['ktadd', '-norandkey', realm.host_princ]) @@ -72,6 +78,7 @@ def test_key_rotate(realm, princ, expected_kvno): msg = 'Key: vno %d,' % expected_kvno out = realm.run_kadmin(['getprinc', princ], expected_msg=msg) +mark('key rotation across boundaries') princ = 'foo/bar@%s' % realm.realm realm.addprinc(princ) os.remove(realm.keytab) @@ -89,6 +96,8 @@ test_key_rotate(realm, princ, 65535) test_key_rotate(realm, princ, 1) test_key_rotate(realm, princ, 2) +mark('32-bit kvno') + # Test that klist -k can read a keytab entry without a 32-bit kvno and # reports the 8-bit key version. record = '\x00\x01' # principal component count @@ -126,6 +135,7 @@ msg = ' 3 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Test parameter expansion in profile variables +mark('parameter expansion') realm.stop() conf = {'libdefaults': { 'default_keytab_name': 'testdir/%{null}abc%{uid}', diff --git a/src/tests/t_localauth.py b/src/tests/t_localauth.py index aa625d038f..63fc563ae3 100755 --- a/src/tests/t_localauth.py +++ b/src/tests/t_localauth.py @@ -26,6 +26,7 @@ def test_userok(env, aname, lname, ok, msg): # The default an2ln method works only in the default realm, and works # for a single-component principal or a two-component principal where # the second component is the default realm. +mark('default') test_an2ln(None, 'user@KRBTEST.COM', 'user', 'default rule 1') test_an2ln(None, 'user/KRBTEST.COM@KRBTEST.COM', 'user', 'default rule 2') test_an2ln_err(None, 'user/KRBTEST.COM/x@KRBTEST.COM', 'No translation', @@ -35,6 +36,7 @@ test_an2ln_err(None, 'user/X@KRBTEST.COM', 'No translation', test_an2ln_err(None, 'user@X', 'No translation', 'default rule realm mismatch') # auth_to_local_names matches ignore the realm but are case-sensitive. +mark('auth_to_local_names') conf_names1 = {'realms': {'$realm': {'auth_to_local_names': {'user': 'abcd'}}}} names1 = realm.special_env('names1', False, conf_names1) test_an2ln(names1, 'user@KRBTEST.COM', 'abcd', 'auth_to_local_names match') @@ -54,10 +56,12 @@ def a2l_realm(name, values): return realm.special_env(name, False, conf) # Test explicit use of default method. +mark('explicit default') auth1 = a2l_realm('auth1', 'DEFAULT') test_an2ln(auth1, 'user@KRBTEST.COM', 'user', 'default rule') # Test some invalid auth_to_local values. +mark('auth_to_local invalid') auth2 = a2l_realm('auth2', 'RULE') test_an2ln_err(auth2, 'user@X', 'Improper format', 'null rule') auth3 = a2l_realm('auth3', 'UNRECOGNIZED:stuff') @@ -65,6 +69,7 @@ test_an2ln_err(auth3, 'user@X', 'Improper format', 'null rule') # An empty rule has the default selection string (unparsed principal # without realm) and no match or substitutions. +mark('rule (empty)') rule1 = a2l_realm('rule1', 'RULE:') test_an2ln(rule1, 'user@KRBTEST.COM', 'user', 'empty rule') test_an2ln(rule1, 'user@X', 'user', 'empty rule (foreign realm)') @@ -72,23 +77,27 @@ test_an2ln(rule1, 'a/b/c@X', 'a/b/c', 'empty rule (multi-component)') # Test explicit selection string. Also test that the default method # is suppressed when auth_to_local values are present. +mark('rule (selection string)') rule2 = a2l_realm('rule2', 'RULE:[2:$$0.$$2.$$1]') test_an2ln(rule2, 'aaron/burr@REALM', 'REALM.burr.aaron', 'selection string') test_an2ln_err(rule2, 'user@KRBTEST.COM', 'No translation', 'suppress default') # Test match string. +mark('rule (match string)') rule3 = a2l_realm('rule3', 'RULE:(.*tail)') test_an2ln(rule3, 'withtail@X', 'withtail', 'rule match 1') test_an2ln(rule3, 'x/withtail@X', 'x/withtail', 'rule match 2') test_an2ln_err(rule3, 'tails@X', 'No translation', 'rule anchor mismatch') # Test substitutions. +mark('rule (substitutions)') rule4 = a2l_realm('rule4', 'RULE:s/birds/bees/') test_an2ln(rule4, 'thebirdsbirdsbirds@X', 'thebeesbirdsbirds', 'subst 1') rule5 = a2l_realm('rule4', 'RULE:s/birds/bees/g s/bees/birds/') test_an2ln(rule4, 'the/birdsbirdsbirds@x', 'the/birdsbeesbees', 'subst 2') # Test a bunch of auth_to_local values and rule features in combination. +mark('rule (combo)') combo = a2l_realm('combo', ['RULE:[1:$$1-$$0](fred.*)s/-/ /g', 'DEFAULT', 'RULE:[3:$$1](z.*z)']) @@ -100,11 +109,14 @@ test_an2ln(combo, 'zazz/b/c@X', 'zazz', 'combo 5') test_an2ln_err(combo, 'a/b@KRBTEST.COM', 'No translation', 'combo 6') # Test the an2ln userok method with the combo environment. +mark('userok (an2ln)') test_userok(combo, 'fred@X', 'fred X', True, 'combo userok 1') test_userok(combo, 'user@KRBTEST.COM', 'user', True, 'combo userok 2') test_userok(combo, 'user@KRBTEST.COM', 'X', False, 'combo userok 3') test_userok(combo, 'a/b@KRBTEST.COM', 'a/b', False, 'combo userok 4') +mark('test modules') + # Register the two test modules and set up some auth_to_local and # auth_to_local_names entries. modpath = os.path.join(buildtop, 'plugins', 'localauth', 'test', diff --git a/src/tests/t_mkey.py b/src/tests/t_mkey.py index 615cd91cac..998297ed64 100755 --- a/src/tests/t_mkey.py +++ b/src/tests/t_mkey.py @@ -150,12 +150,14 @@ def update_princ_encryption(dry_run, expected_mkvno, expected_updated, # Check the initial state of the realm. +mark('initial state') check_mkey_list((1, defetype, True, True)) check_master_dbent(1, (1, defetype)) check_stash((1, defetype)) check_mkvno(realm.user_princ, 1) # Check that stash will fail if a temp stash file is already present. +mark('temp stash collision') collisionfile = os.path.join(realm.testdir, 'stash_tmp') f = open(collisionfile, 'w') f.close() @@ -170,6 +172,7 @@ os.unlink(collisionfile) # encrypt that entry. # 3. The stash file is not modified (since we did not pass -s). # 4. The old key is used for password changes. +mark('add_mkey (second master key)') add_mkey([]) check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) check_master_dbent(2, (2, defetype), (1, defetype)) @@ -177,6 +180,7 @@ change_password_check_mkvno(True, realm.user_princ, 'abcd', 1) change_password_check_mkvno(False, realm.user_princ, 'user', 1) # Verify that use_mkey won't make all master keys inactive. +mark('use_mkey (no active keys)') realm.run([kdb5_util, 'use_mkey', '1', 'now+1day'], expected_code=1, expected_msg='there must be one master key currently active') check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) @@ -185,12 +189,14 @@ check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) # 1. The new key has an activation time in list_mkeys and is active. # 2. The new key is used for password changes. # 3. The running KDC can access the new key. +mark('use_mkey') realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) check_mkey_list((2, defetype, True, True), (1, defetype, True, False)) change_password_check_mkvno(True, realm.user_princ, 'abcd', 2) change_password_check_mkvno(False, realm.user_princ, 'user', 2) # Check purge_mkeys behavior with both master keys still in use. +mark('purge_mkeys (nothing to purge)') realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], expected_msg='All keys in use, nothing purged.') @@ -204,6 +210,7 @@ realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], # 4. The old stashed master key is sufficient to access the DB (via # MKEY_AUX tl-data which keeps the current master key encrypted in # each of the old master keys). +mark('update_princ_encryption') update_princ_encryption(True, 2, nprincs - 2, 1) check_mkvno(realm.admin_princ, 1) update_princ_encryption(False, 2, nprincs - 2, 1) @@ -214,6 +221,7 @@ realm.kinit(realm.user_princ, 'user') # Update all principals back to mkvno 1 and to mkvno 2 again, to # verify that update_princ_encryption targets the active master key. +mark('update_princ_encryption (back and forth)') realm.run([kdb5_util, 'use_mkey', '2', 'now+1day']) update_princ_encryption(False, 1, nprincs - 1, 0) check_mkvno(realm.user_princ, 1) @@ -222,11 +230,13 @@ update_princ_encryption(False, 2, nprincs - 1, 0) check_mkvno(realm.user_princ, 2) # Test the safety check for purging with an outdated stash file. +mark('purge_mkeys (outdated stash file)') realm.run([kdb5_util, 'purge_mkeys', '-f'], expected_code=1, expected_msg='stash file needs updating') # Update the master stash file and check it. Save a copy of the old # one for a later test. +mark('update stash file') shutil.copy(stash_file, stash_file + '.old') realm.run([kdb5_util, 'stash']) check_stash((2, defetype), (1, defetype)) @@ -238,6 +248,7 @@ check_stash((2, defetype), (1, defetype)) # 4. If the stash file is updated, it no longer contains mkvno 1. # 5. use_mkey now gives an error if we refer to mkvno 1. # 6. A second purge_mkeys gives the right message. +mark('purge_mkeys') out = realm.run([kdb5_util, 'purge_mkeys', '-v', '-n', '-f']) if 'KVNO: 1' not in out or '1 key(s) would be purged' not in out: fail('Unexpected output from purge_mkeys dry-run') @@ -263,6 +274,7 @@ realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], # 2. The enctype argument is respected. # 3. The new master key is stashed (by itself, at the moment). # 4. We can roll over to the new master key and use it. +mark('add_mkey and update_princ_encryption (third master key)') add_mkey(['-s', '-e', aes128]) check_mkey_list((3, aes128, False, False), (2, defetype, True, True)) check_master_dbent(3, (3, aes128), (2, defetype)) @@ -274,6 +286,7 @@ check_mkvno(realm.user_princ, 3) # Regression test for #7994 (randkey does not update principal mkvno) # and #7995 (-keepold does not re-encrypt old keys). +mark('#7994 and #7995 regression test') add_mkey(['-s']) realm.run([kdb5_util, 'use_mkey', '4', 'now-1day']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.user_princ]) @@ -295,6 +308,7 @@ realm.stop() # created prior to master key rollover support. Verify that: # 1. We can access the database using the old-format stash file. # 2. list_mkeys displays the same list as for a post-1.7 KDB. +mark('pre-1.7 stash file') dumpfile = os.path.join(srctop, 'tests', 'dumpfiles', 'dump.16') os.remove(stash_file) f = open(stash_file, 'w') @@ -312,6 +326,7 @@ check_mkey_list((1, des3, True, True)) # 2. update_princ_encryption still targets mkvno 1. # 3. libkadm5 still uses mkvno 1 for key changes. # 4. use_mkey creates the same list as for a post-1.7 KDB. +mark('rollover from pre-1.7 KDB') add_mkey([]) check_mkey_list((2, defetype, False, False), (1, des3, True, True)) update_princ_encryption(False, 1, 0, nprincs - 1) @@ -322,6 +337,7 @@ check_mkey_list((2, defetype, True, True), (1, des3, True, False)) # Regression test for #8395. Purge the master key and verify that a # master key fetch does not segfault. +mark('#8395 regression test') realm.run([kadminl, 'purgekeys', '-all', 'K/M']) realm.run([kadminl, 'getprinc', realm.user_princ], expected_code=1, expected_msg='Cannot find master key record in database') diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py index 9b18ff94b9..1142fc799a 100755 --- a/src/tests/t_otp.py +++ b/src/tests/t_otp.py @@ -183,6 +183,7 @@ flags = ['-T', realm.ccache] server_addr = '127.0.0.1:' + str(realm.portbase + 9) ## Test UDP fail / custom username +mark('UDP fail / custom username') daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() @@ -192,6 +193,7 @@ realm.kinit(realm.user_princ, 'reject', flags=flags, expected_code=1) verify(daemon, queue, False, 'custom', 'reject') ## Test UDP success / standard username +mark('UDP success / standard username') daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() @@ -203,6 +205,7 @@ realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indotp1, indotp2]') # Repeat with an indicators override in the string attribute. +mark('auth indicator override') daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() @@ -223,6 +226,7 @@ except AssertionError: skip_rest('OTP UNIX domain socket tests', 'pyrad assertion bug detected') ## Test Unix fail / custom username +mark('Unix socket fail / custom username') daemon = UnixRadiusDaemon(args=(socket_file, '', 'accept', queue)) daemon.start() queue.get() @@ -232,6 +236,7 @@ realm.kinit(realm.user_princ, 'reject', flags=flags, expected_code=1) verify(daemon, queue, False, 'custom', 'reject') ## Test Unix success / standard username +mark('Unix socket success / standard username') daemon = UnixRadiusDaemon(args=(socket_file, '', 'accept', queue)) daemon.start() queue.get() diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py index 1ba3536da5..769ad6a981 100755 --- a/src/tests/t_pkinit.py +++ b/src/tests/t_pkinit.py @@ -79,6 +79,8 @@ realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf, create_kdb=False) realm.start_kdc() +mark('UPN SANs') + # Compatibility check: cert contains UPN "user", which matches the # request principal user@KRBTEST.COM if parsed as a normal principal. realm.kinit(realm.user_princ, @@ -114,6 +116,7 @@ realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, get_creds=False) # Sanity check - password-based preauth should still work. +mark('password preauth sanity check') realm.run(['./responder', '-r', 'password=%s' % password('user'), realm.user_princ]) realm.kinit(realm.user_princ, password=password('user')) @@ -125,6 +128,7 @@ realm.run([kvno, realm.host_princ]) realm.run([kadminl, 'purgekeys', '-all', realm.user_princ]) # Test anonymous PKINIT. +mark('anonymous') realm.kinit('@%s' % realm.realm, flags=['-n'], expected_code=1, expected_msg='not found in Kerberos database') realm.addprinc('WELLKNOWN/ANONYMOUS') @@ -136,6 +140,7 @@ if '97:' in out: fail('auth indicators seen in anonymous PKINIT ticket') # Test anonymous kadmin. +mark('anonymous kadmin') f = open(os.path.join(realm.testdir, 'acl'), 'a') f.write('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS a *') f.close() @@ -146,6 +151,7 @@ realm.run([kadmin, '-n', 'getprinc', 'testadd'], expected_code=1, realm.stop_kadmind() # Test with anonymous restricted; FAST should work but kvno should fail. +mark('anonymous restricted') r_env = realm.special_env('restrict', True, kdc_conf=restrictive_kdc_conf) realm.stop_kdc() realm.start_kdc(env=r_env) @@ -156,6 +162,7 @@ realm.run([kvno, realm.host_princ], expected_code=1, # Regression test for #8458: S4U2Self requests crash the KDC if # anonymous is restricted. +mark('#8458 regression test') realm.kinit(realm.host_princ, flags=['-k']) realm.run([kvno, '-U', 'user', realm.host_princ]) @@ -164,6 +171,7 @@ realm.stop_kdc() realm.start_kdc() # Run the basic test - PKINIT with FILE: identity, with no password on the key. +mark('FILE identity, no password') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -181,6 +189,7 @@ realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Try again using RSA instead of DH. +mark('FILE identity, no password, RSA') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_identity, '-X', 'flag_RSA_PROTOCOL=yes'], @@ -191,6 +200,7 @@ realm.klist(realm.user_princ) # Test a DH parameter renegotiation by temporarily setting a 4096-bit # minimum on the KDC. (Preauth type 16 is PKINIT PA_PK_AS_REQ; # 109 is PKINIT TD_DH_PARAMETERS; 133 is FAST PA-FX-COOKIE.) +mark('DH parameter renegotiation') minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) realm.stop_kdc() @@ -211,6 +221,7 @@ realm.kinit(realm.user_princ, # Test enforcement of required freshness tokens. (We can leave # freshness tokens required after this test.) +mark('freshness token enforcement') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_identity, '-X', 'disable_freshness=yes']) @@ -229,6 +240,7 @@ realm.kinit('@%s' % realm.realm, flags=['-n', '-X', 'disable_freshness=yes']) # Run the basic test - PKINIT with FILE: identity, with a password on the key, # supplied by the prompter. # Expect failure if the responder does nothing, and we have no prompter. +mark('FILE identity, password on key (prompter)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity, '-X', 'X509_user_identity=%s' % file_enc_identity, realm.user_princ], expected_code=2) @@ -243,6 +255,7 @@ realm.run(['./adata', realm.host_princ], # Run the basic test - PKINIT with FILE: identity, with a password on the key, # supplied by the responder. # Supply the response in raw form. +mark('FILE identity, password on key (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % file_enc_identity, '-X', 'X509_user_identity=%s' % file_enc_identity, @@ -254,6 +267,7 @@ realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with no password on the key. +mark('DIR identity, no password') os.mkdir(path) os.mkdir(path_enc) shutil.copy(privkey_pem, os.path.join(path, 'user.key')) @@ -268,6 +282,7 @@ realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with a password on the key, supplied by the # prompter. # Expect failure if the responder does nothing, and we have no prompter. +mark('DIR identity, password on key (prompter)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity, '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ], expected_code=2) @@ -280,6 +295,7 @@ realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with a password on the key, supplied by the # responder. # Supply the response in raw form. +mark('DIR identity, password on key (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % dir_file_enc_identity, '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ]) @@ -291,6 +307,7 @@ realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with no password on the bundle. +mark('PKCS12 identity, no password') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) @@ -299,6 +316,7 @@ realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with a password on the bundle, supplied by the # prompter. # Expect failure if the responder does nothing, and we have no prompter. +mark('PKCS12 identity, password on bundle (prompter)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity, '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ], expected_code=2) @@ -311,6 +329,7 @@ realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with a password on the bundle, supplied by the # responder. # Supply the response in raw form. +mark('PKCS12 identity, password on bundle (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % p12_enc_identity, '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ]) @@ -321,6 +340,8 @@ realm.run(['./responder', '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) +mark('pkinit_cert_match rules') + # Match a single rule. rule = '^user@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) @@ -373,6 +394,7 @@ softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc') realm.env['SOFTPKCS11RC'] = softpkcs11rc # PKINIT with PKCS11: identity, with no need for a PIN. +mark('PKCS11 identity, no PIN') conf = open(softpkcs11rc, 'w') conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem)) conf.close() @@ -383,6 +405,7 @@ realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS11: identity, with a PIN supplied by the prompter. +mark('PKCS11 identity, with PIN (prompter)') os.remove(softpkcs11rc) conf = open(softpkcs11rc, 'w') conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, @@ -400,6 +423,7 @@ realm.run([kvno, realm.host_princ]) # Supply the wrong PIN, and verify that we ignore the draft9 padata offer # in the KDC method data after RFC 4556 PKINIT fails. +mark('PKCS11 identity, wrong PIN') expected_trace = ('PKINIT client has no configured identity; giving up', 'PKINIT client ignoring draft 9 offer from RFC 4556 KDC') realm.kinit(realm.user_princ, @@ -408,6 +432,7 @@ realm.kinit(realm.user_princ, # PKINIT with PKCS11: identity, with a PIN supplied by the responder. # Supply the response in raw form. +mark('PKCS11 identity, with PIN (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity, '-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity, '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ]) diff --git a/src/tests/t_policy.py b/src/tests/t_policy.py index 26c4e466e4..9d92ebdc87 100755 --- a/src/tests/t_policy.py +++ b/src/tests/t_policy.py @@ -5,6 +5,7 @@ import re realm = K5Realm(create_host=False, start_kadmind=True) # Test password quality enforcement. +mark('password quality') realm.run([kadminl, 'addpol', '-minlength', '6', '-minclasses', '2', 'pwpol']) realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'pwpol', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'sh0rt', 'pwuser'], expected_code=1, @@ -15,6 +16,7 @@ realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) # Test some password history enforcement. Even with no history value, # the current password should be denied. +mark('password history') realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'modpol', '-history', '2', 'pwpol']) @@ -25,6 +27,7 @@ realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) # Test references to nonexistent policies. +mark('nonexistent policy references') realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'newpol', 'newuser']) realm.run([kadminl, 'getprinc', 'newuser'], expected_msg='Policy: newpol [does not exist]\n') @@ -36,6 +39,7 @@ realm.run([kadmin, '-p', 'pwuser', '-w', '3rdpassword', 'cpw', '-pw', '3rdpassword', 'pwuser']) # Create newpol and verify that it is enforced. +mark('create referenced policy') realm.run([kadminl, 'addpol', '-minlength', '3', 'newpol']) realm.run([kadminl, 'getprinc', 'pwuser'], expected_msg='Policy: newpol\n') realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser'], expected_code=1, @@ -48,13 +52,14 @@ realm.run([kadminl, 'cpw', '-pw', 'aa', 'newuser'], expected_code=1, expected_msg='Password is too short') # Delete the policy and verify that it is no longer enforced. +mark('delete referenced policy') realm.run([kadminl, 'delpol', 'newpol']) realm.run([kadminl, 'getpol', 'newpol'], expected_code=1, expected_msg='Policy does not exist') realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser']) # Test basic password lockout support. - +mark('password lockout') realm.run([kadminl, 'addpol', '-maxfailure', '2', '-failurecountinterval', '5m', 'lockout']) realm.run([kadminl, 'modprinc', '+requires_preauth', '-policy', 'lockout', @@ -81,7 +86,7 @@ realm.kinit(realm.user_princ, password('user')) # Regression test for issue #7099: databases created prior to krb5 1.3 have # multiple history keys, and kadmin prior to 1.7 didn't necessarily use the # first one to create history entries. - +mark('#7099 regression test') realm.stop() realm = K5Realm(start_kdc=False) # Create a history principal with two keys. @@ -96,6 +101,7 @@ realm.run([kadminl, 'cpw', '-pw', password('user'), 'user'], expected_code=1, expected_msg='Cannot reuse password') # Test key/salt constraints. +mark('allowedkeysalts') realm.stop() krb5_conf1 = {'libdefaults': {'supported_enctypes': 'aes256-cts'}} diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py index 32e35b08ba..be6d2b3dfd 100644 --- a/src/tests/t_preauth.py +++ b/src/tests/t_preauth.py @@ -18,6 +18,7 @@ realm.kinit('nokeyuser', password('user'), expected_code=1, # PA-FX-COOKIE; 2 is encrypted timestamp. # Test normal preauth flow. +mark('normal') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -29,6 +30,7 @@ realm.run(['./icred', realm.user_princ, password('user')], expected_msg='testval', expected_trace=msgs) # Test successful optimistic preauth. +mark('optimistic') expected_trace = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', @@ -39,6 +41,7 @@ realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], # Test optimistic preauth failing on client, falling back to encrypted # timestamp. +mark('optimistic (client failure)') msgs = ('Attempting optimistic preauth', 'Processing preauth types: -123', '/induced optimistic fail', @@ -55,6 +58,7 @@ realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ, # Test optimistic preauth failing on KDC, falling back to encrypted # timestamp. +mark('optimistic (KDC failure)') realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes']) msgs = ('Attempting optimistic preauth', 'Processing preauth types: -123', @@ -73,6 +77,7 @@ realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], # Test optimistic preauth failing on KDC, stopping because the test # module disabled fallback. +mark('optimistic (KDC failure, no fallback)') msgs = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', @@ -84,6 +89,7 @@ realm.run(['./icred', '-X', 'disable_fallback', '-o', '-123', realm.user_princ, realm.run([kadminl, 'delstr', realm.user_princ, 'failopt']) # Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. +mark('second round-trip') realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip']) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', @@ -101,6 +107,7 @@ realm.run(['./icred', realm.user_princ, password('user')], # Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # falling back to encrypted timestamp. +mark('second round-trip (client failure)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -122,6 +129,7 @@ realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')], # Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # stopping because the test module disabled fallback. +mark('second round-trip (client failure, no fallback)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -139,6 +147,7 @@ realm.run(['./icred', '-X', 'fail_2rt', '-X', 'disable_fallback', # Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # falling back to encrypted timestamp. +mark('second round-trip (KDC failure)') realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes']) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', @@ -164,6 +173,7 @@ realm.run(['./icred', realm.user_princ, password('user')], # Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # stopping because the test module disabled fallback. +mark('second round-trip (KDC failure, no fallback)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -182,6 +192,7 @@ realm.run(['./icred', '-X', 'disable_fallback', realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt']) # Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC. +mark('tryagain') realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain']) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', @@ -200,6 +211,7 @@ realm.run(['./icred', realm.user_princ, password('user')], # Test a client-side tryagain failure, falling back to encrypted # timestamp. +mark('tryagain (client failure)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -221,6 +233,7 @@ realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ, # Test a client-side tryagain failure, stopping because the test # module disabled fallback. +mark('tryagain (client failure, no fallback)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', @@ -239,6 +252,7 @@ realm.run(['./icred', '-X', 'fail_tryagain', '-X', 'disable_fallback', # Test that multiple stepwise initial creds operations can be # performed with the same krb5_context, with proper tracking of # clpreauth module request handles. +mark('interleaved') realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1']) realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2']) realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3']) diff --git a/src/tests/t_proxy.py b/src/tests/t_proxy.py index 4e86fce8fb..428d2f6b06 100755 --- a/src/tests/t_proxy.py +++ b/src/tests/t_proxy.py @@ -66,6 +66,7 @@ def start_proxy(realm, keycertpem): return realm.start_server(cmd, sentinel='proxy server ready') # Fail: untrusted issuer and hostname doesn't match. +mark('untrusted issuer, hostname mismatch') output("running pass 1: issuer not trusted and hostname doesn't match\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) @@ -75,6 +76,7 @@ stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, host name matches subject. +mark('untrusted issuer, hostname subject match') output("running pass 2: subject matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) @@ -84,6 +86,7 @@ stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, host name matches subjectAltName. +mark('untrusted issuer, hostname SAN match') output("running pass 3: subjectAltName matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) @@ -93,6 +96,7 @@ stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, certificate signature is bad. +mark('untrusted issuer, bad signature') output("running pass 4: subject matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) @@ -102,6 +106,7 @@ stop_daemon(proxy) realm.stop() # Fail: trusted issuer but hostname doesn't match. +mark('trusted issuer, hostname mismatch') output("running pass 5: issuer trusted but hostname doesn't match\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, create_host=False) @@ -111,6 +116,7 @@ stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subject. +mark('trusted issuer, hostname subject match') output("running pass 6: issuer trusted, subject matches\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, get_creds=False) @@ -122,6 +128,7 @@ stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName. +mark('trusted issuer, hostname SAN match') output("running pass 7: issuer trusted, subjectAltName matches\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, get_creds=False) @@ -133,6 +140,7 @@ stop_daemon(proxy) realm.stop() # Fail: certificate signature is bad. +mark('bad signature') output("running pass 8: issuer trusted and subjectAltName matches, sig bad\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, @@ -143,6 +151,7 @@ stop_daemon(proxy) realm.stop() # Fail: trusted issuer but IP doesn't match. +mark('trusted issuer, IP mismatch') output("running pass 9: issuer trusted but no name matches IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) @@ -152,6 +161,7 @@ stop_daemon(proxy) realm.stop() # Fail: trusted issuer, but subject does not match. +mark('trusted issuer, IP mismatch (hostname in subject)') output("running pass 10: issuer trusted, but subject does not match IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) @@ -161,6 +171,7 @@ stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName. +mark('trusted issuer, IP SAN match') output("running pass 11: issuer trusted, subjectAltName matches IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, start_kadmind=True, get_creds=False) @@ -172,6 +183,7 @@ stop_daemon(proxy) realm.stop() # Fail: certificate signature is bad. +mark('bad signature (IP hostname)') output("running pass 12: issuer trusted, names don't match, signature bad\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) @@ -182,6 +194,7 @@ realm.stop() # Succeed: trusted issuer and host name matches subject, using kadmin # configuration to find kpasswdd. +mark('trusted issuer, hostname subject match (kadmin)') output("running pass 13: issuer trusted, subject matches\n") realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) @@ -192,6 +205,7 @@ realm.stop() # Succeed: trusted issuer and host name matches subjectAltName, using # kadmin configuration to find kpasswdd. +mark('trusted issuer, hostname SAN match (kadmin)') output("running pass 14: issuer trusted, subjectAltName matches\n") realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) @@ -202,6 +216,7 @@ realm.stop() # Succeed: trusted issuer and host name matches subjectAltName (give or take # case). +mark('trusted issuer, hostname SAN case-insensitive match') output("running pass 15: issuer trusted, subjectAltName case-insensitive\n") realm = K5Realm(krb5_conf=anchored_upcasename_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) diff --git a/src/tests/t_pwqual.py b/src/tests/t_pwqual.py index 011110bd1a..6114271fdc 100755 --- a/src/tests/t_pwqual.py +++ b/src/tests/t_pwqual.py @@ -17,6 +17,8 @@ f.close() realm.run([kadminl, 'addpol', 'pol']) +mark('pwqual modules') + # The built-in "empty" module rejects empty passwords even without a policy. realm.run([kadminl, 'addprinc', '-pw', '', 'p1'], expected_code=1, expected_msg='Empty passwords are not allowed') @@ -40,6 +42,8 @@ realm.run([kadminl, 'addprinc', '-pw', 'birdsoranges', 'p6'], expected_code=1, # These plugin ordering tests aren't specifically related to the # password quality interface, but are convenient to put here. +mark('plugin module order') + def test_order(realm, testname, conf, expected): conf = {'plugins': {'pwqual': conf}} env = realm.special_env(testname, False, krb5_conf=conf) diff --git a/src/tests/t_rdreq.py b/src/tests/t_rdreq.py index f67c34866f..1fb258b1a9 100755 --- a/src/tests/t_rdreq.py +++ b/src/tests/t_rdreq.py @@ -25,46 +25,54 @@ def test(tserver, server, expected): # No keytab present. +mark('no keytab') nokeytab_err = "45 Key table file '%s' not found" % realm.keytab test(princ1, None, nokeytab_err) test(princ1, princ1, nokeytab_err) test(princ1, matchprinc, nokeytab_err) # Keytab present, successful decryption. +mark('success') realm.extract_keytab(princ1, realm.keytab) test(princ1, None, '0 success') test(princ1, princ1, '0 success') test(princ1, matchprinc, '0 success') # Explicit server principal not found in keytab. +mark('explicit server not found') test(princ2, princ2, '45 No key table entry found for host/2@KRBTEST.COM') # Matching server principal does not match any entries in keytab (with # and without ticket server present in keytab). +mark('matching server') nomatch_err = '45 Server principal x/@ does not match any keys in keytab' test(princ1, nomatchprinc, nomatch_err) test(princ2, nomatchprinc, nomatch_err) # Ticket server does not match explicit server principal (with and # without ticket server present in keytab). +mark('ticket server mismatch') test(princ1, princ2, '45 No key table entry found for host/2@KRBTEST.COM') test(princ2, princ1, '35 Cannot decrypt ticket for host/2@KRBTEST.COM using keytab key for ' 'host/1@KRBTEST.COM') # Ticket server not found in keytab during iteration. +mark('ticket server not found') test(princ2, None, '35 Request ticket server host/2@KRBTEST.COM not found in keytab ' '(ticket kvno 1)') # Ticket server found in keytab but is not matched by server principal # (but other principals in keytab do match). +mark('ticket server mismatch (matching)') realm.extract_keytab(princ3, realm.keytab) test(princ3, matchprinc, '35 Request ticket server HTTP/3@KRBTEST.COM found in keytab but does ' 'not match server principal host/@') # Service ticket is out of date. +mark('outdated service ticket') os.remove(realm.keytab) realm.run([kadminl, 'ktadd', princ1]) test(princ1, None, @@ -74,11 +82,13 @@ test(princ1, princ1, '44 Cannot find key for host/1@KRBTEST.COM kvno 1 in keytab') # kvno mismatch due to ticket principal mismatch with explicit server. +mark('ticket server mismatch (kvno)') test(princ2, princ1, '35 Cannot find key for host/1@KRBTEST.COM kvno 1 in keytab (request ' 'ticket server host/2@KRBTEST.COM)') # Keytab is out of date. +mark('outdated keytab') realm.run([kadminl, 'cpw', '-randkey', princ1]) realm.kinit(realm.user_princ, password('user')) test(princ1, None, @@ -88,6 +98,7 @@ test(princ1, princ1, '44 Cannot find key for host/1@KRBTEST.COM kvno 3 in keytab') # Ticket server and kvno found but not with ticket enctype. +mark('missing enctype') os.remove(realm.keytab) realm.extract_keytab(princ1, realm.keytab) pkeytab = realm.keytab + '.partial' @@ -105,6 +116,7 @@ test(princ1, None, test(princ1, princ1, '45 No key table entry found for host/1@KRBTEST.COM') # Ticket server, kvno, and enctype matched, but key does not work. +mark('wrong key') realm.run([kadminl, 'cpw', '-randkey', princ1]) realm.run([kadminl, 'modprinc', '-kvno', '3', princ1]) os.remove(realm.keytab) @@ -118,6 +130,7 @@ test(princ1, princ1, # Test that aliases work. The ticket server (princ4) isn't present in # keytab, but there is a usable princ1 entry with the same key. +mark('aliases') realm.run([kadminl, 'renprinc', princ1, princ4]) test(princ4, None, '0 success') test(princ4, princ1, '0 success') diff --git a/src/tests/t_referral.py b/src/tests/t_referral.py index 98fdf29256..5b9f74b986 100755 --- a/src/tests/t_referral.py +++ b/src/tests/t_referral.py @@ -39,6 +39,7 @@ def restart_kdc(realm, kdc_conf): # With no KDC configuration besides [domain_realm], we should get a # referral for a NT-SRV-HST or NT-SRV-INST server name, but not an # NT-UNKNOWN or NT-PRINCIPAL server name. +mark('[domain-realm] only') testref(realm, 'srv-hst') testref(realm, 'srv-inst') testfail(realm, 'principal') @@ -50,6 +51,7 @@ testfail(realm, 'unknown') # section, with the realm values supplementing the kdcdefaults values. # NT-SRV-HST server names should be unaffected by host_based_services, # and NT-PRINCIPAL server names shouldn't get a referral regardless. +mark('host_based_services') restart_kdc(realm, {'kdcdefaults': {'host_based_services': '*'}}) testref(realm, 'unknown') testfail(realm, 'principal') @@ -69,6 +71,7 @@ testref(realm, 'srv-hst') # With no_host_referrals matching the first server name component, we # should not get a referral even for NT-SRV-HOST server names +mark('no_host_referral') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*'}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': ['b', 'a,c']}}) @@ -95,6 +98,7 @@ refrealm.stop() # Regression test for #7483: a KDC should not return a host referral # to its own realm. +mark('#7483 regression test') drealm = {'domain_realm': {'d': 'KRBTEST.COM'}} realm = K5Realm(kdc_conf=drealm, create_host=False) tracefile = os.path.join(realm.testdir, 'trace') @@ -110,6 +114,7 @@ realm.stop() # Test client referrals. Use the test KDB module for KRBTEST1.COM to # simulate referrals since our built-in modules do not support them. # No cross-realm TGTs are necessary. +mark('client referrals') kdcconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'alias': {'user': '@KRBTEST2.COM', diff --git a/src/tests/t_renew.py b/src/tests/t_renew.py index 034190c80e..88404166f5 100755 --- a/src/tests/t_renew.py +++ b/src/tests/t_renew.py @@ -52,6 +52,7 @@ def test(testname, life, rlife, exp_life, exp_rlife, env=None): test('simple', '1h', '2h', 3600, 7200) # Renew twice, to test that renewed tickets are renewable. +mark('renew twice') realm.kinit(realm.user_princ, flags=['-R']) realm.kinit(realm.user_princ, flags=['-R']) realm.klist(realm.user_princ) @@ -60,16 +61,19 @@ realm.klist(realm.user_princ) realm.run([kvno, realm.user_princ]) # Make sure we can't renew non-renewable tickets. +mark('non-renewable') test('non-renewable', '1h', None, 3600, None) realm.kinit(realm.user_princ, flags=['-R'], expected_code=1, expected_msg="KDC can't fulfill requested option") # Test that -allow_renewable on the client principal works. +mark('allow_renewable (client)') realm.run([kadminl, 'modprinc', '-allow_renewable', 'user']) test('disallowed client', '1h', '2h', 3600, None) realm.run([kadminl, 'modprinc', '+allow_renewable', 'user']) # Test that -allow_renewable on the server principal works. +mark('allow_renewable (server)') realm.run([kadminl, 'modprinc', '-allow_renewable', realm.krbtgt_princ]) test('disallowed server', '1h', '2h', 3600, None) realm.run([kadminl, 'modprinc', '+allow_renewable', realm.krbtgt_princ]) @@ -77,10 +81,12 @@ realm.run([kadminl, 'modprinc', '+allow_renewable', realm.krbtgt_princ]) # Test that trivially renewable tickets are issued if renew_till <= # till. (Our client code bumps up the requested renewable life to the # requested life.) +mark('trivially renewable') test('short', '2h', '1h', 7200, 7200) # Test that renewable tickets are issued if till > max life by # default, but not if we configure away the RENEWABLE-OK option. +mark('renewable-ok') no_opts_conf = {'libdefaults': {'kdc_default_options': '0'}} no_opts = realm.special_env('no_opts', False, krb5_conf=no_opts_conf) realm.run([kadminl, 'modprinc', '-maxlife', '10 hours', 'user']) @@ -89,17 +95,20 @@ test('long noopts', '15h', None, 10 * 3600, None, env=no_opts) realm.run([kadminl, 'modprinc', '-maxlife', '20 hours', 'user']) # Test maximum renewable life on the client principal. +mark('maxrenewlife (client)') realm.run([kadminl, 'modprinc', '-maxrenewlife', '5 hours', 'user']) test('maxrenewlife client 1', '4h', '5h', 4 * 3600, 5 * 3600) test('maxrenewlife client 2', '6h', '10h', 6 * 3600, 5 * 3600) # Test maximum renewable life on the server principal. +mark('maxrenewlife (server)') realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', realm.krbtgt_princ]) test('maxrenewlife server 1', '2h', '3h', 2 * 3600, 3 * 3600) test('maxrenewlife server 2', '4h', '8h', 4 * 3600, 3 * 3600) # Test realm maximum life. +mark('realm maximum life') realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', 'user']) realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', realm.krbtgt_princ]) diff --git a/src/tests/t_skew.py b/src/tests/t_skew.py index f2ae066951..fffc634a18 100755 --- a/src/tests/t_skew.py +++ b/src/tests/t_skew.py @@ -7,6 +7,7 @@ realm.start_kdc(['-T', '-3600']) # kinit (no preauth) should work, and should set a clock skew allowing # kvno to work, with or without FAST. +mark('kdc_timesync enabled, no preauth') realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) @@ -14,6 +15,7 @@ realm.run([kvno, realm.host_princ]) realm.run([kdestroy]) # kinit (with preauth) should work, with or without FAST. +mark('kdc_timesync enabled, with preauth') realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) @@ -37,12 +39,14 @@ realm.kinit(realm.user_princ, password('user'), # kinit should detect too much skew in the KDC response. kinit with # FAST should fail from the KDC since the armor AP-REQ won't be valid. +mark('KDC timesync disabled, no preauth') realm.kinit(realm.user_princ, password('user'), expected_code=1, expected_msg='Clock skew too great in KDC reply') realm.kinit(realm.user_princ, None, flags=['-T', fast_cache], expected_code=1, expected_msg='Clock skew too great while') # kinit (with preauth) should fail from the KDC, with or without FAST. +mark('KDC timesync disabled, with preauth') realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user'), expected_code=1, expected_msg='Clock skew too great while') diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py index 19a0d2fa76..66f31e2de7 100755 --- a/src/tests/t_sn2princ.py +++ b/src/tests/t_sn2princ.py @@ -40,6 +40,7 @@ def testu(host, princhost, princrealm): # With the unknown principal type, we do not canonicalize or downcase, # but we do remove a trailing period and look up the realm. +mark('unknown type') testu('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testu('Example.COM', 'Example.COM', 'R2') testu('abcde', 'abcde', '') @@ -47,6 +48,7 @@ testu('abcde', 'abcde', '') # A ':port' or ':instance' trailer should be ignored for realm lookup. # If there is more than one colon in the name, we assume it's an IPv6 # address and don't treat it as having a trailer. +mark('port trailer') testu('example.com.:123', 'example.com.:123', 'R2') testu('Example.COM:xyZ', 'Example.COM:xyZ', 'R2') testu('example.com.::123', 'example.com.::123', '') @@ -54,6 +56,7 @@ testu('example.com.::123', 'example.com.::123', '') # With dns_canonicalize_hostname=false, we downcase and remove # trailing dots but do not canonicalize the hostname. Trailers do not # get downcased. +mark('dns_canonicalize_host=false') testnc('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testnc('Example.COM', 'example.com', 'R2') testnc('abcde', 'abcde', '') @@ -80,6 +83,7 @@ if canonname.lower() != fname: '%s forward resolves to %s, not %s' % (oname, canonname, fname)) # Test forward-only canonicalization (rdns=false). +mark('rdns=false') testnr(oname, fname, 'R1') testnr(oname + ':123', fname + ':123', 'R1') testnr(oname + ':xyZ', fname + ':xyZ', 'R1') @@ -96,6 +100,7 @@ if rname == fname: 'which should be different from %s' % (oname, rname, fname)) # Test default canonicalization (forward and reverse lookup). +mark('default') test(oname, rname, 'R3') test(oname + ':123', rname + ':123', 'R3') test(oname + ':xyZ', rname + ':xyZ', 'R3') diff --git a/src/tests/t_spake.py b/src/tests/t_spake.py index 5b47e62d39..15a6439f82 100644 --- a/src/tests/t_spake.py +++ b/src/tests/t_spake.py @@ -10,7 +10,7 @@ else: groups = builtin_groups for gnum, gname in groups: - output('*** Testing group %s\n' % gname) + mark('group %s' % gname) conf = {'libdefaults': {'spake_preauth_groups': gname}} for realm in multipass_realms(create_user=False, create_host=False, krb5_conf=conf): @@ -49,6 +49,7 @@ realm = K5Realm(create_user=False, krb5_conf=conf, kdc_conf=kdcconf) realm.run([kadminl, 'addprinc', '+preauth', '-pw', 'pw', 'user']) # Test with FAST. +mark('FAST') msgs = ('Using FAST due to armor ccache negotiation', 'FAST armor key:', 'Sending unauthenticated request', @@ -68,6 +69,7 @@ realm.kinit(realm.host_princ, flags=['-k']) realm.kinit('user', 'pw', flags=['-T', realm.ccache], expected_trace=msgs) # Test optimistic client preauth (151 is PA-SPAKE). +mark('client optimistic') msgs = ('Attempting optimistic preauth', 'Processing preauth types: PA-SPAKE (151)', 'Sending SPAKE support message', @@ -82,6 +84,7 @@ msgs = ('Attempting optimistic preauth', realm.run(['./icred', '-o', '151', 'user', 'pw'], expected_trace=msgs) # Test KDC optimistic challenge (accepted by client). +mark('KDC optimistic') oconf = {'kdcdefaults': {'spake_preauth_kdc_challenge': 'edwards25519'}} oenv = realm.special_env('ochal', True, krb5_conf=oconf) realm.stop_kdc() @@ -101,6 +104,7 @@ if runenv.have_spake_openssl != 'yes': # Test optimistic client preauth falling back to encrypted timestamp # because the KDC doesn't support any of the client groups. +mark('client optimistic (fallback)') p256conf={'libdefaults': {'spake_preauth_groups': 'P-256'}} p256env = realm.special_env('p256', False, krb5_conf=p256conf) msgs = ('Attempting optimistic preauth', @@ -117,6 +121,7 @@ realm.run(['./icred', '-o', '151', 'user', 'pw'], env=p256env, expected_trace=msgs) # Test KDC optimistic challenge (rejected by client). +mark('KDC optimistic (rejected)') rconf = {'libdefaults': {'spake_preauth_groups': 'P-384,edwards25519'}, 'kdcdefaults': {'spake_preauth_kdc_challenge': 'P-384'}} renv = realm.special_env('ochal', True, krb5_conf=rconf) @@ -138,6 +143,7 @@ msgs = ('Sending unauthenticated request', realm.kinit('user', 'pw', expected_trace=msgs) # Check that the auth indicator for SPAKE is properly included by the KDC. +mark('auth indicator') realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indspake]') diff --git a/src/tests/t_y2038.py b/src/tests/t_y2038.py index 02e946df46..a9017b40db 100644 --- a/src/tests/t_y2038.py +++ b/src/tests/t_y2038.py @@ -17,6 +17,7 @@ realm.start_kdc(['-T', '662256000']) # kinit without preauth should succeed with clock skew correction, but # will result in an expired ticket, because we sent an absolute end # time and didn't get a chance to correct it.. +mark('kinit, no preauth') realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ], expected_code=1, expected_msg='Ticket expired') @@ -24,6 +25,7 @@ realm.run([kvno, realm.host_princ], expected_code=1, # kinit with preauth should succeed and result in a valid ticket, as # we get a chance to correct the end time based on the KDC time. Try # with encrypted timestamp and encrypted challenge. +mark('kinit, with preauth') realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) @@ -32,6 +34,7 @@ realm.run([kvno, realm.host_princ]) # Test that expiration warning works after y2038, by setting a # password expiration time ten minutes after the KDC time. +mark('expiration warning') realm.run([kadminl, 'modprinc', '-pwexpire', '662256600 seconds', 'user']) out = realm.kinit(realm.user_princ, password('user')) if 'will expire in less than one hour' not in out: @@ -48,11 +51,13 @@ realm.prep_kadmin() # Test getdate parsing of absolute timestamps after 2038 and # marshalling over the kadmin protocol. The local time zone will # affect the display time by a little bit, so just look for the year. +mark('kadmin marshalling') realm.run_kadmin(['modprinc', '-pwexpire', '2040-02-03', realm.host_princ]) realm.run_kadmin(['getprinc', realm.host_princ], expected_msg=' 2040\n') # Get a ticket whose lifetime crosses the y2038 boundary and # range-check the expiration year as reported by klist. +mark('ticket lifetime across y2038') realm.kinit(realm.user_princ, password('user'), flags=['-l', '8000d', '-r', '8500d']) realm.run([kvno, realm.host_princ])