1from k5test import * 2 3# Test that the kdcpreauth client_keyblock() callback matches the key 4# indicated by the etype info, and returns NULL if no key was selected. 5testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') 6conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 7 'clpreauth': {'module': 'test:' + testpreauth}}} 8realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) 9realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) 10realm.run([kadminl, 'setstr', realm.user_princ, 'teststring', 'testval']) 11realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser']) 12realm.kinit(realm.user_princ, password('user'), expected_msg='testval') 13realm.kinit('nokeyuser', password('user'), expected_code=1, 14 expected_msg='no key') 15 16# Preauth type -123 is the test preauth module type; 133 is FAST 17# PA-FX-COOKIE; 2 is encrypted timestamp. 18 19# Test normal preauth flow. 20mark('normal') 21msgs = ('Sending unauthenticated request', 22 '/Additional pre-authentication required', 23 'Preauthenticating using KDC method data', 24 'Processing preauth types:', 25 'Preauth module test (-123) (real) returned: 0/Success', 26 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 27 'Decrypted AS reply') 28realm.run(['./icred', realm.user_princ, password('user')], 29 expected_msg='testval', expected_trace=msgs) 30 31# Test successful optimistic preauth. 32mark('optimistic') 33expected_trace = ('Attempting optimistic preauth', 34 'Processing preauth types: -123', 35 'Preauth module test (-123) (real) returned: 0/Success', 36 'Produced preauth for next request: -123', 37 'Decrypted AS reply') 38realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], 39 expected_trace=expected_trace) 40 41# Test optimistic preauth failing on client, falling back to encrypted 42# timestamp. 43mark('optimistic (client failure)') 44msgs = ('Attempting optimistic preauth', 45 'Processing preauth types: -123', 46 '/induced optimistic fail', 47 'Sending unauthenticated request', 48 '/Additional pre-authentication required', 49 'Preauthenticating using KDC method data', 50 'Processing preauth types:', 51 'Encrypted timestamp (for ', 52 'module encrypted_timestamp (2) (real) returned: 0/Success', 53 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 54 'Decrypted AS reply') 55realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ, 56 password('user')], expected_trace=msgs) 57 58# Test optimistic preauth failing on KDC, falling back to encrypted 59# timestamp. 60mark('optimistic (KDC failure)') 61realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes']) 62msgs = ('Attempting optimistic preauth', 63 'Processing preauth types: -123', 64 'Preauth module test (-123) (real) returned: 0/Success', 65 'Produced preauth for next request: -123', 66 '/Preauthentication failed', 67 'Preauthenticating using KDC method data', 68 'Processing preauth types:', 69 'Encrypted timestamp (for ', 70 'module encrypted_timestamp (2) (real) returned: 0/Success', 71 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 72 'Decrypted AS reply') 73realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], 74 expected_trace=msgs) 75# Leave failopt set for the next test. 76 77# Test optimistic preauth failing on KDC, stopping because the test 78# module disabled fallback. 79mark('optimistic (KDC failure, no fallback)') 80msgs = ('Attempting optimistic preauth', 81 'Processing preauth types: -123', 82 'Preauth module test (-123) (real) returned: 0/Success', 83 'Produced preauth for next request: -123', 84 '/Preauthentication failed') 85realm.run(['./icred', '-X', 'disable_fallback', '-o', '-123', realm.user_princ, 86 password('user')], expected_code=1, 87 expected_msg='Preauthentication failed', expected_trace=msgs) 88realm.run([kadminl, 'delstr', realm.user_princ, 'failopt']) 89 90# Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. 91mark('second round-trip') 92realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip']) 93msgs = ('Sending unauthenticated request', 94 '/Additional pre-authentication required', 95 'Preauthenticating using KDC method data', 96 'Processing preauth types:', 97 'Preauth module test (-123) (real) returned: 0/Success', 98 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 99 '/More preauthentication data is required', 100 'Continuing preauth mech -123', 101 'Processing preauth types: -123, PA-FX-COOKIE (133)', 102 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 103 'Decrypted AS reply') 104realm.run(['./icred', realm.user_princ, password('user')], 105 expected_msg='2rt: secondtrip', expected_trace=msgs) 106 107# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, 108# falling back to encrypted timestamp. 109mark('second round-trip (client failure)') 110msgs = ('Sending unauthenticated request', 111 '/Additional pre-authentication required', 112 'Preauthenticating using KDC method data', 113 'Processing preauth types:', 114 'Preauth module test (-123) (real) returned: 0/Success', 115 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 116 '/More preauthentication data is required', 117 'Continuing preauth mech -123', 118 'Processing preauth types: -123, PA-FX-COOKIE (133)', 119 '/induced 2rt fail', 120 'Preauthenticating using KDC method data', 121 'Processing preauth types:', 122 'Encrypted timestamp (for ', 123 'module encrypted_timestamp (2) (real) returned: 0/Success', 124 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 125 'Decrypted AS reply') 126realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')], 127 expected_msg='2rt: secondtrip', expected_trace=msgs) 128 129# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, 130# stopping because the test module disabled fallback. 131mark('second round-trip (client failure, no fallback)') 132msgs = ('Sending unauthenticated request', 133 '/Additional pre-authentication required', 134 'Preauthenticating using KDC method data', 135 'Processing preauth types:', 136 'Preauth module test (-123) (real) returned: 0/Success', 137 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 138 '/More preauthentication data is required', 139 'Continuing preauth mech -123', 140 'Processing preauth types: -123, PA-FX-COOKIE (133)', 141 '/induced 2rt fail') 142realm.run(['./icred', '-X', 'fail_2rt', '-X', 'disable_fallback', 143 realm.user_princ, password('user')], expected_code=1, 144 expected_msg='Pre-authentication failed: induced 2rt fail', 145 expected_trace=msgs) 146 147# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, 148# falling back to encrypted timestamp. 149mark('second round-trip (KDC failure)') 150realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes']) 151msgs = ('Sending unauthenticated request', 152 '/Additional pre-authentication required', 153 'Preauthenticating using KDC method data', 154 'Processing preauth types:', 155 'Preauth module test (-123) (real) returned: 0/Success', 156 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 157 '/More preauthentication data is required', 158 'Continuing preauth mech -123', 159 'Processing preauth types: -123, PA-FX-COOKIE (133)', 160 'Preauth module test (-123) (real) returned: 0/Success', 161 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 162 '/Preauthentication failed', 163 'Preauthenticating using KDC method data', 164 'Processing preauth types:', 165 'Encrypted timestamp (for ', 166 'module encrypted_timestamp (2) (real) returned: 0/Success', 167 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 168 'Decrypted AS reply') 169realm.run(['./icred', realm.user_princ, password('user')], 170 expected_msg='2rt: secondtrip', expected_trace=msgs) 171# Leave fail2rt set for the next test. 172 173# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, 174# stopping because the test module disabled fallback. 175mark('second round-trip (KDC failure, no fallback)') 176msgs = ('Sending unauthenticated request', 177 '/Additional pre-authentication required', 178 'Preauthenticating using KDC method data', 179 'Processing preauth types:', 180 'Preauth module test (-123) (real) returned: 0/Success', 181 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 182 '/More preauthentication data is required', 183 'Continuing preauth mech -123', 184 'Processing preauth types: -123, PA-FX-COOKIE (133)', 185 'Preauth module test (-123) (real) returned: 0/Success', 186 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 187 '/Preauthentication failed') 188realm.run(['./icred', '-X', 'disable_fallback', 189 realm.user_princ, password('user')], expected_code=1, 190 expected_msg='Preauthentication failed', expected_trace=msgs) 191realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt']) 192 193# Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC. 194mark('tryagain') 195realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain']) 196msgs = ('Sending unauthenticated request', 197 '/Additional pre-authentication required', 198 'Preauthenticating using KDC method data', 199 'Processing preauth types:', 200 'Preauth module test (-123) (real) returned: 0/Success', 201 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 202 '/KDC has no support for encryption type', 203 'Recovering from KDC error 14 using preauth mech -123', 204 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', 205 'Preauth module test (-123) tryagain returned: 0/Success', 206 'Followup preauth for next request: -123, PA-FX-COOKIE (133)', 207 'Decrypted AS reply') 208realm.run(['./icred', realm.user_princ, password('user')], 209 expected_msg='tryagain: testagain', expected_trace=msgs) 210 211# Test a client-side tryagain failure, falling back to encrypted 212# timestamp. 213mark('tryagain (client failure)') 214msgs = ('Sending unauthenticated request', 215 '/Additional pre-authentication required', 216 'Preauthenticating using KDC method data', 217 'Processing preauth types:', 218 'Preauth module test (-123) (real) returned: 0/Success', 219 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 220 '/KDC has no support for encryption type', 221 'Recovering from KDC error 14 using preauth mech -123', 222 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', 223 '/induced tryagain fail', 224 'Preauthenticating using KDC method data', 225 'Processing preauth types:', 226 'Encrypted timestamp (for ', 227 'module encrypted_timestamp (2) (real) returned: 0/Success', 228 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 229 'Decrypted AS reply') 230realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ, 231 password('user')], expected_trace=msgs) 232 233# Test a client-side tryagain failure, stopping because the test 234# module disabled fallback. 235mark('tryagain (client failure, no fallback)') 236msgs = ('Sending unauthenticated request', 237 '/Additional pre-authentication required', 238 'Preauthenticating using KDC method data', 239 'Processing preauth types:', 240 'Preauth module test (-123) (real) returned: 0/Success', 241 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 242 '/KDC has no support for encryption type', 243 'Recovering from KDC error 14 using preauth mech -123', 244 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', 245 '/induced tryagain fail') 246realm.run(['./icred', '-X', 'fail_tryagain', '-X', 'disable_fallback', 247 realm.user_princ, password('user')], expected_code=1, 248 expected_msg='KDC has no support for encryption type', 249 expected_trace=msgs) 250 251# Test that multiple stepwise initial creds operations can be 252# performed with the same krb5_context, with proper tracking of 253# clpreauth module request handles. 254mark('interleaved') 255realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1']) 256realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2']) 257realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3']) 258realm.run([kadminl, 'setstr', 'u2', '2rt', 'extra']) 259out = realm.run(['./icinterleave', 'pw', 'u1', 'u2', 'u3']) 260if out != ('step 1\nstep 2\nstep 3\nstep 1\nfinish 1\nstep 2\nno attr\n' 261 'step 3\nno attr\nstep 2\n2rt: extra\nstep 3\nfinish 3\nstep 2\n' 262 'finish 2\n'): 263 fail('unexpected output from icinterleave') 264 265success('Pre-authentication framework tests') 266