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