/* $OpenBSD: test_iterate.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */
/*
* Regress test for hostfile.h hostkeys_foreach()
*
* Placed in the public domain
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdlib.h>
#include <string.h>
#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;
const 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;
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)
UPDATE_MATCH_STATUS(match_host_p);
UPDATE_MATCH_STATUS(match_host_s);
UPDATE_MATCH_STATUS(match_ipv4);
UPDATE_MATCH_STATUS(match_ipv