1 // SPDX-License-Identifier: GPL-2.0 2 /* Author: Dmitry Safonov <dima@arista.com> */ 3 #include <inttypes.h> 4 #include "../../../../include/linux/kernel.h" 5 #include "aolib.h" 6 7 static union tcp_addr tcp_md5_client; 8 9 #define FILTER_TEST_NKEYS 16 10 11 static int test_port = 7788; 12 static void make_listen(int sk) 13 { 14 sockaddr_af addr; 15 16 tcp_addr_to_sockaddr_in(&addr, &this_ip_addr, htons(test_port++)); 17 if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) 18 test_error("bind()"); 19 if (listen(sk, 1)) 20 test_error("listen()"); 21 } 22 23 static void test_vefify_ao_info(int sk, struct tcp_ao_info_opt *info, 24 const char *tst) 25 { 26 struct tcp_ao_info_opt tmp = {}; 27 socklen_t len = sizeof(tmp); 28 29 if (getsockopt(sk, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len)) 30 test_error("getsockopt(TCP_AO_INFO) failed"); 31 32 #define __cmp_ao(member) \ 33 do { \ 34 if (info->member != tmp.member) { \ 35 test_fail("%s: getsockopt(): " __stringify(member) " %" PRIu64 " != %" PRIu64, \ 36 tst, (uint64_t)info->member, (uint64_t)tmp.member); \ 37 return; \ 38 } \ 39 } while(0) 40 if (info->set_current) 41 __cmp_ao(current_key); 42 if (info->set_rnext) 43 __cmp_ao(rnext); 44 if (info->set_counters) { 45 __cmp_ao(pkt_good); 46 __cmp_ao(pkt_bad); 47 __cmp_ao(pkt_key_not_found); 48 __cmp_ao(pkt_ao_required); 49 __cmp_ao(pkt_dropped_icmp); 50 } 51 __cmp_ao(ao_required); 52 __cmp_ao(accept_icmps); 53 54 test_ok("AO info get: %s", tst); 55 #undef __cmp_ao 56 } 57 58 static void __setsockopt_checked(int sk, int optname, bool get, 59 void *optval, socklen_t *len, 60 int err, const char *tst, const char *tst2) 61 { 62 int ret; 63 64 if (!tst) 65 tst = ""; 66 if (!tst2) 67 tst2 = ""; 68 69 errno = 0; 70 if (get) 71 ret = getsockopt(sk, IPPROTO_TCP, optname, optval, len); 72 else 73 ret = setsockopt(sk, IPPROTO_TCP, optname, optval, *len); 74 if (ret == -1) { 75 if (errno == err) 76 test_ok("%s%s", tst ?: "", tst2 ?: ""); 77 else 78 test_fail("%s%s: %setsockopt() failed", 79 tst, tst2, get ? "g" : "s"); 80 close(sk); 81 return; 82 } 83 84 if (err) { 85 test_fail("%s%s: %setsockopt() was expected to fail with %d", 86 tst, tst2, get ? "g" : "s", err); 87 } else { 88 test_ok("%s%s", tst ?: "", tst2 ?: ""); 89 if (optname == TCP_AO_ADD_KEY) { 90 test_verify_socket_key(sk, optval); 91 } else if (optname == TCP_AO_INFO && !get) { 92 test_vefify_ao_info(sk, optval, tst2); 93 } else if (optname == TCP_AO_GET_KEYS) { 94 if (*len != sizeof(struct tcp_ao_getsockopt)) 95 test_fail("%s%s: get keys returned wrong tcp_ao_getsockopt size", 96 tst, tst2); 97 } 98 } 99 close(sk); 100 } 101 102 static void setsockopt_checked(int sk, int optname, void *optval, 103 int err, const char *tst) 104 { 105 const char *cmd = NULL; 106 socklen_t len; 107 108 switch (optname) { 109 case TCP_AO_ADD_KEY: 110 cmd = "key add: "; 111 len = sizeof(struct tcp_ao_add); 112 break; 113 case TCP_AO_DEL_KEY: 114 cmd = "key del: "; 115 len = sizeof(struct tcp_ao_del); 116 break; 117 case TCP_AO_INFO: 118 cmd = "AO info set: "; 119 len = sizeof(struct tcp_ao_info_opt); 120 break; 121 default: 122 break; 123 } 124 125 __setsockopt_checked(sk, optname, false, optval, &len, err, cmd, tst); 126 } 127 128 static int prepare_defs(int cmd, void *optval) 129 { 130 int sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); 131 132 if (sk < 0) 133 test_error("socket()"); 134 135 switch (cmd) { 136 case TCP_AO_ADD_KEY: { 137 struct tcp_ao_add *add = optval; 138 139 if (test_prepare_def_key(add, DEFAULT_TEST_PASSWORD, 0, this_ip_dest, 140 -1, 0, 100, 100)) 141 test_error("prepare default tcp_ao_add"); 142 break; 143 } 144 case TCP_AO_DEL_KEY: { 145 struct tcp_ao_del *del = optval; 146 147 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, 148 DEFAULT_TEST_PREFIX, 100, 100)) 149 test_error("add default key"); 150 memset(del, 0, sizeof(struct tcp_ao_del)); 151 del->sndid = 100; 152 del->rcvid = 100; 153 del->prefix = DEFAULT_TEST_PREFIX; 154 tcp_addr_to_sockaddr_in(&del->addr, &this_ip_dest, 0); 155 break; 156 } 157 case TCP_AO_INFO: { 158 struct tcp_ao_info_opt *info = optval; 159 160 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, 161 DEFAULT_TEST_PREFIX, 100, 100)) 162 test_error("add default key"); 163 memset(info, 0, sizeof(struct tcp_ao_info_opt)); 164 break; 165 } 166 case TCP_AO_GET_KEYS: { 167 struct tcp_ao_getsockopt *get = optval; 168 169 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, 170 DEFAULT_TEST_PREFIX, 100, 100)) 171 test_error("add default key"); 172 memset(get, 0, sizeof(struct tcp_ao_getsockopt)); 173 get->nkeys = 1; 174 get->get_all = 1; 175 break; 176 } 177 default: 178 test_error("unknown cmd"); 179 } 180 181 return sk; 182 } 183 184 static void test_extend(int cmd, bool get, const char *tst, socklen_t under_size) 185 { 186 struct { 187 union { 188 struct tcp_ao_add add; 189 struct tcp_ao_del del; 190 struct tcp_ao_getsockopt get; 191 struct tcp_ao_info_opt info; 192 }; 193 char *extend[100]; 194 } tmp_opt; 195 socklen_t extended_size = sizeof(tmp_opt); 196 int sk; 197 198 memset(&tmp_opt, 0, sizeof(tmp_opt)); 199 sk = prepare_defs(cmd, &tmp_opt); 200 __setsockopt_checked(sk, cmd, get, &tmp_opt, &under_size, 201 EINVAL, tst, ": minimum size"); 202 203 memset(&tmp_opt, 0, sizeof(tmp_opt)); 204 sk = prepare_defs(cmd, &tmp_opt); 205 __setsockopt_checked(sk, cmd, get, &tmp_opt, &extended_size, 206 0, tst, ": extended size"); 207 208 memset(&tmp_opt, 0, sizeof(tmp_opt)); 209 sk = prepare_defs(cmd, &tmp_opt); 210 __setsockopt_checked(sk, cmd, get, NULL, &extended_size, 211 EFAULT, tst, ": null optval"); 212 213 if (get) { 214 memset(&tmp_opt, 0, sizeof(tmp_opt)); 215 sk = prepare_defs(cmd, &tmp_opt); 216 __setsockopt_checked(sk, cmd, get, &tmp_opt, NULL, 217 EFAULT, tst, ": null optlen"); 218 } 219 } 220 221 static void extend_tests(void) 222 { 223 test_extend(TCP_AO_ADD_KEY, false, "AO add", 224 offsetof(struct tcp_ao_add, key)); 225 test_extend(TCP_AO_DEL_KEY, false, "AO del", 226 offsetof(struct tcp_ao_del, keyflags)); 227 test_extend(TCP_AO_INFO, false, "AO set info", 228 offsetof(struct tcp_ao_info_opt, pkt_dropped_icmp)); 229 test_extend(TCP_AO_INFO, true, "AO get info", -1); 230 test_extend(TCP_AO_GET_KEYS, true, "AO get keys", -1); 231 } 232 233 static void test_optmem_limit(void) 234 { 235 size_t i, keys_limit, current_optmem = test_get_optmem(); 236 struct tcp_ao_add ao; 237 union tcp_addr net = {}; 238 int sk; 239 240 if (inet_pton(TEST_FAMILY, TEST_NETWORK, &net) != 1) 241 test_error("Can't convert ip address %s", TEST_NETWORK); 242 243 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 244 keys_limit = current_optmem / KERNEL_TCP_AO_KEY_SZ_ROUND_UP; 245 for (i = 0;; i++) { 246 union tcp_addr key_peer; 247 int err; 248 249 key_peer = gen_tcp_addr(net, i + 1); 250 tcp_addr_to_sockaddr_in(&ao.addr, &key_peer, 0); 251 err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, 252 &ao, sizeof(ao)); 253 if (!err) { 254 /* 255 * TCP_AO_ADD_KEY should be the same order as the real 256 * sizeof(struct tcp_ao_key) in kernel. 257 */ 258 if (i <= keys_limit * 10) 259 continue; 260 test_fail("optmem limit test failed: added %zu key", i); 261 break; 262 } 263 if (i < keys_limit) { 264 test_fail("optmem limit test failed: couldn't add %zu key", i); 265 break; 266 } 267 test_ok("optmem limit was hit on adding %zu key", i); 268 break; 269 } 270 close(sk); 271 } 272 273 static void test_einval_add_key(void) 274 { 275 struct tcp_ao_add ao; 276 int sk; 277 278 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 279 ao.keylen = TCP_AO_MAXKEYLEN + 1; 280 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too big keylen"); 281 282 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 283 ao.reserved = 1; 284 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "using reserved padding"); 285 286 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 287 ao.reserved2 = 1; 288 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "using reserved2 padding"); 289 290 /* tcp_ao_verify_ipv{4,6}() checks */ 291 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 292 ao.addr.ss_family = AF_UNIX; 293 memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 294 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "wrong address family"); 295 296 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 297 tcp_addr_to_sockaddr_in(&ao.addr, &this_ip_dest, 1234); 298 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "port (unsupported)"); 299 300 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 301 ao.prefix = 0; 302 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "no prefix, addr"); 303 304 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 305 ao.prefix = 0; 306 memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 307 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "no prefix, any addr"); 308 309 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 310 ao.prefix = 32; 311 memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 312 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "prefix, any addr"); 313 314 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 315 ao.prefix = 129; 316 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too big prefix"); 317 318 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 319 ao.prefix = 2; 320 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too short prefix"); 321 322 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 323 ao.keyflags = (uint8_t)(-1); 324 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "bad key flags"); 325 326 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 327 make_listen(sk); 328 ao.set_current = 1; 329 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add current key on a listen socket"); 330 331 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 332 make_listen(sk); 333 ao.set_rnext = 1; 334 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add rnext key on a listen socket"); 335 336 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 337 make_listen(sk); 338 ao.set_current = 1; 339 ao.set_rnext = 1; 340 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add current+rnext key on a listen socket"); 341 342 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 343 ao.set_current = 1; 344 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as current"); 345 346 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 347 ao.set_rnext = 1; 348 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as rnext"); 349 350 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 351 ao.set_current = 1; 352 ao.set_rnext = 1; 353 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as current+rnext"); 354 355 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 356 ao.ifindex = 42; 357 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, 358 "ifindex without TCP_AO_KEYF_IFNINDEX"); 359 360 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 361 ao.keyflags |= TCP_AO_KEYF_IFINDEX; 362 ao.ifindex = 42; 363 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "non-existent VRF"); 364 /* 365 * tcp_md5_do_lookup{,_any_l3index}() are checked in unsigned-md5 366 * see client_vrf_tests(). 367 */ 368 369 test_optmem_limit(); 370 371 /* tcp_ao_parse_crypto() */ 372 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 373 ao.maclen = 100; 374 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EMSGSIZE, "maclen bigger than TCP hdr"); 375 376 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 377 strcpy(ao.alg_name, "imaginary hash algo"); 378 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, ENOENT, "bad algo"); 379 } 380 381 static void test_einval_del_key(void) 382 { 383 struct tcp_ao_del del; 384 int sk; 385 386 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 387 del.reserved = 1; 388 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "using reserved padding"); 389 390 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 391 del.reserved2 = 1; 392 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "using reserved2 padding"); 393 394 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 395 make_listen(sk); 396 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0)) 397 test_error("add key"); 398 del.set_current = 1; 399 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set current key on a listen socket"); 400 401 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 402 make_listen(sk); 403 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0)) 404 test_error("add key"); 405 del.set_rnext = 1; 406 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set rnext key on a listen socket"); 407 408 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 409 make_listen(sk); 410 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0)) 411 test_error("add key"); 412 del.set_current = 1; 413 del.set_rnext = 1; 414 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set current+rnext key on a listen socket"); 415 416 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 417 del.keyflags = (uint8_t)(-1); 418 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "bad key flags"); 419 420 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 421 del.ifindex = 42; 422 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, 423 "ifindex without TCP_AO_KEYF_IFNINDEX"); 424 425 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 426 del.keyflags |= TCP_AO_KEYF_IFINDEX; 427 del.ifindex = 42; 428 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existent VRF"); 429 430 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 431 del.set_current = 1; 432 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing current key"); 433 434 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 435 del.set_rnext = 1; 436 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing rnext key"); 437 438 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 439 del.set_current = 1; 440 del.set_rnext = 1; 441 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing current+rnext key"); 442 443 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 444 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0)) 445 test_error("add key"); 446 del.set_current = 1; 447 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set current key"); 448 449 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 450 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0)) 451 test_error("add key"); 452 del.set_rnext = 1; 453 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set rnext key"); 454 455 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 456 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0)) 457 test_error("add key"); 458 del.set_current = 1; 459 del.set_rnext = 1; 460 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set current+rnext key"); 461 462 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 463 del.set_current = 1; 464 del.current_key = 100; 465 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as current key to be removed"); 466 467 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 468 del.set_rnext = 1; 469 del.rnext = 100; 470 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as rnext key to be removed"); 471 472 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 473 del.set_current = 1; 474 del.current_key = 100; 475 del.set_rnext = 1; 476 del.rnext = 100; 477 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as current+rnext key to be removed"); 478 479 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 480 del.del_async = 1; 481 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "async on non-listen"); 482 483 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 484 del.sndid = 101; 485 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existing sndid"); 486 487 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 488 del.rcvid = 101; 489 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existing rcvid"); 490 491 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 492 tcp_addr_to_sockaddr_in(&del.addr, &this_ip_addr, 0); 493 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "incorrect addr"); 494 495 sk = prepare_defs(TCP_AO_DEL_KEY, &del); 496 setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "correct key delete"); 497 } 498 499 static void test_einval_ao_info(void) 500 { 501 struct tcp_ao_info_opt info; 502 int sk; 503 504 sk = prepare_defs(TCP_AO_INFO, &info); 505 make_listen(sk); 506 info.set_current = 1; 507 setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set current key on a listen socket"); 508 509 sk = prepare_defs(TCP_AO_INFO, &info); 510 make_listen(sk); 511 info.set_rnext = 1; 512 setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set rnext key on a listen socket"); 513 514 sk = prepare_defs(TCP_AO_INFO, &info); 515 make_listen(sk); 516 info.set_current = 1; 517 info.set_rnext = 1; 518 setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set current+rnext key on a listen socket"); 519 520 sk = prepare_defs(TCP_AO_INFO, &info); 521 info.reserved = 1; 522 setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "using reserved padding"); 523 524 sk = prepare_defs(TCP_AO_INFO, &info); 525 info.reserved2 = 1; 526 setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "using reserved2 padding"); 527 528 sk = prepare_defs(TCP_AO_INFO, &info); 529 info.accept_icmps = 1; 530 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "accept_icmps"); 531 532 sk = prepare_defs(TCP_AO_INFO, &info); 533 info.ao_required = 1; 534 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "ao required"); 535 536 if (!should_skip_test("ao required with MD5 key", KCONFIG_TCP_MD5)) { 537 sk = prepare_defs(TCP_AO_INFO, &info); 538 info.ao_required = 1; 539 if (test_set_md5(sk, tcp_md5_client, TEST_PREFIX, -1, 540 "long long secret")) { 541 test_error("setsockopt(TCP_MD5SIG_EXT)"); 542 close(sk); 543 } else { 544 setsockopt_checked(sk, TCP_AO_INFO, &info, EKEYREJECTED, 545 "ao required with MD5 key"); 546 } 547 } 548 549 sk = prepare_defs(TCP_AO_INFO, &info); 550 info.set_current = 1; 551 setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing current key"); 552 553 sk = prepare_defs(TCP_AO_INFO, &info); 554 info.set_rnext = 1; 555 setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing rnext key"); 556 557 sk = prepare_defs(TCP_AO_INFO, &info); 558 info.set_current = 1; 559 info.set_rnext = 1; 560 setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing current+rnext key"); 561 562 sk = prepare_defs(TCP_AO_INFO, &info); 563 info.set_current = 1; 564 info.current_key = 100; 565 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set current key"); 566 567 sk = prepare_defs(TCP_AO_INFO, &info); 568 info.set_rnext = 1; 569 info.rnext = 100; 570 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set rnext key"); 571 572 sk = prepare_defs(TCP_AO_INFO, &info); 573 info.set_current = 1; 574 info.set_rnext = 1; 575 info.current_key = 100; 576 info.rnext = 100; 577 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set current+rnext key"); 578 579 sk = prepare_defs(TCP_AO_INFO, &info); 580 info.set_counters = 1; 581 info.pkt_good = 321; 582 info.pkt_bad = 888; 583 info.pkt_key_not_found = 654; 584 info.pkt_ao_required = 987654; 585 info.pkt_dropped_icmp = 10000; 586 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set counters"); 587 588 sk = prepare_defs(TCP_AO_INFO, &info); 589 setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "no-op"); 590 } 591 592 static void getsockopt_checked(int sk, struct tcp_ao_getsockopt *optval, 593 int err, const char *tst) 594 { 595 socklen_t len = sizeof(struct tcp_ao_getsockopt); 596 597 __setsockopt_checked(sk, TCP_AO_GET_KEYS, true, optval, &len, err, 598 "get keys: ", tst); 599 } 600 601 static void test_einval_get_keys(void) 602 { 603 struct tcp_ao_getsockopt out; 604 int sk; 605 606 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); 607 if (sk < 0) 608 test_error("socket()"); 609 getsockopt_checked(sk, &out, ENOENT, "no ao_info"); 610 611 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 612 getsockopt_checked(sk, &out, 0, "proper tcp_ao_get_mkts()"); 613 614 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 615 out.pkt_good = 643; 616 getsockopt_checked(sk, &out, EINVAL, "set out-only pkt_good counter"); 617 618 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 619 out.pkt_bad = 94; 620 getsockopt_checked(sk, &out, EINVAL, "set out-only pkt_bad counter"); 621 622 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 623 out.keyflags = (uint8_t)(-1); 624 getsockopt_checked(sk, &out, EINVAL, "bad keyflags"); 625 626 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 627 out.ifindex = 42; 628 getsockopt_checked(sk, &out, EINVAL, 629 "ifindex without TCP_AO_KEYF_IFNINDEX"); 630 631 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 632 out.reserved = 1; 633 getsockopt_checked(sk, &out, EINVAL, "using reserved field"); 634 635 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 636 out.get_all = 0; 637 out.prefix = 0; 638 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 639 getsockopt_checked(sk, &out, EINVAL, "no prefix, addr"); 640 641 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 642 out.get_all = 0; 643 out.prefix = 0; 644 memcpy(&out.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 645 getsockopt_checked(sk, &out, 0, "no prefix, any addr"); 646 647 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 648 out.get_all = 0; 649 out.prefix = 32; 650 memcpy(&out.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 651 getsockopt_checked(sk, &out, EINVAL, "prefix, any addr"); 652 653 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 654 out.get_all = 0; 655 out.prefix = 129; 656 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 657 getsockopt_checked(sk, &out, EINVAL, "too big prefix"); 658 659 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 660 out.get_all = 0; 661 out.prefix = 2; 662 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 663 getsockopt_checked(sk, &out, EINVAL, "too short prefix"); 664 665 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 666 out.get_all = 0; 667 out.prefix = DEFAULT_TEST_PREFIX; 668 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 669 getsockopt_checked(sk, &out, 0, "prefix + addr"); 670 671 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 672 out.get_all = 1; 673 out.prefix = DEFAULT_TEST_PREFIX; 674 getsockopt_checked(sk, &out, EINVAL, "get_all + prefix"); 675 676 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 677 out.get_all = 1; 678 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 679 getsockopt_checked(sk, &out, EINVAL, "get_all + addr"); 680 681 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 682 out.get_all = 1; 683 out.sndid = 1; 684 getsockopt_checked(sk, &out, EINVAL, "get_all + sndid"); 685 686 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 687 out.get_all = 1; 688 out.rcvid = 1; 689 getsockopt_checked(sk, &out, EINVAL, "get_all + rcvid"); 690 691 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 692 out.get_all = 0; 693 out.is_current = 1; 694 out.prefix = DEFAULT_TEST_PREFIX; 695 getsockopt_checked(sk, &out, EINVAL, "current + prefix"); 696 697 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 698 out.get_all = 0; 699 out.is_current = 1; 700 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 701 getsockopt_checked(sk, &out, EINVAL, "current + addr"); 702 703 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 704 out.get_all = 0; 705 out.is_current = 1; 706 out.sndid = 1; 707 getsockopt_checked(sk, &out, EINVAL, "current + sndid"); 708 709 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 710 out.get_all = 0; 711 out.is_current = 1; 712 out.rcvid = 1; 713 getsockopt_checked(sk, &out, EINVAL, "current + rcvid"); 714 715 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 716 out.get_all = 0; 717 out.is_rnext = 1; 718 out.prefix = DEFAULT_TEST_PREFIX; 719 getsockopt_checked(sk, &out, EINVAL, "rnext + prefix"); 720 721 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 722 out.get_all = 0; 723 out.is_rnext = 1; 724 tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0); 725 getsockopt_checked(sk, &out, EINVAL, "rnext + addr"); 726 727 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 728 out.get_all = 0; 729 out.is_rnext = 1; 730 out.sndid = 1; 731 getsockopt_checked(sk, &out, EINVAL, "rnext + sndid"); 732 733 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 734 out.get_all = 0; 735 out.is_rnext = 1; 736 out.rcvid = 1; 737 getsockopt_checked(sk, &out, EINVAL, "rnext + rcvid"); 738 739 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 740 out.get_all = 1; 741 out.is_current = 1; 742 getsockopt_checked(sk, &out, EINVAL, "get_all + current"); 743 744 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 745 out.get_all = 1; 746 out.is_rnext = 1; 747 getsockopt_checked(sk, &out, EINVAL, "get_all + rnext"); 748 749 sk = prepare_defs(TCP_AO_GET_KEYS, &out); 750 out.get_all = 0; 751 out.is_current = 1; 752 out.is_rnext = 1; 753 getsockopt_checked(sk, &out, 0, "current + rnext"); 754 } 755 756 static void einval_tests(void) 757 { 758 test_einval_add_key(); 759 test_einval_del_key(); 760 test_einval_ao_info(); 761 test_einval_get_keys(); 762 } 763 764 static void duplicate_tests(void) 765 { 766 union tcp_addr network_dup; 767 struct tcp_ao_add ao, ao2; 768 int sk; 769 770 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 771 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao))) 772 test_error("setsockopt()"); 773 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: full copy"); 774 775 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 776 ao2 = ao; 777 memcpy(&ao2.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 778 ao2.prefix = 0; 779 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao2, sizeof(ao))) 780 test_error("setsockopt()"); 781 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: any addr key on the socket"); 782 783 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 784 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao))) 785 test_error("setsockopt()"); 786 memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY)); 787 ao.prefix = 0; 788 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: add any addr key"); 789 790 if (inet_pton(TEST_FAMILY, TEST_NETWORK, &network_dup) != 1) 791 test_error("Can't convert ip address %s", TEST_NETWORK); 792 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 793 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao))) 794 test_error("setsockopt()"); 795 if (test_prepare_def_key(&ao, "password", 0, network_dup, 796 16, 0, 100, 100)) 797 test_error("prepare default tcp_ao_add"); 798 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: add any addr for the same subnet"); 799 800 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 801 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao))) 802 test_error("setsockopt()"); 803 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: full copy of a key"); 804 805 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 806 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao))) 807 test_error("setsockopt()"); 808 ao.rcvid = 101; 809 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: RecvID differs"); 810 811 sk = prepare_defs(TCP_AO_ADD_KEY, &ao); 812 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao))) 813 test_error("setsockopt()"); 814 ao.sndid = 101; 815 setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: SendID differs"); 816 } 817 818 static void fetch_all_keys(int sk, struct tcp_ao_getsockopt *keys) 819 { 820 socklen_t optlen = sizeof(struct tcp_ao_getsockopt); 821 822 memset(keys, 0, sizeof(struct tcp_ao_getsockopt) * FILTER_TEST_NKEYS); 823 keys[0].get_all = 1; 824 keys[0].nkeys = FILTER_TEST_NKEYS; 825 if (getsockopt(sk, IPPROTO_TCP, TCP_AO_GET_KEYS, &keys[0], &optlen)) 826 test_error("getsockopt"); 827 } 828 829 static int prepare_test_keys(struct tcp_ao_getsockopt *keys) 830 { 831 const char *test_password = "Test password number "; 832 struct tcp_ao_add test_ao[FILTER_TEST_NKEYS]; 833 char test_password_scratch[64] = {}; 834 u8 rcvid = 100, sndid = 100; 835 int sk; 836 837 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); 838 if (sk < 0) 839 test_error("socket()"); 840 841 for (int i = 0; i < FILTER_TEST_NKEYS; i++) { 842 snprintf(test_password_scratch, 64, "%s %d", test_password, i); 843 test_prepare_key(&test_ao[i], DEFAULT_TEST_ALGO, this_ip_dest, 844 false, false, DEFAULT_TEST_PREFIX, 0, sndid++, 845 rcvid++, 0, 0, strlen(test_password_scratch), 846 test_password_scratch); 847 } 848 test_ao[0].set_current = 1; 849 test_ao[1].set_rnext = 1; 850 /* One key with a different addr and overlapping sndid, rcvid */ 851 tcp_addr_to_sockaddr_in(&test_ao[2].addr, &this_ip_addr, 0); 852 test_ao[2].sndid = 100; 853 test_ao[2].rcvid = 100; 854 855 /* Add keys in a random order */ 856 for (int i = 0; i < FILTER_TEST_NKEYS; i++) { 857 int randidx = rand() % (FILTER_TEST_NKEYS - i); 858 859 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, 860 &test_ao[randidx], sizeof(struct tcp_ao_add))) 861 test_error("setsockopt()"); 862 memcpy(&test_ao[randidx], &test_ao[FILTER_TEST_NKEYS - 1 - i], 863 sizeof(struct tcp_ao_add)); 864 } 865 866 fetch_all_keys(sk, keys); 867 868 return sk; 869 } 870 871 /* Assumes passwords are unique */ 872 static int compare_mkts(struct tcp_ao_getsockopt *expected, int nexpected, 873 struct tcp_ao_getsockopt *actual, int nactual) 874 { 875 int matches = 0; 876 877 for (int i = 0; i < nexpected; i++) { 878 for (int j = 0; j < nactual; j++) { 879 if (memcmp(expected[i].key, actual[j].key, 880 TCP_AO_MAXKEYLEN) == 0) 881 matches++; 882 } 883 } 884 return nexpected - matches; 885 } 886 887 static void filter_keys_checked(int sk, struct tcp_ao_getsockopt *filter, 888 struct tcp_ao_getsockopt *expected, 889 unsigned int nexpected, const char *tst) 890 { 891 struct tcp_ao_getsockopt filtered_keys[FILTER_TEST_NKEYS] = {}; 892 struct tcp_ao_getsockopt all_keys[FILTER_TEST_NKEYS] = {}; 893 socklen_t len = sizeof(struct tcp_ao_getsockopt); 894 895 fetch_all_keys(sk, all_keys); 896 memcpy(&filtered_keys[0], filter, sizeof(struct tcp_ao_getsockopt)); 897 filtered_keys[0].nkeys = FILTER_TEST_NKEYS; 898 if (getsockopt(sk, IPPROTO_TCP, TCP_AO_GET_KEYS, filtered_keys, &len)) 899 test_error("getsockopt"); 900 if (filtered_keys[0].nkeys != nexpected) { 901 test_fail("wrong nr of keys, expected %u got %u", nexpected, 902 filtered_keys[0].nkeys); 903 goto out_close; 904 } 905 if (compare_mkts(expected, nexpected, filtered_keys, 906 filtered_keys[0].nkeys)) { 907 test_fail("got wrong keys back"); 908 goto out_close; 909 } 910 test_ok("filter keys: %s", tst); 911 912 out_close: 913 close(sk); 914 memset(filter, 0, sizeof(struct tcp_ao_getsockopt)); 915 } 916 917 static void filter_tests(void) 918 { 919 struct tcp_ao_getsockopt original_keys[FILTER_TEST_NKEYS]; 920 struct tcp_ao_getsockopt expected_keys[FILTER_TEST_NKEYS]; 921 struct tcp_ao_getsockopt filter = {}; 922 int sk, f, nmatches; 923 socklen_t len; 924 925 f = 2; 926 sk = prepare_test_keys(original_keys); 927 filter.rcvid = original_keys[f].rcvid; 928 filter.sndid = original_keys[f].sndid; 929 memcpy(&filter.addr, &original_keys[f].addr, 930 sizeof(original_keys[f].addr)); 931 filter.prefix = original_keys[f].prefix; 932 filter_keys_checked(sk, &filter, &original_keys[f], 1, 933 "by sndid, rcvid, address"); 934 935 f = -1; 936 sk = prepare_test_keys(original_keys); 937 for (int i = 0; i < original_keys[0].nkeys; i++) { 938 if (original_keys[i].is_current) { 939 f = i; 940 break; 941 } 942 } 943 if (f < 0) 944 test_error("No current key after adding one"); 945 filter.is_current = 1; 946 filter_keys_checked(sk, &filter, &original_keys[f], 1, "by is_current"); 947 948 f = -1; 949 sk = prepare_test_keys(original_keys); 950 for (int i = 0; i < original_keys[0].nkeys; i++) { 951 if (original_keys[i].is_rnext) { 952 f = i; 953 break; 954 } 955 } 956 if (f < 0) 957 test_error("No rnext key after adding one"); 958 filter.is_rnext = 1; 959 filter_keys_checked(sk, &filter, &original_keys[f], 1, "by is_rnext"); 960 961 f = -1; 962 nmatches = 0; 963 sk = prepare_test_keys(original_keys); 964 for (int i = 0; i < original_keys[0].nkeys; i++) { 965 if (original_keys[i].sndid == 100) { 966 f = i; 967 memcpy(&expected_keys[nmatches], &original_keys[i], 968 sizeof(struct tcp_ao_getsockopt)); 969 nmatches++; 970 } 971 } 972 if (f < 0) 973 test_error("No key for sndid 100"); 974 if (nmatches != 2) 975 test_error("Should have 2 keys with sndid 100"); 976 filter.rcvid = original_keys[f].rcvid; 977 filter.sndid = original_keys[f].sndid; 978 filter.addr.ss_family = test_family; 979 filter_keys_checked(sk, &filter, expected_keys, nmatches, 980 "by sndid, rcvid"); 981 982 sk = prepare_test_keys(original_keys); 983 filter.get_all = 1; 984 filter.nkeys = FILTER_TEST_NKEYS / 2; 985 len = sizeof(struct tcp_ao_getsockopt); 986 if (getsockopt(sk, IPPROTO_TCP, TCP_AO_GET_KEYS, &filter, &len)) 987 test_error("getsockopt"); 988 if (filter.nkeys == FILTER_TEST_NKEYS) 989 test_ok("filter keys: correct nkeys when in.nkeys < matches"); 990 else 991 test_fail("filter keys: wrong nkeys, expected %u got %u", 992 FILTER_TEST_NKEYS, filter.nkeys); 993 } 994 995 static void *client_fn(void *arg) 996 { 997 if (inet_pton(TEST_FAMILY, __TEST_CLIENT_IP(2), &tcp_md5_client) != 1) 998 test_error("Can't convert ip address"); 999 extend_tests(); 1000 einval_tests(); 1001 filter_tests(); 1002 duplicate_tests(); 1003 1004 return NULL; 1005 } 1006 1007 int main(int argc, char *argv[]) 1008 { 1009 test_init(126, client_fn, NULL); 1010 return 0; 1011 } 1012