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