1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org> 5 * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/queue.h> 32 #include <sys/types.h> 33 #include <sys/wait.h> 34 35 #include <archive.h> 36 #include <archive_entry.h> 37 #include <assert.h> 38 #include <dirent.h> 39 #include <err.h> 40 #include <errno.h> 41 #include <fcntl.h> 42 #include <fetch.h> 43 #include <getopt.h> 44 #include <libutil.h> 45 #include <paths.h> 46 #include <stdbool.h> 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <string.h> 50 #include <ucl.h> 51 52 #include "pkg.h" 53 54 #include "dns_utils.h" 55 #include "config.h" 56 #include "hash.h" 57 58 #define PKGSIGN_MARKER "$PKGSIGN:" 59 60 static const struct pkgsign_impl { 61 const char *pi_name; 62 const struct pkgsign_ops *pi_ops; 63 } pkgsign_builtins[] = { 64 { 65 .pi_name = "rsa", 66 .pi_ops = &pkgsign_rsa, 67 }, 68 { 69 .pi_name = "ecc", 70 .pi_ops = &pkgsign_ecc, 71 }, 72 { 73 .pi_name = "ecdsa", 74 .pi_ops = &pkgsign_ecc, 75 }, 76 { 77 .pi_name = "eddsa", 78 .pi_ops = &pkgsign_ecc, 79 }, 80 }; 81 82 typedef enum { 83 HASH_UNKNOWN, 84 HASH_SHA256, 85 } hash_t; 86 87 struct fingerprint { 88 hash_t type; 89 char *name; 90 char hash[BUFSIZ]; 91 STAILQ_ENTRY(fingerprint) next; 92 }; 93 94 static const char *bootstrap_names [] = { 95 "pkg.pkg", 96 "pkg.txz", 97 NULL 98 }; 99 100 STAILQ_HEAD(fingerprint_list, fingerprint); 101 102 static int debug; 103 104 static int 105 pkgsign_new(const char *name, struct pkgsign_ctx **ctx) 106 { 107 const struct pkgsign_impl *impl; 108 const struct pkgsign_ops *ops; 109 struct pkgsign_ctx *nctx; 110 size_t ctx_size; 111 int ret; 112 113 assert(*ctx == NULL); 114 ops = NULL; 115 for (size_t i = 0; i < nitems(pkgsign_builtins); i++) { 116 impl = &pkgsign_builtins[i]; 117 118 if (strcmp(name, impl->pi_name) == 0) { 119 ops = impl->pi_ops; 120 break; 121 } 122 } 123 124 if (ops == NULL) 125 return (ENOENT); 126 127 ctx_size = ops->pkgsign_ctx_size; 128 if (ctx_size == 0) 129 ctx_size = sizeof(*nctx); 130 assert(ctx_size >= sizeof(*nctx)); 131 132 nctx = calloc(1, ctx_size); 133 if (nctx == NULL) 134 err(EXIT_FAILURE, "calloc"); 135 nctx->impl = impl; 136 137 ret = 0; 138 if (ops->pkgsign_new != NULL) 139 ret = (*ops->pkgsign_new)(name, nctx); 140 141 if (ret != 0) { 142 free(nctx); 143 return (ret); 144 } 145 146 *ctx = nctx; 147 return (0); 148 } 149 150 static bool 151 pkgsign_verify_cert(const struct pkgsign_ctx *ctx, int fd, const char *sigfile, 152 const unsigned char *key, int keylen, unsigned char *sig, int siglen) 153 { 154 155 return ((*ctx->impl->pi_ops->pkgsign_verify_cert)(ctx, fd, sigfile, 156 key, keylen, sig, siglen)); 157 } 158 159 static bool 160 pkgsign_verify_data(const struct pkgsign_ctx *ctx, const char *data, 161 size_t datasz, const char *sigfile, const unsigned char *key, int keylen, 162 unsigned char *sig, int siglen) 163 { 164 165 return ((*ctx->impl->pi_ops->pkgsign_verify_data)(ctx, data, datasz, 166 sigfile, key, keylen, sig, siglen)); 167 } 168 169 170 static int 171 extract_pkg_static(int fd, char *p, int sz) 172 { 173 struct archive *a; 174 struct archive_entry *ae; 175 char *end; 176 int ret, r; 177 178 ret = -1; 179 a = archive_read_new(); 180 if (a == NULL) { 181 warn("archive_read_new"); 182 return (ret); 183 } 184 archive_read_support_filter_all(a); 185 archive_read_support_format_tar(a); 186 187 if (lseek(fd, 0, 0) == -1) { 188 warn("lseek"); 189 goto cleanup; 190 } 191 192 if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) { 193 warnx("archive_read_open_fd: %s", archive_error_string(a)); 194 goto cleanup; 195 } 196 197 ae = NULL; 198 while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) { 199 end = strrchr(archive_entry_pathname(ae), '/'); 200 if (end == NULL) 201 continue; 202 203 if (strcmp(end, "/pkg-static") == 0) { 204 r = archive_read_extract(a, ae, 205 ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | 206 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL | 207 ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR); 208 strlcpy(p, archive_entry_pathname(ae), sz); 209 break; 210 } 211 } 212 213 if (r == ARCHIVE_OK) 214 ret = 0; 215 else 216 warnx("failed to extract pkg-static: %s", 217 archive_error_string(a)); 218 219 cleanup: 220 archive_read_free(a); 221 return (ret); 222 223 } 224 225 static int 226 install_pkg_static(const char *path, const char *pkgpath, bool force) 227 { 228 int pstat; 229 pid_t pid; 230 231 switch ((pid = fork())) { 232 case -1: 233 return (-1); 234 case 0: 235 if (force) 236 execl(path, "pkg-static", "add", "-f", pkgpath, 237 (char *)NULL); 238 else 239 execl(path, "pkg-static", "add", pkgpath, 240 (char *)NULL); 241 _exit(1); 242 default: 243 break; 244 } 245 246 while (waitpid(pid, &pstat, 0) == -1) 247 if (errno != EINTR) 248 return (-1); 249 250 if (WEXITSTATUS(pstat)) 251 return (WEXITSTATUS(pstat)); 252 else if (WIFSIGNALED(pstat)) 253 return (128 & (WTERMSIG(pstat))); 254 return (pstat); 255 } 256 257 static int 258 fetch_to_fd(const char *url, char *path, const char *fetchOpts) 259 { 260 struct url *u; 261 struct dns_srvinfo *mirrors, *current; 262 struct url_stat st; 263 FILE *remote; 264 /* To store _https._tcp. + hostname + \0 */ 265 int fd; 266 int retry, max_retry; 267 ssize_t r; 268 char buf[10240]; 269 char zone[MAXHOSTNAMELEN + 13]; 270 static const char *mirror_type = NULL; 271 272 max_retry = 3; 273 current = mirrors = NULL; 274 remote = NULL; 275 276 if (mirror_type == NULL && config_string(MIRROR_TYPE, &mirror_type) 277 != 0) { 278 warnx("No MIRROR_TYPE defined"); 279 return (-1); 280 } 281 282 if ((fd = mkstemp(path)) == -1) { 283 warn("mkstemp()"); 284 return (-1); 285 } 286 287 retry = max_retry; 288 289 if ((u = fetchParseURL(url)) == NULL) { 290 warn("fetchParseURL('%s')", url); 291 return (-1); 292 } 293 294 while (remote == NULL) { 295 if (retry == max_retry) { 296 if (strcmp(u->scheme, "file") != 0 && 297 strcasecmp(mirror_type, "srv") == 0) { 298 snprintf(zone, sizeof(zone), 299 "_%s._tcp.%s", u->scheme, u->host); 300 mirrors = dns_getsrvinfo(zone); 301 current = mirrors; 302 } 303 } 304 305 if (mirrors != NULL) { 306 strlcpy(u->host, current->host, sizeof(u->host)); 307 u->port = current->port; 308 } 309 310 remote = fetchXGet(u, &st, fetchOpts); 311 if (remote == NULL) { 312 --retry; 313 if (retry <= 0) 314 goto fetchfail; 315 if (mirrors != NULL) { 316 current = current->next; 317 if (current == NULL) 318 current = mirrors; 319 } 320 } 321 } 322 323 while ((r = fread(buf, 1, sizeof(buf), remote)) > 0) { 324 if (write(fd, buf, r) != r) { 325 warn("write()"); 326 goto fetchfail; 327 } 328 } 329 330 if (r != 0) { 331 warn("An error occurred while fetching pkg(8)"); 332 goto fetchfail; 333 } 334 335 if (ferror(remote)) 336 goto fetchfail; 337 338 goto cleanup; 339 340 fetchfail: 341 if (fd != -1) { 342 close(fd); 343 fd = -1; 344 unlink(path); 345 } 346 347 cleanup: 348 if (remote != NULL) 349 fclose(remote); 350 351 return fd; 352 } 353 354 static struct fingerprint * 355 parse_fingerprint(ucl_object_t *obj) 356 { 357 const ucl_object_t *cur; 358 ucl_object_iter_t it = NULL; 359 const char *function, *fp, *key; 360 struct fingerprint *f; 361 hash_t fct = HASH_UNKNOWN; 362 363 function = fp = NULL; 364 365 while ((cur = ucl_iterate_object(obj, &it, true))) { 366 key = ucl_object_key(cur); 367 if (cur->type != UCL_STRING) 368 continue; 369 if (strcasecmp(key, "function") == 0) { 370 function = ucl_object_tostring(cur); 371 continue; 372 } 373 if (strcasecmp(key, "fingerprint") == 0) { 374 fp = ucl_object_tostring(cur); 375 continue; 376 } 377 } 378 379 if (fp == NULL || function == NULL) 380 return (NULL); 381 382 if (strcasecmp(function, "sha256") == 0) 383 fct = HASH_SHA256; 384 385 if (fct == HASH_UNKNOWN) { 386 warnx("Unsupported hashing function: %s", function); 387 return (NULL); 388 } 389 390 f = calloc(1, sizeof(struct fingerprint)); 391 f->type = fct; 392 strlcpy(f->hash, fp, sizeof(f->hash)); 393 394 return (f); 395 } 396 397 static void 398 free_fingerprint_list(struct fingerprint_list* list) 399 { 400 struct fingerprint *fingerprint, *tmp; 401 402 STAILQ_FOREACH_SAFE(fingerprint, list, next, tmp) { 403 free(fingerprint->name); 404 free(fingerprint); 405 } 406 free(list); 407 } 408 409 static struct fingerprint * 410 load_fingerprint(const char *dir, const char *filename) 411 { 412 ucl_object_t *obj = NULL; 413 struct ucl_parser *p = NULL; 414 struct fingerprint *f; 415 char path[MAXPATHLEN]; 416 417 f = NULL; 418 419 snprintf(path, MAXPATHLEN, "%s/%s", dir, filename); 420 421 p = ucl_parser_new(0); 422 if (!ucl_parser_add_file(p, path)) { 423 warnx("%s: %s", path, ucl_parser_get_error(p)); 424 ucl_parser_free(p); 425 return (NULL); 426 } 427 428 obj = ucl_parser_get_object(p); 429 430 if (obj->type == UCL_OBJECT) 431 f = parse_fingerprint(obj); 432 433 if (f != NULL) 434 f->name = strdup(filename); 435 436 ucl_object_unref(obj); 437 ucl_parser_free(p); 438 439 return (f); 440 } 441 442 static struct fingerprint_list * 443 load_fingerprints(const char *path, int *count) 444 { 445 DIR *d; 446 struct dirent *ent; 447 struct fingerprint *finger; 448 struct fingerprint_list *fingerprints; 449 450 *count = 0; 451 452 fingerprints = calloc(1, sizeof(struct fingerprint_list)); 453 if (fingerprints == NULL) 454 return (NULL); 455 STAILQ_INIT(fingerprints); 456 457 if ((d = opendir(path)) == NULL) { 458 free(fingerprints); 459 460 return (NULL); 461 } 462 463 while ((ent = readdir(d))) { 464 if (strcmp(ent->d_name, ".") == 0 || 465 strcmp(ent->d_name, "..") == 0) 466 continue; 467 finger = load_fingerprint(path, ent->d_name); 468 if (finger != NULL) { 469 STAILQ_INSERT_TAIL(fingerprints, finger, next); 470 ++(*count); 471 } 472 } 473 474 closedir(d); 475 476 return (fingerprints); 477 } 478 479 char * 480 pkg_read_fd(int fd, size_t *osz) 481 { 482 char *obuf; 483 char buf[4096]; 484 FILE *fp; 485 ssize_t r; 486 487 obuf = NULL; 488 *osz = 0; 489 fp = open_memstream(&obuf, osz); 490 if (fp == NULL) 491 err(EXIT_FAILURE, "open_memstream()"); 492 493 while ((r = read(fd, buf, sizeof(buf))) >0) { 494 fwrite(buf, 1, r, fp); 495 } 496 497 if (ferror(fp)) 498 errx(EXIT_FAILURE, "reading file"); 499 500 fclose(fp); 501 502 return (obuf); 503 } 504 505 /* 506 * Returns a copy of the signature type stored on the heap, and advances *bufp 507 * past the type. 508 */ 509 static char * 510 parse_sigtype(char **bufp, size_t *bufszp) 511 { 512 char *buf = *bufp; 513 char *endp; 514 char *sigtype; 515 size_t bufsz = *bufszp; 516 517 if (bufsz <= sizeof(PKGSIGN_MARKER) - 1 || 518 strncmp(buf, PKGSIGN_MARKER, sizeof(PKGSIGN_MARKER) - 1) != 0) 519 goto dflt; 520 521 buf += sizeof(PKGSIGN_MARKER) - 1; 522 endp = strchr(buf, '$'); 523 if (endp == NULL) 524 goto dflt; 525 526 sigtype = strndup(buf, endp - buf); 527 *bufp = endp + 1; 528 *bufszp -= *bufp - buf; 529 530 return (sigtype); 531 dflt: 532 return (strdup("rsa")); 533 } 534 535 static struct pubkey * 536 read_pubkey(int fd) 537 { 538 struct pubkey *pk; 539 char *osigb, *sigb, *sigtype; 540 size_t sigsz; 541 542 if (lseek(fd, 0, 0) == -1) { 543 warn("lseek"); 544 return (NULL); 545 } 546 547 osigb = sigb = pkg_read_fd(fd, &sigsz); 548 sigtype = parse_sigtype(&sigb, &sigsz); 549 550 pk = calloc(1, sizeof(struct pubkey)); 551 pk->siglen = sigsz; 552 pk->sig = calloc(1, pk->siglen); 553 memcpy(pk->sig, sigb, pk->siglen); 554 pk->sigtype = sigtype; 555 free(osigb); 556 557 return (pk); 558 } 559 560 static struct sig_cert * 561 parse_cert(int fd) { 562 int my_fd; 563 struct sig_cert *sc; 564 FILE *fp, *sigfp, *certfp, *tmpfp, *typefp; 565 char *line; 566 char *sig, *cert, *type; 567 size_t linecap, sigsz, certsz, typesz; 568 ssize_t linelen; 569 bool end_seen; 570 571 sc = NULL; 572 line = NULL; 573 linecap = 0; 574 sig = cert = type = NULL; 575 sigfp = certfp = tmpfp = typefp = NULL; 576 577 if (lseek(fd, 0, 0) == -1) { 578 warn("lseek"); 579 return (NULL); 580 } 581 582 /* Duplicate the fd so that fclose(3) does not close it. */ 583 if ((my_fd = dup(fd)) == -1) { 584 warnx("dup"); 585 return (NULL); 586 } 587 588 if ((fp = fdopen(my_fd, "rb")) == NULL) { 589 warn("fdopen"); 590 close(my_fd); 591 return (NULL); 592 } 593 594 sigsz = certsz = typesz = 0; 595 sigfp = open_memstream(&sig, &sigsz); 596 if (sigfp == NULL) 597 err(EXIT_FAILURE, "open_memstream()"); 598 certfp = open_memstream(&cert, &certsz); 599 if (certfp == NULL) 600 err(EXIT_FAILURE, "open_memstream()"); 601 typefp = open_memstream(&type, &typesz); 602 if (typefp == NULL) 603 err(EXIT_FAILURE, "open_memstream()"); 604 605 end_seen = false; 606 while ((linelen = getline(&line, &linecap, fp)) > 0) { 607 if (strcmp(line, "SIGNATURE\n") == 0) { 608 tmpfp = sigfp; 609 continue; 610 } else if (strcmp(line, "TYPE\n") == 0) { 611 tmpfp = typefp; 612 continue; 613 } else if (strcmp(line, "CERT\n") == 0) { 614 tmpfp = certfp; 615 continue; 616 } else if (strcmp(line, "END\n") == 0) { 617 end_seen = true; 618 break; 619 } 620 if (tmpfp != NULL) 621 fwrite(line, 1, linelen, tmpfp); 622 } 623 624 fclose(fp); 625 fclose(sigfp); 626 fclose(certfp); 627 fclose(typefp); 628 629 sc = calloc(1, sizeof(struct sig_cert)); 630 sc->siglen = sigsz -1; /* Trim out unrelated trailing newline */ 631 sc->sig = sig; 632 633 if (typesz == 0) { 634 sc->type = strdup("rsa"); 635 free(type); 636 } else { 637 assert(type[typesz - 1] == '\n'); 638 type[typesz - 1] = '\0'; 639 sc->type = type; 640 } 641 642 /* 643 * cert could be DER-encoded rather than PEM, so strip off any trailing 644 * END marker if we ran over it. 645 */ 646 if (!end_seen && certsz > 4 && 647 strcmp(&cert[certsz - 4], "END\n") == 0) 648 certsz -= 4; 649 sc->certlen = certsz; 650 sc->cert = cert; 651 652 return (sc); 653 } 654 655 static bool 656 verify_pubsignature(int fd_pkg, int fd_sig) 657 { 658 struct pubkey *pk; 659 const char *pubkey; 660 char *data; 661 struct pkgsign_ctx *sctx; 662 size_t datasz; 663 bool ret; 664 665 pk = NULL; 666 pubkey = NULL; 667 sctx = NULL; 668 data = NULL; 669 ret = false; 670 if (config_string(PUBKEY, &pubkey) != 0) { 671 warnx("No CONFIG_PUBKEY defined"); 672 goto cleanup; 673 } 674 675 if ((pk = read_pubkey(fd_sig)) == NULL) { 676 warnx("Error reading signature"); 677 goto cleanup; 678 } 679 680 if (lseek(fd_pkg, 0, SEEK_SET) == -1) { 681 warn("lseek"); 682 goto cleanup; 683 } 684 685 if (strcmp(pk->sigtype, "rsa") == 0) { 686 /* Future types shouldn't do this. */ 687 if ((data = sha256_fd(fd_pkg)) == NULL) { 688 warnx("Error creating SHA256 hash for package"); 689 goto cleanup; 690 } 691 692 datasz = strlen(data); 693 } else { 694 if ((data = pkg_read_fd(fd_pkg, &datasz)) == NULL) { 695 warnx("Failed to read package data"); 696 goto cleanup; 697 } 698 } 699 700 if (pkgsign_new(pk->sigtype, &sctx) != 0) { 701 warnx("Failed to fetch '%s' signer", pk->sigtype); 702 goto cleanup; 703 } 704 705 /* Verify the signature. */ 706 printf("Verifying signature with public key %s... ", pubkey); 707 if (pkgsign_verify_data(sctx, data, datasz, pubkey, NULL, 0, pk->sig, 708 pk->siglen) == false) { 709 fprintf(stderr, "Signature is not valid\n"); 710 goto cleanup; 711 } 712 713 ret = true; 714 715 cleanup: 716 free(data); 717 if (pk) { 718 free(pk->sig); 719 free(pk); 720 } 721 722 return (ret); 723 } 724 725 static bool 726 verify_signature(int fd_pkg, int fd_sig) 727 { 728 struct fingerprint_list *trusted, *revoked; 729 struct fingerprint *fingerprint; 730 struct sig_cert *sc; 731 struct pkgsign_ctx *sctx; 732 bool ret; 733 int trusted_count, revoked_count; 734 const char *fingerprints; 735 char path[MAXPATHLEN]; 736 char *hash; 737 738 hash = NULL; 739 sc = NULL; 740 sctx = NULL; 741 trusted = revoked = NULL; 742 ret = false; 743 744 /* Read and parse fingerprints. */ 745 if (config_string(FINGERPRINTS, &fingerprints) != 0) { 746 warnx("No CONFIG_FINGERPRINTS defined"); 747 goto cleanup; 748 } 749 750 snprintf(path, MAXPATHLEN, "%s/trusted", fingerprints); 751 if ((trusted = load_fingerprints(path, &trusted_count)) == NULL) { 752 warnx("Error loading trusted certificates"); 753 goto cleanup; 754 } 755 756 if (trusted_count == 0 || trusted == NULL) { 757 fprintf(stderr, "No trusted certificates found.\n"); 758 goto cleanup; 759 } 760 761 snprintf(path, MAXPATHLEN, "%s/revoked", fingerprints); 762 if ((revoked = load_fingerprints(path, &revoked_count)) == NULL) { 763 warnx("Error loading revoked certificates"); 764 goto cleanup; 765 } 766 767 /* Read certificate and signature in. */ 768 if ((sc = parse_cert(fd_sig)) == NULL) { 769 warnx("Error parsing certificate"); 770 goto cleanup; 771 } 772 /* Explicitly mark as non-trusted until proven otherwise. */ 773 sc->trusted = false; 774 775 /* Parse signature and pubkey out of the certificate */ 776 hash = sha256_buf(sc->cert, sc->certlen); 777 778 /* Check if this hash is revoked */ 779 if (revoked != NULL) { 780 STAILQ_FOREACH(fingerprint, revoked, next) { 781 if (strcasecmp(fingerprint->hash, hash) == 0) { 782 fprintf(stderr, "The package was signed with " 783 "revoked certificate %s\n", 784 fingerprint->name); 785 goto cleanup; 786 } 787 } 788 } 789 790 STAILQ_FOREACH(fingerprint, trusted, next) { 791 if (strcasecmp(fingerprint->hash, hash) == 0) { 792 sc->trusted = true; 793 sc->name = strdup(fingerprint->name); 794 break; 795 } 796 } 797 798 if (sc->trusted == false) { 799 fprintf(stderr, "No trusted fingerprint found matching " 800 "package's certificate\n"); 801 goto cleanup; 802 } 803 804 if (pkgsign_new(sc->type, &sctx) != 0) { 805 fprintf(stderr, "Failed to fetch 'rsa' signer\n"); 806 goto cleanup; 807 } 808 809 /* Verify the signature. */ 810 printf("Verifying signature with trusted certificate %s... ", sc->name); 811 if (pkgsign_verify_cert(sctx, fd_pkg, NULL, sc->cert, sc->certlen, 812 sc->sig, sc->siglen) == false) { 813 fprintf(stderr, "Signature is not valid\n"); 814 goto cleanup; 815 } 816 817 ret = true; 818 819 cleanup: 820 free(hash); 821 if (trusted) 822 free_fingerprint_list(trusted); 823 if (revoked) 824 free_fingerprint_list(revoked); 825 if (sc) { 826 free(sc->cert); 827 free(sc->sig); 828 free(sc->name); 829 free(sc); 830 } 831 832 return (ret); 833 } 834 835 static int 836 bootstrap_pkg(bool force, const char *fetchOpts) 837 { 838 int fd_pkg, fd_sig; 839 int ret; 840 char url[MAXPATHLEN]; 841 char tmppkg[MAXPATHLEN]; 842 char tmpsig[MAXPATHLEN]; 843 const char *packagesite; 844 const char *signature_type; 845 char pkgstatic[MAXPATHLEN]; 846 const char *bootstrap_name; 847 848 fd_sig = -1; 849 ret = -1; 850 851 if (config_string(PACKAGESITE, &packagesite) != 0) { 852 warnx("No PACKAGESITE defined"); 853 return (-1); 854 } 855 856 if (config_string(SIGNATURE_TYPE, &signature_type) != 0) { 857 warnx("Error looking up SIGNATURE_TYPE"); 858 return (-1); 859 } 860 861 printf("Bootstrapping pkg from %s, please wait...\n", packagesite); 862 863 /* Support pkg+http:// for PACKAGESITE which is the new format 864 in 1.2 to avoid confusion on why http://pkg.FreeBSD.org has 865 no A record. */ 866 if (strncmp(URL_SCHEME_PREFIX, packagesite, 867 strlen(URL_SCHEME_PREFIX)) == 0) 868 packagesite += strlen(URL_SCHEME_PREFIX); 869 for (int j = 0; bootstrap_names[j] != NULL; j++) { 870 bootstrap_name = bootstrap_names[j]; 871 872 snprintf(url, MAXPATHLEN, "%s/Latest/%s", packagesite, bootstrap_name); 873 snprintf(tmppkg, MAXPATHLEN, "%s/%s.XXXXXX", 874 getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP, 875 bootstrap_name); 876 if ((fd_pkg = fetch_to_fd(url, tmppkg, fetchOpts)) != -1) 877 break; 878 bootstrap_name = NULL; 879 } 880 if (bootstrap_name == NULL) 881 goto fetchfail; 882 883 if (signature_type != NULL && 884 strcasecmp(signature_type, "NONE") != 0) { 885 if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { 886 887 snprintf(tmpsig, MAXPATHLEN, "%s/%s.sig.XXXXXX", 888 getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP, 889 bootstrap_name); 890 snprintf(url, MAXPATHLEN, "%s/Latest/%s.sig", 891 packagesite, bootstrap_name); 892 893 if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) { 894 fprintf(stderr, "Signature for pkg not " 895 "available.\n"); 896 goto fetchfail; 897 } 898 899 if (verify_signature(fd_pkg, fd_sig) == false) 900 goto cleanup; 901 } else if (strcasecmp(signature_type, "PUBKEY") == 0) { 902 903 snprintf(tmpsig, MAXPATHLEN, 904 "%s/%s.pubkeysig.XXXXXX", 905 getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP, 906 bootstrap_name); 907 snprintf(url, MAXPATHLEN, "%s/Latest/%s.pubkeysig", 908 packagesite, bootstrap_name); 909 910 if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) { 911 fprintf(stderr, "Signature for pkg not " 912 "available.\n"); 913 goto fetchfail; 914 } 915 916 if (verify_pubsignature(fd_pkg, fd_sig) == false) 917 goto cleanup; 918 } else { 919 warnx("Signature type %s is not supported for " 920 "bootstrapping.", signature_type); 921 goto cleanup; 922 } 923 } 924 925 if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) 926 ret = install_pkg_static(pkgstatic, tmppkg, force); 927 928 goto cleanup; 929 930 fetchfail: 931 for (int j = 0; bootstrap_names[j] != NULL; j++) { 932 warnx("Attempted to fetch %s/Latest/%s", packagesite, 933 bootstrap_names[j]); 934 } 935 warnx("Error: %s", fetchLastErrString); 936 if (fetchLastErrCode == FETCH_RESOLV) { 937 fprintf(stderr, "Address resolution failed for %s.\n", packagesite); 938 fprintf(stderr, "Consider changing PACKAGESITE.\n"); 939 } else { 940 fprintf(stderr, "A pre-built version of pkg could not be found for " 941 "your system.\n"); 942 fprintf(stderr, "Consider changing PACKAGESITE or installing it from " 943 "ports: 'ports-mgmt/pkg'.\n"); 944 } 945 946 cleanup: 947 if (fd_sig != -1) { 948 close(fd_sig); 949 unlink(tmpsig); 950 } 951 952 if (fd_pkg != -1) { 953 close(fd_pkg); 954 unlink(tmppkg); 955 } 956 957 return (ret); 958 } 959 960 static const char confirmation_message[] = 961 "The package management tool is not yet installed on your system.\n" 962 "Do you want to fetch and install it now? [y/N]: "; 963 964 static const char non_interactive_message[] = 965 "The package management tool is not yet installed on your system.\n" 966 "Please set ASSUME_ALWAYS_YES=yes environment variable to be able to bootstrap " 967 "in non-interactive (stdin not being a tty)\n"; 968 969 static const char args_bootstrap_message[] = 970 "Too many arguments\n" 971 "Usage: pkg [-4|-6] bootstrap [-f] [-y]\n"; 972 973 static const char args_add_message[] = 974 "Too many arguments\n" 975 "Usage: pkg add [-f] [-y] {pkg.pkg}\n"; 976 977 static int 978 pkg_query_yes_no(void) 979 { 980 int ret, c; 981 982 fflush(stdout); 983 c = getchar(); 984 985 if (c == 'y' || c == 'Y') 986 ret = 1; 987 else 988 ret = 0; 989 990 while (c != '\n' && c != EOF) 991 c = getchar(); 992 993 return (ret); 994 } 995 996 static int 997 bootstrap_pkg_local(const char *pkgpath, bool force) 998 { 999 char path[MAXPATHLEN]; 1000 char pkgstatic[MAXPATHLEN]; 1001 const char *signature_type; 1002 int fd_pkg, fd_sig, ret; 1003 1004 fd_sig = -1; 1005 ret = -1; 1006 1007 fd_pkg = open(pkgpath, O_RDONLY); 1008 if (fd_pkg == -1) 1009 err(EXIT_FAILURE, "Unable to open %s", pkgpath); 1010 1011 if (config_string(SIGNATURE_TYPE, &signature_type) != 0) { 1012 warnx("Error looking up SIGNATURE_TYPE"); 1013 goto cleanup; 1014 } 1015 if (signature_type != NULL && 1016 strcasecmp(signature_type, "NONE") != 0) { 1017 if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { 1018 1019 snprintf(path, sizeof(path), "%s.sig", pkgpath); 1020 1021 if ((fd_sig = open(path, O_RDONLY)) == -1) { 1022 fprintf(stderr, "Signature for pkg not " 1023 "available.\n"); 1024 goto cleanup; 1025 } 1026 1027 if (verify_signature(fd_pkg, fd_sig) == false) 1028 goto cleanup; 1029 1030 } else if (strcasecmp(signature_type, "PUBKEY") == 0) { 1031 1032 snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath); 1033 1034 if ((fd_sig = open(path, O_RDONLY)) == -1) { 1035 fprintf(stderr, "Signature for pkg not " 1036 "available.\n"); 1037 goto cleanup; 1038 } 1039 1040 if (verify_pubsignature(fd_pkg, fd_sig) == false) 1041 goto cleanup; 1042 1043 } else { 1044 warnx("Signature type %s is not supported for " 1045 "bootstrapping.", signature_type); 1046 goto cleanup; 1047 } 1048 } 1049 1050 if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) 1051 ret = install_pkg_static(pkgstatic, pkgpath, force); 1052 1053 cleanup: 1054 close(fd_pkg); 1055 if (fd_sig != -1) 1056 close(fd_sig); 1057 1058 return (ret); 1059 } 1060 1061 #define PKG_NAME "pkg" 1062 #define PKG_DEVEL_NAME PKG_NAME "-devel" 1063 #define PKG_PKG PKG_NAME "." 1064 1065 static bool 1066 pkg_is_pkg_pkg(const char *pkg) 1067 { 1068 char *vstart, *basename; 1069 size_t namelen; 1070 1071 /* Strip path. */ 1072 if ((basename = strrchr(pkg, '/')) != NULL) 1073 pkg = basename + 1; 1074 1075 /* 1076 * Chop off the final "-" (version delimiter) and check the name that 1077 * precedes it. If we didn't have a version delimiter, it must be the 1078 * pkg.$archive short form but we'll check it anyways. pkg-devel short 1079 * form will look like a pkg archive with 'devel' version, but that's 1080 * OK. We otherwise assumed that non-pkg packages will always have a 1081 * version component. 1082 */ 1083 vstart = strrchr(pkg, '-'); 1084 if (vstart == NULL) { 1085 return (strlen(pkg) > sizeof(PKG_PKG) - 1 && 1086 strncmp(pkg, PKG_PKG, sizeof(PKG_PKG) - 1) == 0); 1087 } 1088 1089 namelen = vstart - pkg; 1090 if (namelen == sizeof(PKG_NAME) - 1 && 1091 strncmp(pkg, PKG_NAME, sizeof(PKG_NAME) - 1) == 0) 1092 return (true); 1093 if (namelen == sizeof(PKG_DEVEL_NAME) - 1 && 1094 strncmp(pkg, PKG_DEVEL_NAME, sizeof(PKG_DEVEL_NAME) - 1) == 0) 1095 return (true); 1096 return (false); 1097 } 1098 1099 int 1100 main(int argc, char *argv[]) 1101 { 1102 char pkgpath[MAXPATHLEN]; 1103 const char *pkgarg, *repo_name; 1104 bool activation_test, add_pkg, bootstrap_only, force, yes; 1105 signed char ch; 1106 const char *fetchOpts; 1107 char *command; 1108 1109 activation_test = false; 1110 add_pkg = false; 1111 bootstrap_only = false; 1112 command = NULL; 1113 fetchOpts = ""; 1114 force = false; 1115 pkgarg = NULL; 1116 repo_name = NULL; 1117 yes = false; 1118 1119 struct option longopts[] = { 1120 { "debug", no_argument, NULL, 'd' }, 1121 { "force", no_argument, NULL, 'f' }, 1122 { "only-ipv4", no_argument, NULL, '4' }, 1123 { "only-ipv6", no_argument, NULL, '6' }, 1124 { "yes", no_argument, NULL, 'y' }, 1125 { NULL, 0, NULL, 0 }, 1126 }; 1127 1128 snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", getlocalbase()); 1129 1130 while ((ch = getopt_long(argc, argv, "-:dfr::yN46", longopts, NULL)) != -1) { 1131 switch (ch) { 1132 case 'd': 1133 debug++; 1134 break; 1135 case 'f': 1136 force = true; 1137 break; 1138 case 'N': 1139 activation_test = true; 1140 break; 1141 case 'y': 1142 yes = true; 1143 break; 1144 case '4': 1145 fetchOpts = "4"; 1146 break; 1147 case '6': 1148 fetchOpts = "6"; 1149 break; 1150 case 'r': 1151 /* 1152 * The repository can only be specified for an explicit 1153 * bootstrap request at this time, so that we don't 1154 * confuse the user if they're trying to use a verb that 1155 * has some other conflicting meaning but we need to 1156 * bootstrap. 1157 * 1158 * For that reason, we specify that -r has an optional 1159 * argument above and process the next index ourselves. 1160 * This is mostly significant because getopt(3) will 1161 * otherwise eat the next argument, which could be 1162 * something we need to try and make sense of. 1163 * 1164 * At worst this gets us false positives that we ignore 1165 * in other contexts, and we have to do a little fudging 1166 * in order to support separating -r from the reponame 1167 * with a space since it's not actually optional in 1168 * the bootstrap/add sense. 1169 */ 1170 if (add_pkg || bootstrap_only) { 1171 if (optarg != NULL) { 1172 repo_name = optarg; 1173 } else if (optind < argc) { 1174 repo_name = argv[optind]; 1175 } 1176 1177 if (repo_name == NULL || *repo_name == '\0') { 1178 fprintf(stderr, 1179 "Must specify a repository with -r!\n"); 1180 exit(EXIT_FAILURE); 1181 } 1182 1183 if (optarg == NULL) { 1184 /* Advance past repo name. */ 1185 optreset = 1; 1186 optind++; 1187 } 1188 } 1189 break; 1190 case 1: 1191 // Non-option arguments, first one is the command 1192 if (command == NULL) { 1193 command = argv[optind-1]; 1194 if (strcmp(command, "add") == 0) { 1195 add_pkg = true; 1196 } 1197 else if (strcmp(command, "bootstrap") == 0) { 1198 bootstrap_only = true; 1199 } 1200 } 1201 // bootstrap doesn't accept other arguments 1202 else if (bootstrap_only) { 1203 fprintf(stderr, args_bootstrap_message); 1204 exit(EXIT_FAILURE); 1205 } 1206 else if (add_pkg && pkgarg != NULL) { 1207 /* 1208 * Additional arguments also means it's not a 1209 * local bootstrap request. 1210 */ 1211 add_pkg = false; 1212 } 1213 else if (add_pkg) { 1214 /* 1215 * If it's not a request for pkg or pkg-devel, 1216 * then we must assume they were trying to 1217 * install some other local package and we 1218 * should try to bootstrap from the repo. 1219 */ 1220 if (!pkg_is_pkg_pkg(argv[optind-1])) { 1221 add_pkg = false; 1222 } else { 1223 pkgarg = argv[optind-1]; 1224 } 1225 } 1226 break; 1227 default: 1228 break; 1229 } 1230 } 1231 if (debug > 1) 1232 fetchDebug = 1; 1233 1234 if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) { 1235 /* 1236 * To allow 'pkg -N' to be used as a reliable test for whether 1237 * a system is configured to use pkg, don't bootstrap pkg 1238 * when that option is passed. 1239 */ 1240 if (activation_test) 1241 errx(EXIT_FAILURE, "pkg is not installed"); 1242 1243 config_init(repo_name); 1244 1245 if (add_pkg) { 1246 if (pkgarg == NULL) { 1247 fprintf(stderr, "Path to pkg.pkg required\n"); 1248 exit(EXIT_FAILURE); 1249 } 1250 if (access(pkgarg, R_OK) == -1) { 1251 fprintf(stderr, "No such file: %s\n", pkgarg); 1252 exit(EXIT_FAILURE); 1253 } 1254 if (bootstrap_pkg_local(pkgarg, force) != 0) 1255 exit(EXIT_FAILURE); 1256 exit(EXIT_SUCCESS); 1257 } 1258 /* 1259 * Do not ask for confirmation if either of stdin or stdout is 1260 * not tty. Check the environment to see if user has answer 1261 * tucked in there already. 1262 */ 1263 if (!yes) 1264 config_bool(ASSUME_ALWAYS_YES, &yes); 1265 if (!yes) { 1266 if (!isatty(fileno(stdin))) { 1267 fprintf(stderr, non_interactive_message); 1268 exit(EXIT_FAILURE); 1269 } 1270 1271 printf("%s", confirmation_message); 1272 if (pkg_query_yes_no() == 0) 1273 exit(EXIT_FAILURE); 1274 } 1275 if (bootstrap_pkg(force, fetchOpts) != 0) 1276 exit(EXIT_FAILURE); 1277 config_finish(); 1278 1279 if (bootstrap_only) 1280 exit(EXIT_SUCCESS); 1281 } else if (bootstrap_only) { 1282 printf("pkg already bootstrapped at %s\n", pkgpath); 1283 exit(EXIT_SUCCESS); 1284 } 1285 1286 execv(pkgpath, argv); 1287 1288 /* NOT REACHED */ 1289 return (EXIT_FAILURE); 1290 } 1291