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