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