1 /* $OpenBSD: parser.c,v 1.94 2023/05/11 20:13:30 job Exp $ */ 2 /* 3 * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> 4 * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/queue.h> 20 #include <sys/tree.h> 21 #include <sys/types.h> 22 23 #include <err.h> 24 #include <fcntl.h> 25 #include <poll.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <limits.h> 30 #include <unistd.h> 31 #include <imsg.h> 32 33 #include <openssl/asn1.h> 34 #include <openssl/err.h> 35 #include <openssl/evp.h> 36 #include <openssl/x509.h> 37 #include <openssl/x509v3.h> 38 39 #include "extern.h" 40 41 static X509_STORE_CTX *ctx; 42 static struct auth_tree auths = RB_INITIALIZER(&auths); 43 static struct crl_tree crlt = RB_INITIALIZER(&crlt); 44 45 struct parse_repo { 46 RB_ENTRY(parse_repo) entry; 47 char *path; 48 char *validpath; 49 unsigned int id; 50 }; 51 52 static RB_HEAD(repo_tree, parse_repo) repos = RB_INITIALIZER(&repos); 53 54 static inline int 55 repocmp(struct parse_repo *a, struct parse_repo *b) 56 { 57 return a->id - b->id; 58 } 59 60 RB_GENERATE_STATIC(repo_tree, parse_repo, entry, repocmp); 61 62 static struct parse_repo * 63 repo_get(unsigned int id) 64 { 65 struct parse_repo needle = { .id = id }; 66 67 return RB_FIND(repo_tree, &repos, &needle); 68 } 69 70 static void 71 repo_add(unsigned int id, char *path, char *validpath) 72 { 73 struct parse_repo *rp; 74 75 if ((rp = calloc(1, sizeof(*rp))) == NULL) 76 err(1, NULL); 77 rp->id = id; 78 if (path != NULL) 79 if ((rp->path = strdup(path)) == NULL) 80 err(1, NULL); 81 if (validpath != NULL) 82 if ((rp->validpath = strdup(validpath)) == NULL) 83 err(1, NULL); 84 85 if (RB_INSERT(repo_tree, &repos, rp) != NULL) 86 errx(1, "repository already added: id %d, %s", id, path); 87 } 88 89 /* 90 * Build access path to file based on repoid, path, location and file values. 91 */ 92 static char * 93 parse_filepath(unsigned int repoid, const char *path, const char *file, 94 enum location loc) 95 { 96 struct parse_repo *rp; 97 char *fn, *repopath; 98 99 /* build file path based on repoid, entity path and filename */ 100 rp = repo_get(repoid); 101 if (rp == NULL) 102 errx(1, "build file path: repository %u missing", repoid); 103 104 if (loc == DIR_VALID) 105 repopath = rp->validpath; 106 else 107 repopath = rp->path; 108 109 if (repopath == NULL) 110 return NULL; 111 112 if (path == NULL) { 113 if (asprintf(&fn, "%s/%s", repopath, file) == -1) 114 err(1, NULL); 115 } else { 116 if (asprintf(&fn, "%s/%s/%s", repopath, path, file) == -1) 117 err(1, NULL); 118 } 119 return fn; 120 } 121 122 /* 123 * Parse and validate a ROA. 124 * This is standard stuff. 125 * Returns the roa on success, NULL on failure. 126 */ 127 static struct roa * 128 proc_parser_roa(char *file, const unsigned char *der, size_t len, 129 const char *mftaki) 130 { 131 struct roa *roa; 132 struct auth *a; 133 struct crl *crl; 134 X509 *x509; 135 const char *errstr; 136 137 if ((roa = roa_parse(&x509, file, der, len)) == NULL) 138 return NULL; 139 140 a = valid_ski_aki(file, &auths, roa->ski, roa->aki, mftaki); 141 crl = crl_get(&crlt, a); 142 143 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 144 warnx("%s: %s", file, errstr); 145 X509_free(x509); 146 roa_free(roa); 147 return NULL; 148 } 149 X509_free(x509); 150 151 roa->talid = a->cert->talid; 152 153 roa->expires = x509_find_expires(roa->notafter, a, &crlt); 154 155 return roa; 156 } 157 158 /* 159 * Check all files and their hashes in a MFT structure. 160 * Return zero on failure, non-zero on success. 161 */ 162 static int 163 proc_parser_mft_check(const char *fn, struct mft *p) 164 { 165 const enum location loc[2] = { DIR_TEMP, DIR_VALID }; 166 size_t i; 167 int rc = 1; 168 char *path; 169 170 for (i = 0; i < p->filesz; i++) { 171 struct mftfile *m = &p->files[i]; 172 int try, fd = -1, noent = 0, valid = 0; 173 for (try = 0; try < 2 && !valid; try++) { 174 if ((path = parse_filepath(p->repoid, p->path, m->file, 175 loc[try])) == NULL) 176 continue; 177 fd = open(path, O_RDONLY); 178 if (fd == -1 && errno == ENOENT) 179 noent++; 180 free(path); 181 182 /* remember which path was checked */ 183 m->location = loc[try]; 184 valid = valid_filehash(fd, m->hash, sizeof(m->hash)); 185 } 186 187 if (!valid) { 188 /* silently skip not-existing unknown files */ 189 if (m->type == RTYPE_INVALID && noent == 2) 190 continue; 191 warnx("%s#%s: bad message digest for %s", fn, 192 p->seqnum, m->file); 193 rc = 0; 194 continue; 195 } 196 } 197 198 return rc; 199 } 200 201 /* 202 * Load the CRL from loc using the info from the MFT. 203 */ 204 static struct crl * 205 parse_load_crl_from_mft(struct entity *entp, struct mft *mft, enum location loc, 206 char **crlfile) 207 { 208 struct crl *crl = NULL; 209 unsigned char *f = NULL; 210 char *fn = NULL; 211 size_t flen; 212 213 *crlfile = NULL; 214 215 fn = parse_filepath(entp->repoid, entp->path, mft->crl, loc); 216 if (fn == NULL) 217 goto out; 218 219 f = load_file(fn, &flen); 220 if (f == NULL) { 221 if (errno != ENOENT) 222 warn("parse file %s", fn); 223 goto out; 224 } 225 226 if (!valid_hash(f, flen, mft->crlhash, sizeof(mft->crlhash))) 227 goto out; 228 229 crl = crl_parse(fn, f, flen); 230 if (crl == NULL) 231 goto out; 232 233 if (strcmp(crl->aki, mft->aki) != 0) { 234 warnx("%s: AKI doesn't match Manifest AKI", fn); 235 goto out; 236 } 237 238 *crlfile = fn; 239 free(f); 240 241 return crl; 242 243 out: 244 crl_free(crl); 245 free(f); 246 free(fn); 247 248 return NULL; 249 } 250 251 /* 252 * Parse and validate a manifest file. Skip checking the fileandhash 253 * this is done in the post check. After this step we know the mft is 254 * valid and can be compared. 255 * Return the mft on success or NULL on failure. 256 */ 257 static struct mft * 258 proc_parser_mft_pre(struct entity *entp, enum location loc, char **file, 259 struct crl **crl, char **crlfile, const char **errstr) 260 { 261 struct mft *mft; 262 X509 *x509; 263 struct auth *a; 264 unsigned char *der; 265 size_t len; 266 267 *crl = NULL; 268 *crlfile = NULL; 269 *errstr = NULL; 270 271 *file = parse_filepath(entp->repoid, entp->path, entp->file, loc); 272 if (*file == NULL) 273 return NULL; 274 275 der = load_file(*file, &len); 276 if (der == NULL && errno != ENOENT) 277 warn("parse file %s", *file); 278 279 if ((mft = mft_parse(&x509, *file, der, len)) == NULL) { 280 free(der); 281 return NULL; 282 } 283 free(der); 284 285 *crl = parse_load_crl_from_mft(entp, mft, DIR_TEMP, crlfile); 286 if (*crl == NULL) 287 *crl = parse_load_crl_from_mft(entp, mft, DIR_VALID, crlfile); 288 289 a = valid_ski_aki(*file, &auths, mft->ski, mft->aki, NULL); 290 if (!valid_x509(*file, ctx, x509, a, *crl, errstr)) { 291 X509_free(x509); 292 mft_free(mft); 293 crl_free(*crl); 294 *crl = NULL; 295 free(*crlfile); 296 *crlfile = NULL; 297 return NULL; 298 } 299 X509_free(x509); 300 301 mft->repoid = entp->repoid; 302 mft->talid = a->cert->talid; 303 304 return mft; 305 } 306 307 /* 308 * Do the end of manifest validation. 309 * Return the mft on success or NULL on failure. 310 */ 311 static struct mft * 312 proc_parser_mft_post(char *file, struct mft *mft, const char *path, 313 const char *errstr) 314 { 315 if (mft == NULL) { 316 if (errstr == NULL) 317 errstr = "no valid mft available"; 318 warnx("%s: %s", file, errstr); 319 return NULL; 320 } 321 322 /* check that evaluation_time is not before from */ 323 if (evaluation_time < mft->thisupdate) { 324 warnx("%s: mft not yet valid %s", file, 325 time2str(mft->thisupdate)); 326 mft->stale = 1; 327 } 328 /* check that evaluation_time is not after until */ 329 if (evaluation_time > mft->nextupdate) { 330 warnx("%s: mft expired on %s", file, 331 time2str(mft->nextupdate)); 332 mft->stale = 1; 333 } 334 335 if (path != NULL) 336 if ((mft->path = strdup(path)) == NULL) 337 err(1, NULL); 338 339 if (!mft->stale) 340 if (!proc_parser_mft_check(file, mft)) { 341 mft_free(mft); 342 return NULL; 343 } 344 345 return mft; 346 } 347 348 /* 349 * Load the most recent MFT by opening both options and comparing the two. 350 */ 351 static char * 352 proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile) 353 { 354 struct mft *mft1 = NULL, *mft2 = NULL; 355 struct crl *crl, *crl1, *crl2; 356 char *file, *file1, *file2, *crl1file, *crl2file; 357 const char *err1, *err2; 358 359 *mp = NULL; 360 361 mft1 = proc_parser_mft_pre(entp, DIR_VALID, &file1, &crl1, &crl1file, 362 &err1); 363 mft2 = proc_parser_mft_pre(entp, DIR_TEMP, &file2, &crl2, &crl2file, 364 &err2); 365 366 /* overload error from temp file if it is set */ 367 if (mft1 == NULL && mft2 == NULL) 368 if (err2 != NULL) 369 err1 = err2; 370 371 if (mft_compare(mft1, mft2) == 1) { 372 mft_free(mft2); 373 crl_free(crl2); 374 free(crl2file); 375 free(file2); 376 *mp = proc_parser_mft_post(file1, mft1, entp->path, err1); 377 crl = crl1; 378 file = file1; 379 *crlfile = crl1file; 380 } else { 381 mft_free(mft1); 382 crl_free(crl1); 383 free(crl1file); 384 free(file1); 385 *mp = proc_parser_mft_post(file2, mft2, entp->path, err2); 386 crl = crl2; 387 file = file2; 388 *crlfile = crl2file; 389 } 390 391 if (*mp != NULL) { 392 if (!crl_insert(&crlt, crl)) { 393 warnx("%s: duplicate AKI %s", file, crl->aki); 394 crl_free(crl); 395 } 396 } else { 397 crl_free(crl); 398 } 399 return file; 400 } 401 402 /* 403 * Certificates are from manifests (has a digest and is signed with 404 * another certificate) Parse the certificate, make sure its 405 * signatures are valid (with CRLs), then validate the RPKI content. 406 * This returns a certificate (which must not be freed) or NULL on 407 * parse failure. 408 */ 409 static struct cert * 410 proc_parser_cert(char *file, const unsigned char *der, size_t len, 411 const char *mftaki) 412 { 413 struct cert *cert; 414 struct crl *crl; 415 struct auth *a; 416 const char *errstr = NULL; 417 418 /* Extract certificate data. */ 419 420 cert = cert_parse_pre(file, der, len); 421 cert = cert_parse(file, cert); 422 if (cert == NULL) 423 return NULL; 424 425 a = valid_ski_aki(file, &auths, cert->ski, cert->aki, mftaki); 426 crl = crl_get(&crlt, a); 427 428 if (!valid_x509(file, ctx, cert->x509, a, crl, &errstr) || 429 !valid_cert(file, a, cert)) { 430 if (errstr != NULL) 431 warnx("%s: %s", file, errstr); 432 cert_free(cert); 433 return NULL; 434 } 435 436 cert->talid = a->cert->talid; 437 438 /* 439 * Add validated CA certs to the RPKI auth tree. 440 */ 441 if (cert->purpose == CERT_PURPOSE_CA) 442 auth_insert(&auths, cert, a); 443 444 return cert; 445 } 446 447 /* 448 * Root certificates come from TALs (has a pkey and is self-signed). 449 * Parse the certificate, ensure that its public key matches the 450 * known public key from the TAL, and then validate the RPKI 451 * content. 452 * 453 * This returns a certificate (which must not be freed) or NULL on 454 * parse failure. 455 */ 456 static struct cert * 457 proc_parser_root_cert(char *file, const unsigned char *der, size_t len, 458 unsigned char *pkey, size_t pkeysz, int talid) 459 { 460 struct cert *cert; 461 462 /* Extract certificate data. */ 463 464 cert = cert_parse_pre(file, der, len); 465 cert = ta_parse(file, cert, pkey, pkeysz); 466 if (cert == NULL) 467 return NULL; 468 469 if (!valid_ta(file, &auths, cert)) { 470 warnx("%s: certificate not a valid ta", file); 471 cert_free(cert); 472 return NULL; 473 } 474 475 cert->talid = talid; 476 477 /* 478 * Add valid roots to the RPKI auth tree. 479 */ 480 auth_insert(&auths, cert, NULL); 481 482 return cert; 483 } 484 485 /* 486 * Parse a ghostbuster record 487 */ 488 static void 489 proc_parser_gbr(char *file, const unsigned char *der, size_t len, 490 const char *mftaki) 491 { 492 struct gbr *gbr; 493 X509 *x509; 494 struct crl *crl; 495 struct auth *a; 496 const char *errstr; 497 498 if ((gbr = gbr_parse(&x509, file, der, len)) == NULL) 499 return; 500 501 a = valid_ski_aki(file, &auths, gbr->ski, gbr->aki, mftaki); 502 crl = crl_get(&crlt, a); 503 504 /* return value can be ignored since nothing happens here */ 505 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) 506 warnx("%s: %s", file, errstr); 507 508 X509_free(x509); 509 gbr_free(gbr); 510 } 511 512 /* 513 * Parse an ASPA object 514 */ 515 static struct aspa * 516 proc_parser_aspa(char *file, const unsigned char *der, size_t len, 517 const char *mftaki) 518 { 519 struct aspa *aspa; 520 struct auth *a; 521 struct crl *crl; 522 X509 *x509; 523 const char *errstr; 524 525 if ((aspa = aspa_parse(&x509, file, der, len)) == NULL) 526 return NULL; 527 528 a = valid_ski_aki(file, &auths, aspa->ski, aspa->aki, mftaki); 529 crl = crl_get(&crlt, a); 530 531 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 532 warnx("%s: %s", file, errstr); 533 X509_free(x509); 534 aspa_free(aspa); 535 return NULL; 536 } 537 X509_free(x509); 538 539 aspa->talid = a->cert->talid; 540 541 aspa->expires = x509_find_expires(aspa->notafter, a, &crlt); 542 543 return aspa; 544 } 545 546 /* 547 * Parse a TAK object. 548 */ 549 static struct tak * 550 proc_parser_tak(char *file, const unsigned char *der, size_t len, 551 const char *mftaki) 552 { 553 struct tak *tak; 554 X509 *x509; 555 struct crl *crl; 556 struct auth *a; 557 const char *errstr; 558 int rc = 0; 559 560 if ((tak = tak_parse(&x509, file, der, len)) == NULL) 561 return NULL; 562 563 a = valid_ski_aki(file, &auths, tak->ski, tak->aki, mftaki); 564 crl = crl_get(&crlt, a); 565 566 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 567 warnx("%s: %s", file, errstr); 568 goto out; 569 } 570 571 /* TAK EE must be signed by self-signed CA */ 572 if (a->parent != NULL) 573 goto out; 574 575 tak->talid = a->cert->talid; 576 rc = 1; 577 out: 578 if (rc == 0) { 579 tak_free(tak); 580 tak = NULL; 581 } 582 X509_free(x509); 583 return tak; 584 } 585 586 /* 587 * Load the file specified by the entity information. 588 */ 589 static char * 590 parse_load_file(struct entity *entp, unsigned char **f, size_t *flen) 591 { 592 char *file; 593 594 file = parse_filepath(entp->repoid, entp->path, entp->file, 595 entp->location); 596 if (file == NULL) 597 errx(1, "no path to file"); 598 599 *f = load_file(file, flen); 600 if (*f == NULL) 601 warn("parse file %s", file); 602 603 return file; 604 } 605 606 /* 607 * Process an entity and responing to parent process. 608 */ 609 static void 610 parse_entity(struct entityq *q, struct msgbuf *msgq) 611 { 612 struct entity *entp; 613 struct tal *tal; 614 struct cert *cert; 615 struct mft *mft; 616 struct roa *roa; 617 struct aspa *aspa; 618 struct ibuf *b; 619 unsigned char *f; 620 size_t flen; 621 char *file, *crlfile; 622 int c; 623 624 while ((entp = TAILQ_FIRST(q)) != NULL) { 625 TAILQ_REMOVE(q, entp, entries); 626 627 /* handle RTYPE_REPO first */ 628 if (entp->type == RTYPE_REPO) { 629 repo_add(entp->repoid, entp->path, entp->file); 630 entity_free(entp); 631 continue; 632 } 633 634 /* pass back at least type, repoid and filename */ 635 b = io_new_buffer(); 636 io_simple_buffer(b, &entp->type, sizeof(entp->type)); 637 io_simple_buffer(b, &entp->repoid, sizeof(entp->repoid)); 638 io_simple_buffer(b, &entp->talid, sizeof(entp->talid)); 639 640 file = NULL; 641 f = NULL; 642 switch (entp->type) { 643 case RTYPE_TAL: 644 io_str_buffer(b, entp->file); 645 if ((tal = tal_parse(entp->file, entp->data, 646 entp->datasz)) == NULL) 647 errx(1, "%s: could not parse tal file", 648 entp->file); 649 tal->id = entp->talid; 650 tal_buffer(b, tal); 651 tal_free(tal); 652 break; 653 case RTYPE_CER: 654 file = parse_load_file(entp, &f, &flen); 655 io_str_buffer(b, file); 656 if (entp->data != NULL) 657 cert = proc_parser_root_cert(file, 658 f, flen, entp->data, entp->datasz, 659 entp->talid); 660 else 661 cert = proc_parser_cert(file, f, flen, 662 entp->mftaki); 663 c = (cert != NULL); 664 io_simple_buffer(b, &c, sizeof(int)); 665 if (cert != NULL) { 666 cert->repoid = entp->repoid; 667 cert_buffer(b, cert); 668 } 669 /* 670 * The parsed certificate data "cert" is now 671 * managed in the "auths" table, so don't free 672 * it here. 673 */ 674 break; 675 case RTYPE_MFT: 676 file = proc_parser_mft(entp, &mft, &crlfile); 677 io_str_buffer(b, file); 678 c = (mft != NULL); 679 io_simple_buffer(b, &c, sizeof(int)); 680 if (mft != NULL) 681 mft_buffer(b, mft); 682 683 /* Push valid CRL together with the MFT. */ 684 if (crlfile != NULL) { 685 enum rtype type; 686 struct ibuf *b2; 687 688 b2 = io_new_buffer(); 689 type = RTYPE_CRL; 690 io_simple_buffer(b2, &type, sizeof(type)); 691 io_simple_buffer(b2, &entp->repoid, 692 sizeof(entp->repoid)); 693 io_simple_buffer(b2, &entp->talid, 694 sizeof(entp->talid)); 695 io_str_buffer(b2, crlfile); 696 free(crlfile); 697 698 io_close_buffer(msgq, b2); 699 } 700 mft_free(mft); 701 break; 702 case RTYPE_ROA: 703 file = parse_load_file(entp, &f, &flen); 704 io_str_buffer(b, file); 705 roa = proc_parser_roa(file, f, flen, entp->mftaki); 706 c = (roa != NULL); 707 io_simple_buffer(b, &c, sizeof(int)); 708 if (roa != NULL) 709 roa_buffer(b, roa); 710 roa_free(roa); 711 break; 712 case RTYPE_GBR: 713 file = parse_load_file(entp, &f, &flen); 714 io_str_buffer(b, file); 715 proc_parser_gbr(file, f, flen, entp->mftaki); 716 break; 717 case RTYPE_ASPA: 718 file = parse_load_file(entp, &f, &flen); 719 io_str_buffer(b, file); 720 aspa = proc_parser_aspa(file, f, flen, entp->mftaki); 721 c = (aspa != NULL); 722 io_simple_buffer(b, &c, sizeof(int)); 723 if (aspa != NULL) 724 aspa_buffer(b, aspa); 725 aspa_free(aspa); 726 break; 727 case RTYPE_TAK: 728 file = parse_load_file(entp, &f, &flen); 729 io_str_buffer(b, file); 730 proc_parser_tak(file, f, flen, entp->mftaki); 731 break; 732 case RTYPE_CRL: 733 default: 734 file = parse_filepath(entp->repoid, entp->path, 735 entp->file, entp->location); 736 io_str_buffer(b, file); 737 warnx("%s: unhandled type %d", file, entp->type); 738 break; 739 } 740 741 free(f); 742 free(file); 743 io_close_buffer(msgq, b); 744 entity_free(entp); 745 } 746 } 747 748 /* 749 * Process responsible for parsing and validating content. 750 * All this process does is wait to be told about a file to parse, then 751 * it parses it and makes sure that the data being returned is fully 752 * validated and verified. 753 * The process will exit cleanly only when fd is closed. 754 */ 755 void 756 proc_parser(int fd) 757 { 758 struct entityq q; 759 struct msgbuf msgq; 760 struct pollfd pfd; 761 struct entity *entp; 762 struct ibuf *b, *inbuf = NULL; 763 764 /* Only allow access to the cache directory. */ 765 if (unveil(".", "r") == -1) 766 err(1, "unveil cachedir"); 767 if (pledge("stdio rpath", NULL) == -1) 768 err(1, "pledge"); 769 770 ERR_load_crypto_strings(); 771 OpenSSL_add_all_ciphers(); 772 OpenSSL_add_all_digests(); 773 x509_init_oid(); 774 775 if ((ctx = X509_STORE_CTX_new()) == NULL) 776 cryptoerrx("X509_STORE_CTX_new"); 777 778 TAILQ_INIT(&q); 779 780 msgbuf_init(&msgq); 781 msgq.fd = fd; 782 783 pfd.fd = fd; 784 785 for (;;) { 786 pfd.events = POLLIN; 787 if (msgq.queued) 788 pfd.events |= POLLOUT; 789 790 if (poll(&pfd, 1, INFTIM) == -1) { 791 if (errno == EINTR) 792 continue; 793 err(1, "poll"); 794 } 795 if ((pfd.revents & (POLLERR|POLLNVAL))) 796 errx(1, "poll: bad descriptor"); 797 798 /* If the parent closes, return immediately. */ 799 800 if ((pfd.revents & POLLHUP)) 801 break; 802 803 if ((pfd.revents & POLLIN)) { 804 b = io_buf_read(fd, &inbuf); 805 if (b != NULL) { 806 entp = calloc(1, sizeof(struct entity)); 807 if (entp == NULL) 808 err(1, NULL); 809 entity_read_req(b, entp); 810 TAILQ_INSERT_TAIL(&q, entp, entries); 811 ibuf_free(b); 812 } 813 } 814 815 if (pfd.revents & POLLOUT) { 816 switch (msgbuf_write(&msgq)) { 817 case 0: 818 errx(1, "write: connection closed"); 819 case -1: 820 err(1, "write"); 821 } 822 } 823 824 parse_entity(&q, &msgq); 825 } 826 827 while ((entp = TAILQ_FIRST(&q)) != NULL) { 828 TAILQ_REMOVE(&q, entp, entries); 829 entity_free(entp); 830 } 831 832 auth_tree_free(&auths); 833 crl_tree_free(&crlt); 834 835 X509_STORE_CTX_free(ctx); 836 msgbuf_clear(&msgq); 837 838 ibuf_free(inbuf); 839 840 exit(0); 841 } 842