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