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