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