1from k5test import * 2from datetime import datetime 3import re 4 5conf = {'realms': {'$realm': {'max_life': '20h', 'max_renewable_life': '20h'}}} 6realm = K5Realm(create_host=False, get_creds=False, kdc_conf=conf) 7 8def test(testname, life, rlife, exp_life, exp_rlife, env=None): 9 global realm 10 flags = ['-l', life] 11 if rlife is not None: 12 flags += ['-r', rlife] 13 realm.kinit(realm.user_princ, password('user'), flags=flags, env=env) 14 out = realm.run([klist, '-f']) 15 16 if ('Default principal: %s\n' % realm.user_princ) not in out: 17 fail('%s: did not get tickets' % testname) 18 19 # Extract flags and check the renewable flag against expectations. 20 flags = re.findall(r'Flags: ([a-zA-Z]*)', out)[0] 21 if exp_rlife is None and 'R' in flags: 22 fail('%s: ticket unexpectedly renewable' % testname) 23 if exp_rlife is not None and 'R' not in flags: 24 fail('%s: ticket unexpectedly non-renewable' % testname) 25 26 # Extract the start time, end time, and renewable end time if present. 27 times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) 28 times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] 29 starttime = times[0] 30 endtime = times[1] 31 rtime = times[2] if len(times) >= 3 else None 32 33 # Check the ticket lifetime against expectations. If the lifetime 34 # was determined by the request, there may be a small error 35 # because KDC requests contain an end time rather than a lifetime. 36 life = (endtime - starttime).seconds 37 if abs(life - exp_life) > 5: 38 fail('%s: expected life %d, got %d' % (testname, exp_life, life)) 39 40 # Check the ticket renewable lifetime against expectations. 41 if exp_rlife is None and rtime is not None: 42 fail('%s: ticket has unexpected renew_till' % testname) 43 if exp_rlife is not None and rtime is None: 44 fail('%s: ticket is renewable but has no renew_till' % testname) 45 if rtime is not None: 46 rlife = (rtime - starttime).seconds 47 if abs(rlife - exp_rlife) > 5: 48 fail('%s: expected rlife %d, got %d' (testname, exp_rlife, rlife)) 49 50# Get renewable tickets. 51test('simple', '1h', '2h', 3600, 7200) 52 53# Renew twice, to test that renewed tickets are renewable. 54mark('renew twice') 55realm.kinit(realm.user_princ, flags=['-R']) 56realm.kinit(realm.user_princ, flags=['-R']) 57realm.klist(realm.user_princ) 58 59# Make sure we can use a renewed ticket. 60realm.run([kvno, realm.user_princ]) 61 62# Make sure we can't renew non-renewable tickets. 63mark('non-renewable') 64test('non-renewable', '1h', None, 3600, None) 65realm.kinit(realm.user_princ, flags=['-R'], expected_code=1, 66 expected_msg="KDC can't fulfill requested option") 67 68# Test that -allow_renewable on the client principal works. 69mark('allow_renewable (client)') 70realm.run([kadminl, 'modprinc', '-allow_renewable', 'user']) 71test('disallowed client', '1h', '2h', 3600, None) 72realm.run([kadminl, 'modprinc', '+allow_renewable', 'user']) 73 74# Test that -allow_renewable on the server principal works. 75mark('allow_renewable (server)') 76realm.run([kadminl, 'modprinc', '-allow_renewable', realm.krbtgt_princ]) 77test('disallowed server', '1h', '2h', 3600, None) 78realm.run([kadminl, 'modprinc', '+allow_renewable', realm.krbtgt_princ]) 79 80# Test that trivially renewable tickets are issued if renew_till <= 81# till. (Our client code bumps up the requested renewable life to the 82# requested life.) 83mark('trivially renewable') 84test('short', '2h', '1h', 7200, 7200) 85 86# Test that renewable tickets are issued if till > max life by 87# default, but not if we configure away the RENEWABLE-OK option. 88mark('renewable-ok') 89no_opts_conf = {'libdefaults': {'kdc_default_options': '0'}} 90no_opts = realm.special_env('no_opts', False, krb5_conf=no_opts_conf) 91realm.run([kadminl, 'modprinc', '-maxlife', '10 hours', 'user']) 92test('long', '15h', None, 10 * 3600, 15 * 3600) 93test('long noopts', '15h', None, 10 * 3600, None, env=no_opts) 94realm.run([kadminl, 'modprinc', '-maxlife', '20 hours', 'user']) 95 96# Test maximum renewable life on the client principal. 97mark('maxrenewlife (client)') 98realm.run([kadminl, 'modprinc', '-maxrenewlife', '5 hours', 'user']) 99test('maxrenewlife client 1', '4h', '5h', 4 * 3600, 5 * 3600) 100test('maxrenewlife client 2', '6h', '10h', 6 * 3600, 5 * 3600) 101 102# Test maximum renewable life on the server principal. 103mark('maxrenewlife (server)') 104realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', 105 realm.krbtgt_princ]) 106test('maxrenewlife server 1', '2h', '3h', 2 * 3600, 3 * 3600) 107test('maxrenewlife server 2', '4h', '8h', 4 * 3600, 3 * 3600) 108 109# Test realm maximum life. 110mark('realm maximum life') 111realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', 'user']) 112realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', 113 realm.krbtgt_princ]) 114test('maxrenewlife realm 1', '10h', '20h', 10 * 3600, 20 * 3600) 115test('maxrenewlife realm 2', '21h', '40h', 20 * 3600, 20 * 3600) 116 117success('Renewing credentials') 118