krb5 commit: Add marks to longer Python test scripts
Greg Hudson
ghudson at mit.edu
Sun Apr 22 13:11:01 EDT 2018
https://github.com/krb5/krb5/commit/0879b7d506c0a1bb77c85d7499a55d91743ad9a8
commit 0879b7d506c0a1bb77c85d7499a55d91743ad9a8
Author: Greg Hudson <ghudson at mit.edu>
Date: Wed Apr 18 19:21:56 2018 -0400
Add marks to longer Python test scripts
src/appl/gss-sample/t_gss_sample.py | 4 ++++
src/lib/krb5/ccache/t_cccol.py | 6 ++++++
src/lib/krb5/krb/t_vfy_increds.py | 9 +++++++++
src/tests/t_authdata.py | 24 ++++++++++++++++++++++++
src/tests/t_ccache.py | 9 +++++++++
src/tests/t_crossrealm.py | 7 +++++++
src/tests/t_dump.py | 4 ++++
src/tests/t_etype_info.py | 2 ++
src/tests/t_general.py | 7 +++++++
src/tests/t_hostrealm.py | 12 ++++++++++++
src/tests/t_iprop.py | 17 +++++++++++++++++
src/tests/t_kadmin_acl.py | 18 ++++++++++++++++++
src/tests/t_kdb.py | 19 +++++++++++++++++++
src/tests/t_keytab.py | 10 ++++++++++
src/tests/t_localauth.py | 12 ++++++++++++
src/tests/t_mkey.py | 16 ++++++++++++++++
src/tests/t_otp.py | 5 +++++
src/tests/t_pkinit.py | 25 +++++++++++++++++++++++++
src/tests/t_policy.py | 10 ++++++++--
src/tests/t_preauth.py | 14 ++++++++++++++
src/tests/t_proxy.py | 15 +++++++++++++++
src/tests/t_pwqual.py | 4 ++++
src/tests/t_rdreq.py | 13 +++++++++++++
src/tests/t_referral.py | 5 +++++
src/tests/t_renew.py | 9 +++++++++
src/tests/t_skew.py | 4 ++++
src/tests/t_sn2princ.py | 5 +++++
src/tests/t_spake.py | 8 +++++++-
src/tests/t_y2038.py | 5 +++++
29 files changed, 295 insertions(+), 3 deletions(-)
diff --git a/src/appl/gss-sample/t_gss_sample.py b/src/appl/gss-sample/t_gss_sample.py
index 0299e45..c053b27 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 f7f1785..0d78b5c 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 c820cc6..1e8e262 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 8a577b4..eef701a 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 61d549b..4ddb83a 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 4d595dc..cd7f4aa 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 at 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 8a9462b..2a424d9 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 b2eb0f7..00113aa 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 91ad0cb..3490d28 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 224c067..c14c926 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 8e23cd5..13ef1ca 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 42bdf42..d5a1326 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 at 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 6e563b1..8438a45 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 at 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 at 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 a48740b..91fd23d 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 aa625d0..63fc563 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 at KRBTEST.COM', 'user', 'default rule 1')
test_an2ln(None, 'user/KRBTEST.COM at KRBTEST.COM', 'user', 'default rule 2')
test_an2ln_err(None, 'user/KRBTEST.COM/x at KRBTEST.COM', 'No translation',
@@ -35,6 +36,7 @@ test_an2ln_err(None, 'user/X at KRBTEST.COM', 'No translation',
test_an2ln_err(None, 'user at 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 at 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 at 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 at X', 'Improper format', 'null rule')
auth3 = a2l_realm('auth3', 'UNRECOGNIZED:stuff')
@@ -65,6 +69,7 @@ test_an2ln_err(auth3, 'user at 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 at KRBTEST.COM', 'user', 'empty rule')
test_an2ln(rule1, 'user at X', 'user', 'empty rule (foreign realm)')
@@ -72,23 +77,27 @@ test_an2ln(rule1, 'a/b/c at 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 at REALM', 'REALM.burr.aaron', 'selection string')
test_an2ln_err(rule2, 'user at KRBTEST.COM', 'No translation', 'suppress default')
# Test match string.
+mark('rule (match string)')
rule3 = a2l_realm('rule3', 'RULE:(.*tail)')
test_an2ln(rule3, 'withtail at X', 'withtail', 'rule match 1')
test_an2ln(rule3, 'x/withtail at X', 'x/withtail', 'rule match 2')
test_an2ln_err(rule3, 'tails at X', 'No translation', 'rule anchor mismatch')
# Test substitutions.
+mark('rule (substitutions)')
rule4 = a2l_realm('rule4', 'RULE:s/birds/bees/')
test_an2ln(rule4, 'thebirdsbirdsbirds at X', 'thebeesbirdsbirds', 'subst 1')
rule5 = a2l_realm('rule4', 'RULE:s/birds/bees/g s/bees/birds/')
test_an2ln(rule4, 'the/birdsbirdsbirds at 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 at X', 'zazz', 'combo 5')
test_an2ln_err(combo, 'a/b at KRBTEST.COM', 'No translation', 'combo 6')
# Test the an2ln userok method with the combo environment.
+mark('userok (an2ln)')
test_userok(combo, 'fred at X', 'fred X', True, 'combo userok 1')
test_userok(combo, 'user at KRBTEST.COM', 'user', True, 'combo userok 2')
test_userok(combo, 'user at KRBTEST.COM', 'X', False, 'combo userok 3')
test_userok(combo, 'a/b at 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 615cd91..998297e 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 9b18ff9..1142fc7 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 1ba3536..769ad6a 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 at 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 at 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 = '<SAN>^user at 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 26c4e46..9d92ebd 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 32e35b0..be6d2b3 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 4e86fce..428d2f6 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 011110b..6114271 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 f67c348..1fb258b 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 at 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 at KRBTEST.COM')
test(princ2, princ1,
'35 Cannot decrypt ticket for host/2 at KRBTEST.COM using keytab key for '
'host/1 at KRBTEST.COM')
# Ticket server not found in keytab during iteration.
+mark('ticket server not found')
test(princ2, None,
'35 Request ticket server host/2 at 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 at 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 at 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 at KRBTEST.COM kvno 1 in keytab (request '
'ticket server host/2 at 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 at 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 at 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 98fdf29..5b9f74b 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 034190c..8840416 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 f2ae066..fffc634 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 19a0d2f..66f31e2 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 5b47e62..15a6439 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 02e946d..a9017b4 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])
More information about the cvs-krb5
mailing list