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