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