1 /* $OpenBSD: test_iterate.c,v 1.11 2025/11/17 09:59:13 dtucker 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 <stdio.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "../test_helper/test_helper.h"
17
18 #include "sshkey.h"
19 #include "authfile.h"
20 #include "hostfile.h"
21
22 struct expected {
23 const char *key_file; /* Path for key, NULL for none */
24 int no_parse_status; /* Expected status w/o key parsing */
25 int no_parse_keytype; /* Expected keytype w/o key parsing */
26 int match_host_p; /* Match 'prometheus.example.com' */
27 int match_host_s; /* Match 'sisyphus.example.com' */
28 int match_ipv4; /* Match '192.0.2.1' */
29 int match_ipv6; /* Match '2001:db8::1' */
30 int match_flags; /* Expected flags from match */
31 struct hostkey_foreach_line l; /* Expected line contents */
32 };
33
34 struct cbctx {
35 const struct expected *expected;
36 size_t nexpected;
37 size_t i;
38 int flags;
39 int match_host_p;
40 int match_host_s;
41 int match_ipv4;
42 int match_ipv6;
43 };
44
45 /*
46 * hostkeys_foreach() iterator callback that verifies the line passed
47 * against an array of expected entries.
48 */
49 static int
check(struct hostkey_foreach_line * l,void * _ctx)50 check(struct hostkey_foreach_line *l, void *_ctx)
51 {
52 struct cbctx *ctx = (struct cbctx *)_ctx;
53 const struct expected *expected;
54 int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0;
55 const int matching = (ctx->flags & HKF_WANT_MATCH) != 0;
56 u_int expected_status, expected_match;
57 int expected_keytype, skip = 0;
58
59 test_subtest_info("entry %zu/%zu, file line %ld",
60 ctx->i + 1, ctx->nexpected, l->linenum);
61
62 for (;;) {
63 ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected);
64 expected = ctx->expected + ctx->i++;
65 /* If we are matching host/IP then skip entries that don't */
66 if (!matching)
67 break;
68 if (ctx->match_host_p && expected->match_host_p)
69 break;
70 if (ctx->match_host_s && expected->match_host_s)
71 break;
72 if (ctx->match_ipv4 && expected->match_ipv4)
73 break;
74 if (ctx->match_ipv6 && expected->match_ipv6)
75 break;
76 }
77 expected_status = (parse_key || expected->no_parse_status < 0) ?
78 expected->l.status : (u_int)expected->no_parse_status;
79 expected_match = expected->l.match;
80 #define UPDATE_MATCH_STATUS(x) do { \
81 if (ctx->x && expected->x) { \
82 expected_match |= expected->x; \
83 if (expected_status == HKF_STATUS_OK) \
84 expected_status = HKF_STATUS_MATCHED; \
85 } \
86 } while (0)
87 expected_keytype = (parse_key || expected->no_parse_keytype < 0) ?
88 expected->l.keytype : expected->no_parse_keytype;
89
90 #ifndef OPENSSL_HAS_ECC
91 if (expected->l.keytype == KEY_ECDSA ||
92 expected->no_parse_keytype == KEY_ECDSA)
93 skip = 1;
94 #endif /* OPENSSL_HAS_ECC */
95 #ifndef WITH_OPENSSL
96 if (expected->l.keytype == KEY_RSA ||
97 expected->no_parse_keytype == KEY_RSA ||
98 expected->l.keytype == KEY_ECDSA ||
99 expected->no_parse_keytype == KEY_ECDSA)
100 skip = 1;
101 #endif /* WITH_OPENSSL */
102 if (skip) {
103 expected_status = HKF_STATUS_INVALID;
104 expected_keytype = KEY_UNSPEC;
105 parse_key = 0;
106 }
107 UPDATE_MATCH_STATUS(match_host_p);
108 UPDATE_MATCH_STATUS(match_host_s);
109 UPDATE_MATCH_STATUS(match_ipv4);
110 UPDATE_MATCH_STATUS(match_ipv6);
111
112 ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */
113 ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum);
114 ASSERT_U_INT_EQ(l->status, expected_status);
115 ASSERT_U_INT_EQ(l->match, expected_match);
116 /* Not all test entries contain fulltext */
117 if (expected->l.line != NULL)
118 ASSERT_STRING_EQ(l->line, expected->l.line);
119 ASSERT_INT_EQ(l->marker, expected->l.marker);
120 /* XXX we skip hashed hostnames for now; implement checking */
121 if (expected->l.hosts != NULL)
122 ASSERT_STRING_EQ(l->hosts, expected->l.hosts);
123 /* Not all test entries contain raw keys */
124 if (expected->l.rawkey != NULL)
125 ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey);
126 /* XXX synthesise raw key for cases lacking and compare */
127 ASSERT_INT_EQ(l->keytype, expected_keytype);
128 if (parse_key) {
129 if (expected->l.key == NULL)
130 ASSERT_PTR_EQ(l->key, NULL);
131 if (expected->l.key != NULL) {
132 ASSERT_PTR_NE(l->key, NULL);
133 ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1);
134 }
135 }
136 if (parse_key && l->comment != NULL && expected->l.comment != NULL)
137 ASSERT_STRING_EQ(l->comment, expected->l.comment);
138 return 0;
139 }
140
141 /* Loads public keys for a set of expected results */
142 static void
prepare_expected(struct expected * expected,size_t n)143 prepare_expected(struct expected *expected, size_t n)
144 {
145 size_t i;
146
147 for (i = 0; i < n; i++) {
148 if (expected[i].key_file == NULL)
149 continue;
150 #ifndef OPENSSL_HAS_ECC
151 if (expected[i].l.keytype == KEY_ECDSA)
152 continue;
153 #endif /* OPENSSL_HAS_ECC */
154 #ifndef WITH_OPENSSL
155 switch (expected[i].l.keytype) {
156 case KEY_RSA:
157 case KEY_ECDSA:
158 continue;
159 }
160 #endif /* WITH_OPENSSL */
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 static void
cleanup_expected(struct expected * expected,size_t n)168 cleanup_expected(struct expected *expected, size_t n)
169 {
170 size_t i;
171
172 for (i = 0; i < n; i++) {
173 sshkey_free(expected[i].l.key);
174 expected[i].l.key = NULL;
175 }
176 }
177
178 struct expected expected_full[] = {
179 { NULL, -1, -1, 0, 0, 0, 0, -1, {
180 NULL, /* path, don't care */
181 1, /* line number */
182 HKF_STATUS_COMMENT, /* status */
183 0, /* match flags */
184 "# Plain host keys, plain host names", /* full line, optional */
185 MRK_NONE, /* marker (CA / revoked) */
186 NULL, /* hosts text */
187 NULL, /* raw key, optional */
188 KEY_UNSPEC, /* key type */
189 NULL, /* deserialised key */
190 NULL, /* comment */
191 0, /* note */
192 } },
193 { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
194 NULL,
195 2,
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 0,
206 } },
207 { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
208 NULL,
209 3,
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 0,
220 } },
221 { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
222 NULL,
223 4,
224 HKF_STATUS_OK,
225 0,
226 NULL,
227 MRK_NONE,
228 "sisyphus.example.com",
229 NULL,
230 KEY_RSA,
231 NULL, /* filled at runtime */
232 "RSA #1",
233 0,
234 } },
235 { NULL, -1, -1, 0, 0, 0, 0, -1, {
236 NULL,
237 5,
238 HKF_STATUS_COMMENT,
239 0,
240 "",
241 MRK_NONE,
242 NULL,
243 NULL,
244 KEY_UNSPEC,
245 NULL,
246 NULL,
247 0,
248 } },
249 { NULL, -1, -1, 0, 0, 0, 0, -1, {
250 NULL,
251 6,
252 HKF_STATUS_COMMENT,
253 0,
254 "# Plain host keys, hostnames + addresses",
255 MRK_NONE,
256 NULL,
257 NULL,
258 KEY_UNSPEC,
259 NULL,
260 NULL,
261 0,
262 } },
263 { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
264 NULL,
265 7,
266 HKF_STATUS_OK,
267 0,
268 NULL,
269 MRK_NONE,
270 "prometheus.example.com,192.0.2.1,2001:db8::1",
271 NULL,
272 KEY_ECDSA,
273 NULL, /* filled at runtime */
274 "ECDSA #2",
275 0,
276 } },
277 { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
278 NULL,
279 8,
280 HKF_STATUS_OK,
281 0,
282 NULL,
283 MRK_NONE,
284 "prometheus.example.com,192.0.2.1,2001:db8::1",
285 NULL,
286 KEY_ED25519,
287 NULL, /* filled at runtime */
288 "ED25519 #2",
289 0,
290 } },
291 { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
292 NULL,
293 9,
294 HKF_STATUS_OK,
295 0,
296 NULL,
297 MRK_NONE,
298 "prometheus.example.com,192.0.2.1,2001:db8::1",
299 NULL,
300 KEY_RSA,
301 NULL, /* filled at runtime */
302 "RSA #2",
303 0,
304 } },
305 { NULL, -1, -1, 0, 0, 0, 0, -1, {
306 NULL,
307 10,
308 HKF_STATUS_COMMENT,
309 0,
310 "",
311 MRK_NONE,
312 NULL,
313 NULL,
314 KEY_UNSPEC,
315 NULL,
316 NULL,
317 0,
318 } },
319 { NULL, -1, -1, 0, 0, 0, 0, -1, {
320 NULL,
321 11,
322 HKF_STATUS_COMMENT,
323 0,
324 "# Some hosts with wildcard names / IPs",
325 MRK_NONE,
326 NULL,
327 NULL,
328 KEY_UNSPEC,
329 NULL,
330 NULL,
331 0,
332 } },
333 { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
334 NULL,
335 12,
336 HKF_STATUS_OK,
337 0,
338 NULL,
339 MRK_NONE,
340 "*.example.com,192.0.2.*,2001:*",
341 NULL,
342 KEY_ECDSA,
343 NULL, /* filled at runtime */
344 "ECDSA #3",
345 0,
346 } },
347 { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
348 NULL,
349 13,
350 HKF_STATUS_OK,
351 0,
352 NULL,
353 MRK_NONE,
354 "*.example.com,192.0.2.*,2001:*",
355 NULL,
356 KEY_ED25519,
357 NULL, /* filled at runtime */
358 "ED25519 #3",
359 0,
360 } },
361 { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
362 NULL,
363 14,
364 HKF_STATUS_OK,
365 0,
366 NULL,
367 MRK_NONE,
368 "*.example.com,192.0.2.*,2001:*",
369 NULL,
370 KEY_RSA,
371 NULL, /* filled at runtime */
372 "RSA #3",
373 0,
374 } },
375 { NULL, -1, -1, 0, 0, 0, 0, -1, {
376 NULL,
377 15,
378 HKF_STATUS_COMMENT,
379 0,
380 "",
381 MRK_NONE,
382 NULL,
383 NULL,
384 KEY_UNSPEC,
385 NULL,
386 NULL,
387 0,
388 } },
389 { NULL, -1, -1, 0, 0, 0, 0, -1, {
390 NULL,
391 16,
392 HKF_STATUS_COMMENT,
393 0,
394 "# Hashed hostname and address entries",
395 MRK_NONE,
396 NULL,
397 NULL,
398 KEY_UNSPEC,
399 NULL,
400 NULL,
401 0,
402 } },
403 { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
404 NULL,
405 17,
406 HKF_STATUS_OK,
407 0,
408 NULL,
409 MRK_NONE,
410 NULL,
411 NULL,
412 KEY_ECDSA,
413 NULL, /* filled at runtime */
414 "ECDSA #5",
415 0,
416 } },
417 { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
418 NULL,
419 18,
420 HKF_STATUS_OK,
421 0,
422 NULL,
423 MRK_NONE,
424 NULL,
425 NULL,
426 KEY_ED25519,
427 NULL, /* filled at runtime */
428 "ED25519 #5",
429 0,
430 } },
431 { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
432 NULL,
433 19,
434 HKF_STATUS_OK,
435 0,
436 NULL,
437 MRK_NONE,
438 NULL,
439 NULL,
440 KEY_RSA,
441 NULL, /* filled at runtime */
442 "RSA #5",
443 0,
444 } },
445 { NULL, -1, -1, 0, 0, 0, 0, -1, {
446 NULL,
447 20,
448 HKF_STATUS_COMMENT,
449 0,
450 "",
451 MRK_NONE,
452 NULL,
453 NULL,
454 KEY_UNSPEC,
455 NULL,
456 NULL,
457 0,
458 } },
459 /*
460 * The next series have each key listed multiple times, as the
461 * hostname and addresses in the pre-hashed known_hosts are split
462 * to separate lines.
463 */
464 { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
465 NULL,
466 21,
467 HKF_STATUS_OK,
468 0,
469 NULL,
470 MRK_NONE,
471 NULL,
472 NULL,
473 KEY_ECDSA,
474 NULL, /* filled at runtime */
475 "ECDSA #6",
476 0,
477 } },
478 { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
479 NULL,
480 22,
481 HKF_STATUS_OK,
482 0,
483 NULL,
484 MRK_NONE,
485 NULL,
486 NULL,
487 KEY_ECDSA,
488 NULL, /* filled at runtime */
489 "ECDSA #6",
490 0,
491 } },
492 { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
493 NULL,
494 23,
495 HKF_STATUS_OK,
496 0,
497 NULL,
498 MRK_NONE,
499 NULL,
500 NULL,
501 KEY_ECDSA,
502 NULL, /* filled at runtime */
503 "ECDSA #6",
504 0,
505 } },
506 { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
507 NULL,
508 24,
509 HKF_STATUS_OK,
510 0,
511 NULL,
512 MRK_NONE,
513 NULL,
514 NULL,
515 KEY_ED25519,
516 NULL, /* filled at runtime */
517 "ED25519 #6",
518 0,
519 } },
520 { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
521 NULL,
522 25,
523 HKF_STATUS_OK,
524 0,
525 NULL,
526 MRK_NONE,
527 NULL,
528 NULL,
529 KEY_ED25519,
530 NULL, /* filled at runtime */
531 "ED25519 #6",
532 0,
533 } },
534 { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
535 NULL,
536 26,
537 HKF_STATUS_OK,
538 0,
539 NULL,
540 MRK_NONE,
541 NULL,
542 NULL,
543 KEY_ED25519,
544 NULL, /* filled at runtime */
545 "ED25519 #6",
546 0,
547 } },
548 { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
549 NULL,
550 27,
551 HKF_STATUS_OK,
552 0,
553 NULL,
554 MRK_NONE,
555 NULL,
556 NULL,
557 KEY_RSA,
558 NULL, /* filled at runtime */
559 "RSA #6",
560 0,
561 } },
562 { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
563 NULL,
564 28,
565 HKF_STATUS_OK,
566 0,
567 NULL,
568 MRK_NONE,
569 NULL,
570 NULL,
571 KEY_RSA,
572 NULL, /* filled at runtime */
573 "RSA #6",
574 0,
575 } },
576 { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
577 NULL,
578 29,
579 HKF_STATUS_OK,
580 0,
581 NULL,
582 MRK_NONE,
583 NULL,
584 NULL,
585 KEY_RSA,
586 NULL, /* filled at runtime */
587 "RSA #6",
588 0,
589 } },
590 { NULL, -1, -1, 0, 0, 0, 0, -1, {
591 NULL,
592 30,
593 HKF_STATUS_COMMENT,
594 0,
595 "",
596 MRK_NONE,
597 NULL,
598 NULL,
599 KEY_UNSPEC,
600 NULL,
601 NULL,
602 0,
603 } },
604 { NULL, -1, -1, 0, 0, 0, 0, -1, {
605 NULL,
606 31,
607 HKF_STATUS_COMMENT,
608 0,
609 "",
610 MRK_NONE,
611 NULL,
612 NULL,
613 KEY_UNSPEC,
614 NULL,
615 NULL,
616 0,
617 } },
618 { NULL, -1, -1, 0, 0, 0, 0, -1, {
619 NULL,
620 32,
621 HKF_STATUS_COMMENT,
622 0,
623 "# Revoked and CA keys",
624 MRK_NONE,
625 NULL,
626 NULL,
627 KEY_UNSPEC,
628 NULL,
629 NULL,
630 0,
631 } },
632 { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
633 NULL,
634 33,
635 HKF_STATUS_OK,
636 0,
637 NULL,
638 MRK_REVOKE,
639 "sisyphus.example.com",
640 NULL,
641 KEY_ED25519,
642 NULL, /* filled at runtime */
643 "ED25519 #4",
644 0,
645 } },
646 { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
647 NULL,
648 34,
649 HKF_STATUS_OK,
650 0,
651 NULL,
652 MRK_CA,
653 "prometheus.example.com",
654 NULL,
655 KEY_ECDSA,
656 NULL, /* filled at runtime */
657 "ECDSA #4",
658 0,
659 } },
660 { NULL, -1, -1, 0, 0, 0, 0, -1, {
661 NULL,
662 35,
663 HKF_STATUS_COMMENT,
664 0,
665 "",
666 MRK_NONE,
667 NULL,
668 NULL,
669 KEY_UNSPEC,
670 NULL,
671 NULL,
672 0,
673 } },
674 { NULL, -1, -1, 0, 0, 0, 0, -1, {
675 NULL,
676 36,
677 HKF_STATUS_COMMENT,
678 0,
679 "# Some invalid lines",
680 MRK_NONE,
681 NULL,
682 NULL,
683 KEY_UNSPEC,
684 NULL,
685 NULL,
686 0,
687 } },
688 { NULL, -1, -1, 0, 0, 0, 0, -1, {
689 NULL,
690 37,
691 HKF_STATUS_INVALID,
692 0,
693 NULL,
694 MRK_ERROR,
695 NULL,
696 NULL,
697 KEY_UNSPEC,
698 NULL,
699 NULL,
700 0,
701 } },
702 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
703 NULL,
704 38,
705 HKF_STATUS_INVALID,
706 0,
707 NULL,
708 MRK_NONE,
709 "sisyphus.example.com",
710 NULL,
711 KEY_UNSPEC,
712 NULL,
713 NULL,
714 0,
715 } },
716 { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
717 NULL,
718 39,
719 HKF_STATUS_INVALID,
720 0,
721 NULL,
722 MRK_NONE,
723 "prometheus.example.com",
724 NULL,
725 KEY_UNSPEC,
726 NULL,
727 NULL,
728 0,
729 } },
730 { NULL, HKF_STATUS_OK, KEY_ED25519, 0, HKF_MATCH_HOST, 0, 0, -1, {
731 NULL,
732 40,
733 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
734 0,
735 NULL,
736 MRK_NONE,
737 "sisyphus.example.com",
738 NULL,
739 KEY_UNSPEC,
740 NULL,
741 NULL,
742 0,
743 } },
744 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
745 NULL,
746 41,
747 HKF_STATUS_INVALID,
748 0,
749 NULL,
750 MRK_NONE,
751 "sisyphus.example.com",
752 NULL,
753 KEY_UNSPEC,
754 NULL, /* filled at runtime */
755 NULL,
756 0,
757 } },
758 { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
759 NULL,
760 42,
761 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
762 0,
763 NULL,
764 MRK_NONE,
765 "prometheus.example.com",
766 NULL,
767 KEY_UNSPEC,
768 NULL, /* filled at runtime */
769 NULL,
770 0,
771 } },
772 };
773
774 void test_iterate(void);
775
776 void
test_iterate(void)777 test_iterate(void)
778 {
779 struct cbctx ctx;
780
781 TEST_START("hostkeys_iterate all with key parse");
782 memset(&ctx, 0, sizeof(ctx));
783 ctx.expected = expected_full;
784 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
785 ctx.flags = HKF_WANT_PARSE_KEY;
786 prepare_expected(expected_full, ctx.nexpected);
787 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
788 check, &ctx, NULL, NULL, ctx.flags, 0), 0);
789 cleanup_expected(expected_full, ctx.nexpected);
790 TEST_DONE();
791
792 TEST_START("hostkeys_iterate all without key parse");
793 memset(&ctx, 0, sizeof(ctx));
794 ctx.expected = expected_full;
795 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
796 ctx.flags = 0;
797 prepare_expected(expected_full, ctx.nexpected);
798 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
799 check, &ctx, NULL, NULL, ctx.flags, 0), 0);
800 cleanup_expected(expected_full, ctx.nexpected);
801 TEST_DONE();
802
803 TEST_START("hostkeys_iterate specify host 1");
804 memset(&ctx, 0, sizeof(ctx));
805 ctx.expected = expected_full;
806 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
807 ctx.flags = 0;
808 ctx.match_host_p = 1;
809 prepare_expected(expected_full, ctx.nexpected);
810 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
811 check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0);
812 cleanup_expected(expected_full, ctx.nexpected);
813 TEST_DONE();
814
815 TEST_START("hostkeys_iterate specify host 2");
816 memset(&ctx, 0, sizeof(ctx));
817 ctx.expected = expected_full;
818 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
819 ctx.flags = 0;
820 ctx.match_host_s = 1;
821 prepare_expected(expected_full, ctx.nexpected);
822 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
823 check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0);
824 cleanup_expected(expected_full, ctx.nexpected);
825 TEST_DONE();
826
827 TEST_START("hostkeys_iterate match host 1");
828 memset(&ctx, 0, sizeof(ctx));
829 ctx.expected = expected_full;
830 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
831 ctx.flags = HKF_WANT_MATCH;
832 ctx.match_host_p = 1;
833 prepare_expected(expected_full, ctx.nexpected);
834 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
835 check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0);
836 cleanup_expected(expected_full, ctx.nexpected);
837 TEST_DONE();
838
839 TEST_START("hostkeys_iterate match host 2");
840 memset(&ctx, 0, sizeof(ctx));
841 ctx.expected = expected_full;
842 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
843 ctx.flags = HKF_WANT_MATCH;
844 ctx.match_host_s = 1;
845 prepare_expected(expected_full, ctx.nexpected);
846 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
847 check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0);
848 cleanup_expected(expected_full, ctx.nexpected);
849 TEST_DONE();
850
851 TEST_START("hostkeys_iterate specify host missing");
852 memset(&ctx, 0, sizeof(ctx));
853 ctx.expected = expected_full;
854 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
855 ctx.flags = 0;
856 prepare_expected(expected_full, ctx.nexpected);
857 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
858 check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0);
859 cleanup_expected(expected_full, ctx.nexpected);
860 TEST_DONE();
861
862 TEST_START("hostkeys_iterate match host missing");
863 memset(&ctx, 0, sizeof(ctx));
864 ctx.expected = expected_full;
865 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
866 ctx.flags = HKF_WANT_MATCH;
867 prepare_expected(expected_full, ctx.nexpected);
868 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
869 check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0);
870 cleanup_expected(expected_full, ctx.nexpected);
871 TEST_DONE();
872
873 TEST_START("hostkeys_iterate specify IPv4");
874 memset(&ctx, 0, sizeof(ctx));
875 ctx.expected = expected_full;
876 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
877 ctx.flags = 0;
878 ctx.match_ipv4 = 1;
879 prepare_expected(expected_full, ctx.nexpected);
880 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
881 check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0);
882 cleanup_expected(expected_full, ctx.nexpected);
883 TEST_DONE();
884
885 TEST_START("hostkeys_iterate specify IPv6");
886 memset(&ctx, 0, sizeof(ctx));
887 ctx.expected = expected_full;
888 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
889 ctx.flags = 0;
890 ctx.match_ipv6 = 1;
891 prepare_expected(expected_full, ctx.nexpected);
892 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
893 check, &ctx, "tiresias.example.org", "2001:db8::1",
894 ctx.flags, 0), 0);
895 cleanup_expected(expected_full, ctx.nexpected);
896 TEST_DONE();
897
898 TEST_START("hostkeys_iterate match IPv4");
899 memset(&ctx, 0, sizeof(ctx));
900 ctx.expected = expected_full;
901 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
902 ctx.flags = HKF_WANT_MATCH;
903 ctx.match_ipv4 = 1;
904 prepare_expected(expected_full, ctx.nexpected);
905 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
906 check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0);
907 cleanup_expected(expected_full, ctx.nexpected);
908 TEST_DONE();
909
910 TEST_START("hostkeys_iterate match IPv6");
911 memset(&ctx, 0, sizeof(ctx));
912 ctx.expected = expected_full;
913 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
914 ctx.flags = HKF_WANT_MATCH;
915 ctx.match_ipv6 = 1;
916 prepare_expected(expected_full, ctx.nexpected);
917 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
918 check, &ctx, "tiresias.example.org", "2001:db8::1",
919 ctx.flags, 0), 0);
920 cleanup_expected(expected_full, ctx.nexpected);
921 TEST_DONE();
922
923 TEST_START("hostkeys_iterate specify addr missing");
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 prepare_expected(expected_full, ctx.nexpected);
929 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
930 check, &ctx, "tiresias.example.org", "192.168.0.1",
931 ctx.flags, 0), 0);
932 cleanup_expected(expected_full, ctx.nexpected);
933 TEST_DONE();
934
935 TEST_START("hostkeys_iterate match addr missing");
936 memset(&ctx, 0, sizeof(ctx));
937 ctx.expected = expected_full;
938 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
939 ctx.flags = HKF_WANT_MATCH;
940 prepare_expected(expected_full, ctx.nexpected);
941 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
942 check, &ctx, "tiresias.example.org", "::1", ctx.flags, 0), 0);
943 cleanup_expected(expected_full, ctx.nexpected);
944 TEST_DONE();
945
946 TEST_START("hostkeys_iterate specify host 2 and IPv4");
947 memset(&ctx, 0, sizeof(ctx));
948 ctx.expected = expected_full;
949 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
950 ctx.flags = 0;
951 ctx.match_host_s = 1;
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, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0);
956 cleanup_expected(expected_full, ctx.nexpected);
957 TEST_DONE();
958
959 TEST_START("hostkeys_iterate match host 1 and 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_host_p = 1;
965 ctx.match_ipv6 = 1;
966 prepare_expected(expected_full, ctx.nexpected);
967 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
968 check, &ctx, "prometheus.example.com",
969 "2001:db8::1", ctx.flags, 0), 0);
970 cleanup_expected(expected_full, ctx.nexpected);
971 TEST_DONE();
972
973 TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse");
974 memset(&ctx, 0, sizeof(ctx));
975 ctx.expected = expected_full;
976 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
977 ctx.flags = HKF_WANT_PARSE_KEY;
978 ctx.match_host_s = 1;
979 ctx.match_ipv4 = 1;
980 prepare_expected(expected_full, ctx.nexpected);
981 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
982 check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0);
983 cleanup_expected(expected_full, ctx.nexpected);
984 TEST_DONE();
985
986 TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse");
987 memset(&ctx, 0, sizeof(ctx));
988 ctx.expected = expected_full;
989 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
990 ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY;
991 ctx.match_host_p = 1;
992 ctx.match_ipv6 = 1;
993 prepare_expected(expected_full, ctx.nexpected);
994 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
995 check, &ctx, "prometheus.example.com",
996 "2001:db8::1", ctx.flags, 0), 0);
997 cleanup_expected(expected_full, ctx.nexpected);
998 TEST_DONE();
999 }
1000
1001