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