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