/* $OpenBSD: test_iterate.c,v 1.9 2024/01/11 01:45:58 djm Exp $ */ /* * Regress test for hostfile.h hostkeys_foreach() * * Placed in the public domain */ #include "includes.h" #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include "../test_helper/test_helper.h" #include "sshkey.h" #include "authfile.h" #include "hostfile.h" struct expected { const char *key_file; /* Path for key, NULL for none */ int no_parse_status; /* Expected status w/o key parsing */ int no_parse_keytype; /* Expected keytype w/o key parsing */ int match_host_p; /* Match 'prometheus.example.com' */ int match_host_s; /* Match 'sisyphus.example.com' */ int match_ipv4; /* Match '192.0.2.1' */ int match_ipv6; /* Match '2001:db8::1' */ int match_flags; /* Expected flags from match */ struct hostkey_foreach_line l; /* Expected line contents */ }; struct cbctx { const struct expected *expected; size_t nexpected; size_t i; int flags; int match_host_p; int match_host_s; int match_ipv4; int match_ipv6; }; /* * hostkeys_foreach() iterator callback that verifies the line passed * against an array of expected entries. */ static int check(struct hostkey_foreach_line *l, void *_ctx) { struct cbctx *ctx = (struct cbctx *)_ctx; const struct expected *expected; int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0; const int matching = (ctx->flags & HKF_WANT_MATCH) != 0; u_int expected_status, expected_match; int expected_keytype, skip = 0; test_subtest_info("entry %zu/%zu, file line %ld", ctx->i + 1, ctx->nexpected, l->linenum); for (;;) { ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected); expected = ctx->expected + ctx->i++; /* If we are matching host/IP then skip entries that don't */ if (!matching) break; if (ctx->match_host_p && expected->match_host_p) break; if (ctx->match_host_s && expected->match_host_s) break; if (ctx->match_ipv4 && expected->match_ipv4) break; if (ctx->match_ipv6 && expected->match_ipv6) break; } expected_status = (parse_key || expected->no_parse_status < 0) ? expected->l.status : (u_int)expected->no_parse_status; expected_match = expected->l.match; #define UPDATE_MATCH_STATUS(x) do { \ if (ctx->x && expected->x) { \ expected_match |= expected->x; \ if (expected_status == HKF_STATUS_OK) \ expected_status = HKF_STATUS_MATCHED; \ } \ } while (0) expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? expected->l.keytype : expected->no_parse_keytype; #ifndef OPENSSL_HAS_ECC if (expected->l.keytype == KEY_ECDSA || expected->no_parse_keytype == KEY_ECDSA) skip = 1; #endif /* OPENSSL_HAS_ECC */ #ifndef WITH_DSA if (expected->l.keytype == KEY_DSA || expected->no_parse_keytype == KEY_DSA) skip = 1; #endif #ifndef WITH_OPENSSL if (expected->l.keytype == KEY_DSA || expected->no_parse_keytype == KEY_DSA || expected->l.keytype == KEY_RSA || expected->no_parse_keytype == KEY_RSA || expected->l.keytype == KEY_ECDSA || expected->no_parse_keytype == KEY_ECDSA) skip = 1; #endif /* WITH_OPENSSL */ if (skip) { expected_status = HKF_STATUS_INVALID; expected_keytype = KEY_UNSPEC; parse_key = 0; } UPDATE_MATCH_STATUS(match_host_p); UPDATE_MATCH_STATUS(match_host_s); UPDATE_MATCH_STATUS(match_ipv4); UPDATE_MATCH_STATUS(match_ipv6); ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */ ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum); ASSERT_U_INT_EQ(l->status, expected_status); ASSERT_U_INT_EQ(l->match, expected_match); /* Not all test entries contain fulltext */ if (expected->l.line != NULL) ASSERT_STRING_EQ(l->line, expected->l.line); ASSERT_INT_EQ(l->marker, expected->l.marker); /* XXX we skip hashed hostnames for now; implement checking */ if (expected->l.hosts != NULL) ASSERT_STRING_EQ(l->hosts, expected->l.hosts); /* Not all test entries contain raw keys */ if (expected->l.rawkey != NULL) ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey); /* XXX synthesise raw key for cases lacking and compare */ ASSERT_INT_EQ(l->keytype, expected_keytype); if (parse_key) { if (expected->l.key == NULL) ASSERT_PTR_EQ(l->key, NULL); if (expected->l.key != NULL) { ASSERT_PTR_NE(l->key, NULL); ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); } } if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) ASSERT_STRING_EQ(l->comment, expected->l.comment); return 0; } /* Loads public keys for a set of expected results */ static void prepare_expected(struct expected *expected, size_t n) { size_t i; for (i = 0; i < n; i++) { if (expected[i].key_file == NULL) continue; #ifndef OPENSSL_HAS_ECC if (expected[i].l.keytype == KEY_ECDSA) continue; #endif /* OPENSSL_HAS_ECC */ #ifndef WITH_DSA if (expected[i].l.keytype == KEY_DSA) continue; #endif #ifndef WITH_OPENSSL switch (expected[i].l.keytype) { case KEY_RSA: case KEY_DSA: case KEY_ECDSA: continue; } #endif /* WITH_OPENSSL */ ASSERT_INT_EQ(sshkey_load_public( test_data_file(expected[i].key_file), &expected[i].l.key, NULL), 0); } } static void cleanup_expected(struct expected *expected, size_t n) { size_t i; for (i = 0; i < n; i++) { sshkey_free(expected[i].l.key); expected[i].l.key = NULL; } } struct expected expected_full[] = { { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, /* path, don't care */ 1, /* line number */ HKF_STATUS_COMMENT, /* status */ 0, /* match flags */ "# Plain host keys, plain host names", /* full line, optional */ MRK_NONE, /* marker (CA / revoked) */ NULL, /* hosts text */ NULL, /* raw key, optional */ KEY_UNSPEC, /* key type */ NULL, /* deserialised key */ NULL, /* comment */ 0, /* note */ } }, { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 2, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #1", 0, } }, { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 3, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #1", 0, } }, { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 4, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #1", 0, } }, { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 5, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #1", 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 6, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 7, HKF_STATUS_COMMENT, 0, "# Plain host keys, hostnames + addresses", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 8, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #2", 0, } }, { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 9, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #2", 0, } }, { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 10, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #2", 0, } }, { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 11, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #2", 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 12, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 13, HKF_STATUS_COMMENT, 0, "# Some hosts with wildcard names / IPs", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 14, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #3", 0, } }, { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 15, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #3", 0, } }, { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 16, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #3", 0, } }, { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 17, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #3", 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 18, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 19, HKF_STATUS_COMMENT, 0, "# Hashed hostname and address entries", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 20, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #5", 0, } }, { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 21, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #5", 0, } }, { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 22, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #5", 0, } }, { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 23, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #5", 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 24, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, /* * The next series have each key listed multiple times, as the * hostname and addresses in the pre-hashed known_hosts are split * to separate lines. */ { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 25, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #6", 0, } }, { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 26, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #6", 0, } }, { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 27, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #6", 0, } }, { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 28, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #6", 0, } }, { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 29, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #6", 0, } }, { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 30, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #6", 0, } }, { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 31, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #6", 0, } }, { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 32, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #6", 0, } }, { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 33, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #6", 0, } }, { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 34, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #6", 0, } }, { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 35, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #6", 0, } }, { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 36, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #6", 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 37, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 38, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 39, HKF_STATUS_COMMENT, 0, "# Revoked and CA keys", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 40, HKF_STATUS_OK, 0, NULL, MRK_REVOKE, "sisyphus.example.com", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #4", 0, } }, { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 41, HKF_STATUS_OK, 0, NULL, MRK_CA, "prometheus.example.com", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #4", 0, } }, { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { NULL, 42, HKF_STATUS_OK, 0, NULL, MRK_CA, "*.example.com", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #4", 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 43, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 44, HKF_STATUS_COMMENT, 0, "# Some invalid lines", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 45, HKF_STATUS_INVALID, 0, NULL, MRK_ERROR, NULL, NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 46, HKF_STATUS_INVALID, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 47, HKF_STATUS_INVALID, 0, NULL, MRK_NONE, "prometheus.example.com", NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 48, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, NULL, 0, } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 49, HKF_STATUS_INVALID, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, /* filled at runtime */ NULL, 0, } }, { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 50, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "prometheus.example.com", NULL, KEY_UNSPEC, NULL, /* filled at runtime */ NULL, 0, } }, }; void test_iterate(void); void test_iterate(void) { struct cbctx ctx; TEST_START("hostkeys_iterate all with key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_PARSE_KEY; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, NULL, NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate all without key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, NULL, NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify host 1"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_host_p = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify host 2"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_host_s = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match host 1"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_host_p = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match host 2"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_host_s = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify host missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match host missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify IPv4"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify IPv6"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match IPv4"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match IPv6"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify addr missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match addr missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "::1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify host 2 and IPv4"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_host_s = 1; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match host 1 and IPv6"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_host_p = 1; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_PARSE_KEY; ctx.match_host_s = 1; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY; ctx.match_host_p = 1; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags, 0), 0); cleanup_expected(expected_full, ctx.nexpected); TEST_DONE(); }