1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dmitry Safonov <dima@arista.com> */
3 #include <inttypes.h>
4 #include "aolib.h"
5
6 #define fault(type) (inj == FAULT_ ## type)
7 static const char *md5_password = "Some evil genius, enemy to mankind, must have been the first contriver.";
8 static const char *ao_password = DEFAULT_TEST_PASSWORD;
9
10 static union tcp_addr client2;
11 static union tcp_addr client3;
12
13 static const int test_vrf_ifindex = 200;
14 static const uint8_t test_vrf_tabid = 42;
setup_vrfs(void)15 static void setup_vrfs(void)
16 {
17 int err;
18
19 if (!kernel_config_has(KCONFIG_NET_VRF))
20 return;
21
22 err = add_vrf("ksft-vrf", test_vrf_tabid, test_vrf_ifindex, -1);
23 if (err)
24 test_error("Failed to add a VRF: %d", err);
25
26 err = link_set_up("ksft-vrf");
27 if (err)
28 test_error("Failed to bring up a VRF");
29
30 err = ip_route_add_vrf(veth_name, TEST_FAMILY,
31 this_ip_addr, this_ip_dest, test_vrf_tabid);
32 if (err)
33 test_error("Failed to add a route to VRF: %d", err);
34 }
35
try_accept(const char * tst_name,unsigned int port,union tcp_addr * md5_addr,uint8_t md5_prefix,union tcp_addr * ao_addr,uint8_t ao_prefix,bool set_ao_required,uint8_t sndid,uint8_t rcvid,uint8_t vrf,const char * cnt_name,test_cnt cnt_expected,int needs_tcp_md5,fault_t inj)36 static void try_accept(const char *tst_name, unsigned int port,
37 union tcp_addr *md5_addr, uint8_t md5_prefix,
38 union tcp_addr *ao_addr, uint8_t ao_prefix,
39 bool set_ao_required,
40 uint8_t sndid, uint8_t rcvid, uint8_t vrf,
41 const char *cnt_name, test_cnt cnt_expected,
42 int needs_tcp_md5, fault_t inj)
43 {
44 struct tcp_ao_counters ao_cnt1, ao_cnt2;
45 uint64_t before_cnt = 0, after_cnt = 0; /* silence GCC */
46 int lsk, err, sk = 0;
47 time_t timeout;
48
49 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5))
50 return;
51
52 lsk = test_listen_socket(this_ip_addr, port, 1);
53
54 if (md5_addr && test_set_md5(lsk, *md5_addr, md5_prefix, -1, md5_password))
55 test_error("setsockopt(TCP_MD5SIG_EXT)");
56
57 if (ao_addr && test_add_key(lsk, ao_password,
58 *ao_addr, ao_prefix, sndid, rcvid))
59 test_error("setsockopt(TCP_AO_ADD_KEY)");
60
61 if (set_ao_required && test_set_ao_flags(lsk, true, false))
62 test_error("setsockopt(TCP_AO_INFO)");
63
64 if (cnt_name)
65 before_cnt = netstat_get_one(cnt_name, NULL);
66 if (ao_addr && test_get_tcp_ao_counters(lsk, &ao_cnt1))
67 test_error("test_get_tcp_ao_counters()");
68
69 synchronize_threads(); /* preparations done */
70
71 timeout = fault(TIMEOUT) ? TEST_RETRANSMIT_SEC : TEST_TIMEOUT_SEC;
72 err = test_wait_fd(lsk, timeout, 0);
73 synchronize_threads(); /* connect()/accept() timeouts */
74 if (err == -ETIMEDOUT) {
75 if (!fault(TIMEOUT))
76 test_fail("timed out for accept()");
77 } else if (err < 0) {
78 test_error("test_wait_fd()");
79 } else {
80 if (fault(TIMEOUT))
81 test_fail("ready to accept");
82
83 sk = accept(lsk, NULL, NULL);
84 if (sk < 0) {
85 test_error("accept()");
86 } else {
87 if (fault(TIMEOUT))
88 test_fail("%s: accepted", tst_name);
89 }
90 }
91
92 if (ao_addr && test_get_tcp_ao_counters(lsk, &ao_cnt2))
93 test_error("test_get_tcp_ao_counters()");
94 close(lsk);
95
96 if (!cnt_name) {
97 test_ok("%s: no counter checks", tst_name);
98 goto out;
99 }
100
101 after_cnt = netstat_get_one(cnt_name, NULL);
102
103 if (after_cnt <= before_cnt) {
104 test_fail("%s: %s counter did not increase: %" PRIu64 " <= %" PRIu64,
105 tst_name, cnt_name, after_cnt, before_cnt);
106 } else {
107 test_ok("%s: counter %s increased %" PRIu64 " => %" PRIu64,
108 tst_name, cnt_name, before_cnt, after_cnt);
109 }
110 if (ao_addr)
111 test_tcp_ao_counters_cmp(tst_name, &ao_cnt1, &ao_cnt2, cnt_expected);
112
113 out:
114 synchronize_threads(); /* test_kill_sk() */
115 if (sk > 0)
116 test_kill_sk(sk);
117 }
118
server_add_routes(void)119 static void server_add_routes(void)
120 {
121 int family = TEST_FAMILY;
122
123 synchronize_threads(); /* client_add_ips() */
124
125 if (ip_route_add(veth_name, family, this_ip_addr, client2))
126 test_error("Failed to add route");
127 if (ip_route_add(veth_name, family, this_ip_addr, client3))
128 test_error("Failed to add route");
129 }
130
server_add_fail_tests(unsigned int * port)131 static void server_add_fail_tests(unsigned int *port)
132 {
133 union tcp_addr addr_any = {};
134
135 try_accept("TCP-AO established: add TCP-MD5 key", (*port)++, NULL, 0,
136 &addr_any, 0, 0, 100, 100, 0, "TCPAOGood", TEST_CNT_GOOD,
137 1, 0);
138 try_accept("TCP-MD5 established: add TCP-AO key", (*port)++, &addr_any,
139 0, NULL, 0, 0, 0, 0, 0, NULL, 0, 1, 0);
140 try_accept("non-signed established: add TCP-AO key", (*port)++, NULL, 0,
141 NULL, 0, 0, 0, 0, 0, "CurrEstab", 0, 0, 0);
142 }
143
server_vrf_tests(unsigned int * port)144 static void server_vrf_tests(unsigned int *port)
145 {
146 setup_vrfs();
147 }
148
server_fn(void * arg)149 static void *server_fn(void *arg)
150 {
151 unsigned int port = test_server_port;
152 union tcp_addr addr_any = {};
153
154 server_add_routes();
155
156 try_accept("AO server (INADDR_ANY): AO client", port++, NULL, 0,
157 &addr_any, 0, 0, 100, 100, 0, "TCPAOGood",
158 TEST_CNT_GOOD, 0, 0);
159 try_accept("AO server (INADDR_ANY): MD5 client", port++, NULL, 0,
160 &addr_any, 0, 0, 100, 100, 0, "TCPMD5Unexpected",
161 0, 1, FAULT_TIMEOUT);
162 try_accept("AO server (INADDR_ANY): no sign client", port++, NULL, 0,
163 &addr_any, 0, 0, 100, 100, 0, "TCPAORequired",
164 TEST_CNT_AO_REQUIRED, 0, FAULT_TIMEOUT);
165 try_accept("AO server (AO_REQUIRED): AO client", port++, NULL, 0,
166 &this_ip_dest, TEST_PREFIX, true,
167 100, 100, 0, "TCPAOGood", TEST_CNT_GOOD, 0, 0);
168 try_accept("AO server (AO_REQUIRED): unsigned client", port++, NULL, 0,
169 &this_ip_dest, TEST_PREFIX, true,
170 100, 100, 0, "TCPAORequired",
171 TEST_CNT_AO_REQUIRED, 0, FAULT_TIMEOUT);
172
173 try_accept("MD5 server (INADDR_ANY): AO client", port++, &addr_any, 0,
174 NULL, 0, 0, 0, 0, 0, "TCPAOKeyNotFound",
175 0, 1, FAULT_TIMEOUT);
176 try_accept("MD5 server (INADDR_ANY): MD5 client", port++, &addr_any, 0,
177 NULL, 0, 0, 0, 0, 0, NULL, 0, 1, 0);
178 try_accept("MD5 server (INADDR_ANY): no sign client", port++, &addr_any,
179 0, NULL, 0, 0, 0, 0, 0, "TCPMD5NotFound",
180 0, 1, FAULT_TIMEOUT);
181
182 try_accept("no sign server: AO client", port++, NULL, 0,
183 NULL, 0, 0, 0, 0, 0, "TCPAOKeyNotFound",
184 TEST_CNT_AO_KEY_NOT_FOUND, 0, FAULT_TIMEOUT);
185 try_accept("no sign server: MD5 client", port++, NULL, 0,
186 NULL, 0, 0, 0, 0, 0, "TCPMD5Unexpected",
187 0, 1, FAULT_TIMEOUT);
188 try_accept("no sign server: no sign client", port++, NULL, 0,
189 NULL, 0, 0, 0, 0, 0, "CurrEstab", 0, 0, 0);
190
191 try_accept("AO+MD5 server: AO client (matching)", port++,
192 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
193 100, 100, 0, "TCPAOGood", TEST_CNT_GOOD, 1, 0);
194 try_accept("AO+MD5 server: AO client (misconfig, matching MD5)", port++,
195 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
196 100, 100, 0, "TCPAOKeyNotFound", TEST_CNT_AO_KEY_NOT_FOUND,
197 1, FAULT_TIMEOUT);
198 try_accept("AO+MD5 server: AO client (misconfig, non-matching)", port++,
199 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
200 100, 100, 0, "TCPAOKeyNotFound", TEST_CNT_AO_KEY_NOT_FOUND,
201 1, FAULT_TIMEOUT);
202 try_accept("AO+MD5 server: MD5 client (matching)", port++,
203 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
204 100, 100, 0, NULL, 0, 1, 0);
205 try_accept("AO+MD5 server: MD5 client (misconfig, matching AO)", port++,
206 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
207 100, 100, 0, "TCPMD5Unexpected", 0, 1, FAULT_TIMEOUT);
208 try_accept("AO+MD5 server: MD5 client (misconfig, non-matching)", port++,
209 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
210 100, 100, 0, "TCPMD5Unexpected", 0, 1, FAULT_TIMEOUT);
211 try_accept("AO+MD5 server: no sign client (unmatched)", port++,
212 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
213 100, 100, 0, "CurrEstab", 0, 1, 0);
214 try_accept("AO+MD5 server: no sign client (misconfig, matching AO)",
215 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
216 100, 100, 0, "TCPAORequired",
217 TEST_CNT_AO_REQUIRED, 1, FAULT_TIMEOUT);
218 try_accept("AO+MD5 server: no sign client (misconfig, matching MD5)",
219 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
220 100, 100, 0, "TCPMD5NotFound", 0, 1, FAULT_TIMEOUT);
221
222 try_accept("AO+MD5 server: client with both [TCP-MD5] and TCP-AO keys",
223 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
224 100, 100, 0, NULL, 0, 1, FAULT_TIMEOUT);
225 try_accept("AO+MD5 server: client with both TCP-MD5 and [TCP-AO] keys",
226 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0,
227 100, 100, 0, NULL, 0, 1, FAULT_TIMEOUT);
228
229 server_add_fail_tests(&port);
230
231 server_vrf_tests(&port);
232
233 /* client exits */
234 synchronize_threads();
235 return NULL;
236 }
237
client_bind(int sk,union tcp_addr bind_addr)238 static int client_bind(int sk, union tcp_addr bind_addr)
239 {
240 #ifdef IPV6_TEST
241 struct sockaddr_in6 addr = {
242 .sin6_family = AF_INET6,
243 .sin6_port = 0,
244 .sin6_addr = bind_addr.a6,
245 };
246 #else
247 struct sockaddr_in addr = {
248 .sin_family = AF_INET,
249 .sin_port = 0,
250 .sin_addr = bind_addr.a4,
251 };
252 #endif
253 return bind(sk, &addr, sizeof(addr));
254 }
255
try_connect(const char * tst_name,unsigned int port,union tcp_addr * md5_addr,uint8_t md5_prefix,union tcp_addr * ao_addr,uint8_t ao_prefix,uint8_t sndid,uint8_t rcvid,uint8_t vrf,fault_t inj,int needs_tcp_md5,union tcp_addr * bind_addr)256 static void try_connect(const char *tst_name, unsigned int port,
257 union tcp_addr *md5_addr, uint8_t md5_prefix,
258 union tcp_addr *ao_addr, uint8_t ao_prefix,
259 uint8_t sndid, uint8_t rcvid, uint8_t vrf,
260 fault_t inj, int needs_tcp_md5, union tcp_addr *bind_addr)
261 {
262 time_t timeout;
263 int sk, ret;
264
265 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5))
266 return;
267
268 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
269 if (sk < 0)
270 test_error("socket()");
271
272 if (bind_addr && client_bind(sk, *bind_addr))
273 test_error("bind()");
274
275 if (md5_addr && test_set_md5(sk, *md5_addr, md5_prefix, -1, md5_password))
276 test_error("setsockopt(TCP_MD5SIG_EXT)");
277
278 if (ao_addr && test_add_key(sk, ao_password, *ao_addr,
279 ao_prefix, sndid, rcvid))
280 test_error("setsockopt(TCP_AO_ADD_KEY)");
281
282 synchronize_threads(); /* preparations done */
283
284 timeout = fault(TIMEOUT) ? TEST_RETRANSMIT_SEC : TEST_TIMEOUT_SEC;
285 ret = _test_connect_socket(sk, this_ip_dest, port, timeout);
286
287 synchronize_threads(); /* connect()/accept() timeouts */
288 if (ret < 0) {
289 if (fault(KEYREJECT) && ret == -EKEYREJECTED)
290 test_ok("%s: connect() was prevented", tst_name);
291 else if (ret == -ETIMEDOUT && fault(TIMEOUT))
292 test_ok("%s", tst_name);
293 else if (ret == -ECONNREFUSED &&
294 (fault(TIMEOUT) || fault(KEYREJECT)))
295 test_ok("%s: refused to connect", tst_name);
296 else
297 test_error("%s: connect() returned %d", tst_name, ret);
298 goto out;
299 }
300
301 if (fault(TIMEOUT) || fault(KEYREJECT))
302 test_fail("%s: connected", tst_name);
303 else
304 test_ok("%s: connected", tst_name);
305
306 out:
307 synchronize_threads(); /* test_kill_sk() */
308 /* _test_connect_socket() cleans up on failure */
309 if (ret > 0)
310 test_kill_sk(sk);
311 }
312
313 #define PREINSTALL_MD5_FIRST BIT(0)
314 #define PREINSTALL_AO BIT(1)
315 #define POSTINSTALL_AO BIT(2)
316 #define PREINSTALL_MD5 BIT(3)
317 #define POSTINSTALL_MD5 BIT(4)
318
try_add_key_vrf(int sk,union tcp_addr in_addr,uint8_t prefix,int vrf,uint8_t sndid,uint8_t rcvid,bool set_ao_required)319 static int try_add_key_vrf(int sk, union tcp_addr in_addr, uint8_t prefix,
320 int vrf, uint8_t sndid, uint8_t rcvid,
321 bool set_ao_required)
322 {
323 uint8_t keyflags = 0;
324
325 if (vrf >= 0)
326 keyflags |= TCP_AO_KEYF_IFINDEX;
327 else
328 vrf = 0;
329 if (set_ao_required) {
330 int err = test_set_ao_flags(sk, true, 0);
331
332 if (err)
333 return err;
334 }
335 return test_add_key_vrf(sk, ao_password, keyflags, in_addr, prefix,
336 (uint8_t)vrf, sndid, rcvid);
337 }
338
test_continue(const char * tst_name,int err,fault_t inj,bool added_ao)339 static bool test_continue(const char *tst_name, int err,
340 fault_t inj, bool added_ao)
341 {
342 bool expected_to_fail;
343
344 expected_to_fail = fault(PREINSTALL_AO) && added_ao;
345 expected_to_fail |= fault(PREINSTALL_MD5) && !added_ao;
346
347 if (!err) {
348 if (!expected_to_fail)
349 return true;
350 test_fail("%s: setsockopt()s were expected to fail", tst_name);
351 return false;
352 }
353 if (err != -EKEYREJECTED || !expected_to_fail) {
354 test_error("%s: setsockopt(%s) = %d", tst_name,
355 added_ao ? "TCP_AO_ADD_KEY" : "TCP_MD5SIG_EXT", err);
356 return false;
357 }
358 test_ok("%s: prefailed as expected: %m", tst_name);
359 return false;
360 }
361
open_add(const char * tst_name,unsigned int port,unsigned int strategy,union tcp_addr md5_addr,uint8_t md5_prefix,int md5_vrf,union tcp_addr ao_addr,uint8_t ao_prefix,int ao_vrf,bool set_ao_required,uint8_t sndid,uint8_t rcvid,fault_t inj)362 static int open_add(const char *tst_name, unsigned int port,
363 unsigned int strategy,
364 union tcp_addr md5_addr, uint8_t md5_prefix, int md5_vrf,
365 union tcp_addr ao_addr, uint8_t ao_prefix,
366 int ao_vrf, bool set_ao_required,
367 uint8_t sndid, uint8_t rcvid,
368 fault_t inj)
369 {
370 int sk;
371
372 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
373 if (sk < 0)
374 test_error("socket()");
375
376 if (client_bind(sk, this_ip_addr))
377 test_error("bind()");
378
379 if (strategy & PREINSTALL_MD5_FIRST) {
380 if (test_set_md5(sk, md5_addr, md5_prefix, md5_vrf, md5_password))
381 test_error("setsockopt(TCP_MD5SIG_EXT)");
382 }
383
384 if (strategy & PREINSTALL_AO) {
385 int err = try_add_key_vrf(sk, ao_addr, ao_prefix, ao_vrf,
386 sndid, rcvid, set_ao_required);
387
388 if (!test_continue(tst_name, err, inj, true)) {
389 close(sk);
390 return -1;
391 }
392 }
393
394 if (strategy & PREINSTALL_MD5) {
395 errno = 0;
396 test_set_md5(sk, md5_addr, md5_prefix, md5_vrf, md5_password);
397 if (!test_continue(tst_name, -errno, inj, false)) {
398 close(sk);
399 return -1;
400 }
401 }
402
403 return sk;
404 }
405
try_to_preadd(const char * tst_name,unsigned int port,unsigned int strategy,union tcp_addr md5_addr,uint8_t md5_prefix,int md5_vrf,union tcp_addr ao_addr,uint8_t ao_prefix,int ao_vrf,bool set_ao_required,uint8_t sndid,uint8_t rcvid,int needs_tcp_md5,int needs_vrf,fault_t inj)406 static void try_to_preadd(const char *tst_name, unsigned int port,
407 unsigned int strategy,
408 union tcp_addr md5_addr, uint8_t md5_prefix,
409 int md5_vrf,
410 union tcp_addr ao_addr, uint8_t ao_prefix,
411 int ao_vrf, bool set_ao_required,
412 uint8_t sndid, uint8_t rcvid,
413 int needs_tcp_md5, int needs_vrf, fault_t inj)
414 {
415 int sk;
416
417 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5))
418 return;
419 if (needs_vrf && should_skip_test(tst_name, KCONFIG_NET_VRF))
420 return;
421
422 sk = open_add(tst_name, port, strategy, md5_addr, md5_prefix, md5_vrf,
423 ao_addr, ao_prefix, ao_vrf, set_ao_required,
424 sndid, rcvid, inj);
425 if (sk < 0)
426 return;
427
428 test_ok("%s", tst_name);
429 close(sk);
430 }
431
try_to_add(const char * tst_name,unsigned int port,unsigned int strategy,union tcp_addr md5_addr,uint8_t md5_prefix,int md5_vrf,union tcp_addr ao_addr,uint8_t ao_prefix,int ao_vrf,uint8_t sndid,uint8_t rcvid,int needs_tcp_md5,fault_t inj)432 static void try_to_add(const char *tst_name, unsigned int port,
433 unsigned int strategy,
434 union tcp_addr md5_addr, uint8_t md5_prefix,
435 int md5_vrf,
436 union tcp_addr ao_addr, uint8_t ao_prefix,
437 int ao_vrf, uint8_t sndid, uint8_t rcvid,
438 int needs_tcp_md5, fault_t inj)
439 {
440 time_t timeout;
441 int sk, ret;
442
443 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5))
444 return;
445
446 sk = open_add(tst_name, port, strategy, md5_addr, md5_prefix, md5_vrf,
447 ao_addr, ao_prefix, ao_vrf, 0, sndid, rcvid, inj);
448 if (sk < 0)
449 return;
450
451 synchronize_threads(); /* preparations done */
452
453 timeout = fault(TIMEOUT) ? TEST_RETRANSMIT_SEC : TEST_TIMEOUT_SEC;
454 ret = _test_connect_socket(sk, this_ip_dest, port, timeout);
455
456 synchronize_threads(); /* connect()/accept() timeouts */
457 if (ret <= 0) {
458 test_error("%s: connect() returned %d", tst_name, ret);
459 goto out;
460 }
461
462 if (strategy & POSTINSTALL_MD5) {
463 if (test_set_md5(sk, md5_addr, md5_prefix, md5_vrf, md5_password)) {
464 if (fault(POSTINSTALL)) {
465 test_ok("%s: postfailed as expected", tst_name);
466 goto out;
467 } else {
468 test_error("setsockopt(TCP_MD5SIG_EXT)");
469 }
470 } else if (fault(POSTINSTALL)) {
471 test_fail("%s: post setsockopt() was expected to fail", tst_name);
472 goto out;
473 }
474 }
475
476 if (strategy & POSTINSTALL_AO) {
477 if (try_add_key_vrf(sk, ao_addr, ao_prefix, ao_vrf,
478 sndid, rcvid, 0)) {
479 if (fault(POSTINSTALL)) {
480 test_ok("%s: postfailed as expected", tst_name);
481 goto out;
482 } else {
483 test_error("setsockopt(TCP_AO_ADD_KEY)");
484 }
485 } else if (fault(POSTINSTALL)) {
486 test_fail("%s: post setsockopt() was expected to fail", tst_name);
487 goto out;
488 }
489 }
490
491 out:
492 synchronize_threads(); /* test_kill_sk() */
493 /* _test_connect_socket() cleans up on failure */
494 if (ret > 0)
495 test_kill_sk(sk);
496 }
497
client_add_ip(union tcp_addr * client,const char * ip)498 static void client_add_ip(union tcp_addr *client, const char *ip)
499 {
500 int err, family = TEST_FAMILY;
501
502 if (inet_pton(family, ip, client) != 1)
503 test_error("Can't convert ip address %s", ip);
504
505 err = ip_addr_add(veth_name, family, *client, TEST_PREFIX);
506 if (err)
507 test_error("Failed to add ip address: %d", err);
508 }
509
client_add_ips(void)510 static void client_add_ips(void)
511 {
512 client_add_ip(&client2, __TEST_CLIENT_IP(2));
513 client_add_ip(&client3, __TEST_CLIENT_IP(3));
514 synchronize_threads(); /* server_add_routes() */
515 }
516
client_add_fail_tests(unsigned int * port)517 static void client_add_fail_tests(unsigned int *port)
518 {
519 try_to_add("TCP-AO established: add TCP-MD5 key",
520 (*port)++, POSTINSTALL_MD5 | PREINSTALL_AO,
521 this_ip_dest, TEST_PREFIX, -1, this_ip_dest, TEST_PREFIX, 0,
522 100, 100, 1, FAULT_POSTINSTALL);
523 try_to_add("TCP-MD5 established: add TCP-AO key",
524 (*port)++, PREINSTALL_MD5 | POSTINSTALL_AO,
525 this_ip_dest, TEST_PREFIX, -1, this_ip_dest, TEST_PREFIX, 0,
526 100, 100, 1, FAULT_POSTINSTALL);
527 try_to_add("non-signed established: add TCP-AO key",
528 (*port)++, POSTINSTALL_AO,
529 this_ip_dest, TEST_PREFIX, -1, this_ip_dest, TEST_PREFIX, 0,
530 100, 100, 0, FAULT_POSTINSTALL);
531
532 try_to_add("TCP-AO key intersects with existing TCP-MD5 key",
533 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
534 this_ip_addr, TEST_PREFIX, -1, this_ip_addr, TEST_PREFIX, -1,
535 100, 100, 1, FAULT_PREINSTALL_AO);
536 try_to_add("TCP-MD5 key intersects with existing TCP-AO key",
537 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
538 this_ip_addr, TEST_PREFIX, -1, this_ip_addr, TEST_PREFIX, -1,
539 100, 100, 1, FAULT_PREINSTALL_MD5);
540
541 try_to_preadd("TCP-MD5 key + TCP-AO required",
542 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
543 this_ip_addr, TEST_PREFIX, -1,
544 this_ip_addr, TEST_PREFIX, -1, true,
545 100, 100, 1, 0, FAULT_PREINSTALL_AO);
546 try_to_preadd("TCP-AO required on socket + TCP-MD5 key",
547 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
548 this_ip_addr, TEST_PREFIX, -1,
549 this_ip_addr, TEST_PREFIX, -1, true,
550 100, 100, 1, 0, FAULT_PREINSTALL_MD5);
551 }
552
client_vrf_tests(unsigned int * port)553 static void client_vrf_tests(unsigned int *port)
554 {
555 setup_vrfs();
556
557 /* The following restrictions for setsockopt()s are expected:
558 *
559 * |--------------|-----------------|-------------|-------------|
560 * | | MD5 key without | MD5 key | MD5 key |
561 * | | l3index | l3index=0 | l3index=N |
562 * |--------------|-----------------|-------------|-------------|
563 * | TCP-AO key | | | |
564 * | without | reject | reject | reject |
565 * | l3index | | | |
566 * |--------------|-----------------|-------------|-------------|
567 * | TCP-AO key | | | |
568 * | l3index=0 | reject | reject | allow |
569 * |--------------|-----------------|-------------|-------------|
570 * | TCP-AO key | | | |
571 * | l3index=N | reject | allow | reject |
572 * |--------------|-----------------|-------------|-------------|
573 */
574 try_to_preadd("VRF: TCP-AO key (no l3index) + TCP-MD5 key (no l3index)",
575 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
576 this_ip_addr, TEST_PREFIX, -1,
577 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
578 1, 1, FAULT_PREINSTALL_MD5);
579 try_to_preadd("VRF: TCP-MD5 key (no l3index) + TCP-AO key (no l3index)",
580 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
581 this_ip_addr, TEST_PREFIX, -1,
582 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
583 1, 1, FAULT_PREINSTALL_AO);
584 try_to_preadd("VRF: TCP-AO key (no l3index) + TCP-MD5 key (l3index=0)",
585 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
586 this_ip_addr, TEST_PREFIX, 0,
587 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
588 1, 1, FAULT_PREINSTALL_MD5);
589 try_to_preadd("VRF: TCP-MD5 key (l3index=0) + TCP-AO key (no l3index)",
590 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
591 this_ip_addr, TEST_PREFIX, 0,
592 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
593 1, 1, FAULT_PREINSTALL_AO);
594 try_to_preadd("VRF: TCP-AO key (no l3index) + TCP-MD5 key (l3index=N)",
595 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
596 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
597 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
598 1, 1, FAULT_PREINSTALL_MD5);
599 try_to_preadd("VRF: TCP-MD5 key (l3index=N) + TCP-AO key (no l3index)",
600 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
601 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
602 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
603 1, 1, FAULT_PREINSTALL_AO);
604
605 try_to_preadd("VRF: TCP-AO key (l3index=0) + TCP-MD5 key (no l3index)",
606 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
607 this_ip_addr, TEST_PREFIX, -1,
608 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100,
609 1, 1, FAULT_PREINSTALL_MD5);
610 try_to_preadd("VRF: TCP-MD5 key (no l3index) + TCP-AO key (l3index=0)",
611 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
612 this_ip_addr, TEST_PREFIX, -1,
613 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100,
614 1, 1, FAULT_PREINSTALL_AO);
615 try_to_preadd("VRF: TCP-AO key (l3index=0) + TCP-MD5 key (l3index=0)",
616 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
617 this_ip_addr, TEST_PREFIX, 0,
618 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100,
619 1, 1, FAULT_PREINSTALL_MD5);
620 try_to_preadd("VRF: TCP-MD5 key (l3index=0) + TCP-AO key (l3index=0)",
621 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
622 this_ip_addr, TEST_PREFIX, 0,
623 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100,
624 1, 1, FAULT_PREINSTALL_AO);
625 try_to_preadd("VRF: TCP-AO key (l3index=0) + TCP-MD5 key (l3index=N)",
626 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
627 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
628 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100,
629 1, 1, 0);
630 try_to_preadd("VRF: TCP-MD5 key (l3index=N) + TCP-AO key (l3index=0)",
631 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
632 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
633 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100,
634 1, 1, 0);
635
636 try_to_preadd("VRF: TCP-AO key (l3index=N) + TCP-MD5 key (no l3index)",
637 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
638 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
639 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100,
640 1, 1, FAULT_PREINSTALL_MD5);
641 try_to_preadd("VRF: TCP-MD5 key (no l3index) + TCP-AO key (l3index=N)",
642 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
643 this_ip_addr, TEST_PREFIX, -1,
644 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100,
645 1, 1, FAULT_PREINSTALL_AO);
646 try_to_preadd("VRF: TCP-AO key (l3index=N) + TCP-MD5 key (l3index=0)",
647 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
648 this_ip_addr, TEST_PREFIX, 0,
649 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100,
650 1, 1, 0);
651 try_to_preadd("VRF: TCP-MD5 key (l3index=0) + TCP-AO key (l3index=N)",
652 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
653 this_ip_addr, TEST_PREFIX, 0,
654 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100,
655 1, 1, 0);
656 try_to_preadd("VRF: TCP-AO key (l3index=N) + TCP-MD5 key (l3index=N)",
657 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO,
658 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
659 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100,
660 1, 1, FAULT_PREINSTALL_MD5);
661 try_to_preadd("VRF: TCP-MD5 key (l3index=N) + TCP-AO key (l3index=N)",
662 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO,
663 this_ip_addr, TEST_PREFIX, test_vrf_ifindex,
664 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100,
665 1, 1, FAULT_PREINSTALL_AO);
666 }
667
client_fn(void * arg)668 static void *client_fn(void *arg)
669 {
670 unsigned int port = test_server_port;
671 union tcp_addr addr_any = {};
672
673 client_add_ips();
674
675 try_connect("AO server (INADDR_ANY): AO client", port++, NULL, 0,
676 &addr_any, 0, 100, 100, 0, 0, 0, &this_ip_addr);
677 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, this_ip_addr,
678 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
679 try_connect("AO server (INADDR_ANY): MD5 client", port++, &addr_any, 0,
680 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr);
681 trace_hash_event_expect(TCP_HASH_AO_REQUIRED, this_ip_addr,
682 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
683 try_connect("AO server (INADDR_ANY): unsigned client", port++, NULL, 0,
684 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 0, &this_ip_addr);
685 try_connect("AO server (AO_REQUIRED): AO client", port++, NULL, 0,
686 &addr_any, 0, 100, 100, 0, 0, 0, &this_ip_addr);
687 trace_hash_event_expect(TCP_HASH_AO_REQUIRED, client2,
688 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
689 try_connect("AO server (AO_REQUIRED): unsigned client", port++, NULL, 0,
690 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 0, &client2);
691
692 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest,
693 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
694 try_connect("MD5 server (INADDR_ANY): AO client", port++, NULL, 0,
695 &addr_any, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr);
696 try_connect("MD5 server (INADDR_ANY): MD5 client", port++, &addr_any, 0,
697 NULL, 0, 100, 100, 0, 0, 1, &this_ip_addr);
698 trace_hash_event_expect(TCP_HASH_MD5_REQUIRED, this_ip_addr,
699 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
700 try_connect("MD5 server (INADDR_ANY): no sign client", port++, NULL, 0,
701 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr);
702
703 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest,
704 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
705 try_connect("no sign server: AO client", port++, NULL, 0,
706 &addr_any, 0, 100, 100, 0, FAULT_TIMEOUT, 0, &this_ip_addr);
707 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, this_ip_addr,
708 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
709 try_connect("no sign server: MD5 client", port++, &addr_any, 0,
710 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr);
711 try_connect("no sign server: no sign client", port++, NULL, 0,
712 NULL, 0, 100, 100, 0, 0, 0, &this_ip_addr);
713
714 try_connect("AO+MD5 server: AO client (matching)", port++, NULL, 0,
715 &addr_any, 0, 100, 100, 0, 0, 1, &client2);
716 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest,
717 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
718 try_connect("AO+MD5 server: AO client (misconfig, matching MD5)",
719 port++, NULL, 0, &addr_any, 0, 100, 100, 0,
720 FAULT_TIMEOUT, 1, &this_ip_addr);
721 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, client3, this_ip_dest,
722 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
723 try_connect("AO+MD5 server: AO client (misconfig, non-matching)",
724 port++, NULL, 0, &addr_any, 0, 100, 100, 0,
725 FAULT_TIMEOUT, 1, &client3);
726 try_connect("AO+MD5 server: MD5 client (matching)", port++, &addr_any, 0,
727 NULL, 0, 100, 100, 0, 0, 1, &this_ip_addr);
728 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, client2,
729 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
730 try_connect("AO+MD5 server: MD5 client (misconfig, matching AO)",
731 port++, &addr_any, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT,
732 1, &client2);
733 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, client3,
734 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
735 try_connect("AO+MD5 server: MD5 client (misconfig, non-matching)",
736 port++, &addr_any, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT,
737 1, &client3);
738 try_connect("AO+MD5 server: no sign client (unmatched)",
739 port++, NULL, 0, NULL, 0, 100, 100, 0, 0, 1, &client3);
740 trace_hash_event_expect(TCP_HASH_AO_REQUIRED, client2,
741 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
742 try_connect("AO+MD5 server: no sign client (misconfig, matching AO)",
743 port++, NULL, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT,
744 1, &client2);
745 trace_hash_event_expect(TCP_HASH_MD5_REQUIRED, this_ip_addr,
746 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0);
747 try_connect("AO+MD5 server: no sign client (misconfig, matching MD5)",
748 port++, NULL, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT,
749 1, &this_ip_addr);
750
751 try_connect("AO+MD5 server: client with both [TCP-MD5] and TCP-AO keys",
752 port++, &this_ip_addr, TEST_PREFIX,
753 &client2, TEST_PREFIX, 100, 100, 0, FAULT_KEYREJECT,
754 1, &this_ip_addr);
755 try_connect("AO+MD5 server: client with both TCP-MD5 and [TCP-AO] keys",
756 port++, &this_ip_addr, TEST_PREFIX,
757 &client2, TEST_PREFIX, 100, 100, 0, FAULT_KEYREJECT,
758 1, &client2);
759
760 client_add_fail_tests(&port);
761 client_vrf_tests(&port);
762
763 return NULL;
764 }
765
main(int argc,char * argv[])766 int main(int argc, char *argv[])
767 {
768 test_init(73, server_fn, client_fn);
769 return 0;
770 }
771