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