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