xref: /freebsd/crypto/krb5/src/tests/gssapi/t_negoex.py (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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