1from k5test import * 2 3# The next arc after 2.25 is supposed to be a single-integer UUID, but 4# since our gss_str_to_oid() can't handle arc values that don't fit in 5# an unsigned long, we use random unsigned 32-bit integers instead. 6# The final octet if the OID encoding will be used to identify the 7# mechanism when changing the behavior of just one mech. 8nxtest_oid1 = '2.25.1414534758' # final octet is 102 (0x66) 9nxtest_oid2 = '2.25.1175737388' # final octet is 44 (0x2C) 10nxtest_path = os.path.join(buildtop, 'plugins', 'gssapi', 'negoextest', 11 'gss_negoextest.so') 12 13# Test gss_add_cred(). 14realm = K5Realm(create_kdb=False) 15with open(realm.gss_mech_config, 'w') as f: 16 f.write('negoextest %s %s\n' % (nxtest_oid1, nxtest_path)) 17 f.write('negoextest %s %s\n' % (nxtest_oid2, nxtest_path)) 18 19def test(envvars, **kw): 20 # Python 3.5: e = {**realm.env, **vars} 21 e = realm.env.copy() 22 e.update(envvars) 23 realm.run(['./t_context', 'h:host'], env=e, **kw) 24 25# Test varying numbers of hops, and spot-check that messages are sent 26# in the appropriate sequence. 27 28mark('One hop') 29msgs = ('sending [0]INITIATOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 30 'd1b08469-2ca8-0000-0000-000000000000', 31 'sending [1]INITIATOR_META_DATA: c0a28569-66ac', 32 'sending [2]INITIATOR_META_DATA: d1b08469-2ca8', 33 'sending [3]AP_REQUEST: c0a28569-66ac', 34 'sending [4]VERIFY: c0a28569-66ac', 35 'received [0]INITIATOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 36 'd1b08469-2ca8-0000-0000-000000000000', 37 'received [1]INITIATOR_META_DATA: c0a28569-66ac', 38 'received [2]INITIATOR_META_DATA: d1b08469-2ca8', 39 'received [3]AP_REQUEST: c0a28569-66ac', 40 'received [4]VERIFY: c0a28569-66ac', 41 'sending [5]ACCEPTOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 42 'd1b08469-2ca8-0000-0000-000000000000', 43 'sending [6]ACCEPTOR_META_DATA: c0a28569-66ac', 44 'sending [7]ACCEPTOR_META_DATA: d1b08469-2ca8', 45 'sending [8]VERIFY: c0a28569-66ac', 46 'received [5]ACCEPTOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 47 'd1b08469-2ca8-0000-0000-000000000000', 48 'received [6]ACCEPTOR_META_DATA: c0a28569-66ac', 49 'received [7]ACCEPTOR_META_DATA: d1b08469-2ca8', 50 'received [8]VERIFY: c0a28569-66ac') 51test({'HOPS': '1'}, expected_trace=msgs) 52 53mark('Two hops') 54msgs = ('sending [7]CHALLENGE', 'sending [8]VERIFY', 'received [8]VERIFY', 55 'sending [9]VERIFY') 56test({'HOPS': '2'}, expected_trace=msgs) 57 58mark('Three hops') 59msgs = ('sending [8]AP_REQUEST', 'sending [9]VERIFY', 'received [8]AP_REQUEST', 60 'sending [10]VERIFY') 61test({'HOPS': '3'}, expected_trace=msgs) 62 63mark('Four hops') 64msgs = ('sending [9]CHALLENGE', 'sending [10]VERIFY', 'received [9]CHALLENGE', 65 'sending [11]VERIFY') 66test({'HOPS': '4'}, expected_trace=msgs) 67 68mark('Early keys, three hops') 69msgs = ('sending [4]VERIFY', 'sending [9]VERIFY', 'sending [10]AP_REQUEST') 70test({'HOPS': '3', 'KEY': 'always'}, expected_trace=msgs) 71 72mark('Early keys, four hops') 73msgs = ('sending [4]VERIFY', 'sending [9]VERIFY', 'sending [10]AP_REQUEST', 74 'sending [11]CHALLENGE') 75test({'HOPS': '4', 'KEY': 'always'}, expected_trace=msgs) 76 77mark('No keys') 78test({'KEY': 'never'}, expected_code=1, expected_msg='No NegoEx verify key') 79 80mark('No optimistic token') 81msgs = ('sending [3]ACCEPTOR_NEGO', 'sending [6]AP_REQUEST', 82 'sending [7]VERIFY', 'sending [8]VERIFY') 83test({'NEGOEX_NO_OPTIMISTIC_TOKEN': ''}, expected_trace=msgs) 84 85mark('First mech initiator query fail') 86msgs = ('sending [0]INITIATOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 87 'sending [2]AP_REQUEST', 'sending [3]VERIFY', 88 'sending [4]ACCEPTOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 89 'sending [6]VERIFY') 90test({'INIT_QUERY_FAIL': '102'}, expected_trace=msgs) 91 92mark('First mech acceptor query fail') 93msgs = ('sending [0]INITIATOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 94 'd1b08469-2ca8-0000-0000-000000000000', 95 'sending [3]AP_REQUEST: c0a28569-66ac', 96 'sending [4]VERIFY: c0a28569-66ac', 97 'sending [5]ACCEPTOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 98 'sending [7]AP_REQUEST: d1b08469-2ca8', 99 'sending [8]VERIFY: d1b08469-2ca8', 100 'sending [9]VERIFY: d1b08469-2ca8') 101test({'ACCEPT_QUERY_FAIL': '102'}, expected_trace=msgs) 102 103# Same messages as previous test. 104mark('First mech acceptor exchange fail') 105test({'ACCEPT_EXCHANGE_FAIL': '102'}, expected_trace=msgs) 106 107# Fail the optimistic mech's gss_exchange_meta_data() in the 108# initiator. Since the acceptor has effectively selected the 109# optimistic mech, this causes the authentication to fail. 110mark('First mech initiator exchange fail, one hop') 111test({'HOPS': '1', 'INIT_EXCHANGE_FAIL': '102'}, expected_code=1, 112 expected_msg='No mutually supported NegoEx authentication schemes') 113mark('First mech initiator exchange fail, two hops, early keys') 114test({'HOPS': '2', 'INIT_EXCHANGE_FAIL': '102', 'KEY': 'always'}, 115 expected_code=1, 116 expected_msg='No mutually supported NegoEx authentication schemes') 117mark('First mech initiator exchange fail, two hops') 118test({'HOPS': '2', 'INIT_EXCHANGE_FAIL': '102'}, expected_code=1, 119 expected_msg='No mutually supported NegoEx authentication schemes') 120 121mark('First mech init_sec_context fail') 122msgs = ('sending [0]INITIATOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 123 'sending [2]AP_REQUEST', 'sending [3]VERIFY', 'sending [6]VERIFY') 124test({'INIT_FAIL': '102'}, expected_trace=msgs) 125 126mark('First mech accept_sec_context fail') 127test({'HOPS': '2', 'ACCEPT_FAIL': '102'}, expected_code=1, 128 expected_msg='failure from acceptor') 129 130mark('ALERT from acceptor to initiator') 131msgs = ('sending [3]AP_REQUEST', 'sending [4]VERIFY', 'sending [8]CHALLENGE', 132 'sending [9]ALERT', 'received [9]ALERT', 'sending [10]AP_REQUEST', 133 'sending [11]VERIFY', 'sending [12]VERIFY') 134test({'HOPS': '3', 'KEY': 'init-always'}, expected_trace=msgs) 135 136mark('ALERT from initiator to acceptor') 137msgs = ('sending [3]AP_REQUEST', 'sending [7]CHALLENGE', 'sending [8]VERIFY', 138 'sending [9]AP_REQUEST', 'sending [10]ALERT', 'received [10]ALERT', 139 'sending [11]CHALLENGE', 'sending [12]VERIFY', 'sending [13]VERIFY') 140test({'HOPS': '4', 'KEY': 'accept-always'}, expected_trace=()) 141 142mark('channel bindings') 143e = realm.env.copy() 144e.update({'HOPS': '1', 'GSS_INIT_BINDING': 'a', 'GSS_ACCEPT_BINDING': 'b'}) 145# The test mech will verify that the bindings are communicated to the 146# mech, but does not set the channel-bound flag. 147realm.run(['./t_bindings', '-s', 'h:host', 'a', 'b'], env=e, expected_msg='no') 148 149success('NegoEx tests') 150