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