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