1 /* $OpenBSD: test_iterate.c,v 1.9 2024/01/11 01:45:58 djm Exp $ */ 2 /* 3 * Regress test for hostfile.h hostkeys_foreach() 4 * 5 * Placed in the public domain 6 */ 7 8 #include <sys/types.h> 9 #include <stdio.h> 10 #include <stdint.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include "test_helper.h" 15 16 #include "sshkey.h" 17 #include "authfile.h" 18 #include "hostfile.h" 19 20 struct expected { 21 const char *key_file; /* Path for key, NULL for none */ 22 int no_parse_status; /* Expected status w/o key parsing */ 23 int no_parse_keytype; /* Expected keytype w/o key parsing */ 24 int match_host_p; /* Match 'prometheus.example.com' */ 25 int match_host_s; /* Match 'sisyphus.example.com' */ 26 int match_ipv4; /* Match '192.0.2.1' */ 27 int match_ipv6; /* Match '2001:db8::1' */ 28 int match_flags; /* Expected flags from match */ 29 struct hostkey_foreach_line l; /* Expected line contents */ 30 }; 31 32 struct cbctx { 33 const struct expected *expected; 34 size_t nexpected; 35 size_t i; 36 int flags; 37 int match_host_p; 38 int match_host_s; 39 int match_ipv4; 40 int match_ipv6; 41 }; 42 43 /* 44 * hostkeys_foreach() iterator callback that verifies the line passed 45 * against an array of expected entries. 46 */ 47 static int 48 check(struct hostkey_foreach_line *l, void *_ctx) 49 { 50 struct cbctx *ctx = (struct cbctx *)_ctx; 51 const struct expected *expected; 52 int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0; 53 const int matching = (ctx->flags & HKF_WANT_MATCH) != 0; 54 u_int expected_status, expected_match; 55 int expected_keytype, skip = 0; 56 57 test_subtest_info("entry %zu/%zu, file line %ld", 58 ctx->i + 1, ctx->nexpected, l->linenum); 59 60 for (;;) { 61 ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected); 62 expected = ctx->expected + ctx->i++; 63 /* If we are matching host/IP then skip entries that don't */ 64 if (!matching) 65 break; 66 if (ctx->match_host_p && expected->match_host_p) 67 break; 68 if (ctx->match_host_s && expected->match_host_s) 69 break; 70 if (ctx->match_ipv4 && expected->match_ipv4) 71 break; 72 if (ctx->match_ipv6 && expected->match_ipv6) 73 break; 74 } 75 expected_status = (parse_key || expected->no_parse_status < 0) ? 76 expected->l.status : (u_int)expected->no_parse_status; 77 expected_match = expected->l.match; 78 #define UPDATE_MATCH_STATUS(x) do { \ 79 if (ctx->x && expected->x) { \ 80 expected_match |= expected->x; \ 81 if (expected_status == HKF_STATUS_OK) \ 82 expected_status = HKF_STATUS_MATCHED; \ 83 } \ 84 } while (0) 85 expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? 86 expected->l.keytype : expected->no_parse_keytype; 87 88 #ifndef WITH_DSA 89 if (expected->l.keytype == KEY_DSA || 90 expected->no_parse_keytype == KEY_DSA) 91 skip = 1; 92 #endif 93 94 if (skip) { 95 expected_status = HKF_STATUS_INVALID; 96 expected_keytype = KEY_UNSPEC; 97 parse_key = 0; 98 } 99 UPDATE_MATCH_STATUS(match_host_p); 100 UPDATE_MATCH_STATUS(match_host_s); 101 UPDATE_MATCH_STATUS(match_ipv4); 102 UPDATE_MATCH_STATUS(match_ipv6); 103 104 ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */ 105 ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum); 106 ASSERT_U_INT_EQ(l->status, expected_status); 107 ASSERT_U_INT_EQ(l->match, expected_match); 108 /* Not all test entries contain fulltext */ 109 if (expected->l.line != NULL) 110 ASSERT_STRING_EQ(l->line, expected->l.line); 111 ASSERT_INT_EQ(l->marker, expected->l.marker); 112 /* XXX we skip hashed hostnames for now; implement checking */ 113 if (expected->l.hosts != NULL) 114 ASSERT_STRING_EQ(l->hosts, expected->l.hosts); 115 /* Not all test entries contain raw keys */ 116 if (expected->l.rawkey != NULL) 117 ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey); 118 /* XXX synthesise raw key for cases lacking and compare */ 119 ASSERT_INT_EQ(l->keytype, expected_keytype); 120 if (parse_key) { 121 if (expected->l.key == NULL) 122 ASSERT_PTR_EQ(l->key, NULL); 123 if (expected->l.key != NULL) { 124 ASSERT_PTR_NE(l->key, NULL); 125 ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); 126 } 127 } 128 if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) 129 ASSERT_STRING_EQ(l->comment, expected->l.comment); 130 return 0; 131 } 132 133 /* Loads public keys for a set of expected results */ 134 static void 135 prepare_expected(struct expected *expected, size_t n) 136 { 137 size_t i; 138 139 for (i = 0; i < n; i++) { 140 if (expected[i].key_file == NULL) 141 continue; 142 #ifndef WITH_DSA 143 if (expected[i].l.keytype == KEY_DSA) 144 continue; 145 #endif 146 ASSERT_INT_EQ(sshkey_load_public( 147 test_data_file(expected[i].key_file), &expected[i].l.key, 148 NULL), 0); 149 } 150 } 151 152 static void 153 cleanup_expected(struct expected *expected, size_t n) 154 { 155 size_t i; 156 157 for (i = 0; i < n; i++) { 158 sshkey_free(expected[i].l.key); 159 expected[i].l.key = NULL; 160 } 161 } 162 163 struct expected expected_full[] = { 164 { NULL, -1, -1, 0, 0, 0, 0, -1, { 165 NULL, /* path, don't care */ 166 1, /* line number */ 167 HKF_STATUS_COMMENT, /* status */ 168 0, /* match flags */ 169 "# Plain host keys, plain host names", /* full line, optional */ 170 MRK_NONE, /* marker (CA / revoked) */ 171 NULL, /* hosts text */ 172 NULL, /* raw key, optional */ 173 KEY_UNSPEC, /* key type */ 174 NULL, /* deserialised key */ 175 NULL, /* comment */ 176 0, /* note */ 177 } }, 178 { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 179 NULL, 180 2, 181 HKF_STATUS_OK, 182 0, 183 NULL, 184 MRK_NONE, 185 "sisyphus.example.com", 186 NULL, 187 KEY_DSA, 188 NULL, /* filled at runtime */ 189 "DSA #1", 190 0, 191 } }, 192 { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 193 NULL, 194 3, 195 HKF_STATUS_OK, 196 0, 197 NULL, 198 MRK_NONE, 199 "sisyphus.example.com", 200 NULL, 201 KEY_ECDSA, 202 NULL, /* filled at runtime */ 203 "ECDSA #1", 204 0, 205 } }, 206 { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 207 NULL, 208 4, 209 HKF_STATUS_OK, 210 0, 211 NULL, 212 MRK_NONE, 213 "sisyphus.example.com", 214 NULL, 215 KEY_ED25519, 216 NULL, /* filled at runtime */ 217 "ED25519 #1", 218 0, 219 } }, 220 { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 221 NULL, 222 5, 223 HKF_STATUS_OK, 224 0, 225 NULL, 226 MRK_NONE, 227 "sisyphus.example.com", 228 NULL, 229 KEY_RSA, 230 NULL, /* filled at runtime */ 231 "RSA #1", 232 0, 233 } }, 234 { NULL, -1, -1, 0, 0, 0, 0, -1, { 235 NULL, 236 6, 237 HKF_STATUS_COMMENT, 238 0, 239 "", 240 MRK_NONE, 241 NULL, 242 NULL, 243 KEY_UNSPEC, 244 NULL, 245 NULL, 246 0, 247 } }, 248 { NULL, -1, -1, 0, 0, 0, 0, -1, { 249 NULL, 250 7, 251 HKF_STATUS_COMMENT, 252 0, 253 "# Plain host keys, hostnames + addresses", 254 MRK_NONE, 255 NULL, 256 NULL, 257 KEY_UNSPEC, 258 NULL, 259 NULL, 260 0, 261 } }, 262 { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 263 NULL, 264 8, 265 HKF_STATUS_OK, 266 0, 267 NULL, 268 MRK_NONE, 269 "prometheus.example.com,192.0.2.1,2001:db8::1", 270 NULL, 271 KEY_DSA, 272 NULL, /* filled at runtime */ 273 "DSA #2", 274 0, 275 } }, 276 { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 277 NULL, 278 9, 279 HKF_STATUS_OK, 280 0, 281 NULL, 282 MRK_NONE, 283 "prometheus.example.com,192.0.2.1,2001:db8::1", 284 NULL, 285 KEY_ECDSA, 286 NULL, /* filled at runtime */ 287 "ECDSA #2", 288 0, 289 } }, 290 { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 291 NULL, 292 10, 293 HKF_STATUS_OK, 294 0, 295 NULL, 296 MRK_NONE, 297 "prometheus.example.com,192.0.2.1,2001:db8::1", 298 NULL, 299 KEY_ED25519, 300 NULL, /* filled at runtime */ 301 "ED25519 #2", 302 0, 303 } }, 304 { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 305 NULL, 306 11, 307 HKF_STATUS_OK, 308 0, 309 NULL, 310 MRK_NONE, 311 "prometheus.example.com,192.0.2.1,2001:db8::1", 312 NULL, 313 KEY_RSA, 314 NULL, /* filled at runtime */ 315 "RSA #2", 316 0, 317 } }, 318 { NULL, -1, -1, 0, 0, 0, 0, -1, { 319 NULL, 320 12, 321 HKF_STATUS_COMMENT, 322 0, 323 "", 324 MRK_NONE, 325 NULL, 326 NULL, 327 KEY_UNSPEC, 328 NULL, 329 NULL, 330 0, 331 } }, 332 { NULL, -1, -1, 0, 0, 0, 0, -1, { 333 NULL, 334 13, 335 HKF_STATUS_COMMENT, 336 0, 337 "# Some hosts with wildcard names / IPs", 338 MRK_NONE, 339 NULL, 340 NULL, 341 KEY_UNSPEC, 342 NULL, 343 NULL, 344 0, 345 } }, 346 { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 347 NULL, 348 14, 349 HKF_STATUS_OK, 350 0, 351 NULL, 352 MRK_NONE, 353 "*.example.com,192.0.2.*,2001:*", 354 NULL, 355 KEY_DSA, 356 NULL, /* filled at runtime */ 357 "DSA #3", 358 0, 359 } }, 360 { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 361 NULL, 362 15, 363 HKF_STATUS_OK, 364 0, 365 NULL, 366 MRK_NONE, 367 "*.example.com,192.0.2.*,2001:*", 368 NULL, 369 KEY_ECDSA, 370 NULL, /* filled at runtime */ 371 "ECDSA #3", 372 0, 373 } }, 374 { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 375 NULL, 376 16, 377 HKF_STATUS_OK, 378 0, 379 NULL, 380 MRK_NONE, 381 "*.example.com,192.0.2.*,2001:*", 382 NULL, 383 KEY_ED25519, 384 NULL, /* filled at runtime */ 385 "ED25519 #3", 386 0, 387 } }, 388 { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 389 NULL, 390 17, 391 HKF_STATUS_OK, 392 0, 393 NULL, 394 MRK_NONE, 395 "*.example.com,192.0.2.*,2001:*", 396 NULL, 397 KEY_RSA, 398 NULL, /* filled at runtime */ 399 "RSA #3", 400 0, 401 } }, 402 { NULL, -1, -1, 0, 0, 0, 0, -1, { 403 NULL, 404 18, 405 HKF_STATUS_COMMENT, 406 0, 407 "", 408 MRK_NONE, 409 NULL, 410 NULL, 411 KEY_UNSPEC, 412 NULL, 413 NULL, 414 0, 415 } }, 416 { NULL, -1, -1, 0, 0, 0, 0, -1, { 417 NULL, 418 19, 419 HKF_STATUS_COMMENT, 420 0, 421 "# Hashed hostname and address entries", 422 MRK_NONE, 423 NULL, 424 NULL, 425 KEY_UNSPEC, 426 NULL, 427 NULL, 428 0, 429 } }, 430 { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 431 NULL, 432 20, 433 HKF_STATUS_OK, 434 0, 435 NULL, 436 MRK_NONE, 437 NULL, 438 NULL, 439 KEY_DSA, 440 NULL, /* filled at runtime */ 441 "DSA #5", 442 0, 443 } }, 444 { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 445 NULL, 446 21, 447 HKF_STATUS_OK, 448 0, 449 NULL, 450 MRK_NONE, 451 NULL, 452 NULL, 453 KEY_ECDSA, 454 NULL, /* filled at runtime */ 455 "ECDSA #5", 456 0, 457 } }, 458 { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 459 NULL, 460 22, 461 HKF_STATUS_OK, 462 0, 463 NULL, 464 MRK_NONE, 465 NULL, 466 NULL, 467 KEY_ED25519, 468 NULL, /* filled at runtime */ 469 "ED25519 #5", 470 0, 471 } }, 472 { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 473 NULL, 474 23, 475 HKF_STATUS_OK, 476 0, 477 NULL, 478 MRK_NONE, 479 NULL, 480 NULL, 481 KEY_RSA, 482 NULL, /* filled at runtime */ 483 "RSA #5", 484 0, 485 } }, 486 { NULL, -1, -1, 0, 0, 0, 0, -1, { 487 NULL, 488 24, 489 HKF_STATUS_COMMENT, 490 0, 491 "", 492 MRK_NONE, 493 NULL, 494 NULL, 495 KEY_UNSPEC, 496 NULL, 497 NULL, 498 0, 499 } }, 500 /* 501 * The next series have each key listed multiple times, as the 502 * hostname and addresses in the pre-hashed known_hosts are split 503 * to separate lines. 504 */ 505 { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 506 NULL, 507 25, 508 HKF_STATUS_OK, 509 0, 510 NULL, 511 MRK_NONE, 512 NULL, 513 NULL, 514 KEY_DSA, 515 NULL, /* filled at runtime */ 516 "DSA #6", 517 0, 518 } }, 519 { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 520 NULL, 521 26, 522 HKF_STATUS_OK, 523 0, 524 NULL, 525 MRK_NONE, 526 NULL, 527 NULL, 528 KEY_DSA, 529 NULL, /* filled at runtime */ 530 "DSA #6", 531 0, 532 } }, 533 { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 534 NULL, 535 27, 536 HKF_STATUS_OK, 537 0, 538 NULL, 539 MRK_NONE, 540 NULL, 541 NULL, 542 KEY_DSA, 543 NULL, /* filled at runtime */ 544 "DSA #6", 545 0, 546 } }, 547 { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 548 NULL, 549 28, 550 HKF_STATUS_OK, 551 0, 552 NULL, 553 MRK_NONE, 554 NULL, 555 NULL, 556 KEY_ECDSA, 557 NULL, /* filled at runtime */ 558 "ECDSA #6", 559 0, 560 } }, 561 { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 562 NULL, 563 29, 564 HKF_STATUS_OK, 565 0, 566 NULL, 567 MRK_NONE, 568 NULL, 569 NULL, 570 KEY_ECDSA, 571 NULL, /* filled at runtime */ 572 "ECDSA #6", 573 0, 574 } }, 575 { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 576 NULL, 577 30, 578 HKF_STATUS_OK, 579 0, 580 NULL, 581 MRK_NONE, 582 NULL, 583 NULL, 584 KEY_ECDSA, 585 NULL, /* filled at runtime */ 586 "ECDSA #6", 587 0, 588 } }, 589 { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 590 NULL, 591 31, 592 HKF_STATUS_OK, 593 0, 594 NULL, 595 MRK_NONE, 596 NULL, 597 NULL, 598 KEY_ED25519, 599 NULL, /* filled at runtime */ 600 "ED25519 #6", 601 0, 602 } }, 603 { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 604 NULL, 605 32, 606 HKF_STATUS_OK, 607 0, 608 NULL, 609 MRK_NONE, 610 NULL, 611 NULL, 612 KEY_ED25519, 613 NULL, /* filled at runtime */ 614 "ED25519 #6", 615 0, 616 } }, 617 { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 618 NULL, 619 33, 620 HKF_STATUS_OK, 621 0, 622 NULL, 623 MRK_NONE, 624 NULL, 625 NULL, 626 KEY_ED25519, 627 NULL, /* filled at runtime */ 628 "ED25519 #6", 629 0, 630 } }, 631 { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 632 NULL, 633 34, 634 HKF_STATUS_OK, 635 0, 636 NULL, 637 MRK_NONE, 638 NULL, 639 NULL, 640 KEY_RSA, 641 NULL, /* filled at runtime */ 642 "RSA #6", 643 0, 644 } }, 645 { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 646 NULL, 647 35, 648 HKF_STATUS_OK, 649 0, 650 NULL, 651 MRK_NONE, 652 NULL, 653 NULL, 654 KEY_RSA, 655 NULL, /* filled at runtime */ 656 "RSA #6", 657 0, 658 } }, 659 { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 660 NULL, 661 36, 662 HKF_STATUS_OK, 663 0, 664 NULL, 665 MRK_NONE, 666 NULL, 667 NULL, 668 KEY_RSA, 669 NULL, /* filled at runtime */ 670 "RSA #6", 671 0, 672 } }, 673 { NULL, -1, -1, 0, 0, 0, 0, -1, { 674 NULL, 675 37, 676 HKF_STATUS_COMMENT, 677 0, 678 "", 679 MRK_NONE, 680 NULL, 681 NULL, 682 KEY_UNSPEC, 683 NULL, 684 NULL, 685 0, 686 } }, 687 { NULL, -1, -1, 0, 0, 0, 0, -1, { 688 NULL, 689 38, 690 HKF_STATUS_COMMENT, 691 0, 692 "", 693 MRK_NONE, 694 NULL, 695 NULL, 696 KEY_UNSPEC, 697 NULL, 698 NULL, 699 0, 700 } }, 701 { NULL, -1, -1, 0, 0, 0, 0, -1, { 702 NULL, 703 39, 704 HKF_STATUS_COMMENT, 705 0, 706 "# Revoked and CA keys", 707 MRK_NONE, 708 NULL, 709 NULL, 710 KEY_UNSPEC, 711 NULL, 712 NULL, 713 0, 714 } }, 715 { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 716 NULL, 717 40, 718 HKF_STATUS_OK, 719 0, 720 NULL, 721 MRK_REVOKE, 722 "sisyphus.example.com", 723 NULL, 724 KEY_ED25519, 725 NULL, /* filled at runtime */ 726 "ED25519 #4", 727 0, 728 } }, 729 { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { 730 NULL, 731 41, 732 HKF_STATUS_OK, 733 0, 734 NULL, 735 MRK_CA, 736 "prometheus.example.com", 737 NULL, 738 KEY_ECDSA, 739 NULL, /* filled at runtime */ 740 "ECDSA #4", 741 0, 742 } }, 743 { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { 744 NULL, 745 42, 746 HKF_STATUS_OK, 747 0, 748 NULL, 749 MRK_CA, 750 "*.example.com", 751 NULL, 752 KEY_DSA, 753 NULL, /* filled at runtime */ 754 "DSA #4", 755 0, 756 } }, 757 { NULL, -1, -1, 0, 0, 0, 0, -1, { 758 NULL, 759 43, 760 HKF_STATUS_COMMENT, 761 0, 762 "", 763 MRK_NONE, 764 NULL, 765 NULL, 766 KEY_UNSPEC, 767 NULL, 768 NULL, 769 0, 770 } }, 771 { NULL, -1, -1, 0, 0, 0, 0, -1, { 772 NULL, 773 44, 774 HKF_STATUS_COMMENT, 775 0, 776 "# Some invalid lines", 777 MRK_NONE, 778 NULL, 779 NULL, 780 KEY_UNSPEC, 781 NULL, 782 NULL, 783 0, 784 } }, 785 { NULL, -1, -1, 0, 0, 0, 0, -1, { 786 NULL, 787 45, 788 HKF_STATUS_INVALID, 789 0, 790 NULL, 791 MRK_ERROR, 792 NULL, 793 NULL, 794 KEY_UNSPEC, 795 NULL, 796 NULL, 797 0, 798 } }, 799 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 800 NULL, 801 46, 802 HKF_STATUS_INVALID, 803 0, 804 NULL, 805 MRK_NONE, 806 "sisyphus.example.com", 807 NULL, 808 KEY_UNSPEC, 809 NULL, 810 NULL, 811 0, 812 } }, 813 { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { 814 NULL, 815 47, 816 HKF_STATUS_INVALID, 817 0, 818 NULL, 819 MRK_NONE, 820 "prometheus.example.com", 821 NULL, 822 KEY_UNSPEC, 823 NULL, 824 NULL, 825 0, 826 } }, 827 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 828 NULL, 829 48, 830 HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 831 0, 832 NULL, 833 MRK_NONE, 834 "sisyphus.example.com", 835 NULL, 836 KEY_UNSPEC, 837 NULL, 838 NULL, 839 0, 840 } }, 841 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 842 NULL, 843 49, 844 HKF_STATUS_INVALID, 845 0, 846 NULL, 847 MRK_NONE, 848 "sisyphus.example.com", 849 NULL, 850 KEY_UNSPEC, 851 NULL, /* filled at runtime */ 852 NULL, 853 0, 854 } }, 855 { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { 856 NULL, 857 50, 858 HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 859 0, 860 NULL, 861 MRK_NONE, 862 "prometheus.example.com", 863 NULL, 864 KEY_UNSPEC, 865 NULL, /* filled at runtime */ 866 NULL, 867 0, 868 } }, 869 }; 870 871 void test_iterate(void); 872 873 void 874 test_iterate(void) 875 { 876 struct cbctx ctx; 877 878 TEST_START("hostkeys_iterate all with key parse"); 879 memset(&ctx, 0, sizeof(ctx)); 880 ctx.expected = expected_full; 881 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 882 ctx.flags = HKF_WANT_PARSE_KEY; 883 prepare_expected(expected_full, ctx.nexpected); 884 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 885 check, &ctx, NULL, NULL, ctx.flags, 0), 0); 886 cleanup_expected(expected_full, ctx.nexpected); 887 TEST_DONE(); 888 889 TEST_START("hostkeys_iterate all without key parse"); 890 memset(&ctx, 0, sizeof(ctx)); 891 ctx.expected = expected_full; 892 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 893 ctx.flags = 0; 894 prepare_expected(expected_full, ctx.nexpected); 895 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 896 check, &ctx, NULL, NULL, ctx.flags, 0), 0); 897 cleanup_expected(expected_full, ctx.nexpected); 898 TEST_DONE(); 899 900 TEST_START("hostkeys_iterate specify host 1"); 901 memset(&ctx, 0, sizeof(ctx)); 902 ctx.expected = expected_full; 903 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 904 ctx.flags = 0; 905 ctx.match_host_p = 1; 906 prepare_expected(expected_full, ctx.nexpected); 907 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 908 check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0); 909 cleanup_expected(expected_full, ctx.nexpected); 910 TEST_DONE(); 911 912 TEST_START("hostkeys_iterate specify host 2"); 913 memset(&ctx, 0, sizeof(ctx)); 914 ctx.expected = expected_full; 915 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 916 ctx.flags = 0; 917 ctx.match_host_s = 1; 918 prepare_expected(expected_full, ctx.nexpected); 919 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 920 check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0); 921 cleanup_expected(expected_full, ctx.nexpected); 922 TEST_DONE(); 923 924 TEST_START("hostkeys_iterate match host 1"); 925 memset(&ctx, 0, sizeof(ctx)); 926 ctx.expected = expected_full; 927 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 928 ctx.flags = HKF_WANT_MATCH; 929 ctx.match_host_p = 1; 930 prepare_expected(expected_full, ctx.nexpected); 931 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 932 check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0); 933 cleanup_expected(expected_full, ctx.nexpected); 934 TEST_DONE(); 935 936 TEST_START("hostkeys_iterate match host 2"); 937 memset(&ctx, 0, sizeof(ctx)); 938 ctx.expected = expected_full; 939 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 940 ctx.flags = HKF_WANT_MATCH; 941 ctx.match_host_s = 1; 942 prepare_expected(expected_full, ctx.nexpected); 943 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 944 check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0); 945 cleanup_expected(expected_full, ctx.nexpected); 946 TEST_DONE(); 947 948 TEST_START("hostkeys_iterate specify host missing"); 949 memset(&ctx, 0, sizeof(ctx)); 950 ctx.expected = expected_full; 951 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 952 ctx.flags = 0; 953 prepare_expected(expected_full, ctx.nexpected); 954 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 955 check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0); 956 cleanup_expected(expected_full, ctx.nexpected); 957 TEST_DONE(); 958 959 TEST_START("hostkeys_iterate match host missing"); 960 memset(&ctx, 0, sizeof(ctx)); 961 ctx.expected = expected_full; 962 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 963 ctx.flags = HKF_WANT_MATCH; 964 prepare_expected(expected_full, ctx.nexpected); 965 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 966 check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0); 967 cleanup_expected(expected_full, ctx.nexpected); 968 TEST_DONE(); 969 970 TEST_START("hostkeys_iterate specify IPv4"); 971 memset(&ctx, 0, sizeof(ctx)); 972 ctx.expected = expected_full; 973 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 974 ctx.flags = 0; 975 ctx.match_ipv4 = 1; 976 prepare_expected(expected_full, ctx.nexpected); 977 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 978 check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0); 979 cleanup_expected(expected_full, ctx.nexpected); 980 TEST_DONE(); 981 982 TEST_START("hostkeys_iterate specify IPv6"); 983 memset(&ctx, 0, sizeof(ctx)); 984 ctx.expected = expected_full; 985 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 986 ctx.flags = 0; 987 ctx.match_ipv6 = 1; 988 prepare_expected(expected_full, ctx.nexpected); 989 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 990 check, &ctx, "tiresias.example.org", "2001:db8::1", 991 ctx.flags, 0), 0); 992 cleanup_expected(expected_full, ctx.nexpected); 993 TEST_DONE(); 994 995 TEST_START("hostkeys_iterate match IPv4"); 996 memset(&ctx, 0, sizeof(ctx)); 997 ctx.expected = expected_full; 998 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 999 ctx.flags = HKF_WANT_MATCH; 1000 ctx.match_ipv4 = 1; 1001 prepare_expected(expected_full, ctx.nexpected); 1002 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1003 check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0); 1004 cleanup_expected(expected_full, ctx.nexpected); 1005 TEST_DONE(); 1006 1007 TEST_START("hostkeys_iterate match IPv6"); 1008 memset(&ctx, 0, sizeof(ctx)); 1009 ctx.expected = expected_full; 1010 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1011 ctx.flags = HKF_WANT_MATCH; 1012 ctx.match_ipv6 = 1; 1013 prepare_expected(expected_full, ctx.nexpected); 1014 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1015 check, &ctx, "tiresias.example.org", "2001:db8::1", 1016 ctx.flags, 0), 0); 1017 cleanup_expected(expected_full, ctx.nexpected); 1018 TEST_DONE(); 1019 1020 TEST_START("hostkeys_iterate specify addr missing"); 1021 memset(&ctx, 0, sizeof(ctx)); 1022 ctx.expected = expected_full; 1023 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1024 ctx.flags = 0; 1025 prepare_expected(expected_full, ctx.nexpected); 1026 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1027 check, &ctx, "tiresias.example.org", "192.168.0.1", 1028 ctx.flags, 0), 0); 1029 cleanup_expected(expected_full, ctx.nexpected); 1030 TEST_DONE(); 1031 1032 TEST_START("hostkeys_iterate match addr missing"); 1033 memset(&ctx, 0, sizeof(ctx)); 1034 ctx.expected = expected_full; 1035 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1036 ctx.flags = HKF_WANT_MATCH; 1037 prepare_expected(expected_full, ctx.nexpected); 1038 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1039 check, &ctx, "tiresias.example.org", "::1", ctx.flags, 0), 0); 1040 cleanup_expected(expected_full, ctx.nexpected); 1041 TEST_DONE(); 1042 1043 TEST_START("hostkeys_iterate specify host 2 and IPv4"); 1044 memset(&ctx, 0, sizeof(ctx)); 1045 ctx.expected = expected_full; 1046 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1047 ctx.flags = 0; 1048 ctx.match_host_s = 1; 1049 ctx.match_ipv4 = 1; 1050 prepare_expected(expected_full, ctx.nexpected); 1051 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1052 check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0); 1053 cleanup_expected(expected_full, ctx.nexpected); 1054 TEST_DONE(); 1055 1056 TEST_START("hostkeys_iterate match host 1 and IPv6"); 1057 memset(&ctx, 0, sizeof(ctx)); 1058 ctx.expected = expected_full; 1059 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1060 ctx.flags = HKF_WANT_MATCH; 1061 ctx.match_host_p = 1; 1062 ctx.match_ipv6 = 1; 1063 prepare_expected(expected_full, ctx.nexpected); 1064 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1065 check, &ctx, "prometheus.example.com", 1066 "2001:db8::1", ctx.flags, 0), 0); 1067 cleanup_expected(expected_full, ctx.nexpected); 1068 TEST_DONE(); 1069 1070 TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse"); 1071 memset(&ctx, 0, sizeof(ctx)); 1072 ctx.expected = expected_full; 1073 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1074 ctx.flags = HKF_WANT_PARSE_KEY; 1075 ctx.match_host_s = 1; 1076 ctx.match_ipv4 = 1; 1077 prepare_expected(expected_full, ctx.nexpected); 1078 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1079 check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0); 1080 cleanup_expected(expected_full, ctx.nexpected); 1081 TEST_DONE(); 1082 1083 TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse"); 1084 memset(&ctx, 0, sizeof(ctx)); 1085 ctx.expected = expected_full; 1086 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); 1087 ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY; 1088 ctx.match_host_p = 1; 1089 ctx.match_ipv6 = 1; 1090 prepare_expected(expected_full, ctx.nexpected); 1091 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), 1092 check, &ctx, "prometheus.example.com", 1093 "2001:db8::1", ctx.flags, 0), 0); 1094 cleanup_expected(expected_full, ctx.nexpected); 1095 TEST_DONE(); 1096 } 1097 1098