#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_helper.h"
#include "sshkey.h"
#include "authfile.h"
#include "hostfile.h"
struct expected {
const char *key_file;
int no_parse_status;
int no_parse_keytype;
int match_host_p;
int match_host_s;
int match_ipv4;
int match_ipv6;
int match_flags;
struct hostkey_foreach_line l;
};
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;
};
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 (!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;
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);
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);
if (expected->l.line != NULL)
ASSERT_STRING_EQ(l->line, expected->l.line);
ASSERT_INT_EQ(l->marker, expected->l.marker);
if (expected->l.hosts != NULL)
ASSERT_STRING_EQ(l->hosts, expected->l.hosts);
if (expected->l.rawkey != NULL)
ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey);
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;
}
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;
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,
1,
HKF_STATUS_COMMENT,
0,
"# Plain host keys, plain host names",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ "ecdsa_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_ECDSA,
NULL,
"ECDSA #1",
0,
} },
{ "ed25519_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_ED25519,
NULL,
"ED25519 #1",
0,
} },
{ "rsa_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_RSA,
NULL,
"RSA #1",
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
5,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
6,
HKF_STATUS_COMMENT,
0,
"# Plain host keys, hostnames + addresses",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
7,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
"prometheus.example.com,192.0.2.1,2001:db8::1",
NULL,
KEY_ECDSA,
NULL,
"ECDSA #2",
0,
} },
{ "ed25519_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_ED25519,
NULL,
"ED25519 #2",
0,
} },
{ "rsa_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_RSA,
NULL,
"RSA #2",
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
10,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
11,
HKF_STATUS_COMMENT,
0,
"# Some hosts with wildcard names / IPs",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
12,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
"*.example.com,192.0.2.*,2001:*",
NULL,
KEY_ECDSA,
NULL,
"ECDSA #3",
0,
} },
{ "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
13,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
"*.example.com,192.0.2.*,2001:*",
NULL,
KEY_ED25519,
NULL,
"ED25519 #3",
0,
} },
{ "rsa_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_RSA,
NULL,
"RSA #3",
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
15,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
16,
HKF_STATUS_COMMENT,
0,
"# Hashed hostname and address entries",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
17,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ECDSA,
NULL,
"ECDSA #5",
0,
} },
{ "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
18,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ED25519,
NULL,
"ED25519 #5",
0,
} },
{ "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
19,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_RSA,
NULL,
"RSA #5",
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
20,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
NULL,
21,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ECDSA,
NULL,
"ECDSA #6",
0,
} },
{ "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
22,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ECDSA,
NULL,
"ECDSA #6",
0,
} },
{ "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
23,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ECDSA,
NULL,
"ECDSA #6",
0,
} },
{ "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
NULL,
24,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ED25519,
NULL,
"ED25519 #6",
0,
} },
{ "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
25,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ED25519,
NULL,
"ED25519 #6",
0,
} },
{ "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
26,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_ED25519,
NULL,
"ED25519 #6",
0,
} },
{ "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
NULL,
27,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_RSA,
NULL,
"RSA #6",
0,
} },
{ "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
28,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_RSA,
NULL,
"RSA #6",
0,
} },
{ "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
29,
HKF_STATUS_OK,
0,
NULL,
MRK_NONE,
NULL,
NULL,
KEY_RSA,
NULL,
"RSA #6",
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
30,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
31,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
32,
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,
33,
HKF_STATUS_OK,
0,
NULL,
MRK_REVOKE,
"sisyphus.example.com",
NULL,
KEY_ED25519,
NULL,
"ED25519 #4",
0,
} },
{ "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
NULL,
34,
HKF_STATUS_OK,
0,
NULL,
MRK_CA,
"prometheus.example.com",
NULL,
KEY_ECDSA,
NULL,
"ECDSA #4",
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
35,
HKF_STATUS_COMMENT,
0,
"",
MRK_NONE,
NULL,
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
36,
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,
37,
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,
38,
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,
39,
HKF_STATUS_INVALID,
0,
NULL,
MRK_NONE,
"prometheus.example.com",
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, HKF_STATUS_OK, KEY_ED25519, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
40,
HKF_STATUS_INVALID,
0,
NULL,
MRK_NONE,
"sisyphus.example.com",
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
41,
HKF_STATUS_INVALID,
0,
NULL,
MRK_NONE,
"sisyphus.example.com",
NULL,
KEY_UNSPEC,
NULL,
NULL,
0,
} },
{ NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
NULL,
42,
HKF_STATUS_INVALID,
0,
NULL,
MRK_NONE,
"prometheus.example.com",
NULL,
KEY_UNSPEC,
NULL,
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();
}