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