main.c revision 1.17
1/*	$OpenBSD: main.c,v 1.17 2019/09/26 17:07:30 claudio Exp $ */
2/*
3 * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/queue.h>
19#include <sys/socket.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23
24#include <assert.h>
25#include <err.h>
26#include <dirent.h>
27#include <fcntl.h>
28#include <fnmatch.h>
29#include <fts.h>
30#include <inttypes.h>
31#include <poll.h>
32#include <signal.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
37
38#include <openssl/err.h>
39#include <openssl/evp.h>
40#include <openssl/x509v3.h>
41
42#include "extern.h"
43
44/*
45 * Base directory for where we'll look for all media.
46 */
47#define	BASE_DIR "/var/cache/rpki-client"
48
49/*
50 * Statistics collected during run-time.
51 */
52struct	stats {
53	size_t	 tals; /* total number of locators */
54	size_t	 mfts; /* total number of manifests */
55	size_t	 mfts_fail; /* failing syntactic parse */
56	size_t	 mfts_stale; /* stale manifests */
57	size_t	 certs; /* certificates */
58	size_t	 certs_fail; /* failing syntactic parse */
59	size_t	 certs_invalid; /* invalid resources */
60	size_t	 roas; /* route origin authorizations */
61	size_t	 roas_fail; /* failing syntactic parse */
62	size_t	 roas_invalid; /* invalid resources */
63	size_t	 repos; /* repositories */
64	size_t	 crls; /* revocation lists */
65};
66
67/*
68 * An rsync repository.
69 */
70struct	repo {
71	char	*host; /* hostname */
72	char	*module; /* module name */
73	int	 loaded; /* whether loaded or not */
74	size_t	 id; /* identifier (array index) */
75};
76
77/*
78 * A running rsync process.
79 * We can have multiple of these simultaneously and need to keep track
80 * of which process maps to which request.
81 */
82struct	rsyncproc {
83	char	*uri; /* uri of this rsync proc */
84	size_t	 id; /* identity of request */
85	pid_t	 pid; /* pid of process or 0 if unassociated */
86};
87
88/*
89 * Table of all known repositories.
90 */
91struct	repotab {
92	struct repo	*repos; /* repositories */
93	size_t		 reposz; /* number of repos */
94};
95
96/*
97 * An entity (MFT, ROA, certificate, etc.) that needs to be downloaded
98 * and parsed.
99 */
100struct	entity {
101	size_t		 id; /* unique identifier */
102	enum rtype	 type; /* type of entity (not RTYPE_EOF) */
103	char		*uri; /* file or rsync:// URI */
104	int		 has_dgst; /* whether dgst is specified */
105	unsigned char	 dgst[SHA256_DIGEST_LENGTH]; /* optional */
106	ssize_t		 repo; /* repo index or <0 if w/o repo */
107	int		 has_pkey; /* whether pkey/sz is specified */
108	unsigned char	*pkey; /* public key (optional) */
109	size_t		 pkeysz; /* public key length (optional) */
110	TAILQ_ENTRY(entity) entries;
111};
112
113TAILQ_HEAD(entityq, entity);
114
115/*
116 * Mark that our subprocesses will never return.
117 */
118static void	 proc_parser(int, int, int)
119			__attribute__((noreturn));
120static void	 proc_rsync(const char *, const char *, int, int)
121			__attribute__((noreturn));
122static void	 logx(const char *fmt, ...)
123			__attribute__((format(printf, 1, 2)));
124
125int	 verbose;
126
127/*
128 * Log a message to stderr if and only if "verbose" is non-zero.
129 * This uses the err(3) functionality.
130 */
131static void
132logx(const char *fmt, ...)
133{
134	va_list		 ap;
135
136	if (verbose && fmt != NULL) {
137		va_start(ap, fmt);
138		vwarnx(fmt, ap);
139		va_end(ap);
140	}
141}
142
143/*
144 * Resolve the media type of a resource by looking at its suffice.
145 * Returns the type of RTYPE_EOF if not found.
146 */
147static enum rtype
148rtype_resolve(const char *uri)
149{
150	enum rtype	 rp;
151
152	rsync_uri_parse(NULL, NULL, NULL, NULL, NULL, NULL, &rp, uri);
153	return rp;
154}
155
156static void
157entity_free(struct entity *ent)
158{
159
160	if (ent == NULL)
161		return;
162
163	free(ent->pkey);
164	free(ent->uri);
165	free(ent);
166}
167
168/*
169 * Read a queue entity from the descriptor.
170 * Matched by entity_buffer_req().
171 * The pointer must be passed entity_free().
172 */
173static void
174entity_read_req(int fd, struct entity *ent)
175{
176
177	io_simple_read(fd, &ent->id, sizeof(size_t));
178	io_simple_read(fd, &ent->type, sizeof(enum rtype));
179	io_str_read(fd, &ent->uri);
180	io_simple_read(fd, &ent->has_dgst, sizeof(int));
181	if (ent->has_dgst)
182		io_simple_read(fd, ent->dgst, sizeof(ent->dgst));
183	io_simple_read(fd, &ent->has_pkey, sizeof(int));
184	if (ent->has_pkey)
185		io_buf_read_alloc(fd, (void **)&ent->pkey, &ent->pkeysz);
186}
187
188/*
189 * Look up a repository, queueing it for discovery if not found.
190 */
191static const struct repo *
192repo_lookup(int fd, struct repotab *rt, const char *uri)
193{
194	const char	*host, *mod;
195	size_t		 hostsz, modsz, i;
196	struct repo	*rp;
197
198	if (!rsync_uri_parse(&host, &hostsz,
199	    &mod, &modsz, NULL, NULL, NULL, uri))
200		errx(EXIT_FAILURE, "%s: malformed", uri);
201
202	/* Look up in repository table. */
203
204	for (i = 0; i < rt->reposz; i++) {
205		if (strlen(rt->repos[i].host) != hostsz)
206			continue;
207		if (strlen(rt->repos[i].module) != modsz)
208			continue;
209		if (strncasecmp(rt->repos[i].host, host, hostsz))
210			continue;
211		if (strncasecmp(rt->repos[i].module, mod, modsz))
212			continue;
213		return &rt->repos[i];
214	}
215
216	rt->repos = reallocarray(rt->repos,
217		rt->reposz + 1, sizeof(struct repo));
218	if (rt->repos == NULL)
219		err(EXIT_FAILURE, "reallocarray");
220
221	rp = &rt->repos[rt->reposz++];
222	memset(rp, 0, sizeof(struct repo));
223	rp->id = rt->reposz - 1;
224
225	if ((rp->host = strndup(host, hostsz)) == NULL ||
226	    (rp->module = strndup(mod, modsz)) == NULL)
227		err(EXIT_FAILURE, "strndup");
228
229	i = rt->reposz - 1;
230
231	logx("%s/%s: loading", rp->host, rp->module);
232	io_simple_write(fd, &i, sizeof(size_t));
233	io_str_write(fd, rp->host);
234	io_str_write(fd, rp->module);
235	return rp;
236}
237
238/*
239 * Read the next entity from the parser process, removing it from the
240 * queue of pending requests in the process.
241 * This always returns a valid entity.
242 */
243static struct entity *
244entityq_next(int fd, struct entityq *q)
245{
246	size_t		 id;
247	struct entity	*entp;
248
249	io_simple_read(fd, &id, sizeof(size_t));
250
251	TAILQ_FOREACH(entp, q, entries)
252		if (entp->id == id)
253			break;
254
255	assert(entp != NULL);
256	TAILQ_REMOVE(q, entp, entries);
257	return entp;
258}
259
260static void
261entity_buffer_resp(char **b, size_t *bsz, size_t *bmax,
262    const struct entity *ent)
263{
264
265	io_simple_buffer(b, bsz, bmax, &ent->id, sizeof(size_t));
266}
267
268/*
269 * Like entity_write_req() but into a buffer.
270 * Matched by entity_read_req().
271 */
272static void
273entity_buffer_req(char **b, size_t *bsz, size_t *bmax,
274    const struct entity *ent)
275{
276
277	io_simple_buffer(b, bsz, bmax, &ent->id, sizeof(size_t));
278	io_simple_buffer(b, bsz, bmax, &ent->type, sizeof(enum rtype));
279	io_str_buffer(b, bsz, bmax, ent->uri);
280	io_simple_buffer(b, bsz, bmax, &ent->has_dgst, sizeof(int));
281	if (ent->has_dgst)
282		io_simple_buffer(b, bsz, bmax, ent->dgst, sizeof(ent->dgst));
283	io_simple_buffer(b, bsz, bmax, &ent->has_pkey, sizeof(int));
284	if (ent->has_pkey)
285		io_buf_buffer(b, bsz, bmax, ent->pkey, ent->pkeysz);
286}
287
288/*
289 * Write the queue entity.
290 * Simply a wrapper around entity_buffer_req().
291 */
292static void
293entity_write_req(int fd, const struct entity *ent)
294{
295	char	*b = NULL;
296	size_t	 bsz = 0, bmax = 0;
297
298	entity_buffer_req(&b, &bsz, &bmax, ent);
299	io_simple_write(fd, b, bsz);
300	free(b);
301}
302
303/*
304 * Scan through all queued requests and see which ones are in the given
305 * repo, then flush those into the parser process.
306 */
307static void
308entityq_flush(int fd, struct entityq *q, const struct repo *repo)
309{
310	struct entity	*p;
311
312	TAILQ_FOREACH(p, q, entries) {
313		if (p->repo < 0 || repo->id != (size_t)p->repo)
314			continue;
315		entity_write_req(fd, p);
316	}
317}
318
319/*
320 * Add the heap-allocated file to the queue for processing.
321 */
322static void
323entityq_add(int fd, struct entityq *q, char *file, enum rtype type,
324    const struct repo *rp, const unsigned char *dgst,
325    const unsigned char *pkey, size_t pkeysz, size_t *eid)
326{
327	struct entity	*p;
328
329	if ((p = calloc(1, sizeof(struct entity))) == NULL)
330		err(EXIT_FAILURE, "calloc");
331
332	p->id = (*eid)++;
333	p->type = type;
334	p->uri = file;
335	p->repo = (rp != NULL) ? (ssize_t)rp->id : -1;
336	p->has_dgst = dgst != NULL;
337	p->has_pkey = pkey != NULL;
338	if (p->has_dgst)
339		memcpy(p->dgst, dgst, sizeof(p->dgst));
340	if (p->has_pkey) {
341		p->pkeysz = pkeysz;
342		if ((p->pkey = malloc(pkeysz)) == NULL)
343			err(EXIT_FAILURE, "malloc");
344		memcpy(p->pkey, pkey, pkeysz);
345	}
346	TAILQ_INSERT_TAIL(q, p, entries);
347
348	/*
349	 * Write to the queue if there's no repo or the repo has already
350	 * been loaded.
351	 */
352
353	if (rp == NULL || rp->loaded)
354		entity_write_req(fd, p);
355}
356
357/*
358 * Add a file (CER, ROA, CRL) from an MFT file, RFC 6486.
359 * These are always relative to the directory in which "mft" sits.
360 */
361static void
362queue_add_from_mft(int fd, struct entityq *q, const char *mft,
363    const struct mftfile *file, enum rtype type, size_t *eid)
364{
365	size_t		 sz;
366	char		*cp, *nfile;
367
368	assert(strncmp(mft, BASE_DIR, strlen(BASE_DIR)) == 0);
369
370	/* Construct local path from filename. */
371
372	sz = strlen(file->file) + strlen(mft);
373	if ((nfile = calloc(sz + 1, 1)) == NULL)
374		err(EXIT_FAILURE, "calloc");
375
376	/* We know this is BASE_DIR/host/module/... */
377
378	strlcpy(nfile, mft, sz + 1);
379	cp = strrchr(nfile, '/');
380	assert(cp != NULL);
381	cp++;
382	*cp = '\0';
383	strlcat(nfile, file->file, sz + 1);
384
385	/*
386	 * Since we're from the same directory as the MFT file, we know
387	 * that the repository has already been loaded.
388	 */
389
390	entityq_add(fd, q, nfile, type, NULL, file->hash, NULL, 0, eid);
391}
392
393/*
394 * Loops over queue_add_from_mft() for all files.
395 * The order here is important: we want to parse the revocation
396 * list *before* we parse anything else.
397 * FIXME: set the type of file in the mftfile so that we don't need to
398 * keep doing the check (this should be done in the parser, where we
399 * check the suffix anyway).
400 */
401static void
402queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
403    size_t *eid)
404{
405	size_t			 i, sz;
406	const struct mftfile	*f;
407
408	for (i = 0; i < mft->filesz; i++) {
409		f = &mft->files[i];
410		sz = strlen(f->file);
411		assert(sz > 4);
412		if (strcasecmp(f->file + sz - 4, ".crl"))
413			continue;
414		queue_add_from_mft(fd, q, mft->file, f, RTYPE_CRL, eid);
415	}
416
417	for (i = 0; i < mft->filesz; i++) {
418		f = &mft->files[i];
419		sz = strlen(f->file);
420		assert(sz > 4);
421		if (strcasecmp(f->file + sz - 4, ".cer"))
422			continue;
423		queue_add_from_mft(fd, q, mft->file, f, RTYPE_CER, eid);
424	}
425
426	for (i = 0; i < mft->filesz; i++) {
427		f = &mft->files[i];
428		sz = strlen(f->file);
429		assert(sz > 4);
430		if (strcasecmp(f->file + sz - 4, ".roa"))
431			continue;
432		queue_add_from_mft(fd, q, mft->file, f, RTYPE_ROA, eid);
433	}
434}
435
436/*
437 * Add a local TAL file (RFC 7730) to the queue of files to fetch.
438 */
439static void
440queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid)
441{
442	char		*nfile;
443
444	if ((nfile = strdup(file)) == NULL)
445		err(EXIT_FAILURE, "strdup");
446
447	/* Not in a repository, so directly add to queue. */
448
449	entityq_add(fd, q, nfile, RTYPE_TAL, NULL, NULL, NULL, 0, eid);
450}
451
452/*
453 * Add rsync URIs (CER) from a TAL file, RFC 7730.
454 * Only use the first URI of the set.
455 */
456static void
457queue_add_from_tal(int proc, int rsync, struct entityq *q,
458    const struct tal *tal, struct repotab *rt, size_t *eid)
459{
460	char			*nfile;
461	const struct repo	*repo;
462	const char		*uri;
463
464	assert(tal->urisz);
465	uri = tal->uri[0];
466
467	/* Look up the repository. */
468
469	assert(rtype_resolve(uri) == RTYPE_CER);
470	repo = repo_lookup(rsync, rt, uri);
471	uri += 8 + strlen(repo->host) + 1 + strlen(repo->module) + 1;
472
473	if (asprintf(&nfile, "%s/%s/%s/%s",
474	    BASE_DIR, repo->host, repo->module, uri) == -1)
475		err(EXIT_FAILURE, "asprintf");
476
477	entityq_add(proc, q, nfile, RTYPE_CER, repo, NULL, tal->pkey,
478	    tal->pkeysz, eid);
479}
480
481/*
482 * Add a manifest (MFT) or CRL found in an X509 certificate, RFC 6487.
483 */
484static void
485queue_add_from_cert(int proc, int rsync, struct entityq *q,
486    const char *uri, struct repotab *rt, size_t *eid)
487{
488	char			*nfile;
489	enum rtype		 type;
490	const struct repo	*repo;
491
492	if ((type = rtype_resolve(uri)) == RTYPE_EOF)
493		errx(EXIT_FAILURE, "%s: unknown file type", uri);
494	if (type != RTYPE_MFT && type != RTYPE_CRL)
495		errx(EXIT_FAILURE, "%s: invalid file type", uri);
496
497	/* Look up the repository. */
498
499	repo = repo_lookup(rsync, rt, uri);
500	uri += 8 + strlen(repo->host) + 1 + strlen(repo->module) + 1;
501
502	if (asprintf(&nfile, "%s/%s/%s/%s",
503	    BASE_DIR, repo->host, repo->module, uri) == -1)
504		err(EXIT_FAILURE, "asprintf");
505
506	entityq_add(proc, q, nfile, type, repo, NULL, NULL, 0, eid);
507}
508
509static void
510proc_child(int signal)
511{
512
513	/* Nothing: just discard. */
514}
515
516/*
517 * Process used for synchronising repositories.
518 * This simply waits to be told which repository to synchronise, then
519 * does so.
520 * It then responds with the identifier of the repo that it updated.
521 * It only exits cleanly when fd is closed.
522 * FIXME: this should use buffered output to prevent deadlocks, but it's
523 * very unlikely that we're going to fill our buffer, so whatever.
524 * FIXME: limit the number of simultaneous process.
525 * Currently, an attacker can trivially specify thousands of different
526 * repositories and saturate our system.
527 */
528static void
529proc_rsync(const char *prog, const char *bind_addr, int fd, int noop)
530{
531	size_t			 id, i, idsz = 0;
532	ssize_t			 ssz;
533	char			*host = NULL, *mod = NULL, *uri = NULL,
534				*dst = NULL, *path, *save, *cmd;
535	const char		*pp;
536	pid_t			 pid;
537	char			*args[32];
538	int			 st, rc = 0;
539	struct stat		 stt;
540	struct pollfd		 pfd;
541	sigset_t		 mask, oldmask;
542	struct rsyncproc	*ids = NULL;
543
544	pfd.fd = fd;
545	pfd.events = POLLIN;
546
547	/*
548	 * Unveil the command we want to run.
549	 * If this has a pathname component in it, interpret as a file
550	 * and unveil the file directly.
551	 * Otherwise, look up the command in our PATH.
552	 */
553
554	if (!noop) {
555		if (strchr(prog, '/') == NULL) {
556			if (getenv("PATH") == NULL)
557				errx(EXIT_FAILURE, "PATH is unset");
558			if ((path = strdup(getenv("PATH"))) == NULL)
559				err(EXIT_FAILURE, "strdup");
560			save = path;
561			while ((pp = strsep(&path, ":")) != NULL) {
562				if (*pp == '\0')
563					continue;
564				if (asprintf(&cmd, "%s/%s", pp, prog) == -1)
565					err(EXIT_FAILURE, "asprintf");
566				if (lstat(cmd, &stt) == -1) {
567					free(cmd);
568					continue;
569				} else if (unveil(cmd, "x") == -1)
570					err(EXIT_FAILURE, "%s: unveil", cmd);
571				free(cmd);
572				break;
573			}
574			free(save);
575		} else if (unveil(prog, "x") == -1)
576			err(EXIT_FAILURE, "%s: unveil", prog);
577
578		/* Unveil the repository directory and terminate unveiling. */
579
580		if (unveil(BASE_DIR, "c") == -1)
581			err(EXIT_FAILURE, "%s: unveil", BASE_DIR);
582		if (unveil(NULL, NULL) == -1)
583			err(EXIT_FAILURE, "unveil");
584	}
585
586	/* Initialise retriever for children exiting. */
587
588	if (sigemptyset(&mask) == -1)
589		err(EXIT_FAILURE, NULL);
590	if (signal(SIGCHLD, proc_child) == SIG_ERR)
591		err(EXIT_FAILURE, NULL);
592	if (sigaddset(&mask, SIGCHLD) == -1)
593		err(EXIT_FAILURE, NULL);
594	if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
595		err(EXIT_FAILURE, NULL);
596
597	for (;;) {
598		if (ppoll(&pfd, 1, NULL, &oldmask) == -1) {
599			if (errno != EINTR)
600				err(EXIT_FAILURE, "ppoll");
601
602			/*
603			 * If we've received an EINTR, it means that one
604			 * of our children has exited and we can reap it
605			 * and look up its identifier.
606			 * Then we respond to the parent.
607			 */
608
609			if ((pid = waitpid(WAIT_ANY, &st, 0)) == -1)
610				err(EXIT_FAILURE, "waitpid");
611
612			for (i = 0; i < idsz; i++)
613				if (ids[i].pid == pid)
614					break;
615			assert(i < idsz);
616
617			if (!WIFEXITED(st)) {
618				warnx("rsync %s did not exit", ids[i].uri);
619				goto out;
620			} else if (WEXITSTATUS(st) != EXIT_SUCCESS) {
621				warnx("rsync %s failed", ids[i].uri);
622				goto out;
623			}
624
625			io_simple_write(fd, &ids[i].id, sizeof(size_t));
626			free(ids[i].uri);
627			ids[i].uri = NULL;
628			ids[i].pid = 0;
629			ids[i].id = 0;
630			continue;
631		}
632
633		/*
634		 * Read til the parent exits.
635		 * That will mean that we can safely exit.
636		 */
637
638		if ((ssz = read(fd, &id, sizeof(size_t))) == -1)
639			err(EXIT_FAILURE, "read");
640		if (ssz == 0)
641			break;
642
643		/* Read host and module. */
644
645		io_str_read(fd, &host);
646		io_str_read(fd, &mod);
647
648		if (noop) {
649			io_simple_write(fd, &id, sizeof(size_t));
650			free(host);
651			free(mod);
652			continue;
653		}
654
655		/*
656		 * Create source and destination locations.
657		 * Build up the tree to this point because GPL rsync(1)
658		 * will not build the destination for us.
659		 */
660
661		if (asprintf(&dst, "%s/%s", BASE_DIR, host) == -1)
662			err(EXIT_FAILURE, NULL);
663		if (mkdir(dst, 0700) == -1 && EEXIST != errno)
664			err(EXIT_FAILURE, "%s", dst);
665		free(dst);
666
667		if (asprintf(&dst, "%s/%s/%s", BASE_DIR, host, mod) == -1)
668			err(EXIT_FAILURE, NULL);
669		if (mkdir(dst, 0700) == -1 && EEXIST != errno)
670			err(EXIT_FAILURE, "%s", dst);
671
672		if (asprintf(&uri, "rsync://%s/%s", host, mod) == -1)
673			err(EXIT_FAILURE, NULL);
674
675		/* Run process itself, wait for exit, check error. */
676
677		if ((pid = fork()) == -1)
678			err(EXIT_FAILURE, "fork");
679
680		if (pid == 0) {
681			if (pledge("stdio exec", NULL) == -1)
682				err(EXIT_FAILURE, "pledge");
683			i = 0;
684			args[i++] = (char *)prog;
685			args[i++] = "-rlt";
686			args[i++] = "--delete";
687			if (bind_addr != NULL) {
688				args[i++] = "--address";
689				args[i++] = (char *)bind_addr;
690			}
691			args[i++] = uri;
692			args[i++] = dst;
693			args[i] = NULL;
694			execvp(args[0], args);
695			err(EXIT_FAILURE, "%s: execvp", prog);
696		}
697
698		/* Augment the list of running processes. */
699
700		for (i = 0; i < idsz; i++)
701			if (ids[i].pid == 0)
702				break;
703		if (i == idsz) {
704			ids = reallocarray(ids, idsz + 1, sizeof(*ids));
705			if (ids == NULL)
706				err(EXIT_FAILURE, NULL);
707			idsz++;
708		}
709
710		ids[i].id = id;
711		ids[i].pid = pid;
712		ids[i].uri = uri;
713
714		/* Clean up temporary values. */
715
716		free(mod);
717		free(dst);
718		free(host);
719	}
720	rc = 1;
721out:
722
723	/* No need for these to be hanging around. */
724
725	for (i = 0; i < idsz; i++)
726		if (ids[i].pid > 0) {
727			kill(ids[i].pid, SIGTERM);
728			free(ids[i].uri);
729		}
730
731	free(ids);
732	exit(rc ? EXIT_SUCCESS : EXIT_FAILURE);
733	/* NOTREACHED */
734}
735
736/*
737 * Parse and validate a ROA, not parsing the CRL bits of "norev" has
738 * been set.
739 * This is standard stuff.
740 * Returns the roa on success, NULL on failure.
741 */
742static struct roa *
743proc_parser_roa(struct entity *entp, int norev,
744    X509_STORE *store, X509_STORE_CTX *ctx,
745    const struct auth *auths, size_t authsz)
746{
747	struct roa		*roa;
748	X509			*x509;
749	int			 c;
750	X509_VERIFY_PARAM	*param;
751	unsigned int		fl, nfl;
752
753	assert(entp->has_dgst);
754	if ((roa = roa_parse(&x509, entp->uri, entp->dgst)) == NULL)
755		return NULL;
756
757	assert(x509 != NULL);
758	if (!X509_STORE_CTX_init(ctx, store, x509, NULL))
759		cryptoerrx("X509_STORE_CTX_init");
760
761	if ((param = X509_STORE_CTX_get0_param(ctx)) == NULL)
762		cryptoerrx("X509_STORE_CTX_get0_param");
763	fl = X509_VERIFY_PARAM_get_flags(param);
764	nfl = X509_V_FLAG_IGNORE_CRITICAL;
765	if (!norev)
766		nfl |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
767	if (!X509_VERIFY_PARAM_set_flags(param, fl | nfl))
768		cryptoerrx("X509_VERIFY_PARAM_set_flags");
769
770	if (X509_verify_cert(ctx) <= 0) {
771		c = X509_STORE_CTX_get_error(ctx);
772		X509_STORE_CTX_cleanup(ctx);
773		if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL)
774			warnx("%s: %s", entp->uri,
775			    X509_verify_cert_error_string(c));
776		X509_free(x509);
777		roa_free(roa);
778		return NULL;
779	}
780	X509_STORE_CTX_cleanup(ctx);
781	X509_free(x509);
782
783	/*
784	 * If the ROA isn't valid, we accept it anyway and depend upon
785	 * the code around roa_read() to check the "valid" field itself.
786	 */
787
788	roa->valid = valid_roa(entp->uri, auths, authsz, roa);
789	return roa;
790}
791
792/*
793 * Parse and validate a manifest file.
794 * Here we *don't* validate against the list of CRLs, because the
795 * certificate used to sign the manifest may specify a CRL that the root
796 * certificate didn't, and we haven't scanned for it yet.
797 * This chicken-and-egg isn't important, however, because we'll catch
798 * the revocation list by the time we scan for any contained resources
799 * (ROA, CER) and will see it then.
800 * Return the mft on success or NULL on failure.
801 */
802static struct mft *
803proc_parser_mft(struct entity *entp, int force, X509_STORE *store,
804    X509_STORE_CTX *ctx, const struct auth *auths, size_t authsz)
805{
806	struct mft		*mft;
807	X509			*x509;
808	int			 c;
809	unsigned int		 fl, nfl;
810	X509_VERIFY_PARAM	*param;
811
812	assert(!entp->has_dgst);
813	if ((mft = mft_parse(&x509, entp->uri, force)) == NULL)
814		return NULL;
815
816	if (!X509_STORE_CTX_init(ctx, store, x509, NULL))
817		cryptoerrx("X509_STORE_CTX_init");
818
819	if ((param = X509_STORE_CTX_get0_param(ctx)) == NULL)
820		cryptoerrx("X509_STORE_CTX_get0_param");
821	fl = X509_VERIFY_PARAM_get_flags(param);
822	nfl = X509_V_FLAG_IGNORE_CRITICAL;
823	if (!X509_VERIFY_PARAM_set_flags(param, fl | nfl))
824		cryptoerrx("X509_VERIFY_PARAM_set_flags");
825
826	if (X509_verify_cert(ctx) <= 0) {
827		c = X509_STORE_CTX_get_error(ctx);
828		X509_STORE_CTX_cleanup(ctx);
829		warnx("%s: %s", entp->uri, X509_verify_cert_error_string(c));
830		mft_free(mft);
831		X509_free(x509);
832		return NULL;
833	}
834
835	X509_STORE_CTX_cleanup(ctx);
836	X509_free(x509);
837	return mft;
838}
839
840/*
841 * Certificates are from manifests (has a digest and is signed with
842 * another certificate) or TALs (has a pkey and is self-signed).
843 * Parse the certificate, make sure its signatures are valid (with CRLs
844 * unless "norev" has been specified), then validate the RPKI content.
845 * This returns a certificate (which must not be freed) or NULL on parse
846 * failure.
847 */
848static struct cert *
849proc_parser_cert(const struct entity *entp, int norev,
850    X509_STORE *store, X509_STORE_CTX *ctx,
851    struct auth **auths, size_t *authsz)
852{
853	struct cert		*cert;
854	X509			*x509;
855	int			 c;
856	X509_VERIFY_PARAM	*param;
857	unsigned int		 fl, nfl;
858	ssize_t			 id;
859
860	assert(!entp->has_dgst != !entp->has_pkey);
861
862	/* Extract certificate data and X509. */
863
864	cert = entp->has_dgst ? cert_parse(&x509, entp->uri, entp->dgst) :
865	    ta_parse(&x509, entp->uri, entp->pkey, entp->pkeysz);
866	if (cert == NULL)
867		return NULL;
868
869	/*
870	 * Validate certificate chain w/CRLs.
871	 * Only check the CRLs if specifically asked.
872	 */
873
874	assert(x509 != NULL);
875	if (!X509_STORE_CTX_init(ctx, store, x509, NULL))
876		cryptoerrx("X509_STORE_CTX_init");
877	if ((param = X509_STORE_CTX_get0_param(ctx)) == NULL)
878		cryptoerrx("X509_STORE_CTX_get0_param");
879	fl = X509_VERIFY_PARAM_get_flags(param);
880	nfl = X509_V_FLAG_IGNORE_CRITICAL;
881	if (!norev)
882		nfl |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
883	if (!X509_VERIFY_PARAM_set_flags(param, fl | nfl))
884		cryptoerrx("X509_VERIFY_PARAM_set_flags");
885
886	/*
887	 * FIXME: can we pass any options to the verification that make
888	 * the depth-zero self-signed bits verify properly?
889	 */
890
891	if (X509_verify_cert(ctx) <= 0) {
892		c = X509_STORE_CTX_get_error(ctx);
893		if (c != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
894		    !entp->has_pkey) {
895			warnx("%s: %s", entp->uri,
896			    X509_verify_cert_error_string(c));
897			X509_STORE_CTX_cleanup(ctx);
898			X509_free(x509);
899			cert_free(cert);
900			return NULL;
901		}
902	}
903	X509_STORE_CTX_cleanup(ctx);
904
905	/* Semantic validation of RPKI content. */
906
907	id = entp->has_pkey ?
908		valid_ta(entp->uri, *auths, *authsz, cert) :
909		valid_cert(entp->uri, *auths, *authsz, cert);
910
911	if (id < 0) {
912		X509_free(x509);
913		return cert;
914	}
915
916	/*
917	 * Only on success of all do we add the certificate to the store
918	 * of trusted certificates, both X509 and RPKI semantic.
919	 */
920
921	cert->valid = 1;
922	*auths = reallocarray(*auths, *authsz + 1, sizeof(struct auth));
923	if (*auths == NULL)
924		err(EXIT_FAILURE, NULL);
925
926	(*auths)[*authsz].id = *authsz;
927	(*auths)[*authsz].parent = id;
928	(*auths)[*authsz].cert = cert;
929	(*auths)[*authsz].fn = strdup(entp->uri);
930	if ((*auths)[*authsz].fn == NULL)
931		err(EXIT_FAILURE, NULL);
932	(*authsz)++;
933
934	X509_STORE_add_cert(store, x509);
935	X509_free(x509);
936	return cert;
937}
938
939/*
940 * Parse a certificate revocation list (unless "norev", in which case
941 * this is a noop that returns success).
942 * This simply parses the CRL content itself, optionally validating it
943 * within the digest if it comes from a manifest, then adds it to the
944 * store of CRLs.
945 */
946static void
947proc_parser_crl(struct entity *entp, int norev, X509_STORE *store,
948    X509_STORE_CTX *ctx, const struct auth *auths, size_t authsz)
949{
950	X509_CRL	    *x509;
951	const unsigned char *dgst;
952
953	if (norev)
954		return;
955
956	dgst = entp->has_dgst ? entp->dgst : NULL;
957	if ((x509 = crl_parse(entp->uri, dgst)) != NULL) {
958		X509_STORE_add_crl(store, x509);
959		X509_CRL_free(x509);
960	}
961}
962
963/*
964 * Process responsible for parsing and validating content.
965 * All this process does is wait to be told about a file to parse, then
966 * it parses it and makes sure that the data being returned is fully
967 * validated and verified.
968 * The process will exit cleanly only when fd is closed.
969 */
970static void
971proc_parser(int fd, int force, int norev)
972{
973	struct tal	*tal;
974	struct cert	*cert;
975	struct mft	*mft;
976	struct roa	*roa;
977	struct entity	*entp;
978	struct entityq	 q;
979	int		 c, rc = 0;
980	struct pollfd	 pfd;
981	char		*b = NULL;
982	size_t		 i, bsz = 0, bmax = 0, bpos = 0, authsz = 0;
983	ssize_t		 ssz;
984	X509_STORE	*store;
985	X509_STORE_CTX	*ctx;
986	struct auth	*auths = NULL;
987	int		 first_tals = 1;
988
989	ERR_load_crypto_strings();
990	OpenSSL_add_all_ciphers();
991	OpenSSL_add_all_digests();
992
993	if ((store = X509_STORE_new()) == NULL)
994		cryptoerrx("X509_STORE_new");
995	if ((ctx = X509_STORE_CTX_new()) == NULL)
996		cryptoerrx("X509_STORE_CTX_new");
997
998	TAILQ_INIT(&q);
999
1000	pfd.fd = fd;
1001	pfd.events = POLLIN;
1002
1003	io_socket_nonblocking(pfd.fd);
1004
1005	for (;;) {
1006		if (poll(&pfd, 1, INFTIM) == -1)
1007			err(EXIT_FAILURE, "poll");
1008		if ((pfd.revents & (POLLERR|POLLNVAL)))
1009			errx(EXIT_FAILURE, "poll: bad descriptor");
1010
1011		/* If the parent closes, return immediately. */
1012
1013		if ((pfd.revents & POLLHUP))
1014			break;
1015
1016		/*
1017		 * Start with read events.
1018		 * This means that the parent process is sending us
1019		 * something we need to parse.
1020		 * We don't actually parse it til we have space in our
1021		 * outgoing buffer for responding, though.
1022		 */
1023
1024		if ((pfd.revents & POLLIN)) {
1025			io_socket_blocking(fd);
1026			entp = calloc(1, sizeof(struct entity));
1027			if (entp == NULL)
1028				err(EXIT_FAILURE, NULL);
1029			entity_read_req(fd, entp);
1030			TAILQ_INSERT_TAIL(&q, entp, entries);
1031			pfd.events |= POLLOUT;
1032			io_socket_nonblocking(fd);
1033		}
1034
1035		if (!(pfd.revents & POLLOUT))
1036			continue;
1037
1038		/*
1039		 * If we have a write buffer, then continue trying to
1040		 * push it all out.
1041		 * When it's all pushed out, reset it and get ready to
1042		 * continue sucking down more data.
1043		 */
1044
1045		if (bsz) {
1046			assert(bpos < bmax);
1047			if ((ssz = write(fd, b + bpos, bsz)) == -1)
1048				err(EXIT_FAILURE, "write");
1049			bpos += ssz;
1050			bsz -= ssz;
1051			if (bsz)
1052				continue;
1053			bpos = bsz = 0;
1054		}
1055
1056		/*
1057		 * If there's nothing to parse, then stop waiting for
1058		 * the write signal.
1059		 */
1060
1061		if (TAILQ_EMPTY(&q)) {
1062			pfd.events &= ~POLLOUT;
1063			continue;
1064		}
1065
1066		entp = TAILQ_FIRST(&q);
1067		assert(entp != NULL);
1068
1069		/*
1070		 * Extra security.
1071		 * Our TAL files may be anywhere, but the repository
1072		 * resources may only be in BASE_DIR.
1073		 * When we've finished processing TAL files, make sure
1074		 * that we can only see what's under that.
1075		 */
1076
1077		if (entp->type != RTYPE_TAL && first_tals) {
1078			if (unveil(BASE_DIR, "r") == -1)
1079				err(EXIT_FAILURE, "%s: unveil", BASE_DIR);
1080			if (unveil(NULL, NULL) == -1)
1081				err(EXIT_FAILURE, "unveil");
1082			first_tals = 0;
1083		} else if (entp->type != RTYPE_TAL) {
1084			assert(!first_tals);
1085		} else if (entp->type == RTYPE_TAL)
1086			assert(first_tals);
1087
1088		entity_buffer_resp(&b, &bsz, &bmax, entp);
1089
1090		switch (entp->type) {
1091		case RTYPE_TAL:
1092			assert(!entp->has_dgst);
1093			if ((tal = tal_parse(entp->uri)) == NULL)
1094				goto out;
1095			tal_buffer(&b, &bsz, &bmax, tal);
1096			tal_free(tal);
1097			break;
1098		case RTYPE_CER:
1099			cert = proc_parser_cert(entp, norev,
1100				store, ctx, &auths, &authsz);
1101			c = (cert != NULL);
1102			io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
1103			if (cert != NULL)
1104				cert_buffer(&b, &bsz, &bmax, cert);
1105			/*
1106			 * The parsed certificate data "cert" is now
1107			 * managed in the "auths" table, so don't free
1108			 * it here (see the loop after "out").
1109			 */
1110			break;
1111		case RTYPE_MFT:
1112			mft = proc_parser_mft(entp, force,
1113			    store, ctx, auths, authsz);
1114			c = (mft != NULL);
1115			io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
1116			if (mft != NULL)
1117				mft_buffer(&b, &bsz, &bmax, mft);
1118			mft_free(mft);
1119			break;
1120		case RTYPE_CRL:
1121			proc_parser_crl(entp, norev,
1122			    store, ctx, auths, authsz);
1123			break;
1124		case RTYPE_ROA:
1125			assert(entp->has_dgst);
1126			roa = proc_parser_roa(entp, norev,
1127			    store, ctx, auths, authsz);
1128			c = (roa != NULL);
1129			io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
1130			if (roa != NULL)
1131				roa_buffer(&b, &bsz, &bmax, roa);
1132			roa_free(roa);
1133			break;
1134		default:
1135			abort();
1136		}
1137
1138		TAILQ_REMOVE(&q, entp, entries);
1139		entity_free(entp);
1140	}
1141
1142	rc = 1;
1143out:
1144	while ((entp = TAILQ_FIRST(&q)) != NULL) {
1145		TAILQ_REMOVE(&q, entp, entries);
1146		entity_free(entp);
1147	}
1148
1149	for (i = 0; i < authsz; i++) {
1150		free(auths[i].fn);
1151		cert_free(auths[i].cert);
1152	}
1153
1154	X509_STORE_CTX_free(ctx);
1155	X509_STORE_free(store);
1156	free(auths);
1157
1158	free(b);
1159
1160	EVP_cleanup();
1161	CRYPTO_cleanup_all_ex_data();
1162	ERR_remove_state(0);
1163	ERR_free_strings();
1164
1165	exit(rc ? EXIT_SUCCESS : EXIT_FAILURE);
1166}
1167
1168/*
1169 * Process parsed content.
1170 * For non-ROAs, we grok for more data.
1171 * For ROAs, we want to extract the valid info.
1172 * In all cases, we gather statistics.
1173 */
1174static void
1175entity_process(int proc, int rsync, struct stats *st,
1176    struct entityq *q, const struct entity *ent, struct repotab *rt,
1177    size_t *eid, struct roa ***out, size_t *outsz)
1178{
1179	struct tal	*tal;
1180	struct cert	*cert;
1181	struct mft	*mft;
1182	struct roa	*roa;
1183	int		 c;
1184
1185	/*
1186	 * For most of these, we first read whether there's any content
1187	 * at all---this means that the syntactic parse failed (X509
1188	 * certificate, for example).
1189	 * We follow that up with whether the resources didn't parse.
1190	 */
1191
1192	switch (ent->type) {
1193	case RTYPE_TAL:
1194		st->tals++;
1195		tal = tal_read(proc);
1196		queue_add_from_tal(proc, rsync, q, tal, rt, eid);
1197		tal_free(tal);
1198		break;
1199	case RTYPE_CER:
1200		st->certs++;
1201		io_simple_read(proc, &c, sizeof(int));
1202		if (c == 0) {
1203			st->certs_fail++;
1204			break;
1205		}
1206		cert = cert_read(proc);
1207		if (cert->valid) {
1208			/*
1209			 * Process the revocation list from the
1210			 * certificate *first*, since it might mark that
1211			 * we're revoked and then we don't want to
1212			 * process the MFT.
1213			 */
1214			if (cert->crl != NULL)
1215				queue_add_from_cert(proc, rsync,
1216				    q, cert->crl, rt, eid);
1217			if (cert->mft != NULL)
1218				queue_add_from_cert(proc, rsync,
1219				    q, cert->mft, rt, eid);
1220		} else
1221			st->certs_invalid++;
1222		cert_free(cert);
1223		break;
1224	case RTYPE_MFT:
1225		st->mfts++;
1226		io_simple_read(proc, &c, sizeof(int));
1227		if (c == 0) {
1228			st->mfts_fail++;
1229			break;
1230		}
1231		mft = mft_read(proc);
1232		if (mft->stale)
1233			st->mfts_stale++;
1234		queue_add_from_mft_set(proc, q, mft, eid);
1235		mft_free(mft);
1236		break;
1237	case RTYPE_CRL:
1238		st->crls++;
1239		break;
1240	case RTYPE_ROA:
1241		st->roas++;
1242		io_simple_read(proc, &c, sizeof(int));
1243		if (c == 0) {
1244			st->roas_fail++;
1245			break;
1246		}
1247		roa = roa_read(proc);
1248		if (roa->valid) {
1249			*out = reallocarray(*out,
1250			    *outsz + 1, sizeof(struct roa *));
1251			if (*out == NULL)
1252				err(EXIT_FAILURE, "reallocarray");
1253			(*out)[*outsz] = roa;
1254			(*outsz)++;
1255			/* We roa_free() on exit. */
1256		} else {
1257			st->roas_invalid++;
1258			roa_free(roa);
1259		}
1260		break;
1261	default:
1262		abort();
1263	}
1264}
1265
1266#define	TALSZ_MAX	8
1267
1268size_t
1269tal_load_default(const char *tals[], size_t max)
1270{
1271	static const char *basedir = "/etc/rpki";
1272	size_t s = 0;
1273	char *path;
1274	DIR *dirp;
1275	struct dirent *dp;
1276
1277	dirp = opendir(basedir);
1278	if (dirp == NULL)
1279		err(EXIT_FAILURE, "open %s", basedir);
1280	while ((dp = readdir(dirp)) != NULL) {
1281		if (fnmatch("*.tal", dp->d_name, FNM_PERIOD) == FNM_NOMATCH)
1282			continue;
1283		if (s >= max)
1284			err(EXIT_FAILURE, "too many tal files found in %s",
1285			    basedir);
1286		if (asprintf(&path, "%s/%s", basedir, dp->d_name) == -1)
1287			err(EXIT_FAILURE, "asprintf");
1288		tals[s++] = path;
1289	}
1290	closedir (dirp);
1291	return (s);
1292}
1293
1294int
1295main(int argc, char *argv[])
1296{
1297	int		 rc = 0, c, proc, st, rsync,
1298			 fl = SOCK_STREAM | SOCK_CLOEXEC, noop = 0,
1299			 force = 0, norev = 0;
1300	size_t		 i, j, eid = 1, outsz = 0, talsz = 0, vrps, uniqs;
1301	pid_t		 procpid, rsyncpid;
1302	int		 fd[2];
1303	struct entityq	 q;
1304	struct entity	*ent;
1305	struct pollfd	 pfd[2];
1306	struct repotab	 rt;
1307	struct stats	 stats;
1308	struct roa	**out = NULL;
1309	const char	*rsync_prog = "openrsync";
1310	const char	*bind_addr = NULL;
1311	const char	*tals[TALSZ_MAX];
1312	FILE		*output = NULL;
1313
1314	if (pledge("stdio rpath wpath cpath proc exec unveil", NULL) == -1)
1315		err(EXIT_FAILURE, "pledge");
1316
1317	while ((c = getopt(argc, argv, "b:e:fnrt:v")) != -1)
1318		switch (c) {
1319		case 'b':
1320			bind_addr = optarg;
1321			break;
1322		case 'e':
1323			rsync_prog = optarg;
1324			break;
1325		case 'f':
1326			force = 1;
1327			break;
1328		case 'n':
1329			noop = 1;
1330			break;
1331		case 'r':
1332			norev = 1;
1333			break;
1334		case 't':
1335			if (talsz >= TALSZ_MAX)
1336				err(EXIT_FAILURE,
1337				    "too many tal files specified");
1338			tals[talsz++] = optarg;
1339			break;
1340		case 'v':
1341			verbose++;
1342			break;
1343		default:
1344			goto usage;
1345		}
1346
1347	argv += optind;
1348	argc -= optind;
1349	if (argc != 1)
1350		goto usage;
1351	output = fopen(argv[0], "we");
1352	if (output == NULL)
1353		err(EXIT_FAILURE, "failed to open %s", argv[0]);
1354
1355	if (talsz == 0)
1356		talsz = tal_load_default(tals, TALSZ_MAX);
1357	if (talsz == 0)
1358		err(EXIT_FAILURE, "no TAL files found in %s", "/etc/rpki");
1359
1360	memset(&rt, 0, sizeof(struct repotab));
1361	memset(&stats, 0, sizeof(struct stats));
1362	TAILQ_INIT(&q);
1363
1364	/*
1365	 * Create the file reader as a jailed child process.
1366	 * It will be responsible for reading all of the files (ROAs,
1367	 * manifests, certificates, etc.) and returning contents.
1368	 */
1369
1370	if (socketpair(AF_UNIX, fl, 0, fd) == -1)
1371		err(EXIT_FAILURE, "socketpair");
1372	if ((procpid = fork()) == -1)
1373		err(EXIT_FAILURE, "fork");
1374
1375	if (procpid == 0) {
1376		close(fd[1]);
1377		if (pledge("stdio rpath unveil", NULL) == -1)
1378			err(EXIT_FAILURE, "pledge");
1379		proc_parser(fd[0], force, norev);
1380		/* NOTREACHED */
1381	}
1382
1383	close(fd[0]);
1384	proc = fd[1];
1385
1386	/*
1387	 * Create a process that will do the rsync'ing.
1388	 * This process is responsible for making sure that all the
1389	 * repositories referenced by a certificate manifest (or the
1390	 * TAL) exists and has been downloaded.
1391	 */
1392
1393	if (socketpair(AF_UNIX, fl, 0, fd) == -1)
1394		err(EXIT_FAILURE, "socketpair");
1395	if ((rsyncpid = fork()) == -1)
1396		err(EXIT_FAILURE, "fork");
1397
1398	if (rsyncpid == 0) {
1399		close(proc);
1400		close(fd[1]);
1401		if (pledge("stdio rpath cpath proc exec unveil", NULL) == -1)
1402			err(EXIT_FAILURE, "pledge");
1403
1404		/* If -n, we don't exec or mkdir. */
1405
1406		if (noop && pledge("stdio", NULL) == -1)
1407			err(EXIT_FAILURE, "pledge");
1408		proc_rsync(rsync_prog, bind_addr, fd[0], noop);
1409		/* NOTREACHED */
1410	}
1411
1412	close(fd[0]);
1413	rsync = fd[1];
1414
1415	assert(rsync != proc);
1416
1417	/*
1418	 * The main process drives the top-down scan to leaf ROAs using
1419	 * data downloaded by the rsync process and parsed by the
1420	 * parsing process.
1421	 */
1422
1423	if (pledge("stdio", NULL) == -1)
1424		err(EXIT_FAILURE, "pledge");
1425
1426	/*
1427	 * Prime the process with our TAL file.
1428	 * This will contain (hopefully) links to our manifest and we
1429	 * can get the ball rolling.
1430	 */
1431
1432	for (i = 0; i < talsz; i++)
1433		queue_add_tal(proc, &q, tals[i], &eid);
1434
1435	pfd[0].fd = rsync;
1436	pfd[1].fd = proc;
1437	pfd[0].events = pfd[1].events = POLLIN;
1438
1439	while (!TAILQ_EMPTY(&q)) {
1440		if ((c = poll(pfd, 2, verbose ? 10000 : INFTIM)) == -1)
1441			err(EXIT_FAILURE, "poll");
1442
1443		/* Debugging: print some statistics if we stall. */
1444
1445		if (c == 0) {
1446			for (i = j = 0; i < rt.reposz; i++)
1447				if (!rt.repos[i].loaded)
1448					j++;
1449			logx("period stats: %zu pending repos", j);
1450			j = 0;
1451			TAILQ_FOREACH(ent, &q, entries)
1452				j++;
1453			logx("period stats: %zu pending entries", j);
1454			continue;
1455		}
1456
1457		if ((pfd[0].revents & (POLLERR|POLLNVAL)) ||
1458		    (pfd[1].revents & (POLLERR|POLLNVAL)))
1459			errx(EXIT_FAILURE, "poll: bad fd");
1460		if ((pfd[0].revents & POLLHUP) ||
1461		    (pfd[1].revents & POLLHUP))
1462			errx(EXIT_FAILURE, "poll: hangup");
1463
1464		/*
1465		 * Check the rsync process.
1466		 * This means that one of our modules has completed
1467		 * downloading and we can flush the module requests into
1468		 * the parser process.
1469		 */
1470
1471		if ((pfd[0].revents & POLLIN)) {
1472			io_simple_read(rsync, &i, sizeof(size_t));
1473			assert(i < rt.reposz);
1474			assert(!rt.repos[i].loaded);
1475			rt.repos[i].loaded = 1;
1476			logx("%s/%s/%s: loaded", BASE_DIR,
1477			    rt.repos[i].host, rt.repos[i].module);
1478			stats.repos++;
1479			entityq_flush(proc, &q, &rt.repos[i]);
1480		}
1481
1482		/*
1483		 * The parser has finished something for us.
1484		 * Dequeue these one by one.
1485		 */
1486
1487		if ((pfd[1].revents & POLLIN)) {
1488			ent = entityq_next(proc, &q);
1489			entity_process(proc, rsync, &stats,
1490			    &q, ent, &rt, &eid, &out, &outsz);
1491			if (verbose > 1)
1492				fprintf(stderr, "%s\n", ent->uri);
1493			entity_free(ent);
1494		}
1495	}
1496
1497	assert(TAILQ_EMPTY(&q));
1498	logx("all files parsed: exiting");
1499	rc = 1;
1500
1501	/*
1502	 * For clean-up, close the input for the parser and rsync
1503	 * process.
1504	 * This will cause them to exit, then we reap them.
1505	 */
1506
1507	close(proc);
1508	close(rsync);
1509
1510	if (waitpid(procpid, &st, 0) == -1)
1511		err(EXIT_FAILURE, "waitpid");
1512	if (!WIFEXITED(st) || WEXITSTATUS(st) != EXIT_SUCCESS) {
1513		warnx("parser process exited abnormally");
1514		rc = 0;
1515	}
1516	if (waitpid(rsyncpid, &st, 0) == -1)
1517		err(EXIT_FAILURE, "waitpid");
1518	if (!WIFEXITED(st) || WEXITSTATUS(st) != EXIT_SUCCESS) {
1519		warnx("rsync process exited abnormally");
1520		rc = 0;
1521	}
1522
1523	/* Output and statistics. */
1524
1525	output_bgpd(output, (const struct roa **)out,
1526	    outsz, &vrps, &uniqs);
1527	logx("Route Origin Authorizations: %zu (%zu failed parse, %zu invalid)",
1528	    stats.roas, stats.roas_fail, stats.roas_invalid);
1529	logx("Certificates: %zu (%zu failed parse, %zu invalid)",
1530	    stats.certs, stats.certs_fail, stats.certs_invalid);
1531	logx("Trust Anchor Locators: %zu", stats.tals);
1532	logx("Manifests: %zu (%zu failed parse, %zu stale)",
1533	    stats.mfts, stats.mfts_fail, stats.mfts_stale);
1534	logx("Certificate revocation lists: %zu", stats.crls);
1535	logx("Repositories: %zu", stats.repos);
1536	logx("VRP Entries: %zu (%zu unique)", vrps, uniqs);
1537
1538	/* Memory cleanup. */
1539
1540	for (i = 0; i < rt.reposz; i++) {
1541		free(rt.repos[i].host);
1542		free(rt.repos[i].module);
1543	}
1544	free(rt.repos);
1545
1546	for (i = 0; i < outsz; i++)
1547		roa_free(out[i]);
1548	free(out);
1549
1550	return rc ? EXIT_SUCCESS : EXIT_FAILURE;
1551
1552usage:
1553	fprintf(stderr,
1554	    "usage: rpki-client [-fnqrv] [-b bind_addr] [-e rsync_prog] "
1555	    "[-t tal] output\n");
1556	return EXIT_FAILURE;
1557}
1558