1from k5test import * 2import re 3 4realm = K5Realm(create_host=False, start_kadmind=True) 5 6# Test password quality enforcement. 7mark('password quality') 8realm.run([kadminl, 'addpol', '-minlength', '6', '-minclasses', '2', 'pwpol']) 9realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'pwpol', 'pwuser']) 10realm.run([kadminl, 'cpw', '-pw', 'sh0rt', 'pwuser'], expected_code=1, 11 expected_msg='Password is too short') 12realm.run([kadminl, 'cpw', '-pw', 'longenough', 'pwuser'], expected_code=1, 13 expected_msg='Password does not contain enough character classes') 14realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) 15 16# Test some password history enforcement. Even with no history value, 17# the current password should be denied. 18mark('password history') 19realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, 20 expected_msg='Cannot reuse password') 21realm.run([kadminl, 'modpol', '-history', '2', 'pwpol']) 22realm.run([kadminl, 'cpw', '-pw', 'an0therpw', 'pwuser']) 23realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, 24 expected_msg='Cannot reuse password') 25realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) 26realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) 27 28# Regression test for #929 (kadmind crash with more historical 29# passwords in a principal entry than current policy history setting). 30mark('password history (policy value reduced below current array size)') 31realm.run([kadminl, 'addpol', '-history', '5', 'histpol']) 32realm.addprinc('histprinc', 'first') 33realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc']) 34realm.run([kadminl, 'cpw', '-pw', 'second', 'histprinc']) 35realm.run([kadminl, 'cpw', '-pw', 'third', 'histprinc']) 36realm.run([kadminl, 'cpw', '-pw', 'fourth', 'histprinc']) 37realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) 38realm.run([kadminl, 'cpw', '-pw', 'fifth', 'histprinc']) 39realm.run([kadminl, 'delprinc', 'histprinc']) 40 41# Regression test for #2841 (heap buffer overflow when policy history 42# value is reduced to match the number of historical passwords for a 43# principal). 44mark('password history (policy value reduced to current array size)') 45def histfail(*pwlist): 46 for pw in pwlist: 47 realm.run([kadminl, 'cpw', '-pw', pw, 'histprinc'], expected_code=1, 48 expected_msg='Cannot reuse password') 49realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) 50realm.addprinc('histprinc', '1111') 51realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc']) 52realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc']) 53histfail('2222', '1111') 54realm.run([kadminl, 'modpol', '-history', '2', 'histpol']) 55realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc']) 56 57# Test that the history array is properly resized if the policy 58# history value is increased after the array is filled. 59mark('password history (policy value increase)') 60realm.run([kadminl, 'delprinc', 'histprinc']) 61realm.addprinc('histprinc', '1111') 62realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc']) 63realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc']) 64histfail('2222', '1111') 65realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc'], expected_code=1, 66 expected_msg='Cannot reuse password') 67realm.run([kadminl, 'cpw', '-pw', '1111', 'histprinc'], expected_code=1, 68 expected_msg='Cannot reuse password') 69realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) 70realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc']) 71histfail('3333', '2222', '1111') 72realm.run([kadminl, 'modpol', '-history', '4', 'histpol']) 73histfail('3333', '2222', '1111') 74realm.run([kadminl, 'cpw', '-pw', '4444', 'histprinc']) 75histfail('4444', '3333', '2222', '1111') 76 77# Test that when the policy history value is reduced, all currently 78# known old passwords still fail until the next password change, after 79# which the new number of old passwords fails (but no more). 80mark('password history (policy value reduction)') 81realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) 82histfail('4444', '3333', '2222', '1111') 83realm.run([kadminl, 'cpw', '-pw', '5555', 'histprinc']) 84histfail('5555', '3333', '3333') 85realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc']) 86realm.run([kadminl, 'modpol', '-history', '2', 'histpol']) 87histfail('2222', '5555', '4444') 88realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc']) 89 90# Test references to nonexistent policies. 91mark('nonexistent policy references') 92realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'newpol', 'newuser']) 93realm.run([kadminl, 'getprinc', 'newuser'], 94 expected_msg='Policy: newpol [does not exist]\n') 95realm.run([kadminl, 'modprinc', '-policy', 'newpol', 'pwuser']) 96# pwuser should allow reuse of the current password since newpol doesn't exist. 97realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) 98# Regression test for #8427 (min_life check with nonexistent policy). 99realm.run([kadmin, '-p', 'pwuser', '-w', '3rdpassword', 'cpw', '-pw', 100 '3rdpassword', 'pwuser']) 101 102# Create newpol and verify that it is enforced. 103mark('create referenced policy') 104realm.run([kadminl, 'addpol', '-minlength', '3', 'newpol']) 105realm.run([kadminl, 'getprinc', 'pwuser'], expected_msg='Policy: newpol\n') 106realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser'], expected_code=1, 107 expected_msg='Password is too short') 108realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser'], expected_code=1, 109 expected_msg='Cannot reuse password') 110 111realm.run([kadminl, 'getprinc', 'newuser'], expected_msg='Policy: newpol\n') 112realm.run([kadminl, 'cpw', '-pw', 'aa', 'newuser'], expected_code=1, 113 expected_msg='Password is too short') 114 115# Delete the policy and verify that it is no longer enforced. 116mark('delete referenced policy') 117realm.run([kadminl, 'delpol', 'newpol']) 118realm.run([kadminl, 'getpol', 'newpol'], expected_code=1, 119 expected_msg='Policy does not exist') 120realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser']) 121 122# Test basic password lockout support. 123mark('password lockout') 124realm.stop() 125for realm in multidb_realms(create_host=False): 126 realm.run([kadminl, 'addpol', '-maxfailure', '2', '-failurecountinterval', 127 '5m', 'lockout']) 128 realm.run([kadminl, 'modprinc', '+requires_preauth', '-policy', 'lockout', 129 'user']) 130 131 # kinit twice with the wrong password. 132 msg = 'Password incorrect while getting initial credentials' 133 realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, 134 expected_msg=msg) 135 realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, 136 expected_msg=msg) 137 138 # Now the account should be locked out. 139 msg = 'credentials have been revoked while getting initial credentials' 140 realm.run([kinit, realm.user_princ], expected_code=1, expected_msg=msg) 141 142 # Check that modprinc -unlock allows a further attempt. 143 realm.run([kadminl, 'modprinc', '-unlock', 'user']) 144 realm.kinit(realm.user_princ, password('user')) 145 146 # Make sure a nonexistent policy reference doesn't prevent authentication. 147 realm.run([kadminl, 'delpol', 'lockout']) 148 realm.kinit(realm.user_princ, password('user')) 149 150# Regression test for issue #7099: databases created prior to krb5 1.3 have 151# multiple history keys, and kadmin prior to 1.7 didn't necessarily use the 152# first one to create history entries. 153mark('#7099 regression test') 154realm = K5Realm(start_kdc=False) 155# Create a history principal with two keys. 156realm.run(['./hist', 'make']) 157realm.run([kadminl, 'addpol', '-history', '2', 'pol']) 158realm.run([kadminl, 'modprinc', '-policy', 'pol', 'user']) 159realm.run([kadminl, 'cpw', '-pw', 'pw2', 'user']) 160# Swap the keys, simulating older kadmin having chosen the second entry. 161realm.run(['./hist', 'swap']) 162# Make sure we can read the history entry. 163realm.run([kadminl, 'cpw', '-pw', password('user'), 'user'], expected_code=1, 164 expected_msg='Cannot reuse password') 165 166# Test key/salt constraints. 167mark('allowedkeysalts') 168 169realm.stop() 170krb5_conf1 = {'libdefaults': {'supported_enctypes': 'aes256-cts'}} 171realm = K5Realm(krb5_conf=krb5_conf1, create_host=False, get_creds=False) 172 173# Add policy. 174realm.run([kadminl, 'addpol', '-allowedkeysalts', 'aes256-cts', 'ak']) 175realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) 176 177# Test with one-enctype allowed_keysalts. 178realm.run([kadminl, 'modprinc', '-policy', 'ak', 'server']) 179out = realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes128-cts', 'server'], 180 expected_code=1) 181if not 'Invalid key/salt tuples' in out: 182 fail('allowed_keysalts policy not applied properly') 183realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', 'server']) 184 185# Now test a multi-enctype allowed_keysalts. Test that subsets are allowed, 186# the the complete set is allowed, that order doesn't matter, and that 187# enctypes outside the set are not allowed. 188 189# Test modpol. 190realm.run([kadminl, 'modpol', '-allowedkeysalts', 'aes256-cts,rc4-hmac', 'ak']) 191realm.run([kadminl, 'getpol', 'ak'], 192 expected_msg='Allowed key/salt types: aes256-cts,rc4-hmac') 193 194# Test subsets and full set. 195realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac', 'server']) 196realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', 'server']) 197realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts,rc4-hmac', 'server']) 198realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes256-cts', 'server']) 199 200# Check that the order we got is the one from the policy. 201realm.run([kadminl, 'getprinc', '-terse', 'server'], 202 expected_msg='2\t1\t6\t18\t0\t1\t6\t23\t0') 203 204# Test partially intersecting sets. 205realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes128-cts', 'server'], 206 expected_code=1, expected_msg='Invalid key/salt tuples') 207realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes256-cts,aes128-cts', 208 'server'], expected_code=1, expected_msg='Invalid key/salt tuples') 209 210# Test reset of allowedkeysalts. 211realm.run([kadminl, 'modpol', '-allowedkeysalts', '-', 'ak']) 212out = realm.run([kadminl, 'getpol', 'ak']) 213if 'Allowed key/salt types' in out: 214 fail('failed to clear allowedkeysalts') 215realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes128-cts', 'server']) 216 217success('Policy tests') 218