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