1/*- 2 * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org> 3 * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD$"); 30 31#include <sys/param.h> 32#include <sys/queue.h> 33#include <sys/types.h> 34#include <sys/sbuf.h> 35#include <sys/wait.h> 36 37#define _WITH_GETLINE 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 <paths.h> 46#include <stdbool.h> 47#include <stdlib.h> 48#include <stdio.h> 49#include <string.h> 50#include <unistd.h> 51#include <ucl.h> 52 53#include <openssl/err.h> 54#include <openssl/ssl.h> 55 56#include "dns_utils.h" 57#include "config.h" 58 59struct sig_cert { 60 char *name; 61 unsigned char *sig; 62 int siglen; 63 unsigned char *cert; 64 int certlen; 65 bool trusted; 66}; 67 68struct pubkey { 69 unsigned char *sig; 70 int siglen; 71}; 72 73typedef enum { 74 HASH_UNKNOWN, 75 HASH_SHA256, 76} hash_t; 77 78struct fingerprint { 79 hash_t type; 80 char *name; 81 char hash[BUFSIZ]; 82 STAILQ_ENTRY(fingerprint) next; 83}; 84 85STAILQ_HEAD(fingerprint_list, fingerprint); 86 87static int 88extract_pkg_static(int fd, char *p, int sz) 89{ 90 struct archive *a; 91 struct archive_entry *ae; 92 char *end; 93 int ret, r; 94 95 ret = -1; 96 a = archive_read_new(); 97 if (a == NULL) { 98 warn("archive_read_new"); 99 return (ret); 100 } 101 archive_read_support_compression_all(a); 102 archive_read_support_format_tar(a); 103 104 if (lseek(fd, 0, 0) == -1) { 105 warn("lseek"); 106 goto cleanup; 107 } 108 109 if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) { 110 warnx("archive_read_open_fd: %s", archive_error_string(a)); 111 goto cleanup; 112 } 113 114 ae = NULL; 115 while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) { 116 end = strrchr(archive_entry_pathname(ae), '/'); 117 if (end == NULL) 118 continue; 119 120 if (strcmp(end, "/pkg-static") == 0) { 121 r = archive_read_extract(a, ae, 122 ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | 123 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL | 124 ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR); 125 strlcpy(p, archive_entry_pathname(ae), sz); 126 break; 127 } 128 } 129 130 if (r == ARCHIVE_OK) 131 ret = 0; 132 else 133 warnx("fail to extract pkg-static"); 134 135cleanup: 136 archive_read_free(a); 137 return (ret); 138 139} 140 141static int 142install_pkg_static(const char *path, const char *pkgpath, bool force) 143{ 144 int pstat; 145 pid_t pid; 146 147 switch ((pid = fork())) { 148 case -1: 149 return (-1); 150 case 0: 151 if (force) 152 execl(path, "pkg-static", "add", "-f", pkgpath, 153 (char *)NULL); 154 else 155 execl(path, "pkg-static", "add", pkgpath, 156 (char *)NULL); 157 _exit(1); 158 default: 159 break; 160 } 161 162 while (waitpid(pid, &pstat, 0) == -1) 163 if (errno != EINTR) 164 return (-1); 165 166 if (WEXITSTATUS(pstat)) 167 return (WEXITSTATUS(pstat)); 168 else if (WIFSIGNALED(pstat)) 169 return (128 & (WTERMSIG(pstat))); 170 return (pstat); 171} 172 173static int 174fetch_to_fd(const char *url, char *path) 175{ 176 struct url *u; 177 struct dns_srvinfo *mirrors, *current; 178 struct url_stat st; 179 FILE *remote; 180 /* To store _https._tcp. + hostname + \0 */ 181 int fd; 182 int retry, max_retry; 183 ssize_t r; 184 char buf[10240]; 185 char zone[MAXHOSTNAMELEN + 13]; 186 static const char *mirror_type = NULL; 187 188 max_retry = 3; 189 current = mirrors = NULL; 190 remote = NULL; 191 192 if (mirror_type == NULL && config_string(MIRROR_TYPE, &mirror_type) 193 != 0) { 194 warnx("No MIRROR_TYPE defined"); 195 return (-1); 196 } 197 198 if ((fd = mkstemp(path)) == -1) { 199 warn("mkstemp()"); 200 return (-1); 201 } 202 203 retry = max_retry; 204 205 u = fetchParseURL(url); 206 while (remote == NULL) { 207 if (retry == max_retry) { 208 if (strcmp(u->scheme, "file") != 0 && 209 strcasecmp(mirror_type, "srv") == 0) { 210 snprintf(zone, sizeof(zone), 211 "_%s._tcp.%s", u->scheme, u->host); 212 mirrors = dns_getsrvinfo(zone); 213 current = mirrors; 214 } 215 } 216 217 if (mirrors != NULL) { 218 strlcpy(u->host, current->host, sizeof(u->host)); 219 u->port = current->port; 220 } 221 222 remote = fetchXGet(u, &st, ""); 223 if (remote == NULL) { 224 --retry; 225 if (retry <= 0) 226 goto fetchfail; 227 if (mirrors == NULL) { 228 sleep(1); 229 } else { 230 current = current->next; 231 if (current == NULL) 232 current = mirrors; 233 } 234 } 235 } 236 237 while ((r = fread(buf, 1, sizeof(buf), remote)) > 0) { 238 if (write(fd, buf, r) != r) { 239 warn("write()"); 240 goto fetchfail; 241 } 242 } 243 244 if (r != 0) { 245 warn("An error occurred while fetching pkg(8)"); 246 goto fetchfail; 247 } 248 249 if (ferror(remote)) 250 goto fetchfail; 251 252 goto cleanup; 253 254fetchfail: 255 if (fd != -1) { 256 close(fd); 257 fd = -1; 258 unlink(path); 259 } 260 261cleanup: 262 if (remote != NULL) 263 fclose(remote); 264 265 return fd; 266} 267 268static struct fingerprint * 269parse_fingerprint(ucl_object_t *obj) 270{ 271 ucl_object_t *cur; 272 ucl_object_iter_t it = NULL; 273 const char *function, *fp, *key; 274 struct fingerprint *f; 275 hash_t fct = HASH_UNKNOWN; 276 277 function = fp = NULL; 278 279 while ((cur = ucl_iterate_object(obj, &it, true))) { 280 key = ucl_object_key(cur); 281 if (cur->type != UCL_STRING) 282 continue; 283 if (strcasecmp(key, "function") == 0) { 284 function = ucl_object_tostring(cur); 285 continue; 286 } 287 if (strcasecmp(key, "fingerprint") == 0) { 288 fp = ucl_object_tostring(cur); 289 continue; 290 } 291 } 292 293 if (fp == NULL || function == NULL) 294 return (NULL); 295 296 if (strcasecmp(function, "sha256") == 0) 297 fct = HASH_SHA256; 298 299 if (fct == HASH_UNKNOWN) { 300 warnx("Unsupported hashing function: %s", function); 301 return (NULL); 302 } 303 304 f = calloc(1, sizeof(struct fingerprint)); 305 f->type = fct; 306 strlcpy(f->hash, fp, sizeof(f->hash)); 307 308 return (f); 309} 310 311static void 312free_fingerprint_list(struct fingerprint_list* list) 313{ 314 struct fingerprint *fingerprint, *tmp; 315 316 STAILQ_FOREACH_SAFE(fingerprint, list, next, tmp) { 317 free(fingerprint->name); 318 free(fingerprint); 319 } 320 free(list); 321} 322 323static struct fingerprint * 324load_fingerprint(const char *dir, const char *filename) 325{ 326 ucl_object_t *obj = NULL; 327 struct ucl_parser *p = NULL; 328 struct fingerprint *f; 329 char path[MAXPATHLEN]; 330 331 f = NULL; 332 333 snprintf(path, MAXPATHLEN, "%s/%s", dir, filename); 334 335 p = ucl_parser_new(0); 336 if (!ucl_parser_add_file(p, path)) { 337 warnx("%s: %s", path, ucl_parser_get_error(p)); 338 ucl_parser_free(p); 339 return (NULL); 340 } 341 342 obj = ucl_parser_get_object(p); 343 344 if (obj->type == UCL_OBJECT) 345 f = parse_fingerprint(obj); 346 347 if (f != NULL) 348 f->name = strdup(filename); 349 350 ucl_object_free(obj); 351 ucl_parser_free(p); 352 353 return (f); 354} 355 356static struct fingerprint_list * 357load_fingerprints(const char *path, int *count) 358{ 359 DIR *d; 360 struct dirent *ent; 361 struct fingerprint *finger; 362 struct fingerprint_list *fingerprints; 363 364 *count = 0; 365 366 fingerprints = calloc(1, sizeof(struct fingerprint_list)); 367 if (fingerprints == NULL) 368 return (NULL); 369 STAILQ_INIT(fingerprints); 370 371 if ((d = opendir(path)) == NULL) 372 return (NULL); 373 374 while ((ent = readdir(d))) { 375 if (strcmp(ent->d_name, ".") == 0 || 376 strcmp(ent->d_name, "..") == 0) 377 continue; 378 finger = load_fingerprint(path, ent->d_name); 379 if (finger != NULL) { 380 STAILQ_INSERT_TAIL(fingerprints, finger, next); 381 ++(*count); 382 } 383 } 384 385 closedir(d); 386 387 return (fingerprints); 388} 389 390static void 391sha256_hash(unsigned char hash[SHA256_DIGEST_LENGTH], 392 char out[SHA256_DIGEST_LENGTH * 2 + 1]) 393{ 394 int i; 395 396 for (i = 0; i < SHA256_DIGEST_LENGTH; i++) 397 sprintf(out + (i * 2), "%02x", hash[i]); 398 399 out[SHA256_DIGEST_LENGTH * 2] = '\0'; 400} 401 402static void 403sha256_buf_bin(char *buf, size_t len, char hash[SHA256_DIGEST_LENGTH]) 404{ 405 SHA256_CTX sha256; 406 407 SHA256_Init(&sha256); 408 SHA256_Update(&sha256, buf, len); 409 SHA256_Final(hash, &sha256); 410} 411 412 413static void 414sha256_buf(char *buf, size_t len, char out[SHA256_DIGEST_LENGTH * 2 + 1]) 415{ 416 unsigned char hash[SHA256_DIGEST_LENGTH]; 417 SHA256_CTX sha256; 418 419 out[0] = '\0'; 420 421 SHA256_Init(&sha256); 422 SHA256_Update(&sha256, buf, len); 423 SHA256_Final(hash, &sha256); 424 sha256_hash(hash, out); 425} 426 427static int 428sha256_fd(int fd, char out[SHA256_DIGEST_LENGTH * 2 + 1]) 429{ 430 int my_fd; 431 FILE *fp; 432 char buffer[BUFSIZ]; 433 unsigned char hash[SHA256_DIGEST_LENGTH]; 434 size_t r; 435 int ret; 436 SHA256_CTX sha256; 437 438 my_fd = -1; 439 fp = NULL; 440 r = 0; 441 ret = 1; 442 443 out[0] = '\0'; 444 445 /* Duplicate the fd so that fclose(3) does not close it. */ 446 if ((my_fd = dup(fd)) == -1) { 447 warnx("dup"); 448 goto cleanup; 449 } 450 451 if ((fp = fdopen(my_fd, "rb")) == NULL) { 452 warnx("fdopen"); 453 goto cleanup; 454 } 455 456 SHA256_Init(&sha256); 457 458 while ((r = fread(buffer, 1, BUFSIZ, fp)) > 0) 459 SHA256_Update(&sha256, buffer, r); 460 461 if (ferror(fp) != 0) { 462 warnx("fread"); 463 goto cleanup; 464 } 465 466 SHA256_Final(hash, &sha256); 467 sha256_hash(hash, out); 468 ret = 0; 469 470cleanup: 471 if (fp != NULL) 472 fclose(fp); 473 else if (my_fd != -1) 474 close(my_fd); 475 (void)lseek(fd, 0, SEEK_SET); 476 477 return (ret); 478} 479 480static RSA * 481load_rsa_public_key_file(const char *file) 482{ 483 RSA *rsa = NULL; 484 BIO *bp; 485 char errbuf[1024]; 486 487 bp = BIO_new_file(file, "r"); 488 if (!bp) 489 errx(EXIT_FAILURE, "Unable to read %s", file); 490 491 if (!PEM_read_bio_RSA_PUBKEY(bp, &rsa, NULL, NULL)) { 492 warn("error reading public key: %s", 493 ERR_error_string(ERR_get_error(), errbuf)); 494 BIO_free(bp); 495 return (NULL); 496 } 497 498 BIO_free(bp); 499 500 return (rsa); 501} 502 503static RSA * 504load_rsa_public_key_buf(unsigned char *cert, int certlen) 505{ 506 RSA *rsa = NULL; 507 BIO *bp; 508 char errbuf[1024]; 509 510 bp = BIO_new_mem_buf((void *)cert, certlen); 511 if (!PEM_read_bio_RSA_PUBKEY(bp, &rsa, NULL, NULL)) { 512 warn("error reading public key: %s", 513 ERR_error_string(ERR_get_error(), errbuf)); 514 BIO_free(bp); 515 return (NULL); 516 } 517 BIO_free(bp); 518 return (rsa); 519} 520 521 522static bool 523rsa_verify_cert(int fd, const char *sigfile, unsigned char *key, 524 int keylen, unsigned char *sig, int siglen) 525{ 526 char sha256[SHA256_DIGEST_LENGTH *2 +1]; 527 char hash[SHA256_DIGEST_LENGTH]; 528 char errbuf[1024]; 529 RSA *rsa = NULL; 530 int ret; 531 532 lseek(fd, 0, SEEK_SET); 533 sha256_fd(fd, sha256); 534 535 SSL_load_error_strings(); 536 OpenSSL_add_all_algorithms(); 537 OpenSSL_add_all_ciphers(); 538 539 sha256_buf_bin(sha256, strlen(sha256), hash); 540 541 if (sigfile != NULL) { 542 rsa = load_rsa_public_key_file(sigfile); 543 } else { 544 rsa = load_rsa_public_key_buf(key, keylen); 545 } 546 if (rsa == NULL) 547 return (false); 548 ret = RSA_verify(NID_sha256, hash, sizeof(hash), sig, siglen, rsa); 549 if (ret == 0) { 550 warnx("%s: %s", key, ERR_error_string(ERR_get_error(), errbuf)); 551 return (false); 552 } 553 554 RSA_free(rsa); 555 ERR_free_strings(); 556 557 return (true); 558} 559 560static struct pubkey * 561read_pubkey(int fd) 562{ 563 struct pubkey *pk; 564 struct sbuf *sig; 565 char buf[4096]; 566 int r; 567 568 if (lseek(fd, 0, 0) == -1) { 569 warn("lseek"); 570 return (NULL); 571 } 572 573 sig = sbuf_new_auto(); 574 575 while ((r = read(fd, buf, sizeof(buf))) >0) { 576 sbuf_bcat(sig, buf, r); 577 } 578 579 sbuf_finish(sig); 580 pk = calloc(1, sizeof(struct pubkey)); 581 pk->siglen = sbuf_len(sig); 582 pk->sig = calloc(1, pk->siglen); 583 memcpy(pk->sig, sbuf_data(sig), pk->siglen); 584 sbuf_delete(sig); 585 586 return (pk); 587} 588 589static struct sig_cert * 590parse_cert(int fd) { 591 int my_fd; 592 struct sig_cert *sc; 593 FILE *fp; 594 struct sbuf *buf, *sig, *cert; 595 char *line; 596 size_t linecap; 597 ssize_t linelen; 598 599 buf = NULL; 600 my_fd = -1; 601 sc = NULL; 602 line = NULL; 603 linecap = 0; 604 605 if (lseek(fd, 0, 0) == -1) { 606 warn("lseek"); 607 return (NULL); 608 } 609 610 /* Duplicate the fd so that fclose(3) does not close it. */ 611 if ((my_fd = dup(fd)) == -1) { 612 warnx("dup"); 613 return (NULL); 614 } 615 616 if ((fp = fdopen(my_fd, "rb")) == NULL) { 617 warn("fdopen"); 618 close(my_fd); 619 return (NULL); 620 } 621 622 sig = sbuf_new_auto(); 623 cert = sbuf_new_auto(); 624 625 while ((linelen = getline(&line, &linecap, fp)) > 0) { 626 if (strcmp(line, "SIGNATURE\n") == 0) { 627 buf = sig; 628 continue; 629 } else if (strcmp(line, "CERT\n") == 0) { 630 buf = cert; 631 continue; 632 } else if (strcmp(line, "END\n") == 0) { 633 break; 634 } 635 if (buf != NULL) 636 sbuf_bcat(buf, line, linelen); 637 } 638 639 fclose(fp); 640 641 /* Trim out unrelated trailing newline */ 642 sbuf_setpos(sig, sbuf_len(sig) - 1); 643 644 sbuf_finish(sig); 645 sbuf_finish(cert); 646 647 sc = calloc(1, sizeof(struct sig_cert)); 648 sc->siglen = sbuf_len(sig); 649 sc->sig = calloc(1, sc->siglen); 650 memcpy(sc->sig, sbuf_data(sig), sc->siglen); 651 652 sc->certlen = sbuf_len(cert); 653 sc->cert = strdup(sbuf_data(cert)); 654 655 sbuf_delete(sig); 656 sbuf_delete(cert); 657 658 return (sc); 659} 660 661static bool 662verify_pubsignature(int fd_pkg, int fd_sig) 663{ 664 struct pubkey *pk; 665 const char *pubkey; 666 bool ret; 667 668 pk = NULL; 669 pubkey = NULL; 670 ret = false; 671 if (config_string(PUBKEY, &pubkey) != 0) { 672 warnx("No CONFIG_PUBKEY defined"); 673 goto cleanup; 674 } 675 676 if ((pk = read_pubkey(fd_sig)) == NULL) { 677 warnx("Error reading signature"); 678 goto cleanup; 679 } 680 681 /* Verify the signature. */ 682 printf("Verifying signature with public key %s... ", pubkey); 683 if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig, 684 pk->siglen) == false) { 685 fprintf(stderr, "Signature is not valid\n"); 686 goto cleanup; 687 } 688 689 ret = true; 690 691cleanup: 692 if (pk) { 693 free(pk->sig); 694 free(pk); 695 } 696 697 return (ret); 698} 699 700static bool 701verify_signature(int fd_pkg, int fd_sig) 702{ 703 struct fingerprint_list *trusted, *revoked; 704 struct fingerprint *fingerprint; 705 struct sig_cert *sc; 706 bool ret; 707 int trusted_count, revoked_count; 708 const char *fingerprints; 709 char path[MAXPATHLEN]; 710 char hash[SHA256_DIGEST_LENGTH * 2 + 1]; 711 712 sc = NULL; 713 trusted = revoked = NULL; 714 ret = false; 715 716 /* Read and parse fingerprints. */ 717 if (config_string(FINGERPRINTS, &fingerprints) != 0) { 718 warnx("No CONFIG_FINGERPRINTS defined"); 719 goto cleanup; 720 } 721 722 snprintf(path, MAXPATHLEN, "%s/trusted", fingerprints); 723 if ((trusted = load_fingerprints(path, &trusted_count)) == NULL) { 724 warnx("Error loading trusted certificates"); 725 goto cleanup; 726 } 727 728 if (trusted_count == 0 || trusted == NULL) { 729 fprintf(stderr, "No trusted certificates found.\n"); 730 goto cleanup; 731 } 732 733 snprintf(path, MAXPATHLEN, "%s/revoked", fingerprints); 734 if ((revoked = load_fingerprints(path, &revoked_count)) == NULL) { 735 warnx("Error loading revoked certificates"); 736 goto cleanup; 737 } 738 739 /* Read certificate and signature in. */ 740 if ((sc = parse_cert(fd_sig)) == NULL) { 741 warnx("Error parsing certificate"); 742 goto cleanup; 743 } 744 /* Explicitly mark as non-trusted until proven otherwise. */ 745 sc->trusted = false; 746 747 /* Parse signature and pubkey out of the certificate */ 748 sha256_buf(sc->cert, sc->certlen, hash); 749 750 /* Check if this hash is revoked */ 751 if (revoked != NULL) { 752 STAILQ_FOREACH(fingerprint, revoked, next) { 753 if (strcasecmp(fingerprint->hash, hash) == 0) { 754 fprintf(stderr, "The package was signed with " 755 "revoked certificate %s\n", 756 fingerprint->name); 757 goto cleanup; 758 } 759 } 760 } 761 762 STAILQ_FOREACH(fingerprint, trusted, next) { 763 if (strcasecmp(fingerprint->hash, hash) == 0) { 764 sc->trusted = true; 765 sc->name = strdup(fingerprint->name); 766 break; 767 } 768 } 769 770 if (sc->trusted == false) { 771 fprintf(stderr, "No trusted fingerprint found matching " 772 "package's certificate\n"); 773 goto cleanup; 774 } 775 776 /* Verify the signature. */ 777 printf("Verifying signature with trusted certificate %s... ", sc->name); 778 if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig, 779 sc->siglen) == false) { 780 printf("failed\n"); 781 fprintf(stderr, "Signature is not valid\n"); 782 goto cleanup; 783 } 784 printf("done\n"); 785 786 ret = true; 787 788cleanup: 789 if (trusted) 790 free_fingerprint_list(trusted); 791 if (revoked) 792 free_fingerprint_list(revoked); 793 if (sc) { 794 free(sc->cert); 795 free(sc->sig); 796 free(sc->name); 797 free(sc); 798 } 799 800 return (ret); 801} 802 803static int 804bootstrap_pkg(bool force) 805{ 806 int fd_pkg, fd_sig; 807 int ret; 808 char url[MAXPATHLEN]; 809 char tmppkg[MAXPATHLEN]; 810 char tmpsig[MAXPATHLEN]; 811 const char *packagesite; 812 const char *signature_type; 813 char pkgstatic[MAXPATHLEN]; 814 815 fd_sig = -1; 816 ret = -1; 817 818 if (config_string(PACKAGESITE, &packagesite) != 0) { 819 warnx("No PACKAGESITE defined"); 820 return (-1); 821 } 822 823 if (config_string(SIGNATURE_TYPE, &signature_type) != 0) { 824 warnx("Error looking up SIGNATURE_TYPE"); 825 return (-1); 826 } 827 828 printf("Bootstrapping pkg from %s, please wait...\n", packagesite); 829 830 /* Support pkg+http:// for PACKAGESITE which is the new format 831 in 1.2 to avoid confusion on why http://pkg.FreeBSD.org has 832 no A record. */ 833 if (strncmp(URL_SCHEME_PREFIX, packagesite, 834 strlen(URL_SCHEME_PREFIX)) == 0) 835 packagesite += strlen(URL_SCHEME_PREFIX); 836 snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", packagesite); 837 838 snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX", 839 getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); 840 841 if ((fd_pkg = fetch_to_fd(url, tmppkg)) == -1) 842 goto fetchfail; 843 844 if (signature_type != NULL && 845 strcasecmp(signature_type, "NONE") != 0) { 846 if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { 847 848 snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", 849 getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); 850 snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", 851 packagesite); 852 853 if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { 854 fprintf(stderr, "Signature for pkg not " 855 "available.\n"); 856 goto fetchfail; 857 } 858 859 if (verify_signature(fd_pkg, fd_sig) == false) 860 goto cleanup; 861 } else if (strcasecmp(signature_type, "PUBKEY") == 0) { 862 863 snprintf(tmpsig, MAXPATHLEN, 864 "%s/pkg.txz.pubkeysig.XXXXXX", 865 getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); 866 snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.pubkeysig", 867 packagesite); 868 869 if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { 870 fprintf(stderr, "Signature for pkg not " 871 "available.\n"); 872 goto fetchfail; 873 } 874 875 if (verify_pubsignature(fd_pkg, fd_sig) == false) 876 goto cleanup; 877 } else { 878 warnx("Signature type %s is not supported for " 879 "bootstrapping.", signature_type); 880 goto cleanup; 881 } 882 } 883 884 if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) 885 ret = install_pkg_static(pkgstatic, tmppkg, force); 886 887 goto cleanup; 888 889fetchfail: 890 warnx("Error fetching %s: %s", url, fetchLastErrString); 891 fprintf(stderr, "A pre-built version of pkg could not be found for " 892 "your system.\n"); 893 fprintf(stderr, "Consider changing PACKAGESITE or installing it from " 894 "ports: 'ports-mgmt/pkg'.\n"); 895 896cleanup: 897 if (fd_sig != -1) { 898 close(fd_sig); 899 unlink(tmpsig); 900 } 901 close(fd_pkg); 902 unlink(tmppkg); 903 904 return (ret); 905} 906 907static const char confirmation_message[] = 908"The package management tool is not yet installed on your system.\n" 909"Do you want to fetch and install it now? [y/N]: "; 910 911static const char non_interactive_message[] = 912"The package management tool is not yet installed on your system.\n" 913"Please set ASSUME_ALWAYS_YES=yes environment variable to be able to bootstrap " 914"in non-interactive (stdin not being a tty)\n"; 915 916static int 917pkg_query_yes_no(void) 918{ 919 int ret, c; 920 921 c = getchar(); 922 923 if (c == 'y' || c == 'Y') 924 ret = 1; 925 else 926 ret = 0; 927 928 while (c != '\n' && c != EOF) 929 c = getchar(); 930 931 return (ret); 932} 933 934static int 935bootstrap_pkg_local(const char *pkgpath, bool force) 936{ 937 char path[MAXPATHLEN]; 938 char pkgstatic[MAXPATHLEN]; 939 const char *signature_type; 940 int fd_pkg, fd_sig, ret; 941 942 fd_sig = -1; 943 ret = -1; 944 945 fd_pkg = open(pkgpath, O_RDONLY); 946 if (fd_pkg == -1) 947 err(EXIT_FAILURE, "Unable to open %s", pkgpath); 948 949 if (config_string(SIGNATURE_TYPE, &signature_type) != 0) { 950 warnx("Error looking up SIGNATURE_TYPE"); 951 return (-1); 952 } 953 if (signature_type != NULL && 954 strcasecmp(signature_type, "NONE") != 0) { 955 if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { 956 957 snprintf(path, sizeof(path), "%s.sig", pkgpath); 958 959 if ((fd_sig = open(path, O_RDONLY)) == -1) { 960 fprintf(stderr, "Signature for pkg not " 961 "available.\n"); 962 goto cleanup; 963 } 964 965 if (verify_signature(fd_pkg, fd_sig) == false) 966 goto cleanup; 967 968 } else if (strcasecmp(signature_type, "PUBKEY") == 0) { 969 970 snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath); 971 972 if ((fd_sig = open(path, O_RDONLY)) == -1) { 973 fprintf(stderr, "Signature for pkg not " 974 "available.\n"); 975 goto cleanup; 976 } 977 978 if (verify_pubsignature(fd_pkg, fd_sig) == false) 979 goto cleanup; 980 981 } else { 982 warnx("Signature type %s is not supported for " 983 "bootstrapping.", signature_type); 984 goto cleanup; 985 } 986 } 987 988 if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) 989 ret = install_pkg_static(pkgstatic, pkgpath, force); 990 991cleanup: 992 close(fd_pkg); 993 if (fd_sig != -1) 994 close(fd_sig); 995 996 return (ret); 997} 998 999int 1000main(int argc, char *argv[]) 1001{ 1002 char pkgpath[MAXPATHLEN]; 1003 const char *pkgarg; 1004 bool bootstrap_only, force, yes; 1005 1006 bootstrap_only = false; 1007 force = false; 1008 pkgarg = NULL; 1009 yes = false; 1010 1011 snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", 1012 getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE); 1013 1014 if (argc > 1 && strcmp(argv[1], "bootstrap") == 0) { 1015 bootstrap_only = true; 1016 if (argc == 3 && strcmp(argv[2], "-f") == 0) 1017 force = true; 1018 } 1019 1020 if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) { 1021 /* 1022 * To allow 'pkg -N' to be used as a reliable test for whether 1023 * a system is configured to use pkg, don't bootstrap pkg 1024 * when that argument is given as argv[1]. 1025 */ 1026 if (argv[1] != NULL && strcmp(argv[1], "-N") == 0) 1027 errx(EXIT_FAILURE, "pkg is not installed"); 1028 1029 config_init(); 1030 1031 if (argc > 1 && strcmp(argv[1], "add") == 0) { 1032 if (argc > 2 && strcmp(argv[2], "-f") == 0) { 1033 force = true; 1034 pkgarg = argv[3]; 1035 } else 1036 pkgarg = argv[2]; 1037 if (pkgarg == NULL) { 1038 fprintf(stderr, "Path to pkg.txz required\n"); 1039 exit(EXIT_FAILURE); 1040 } 1041 if (access(pkgarg, R_OK) == -1) { 1042 fprintf(stderr, "No such file: %s\n", pkgarg); 1043 exit(EXIT_FAILURE); 1044 } 1045 if (bootstrap_pkg_local(pkgarg, force) != 0) 1046 exit(EXIT_FAILURE); 1047 exit(EXIT_SUCCESS); 1048 } 1049 /* 1050 * Do not ask for confirmation if either of stdin or stdout is 1051 * not tty. Check the environment to see if user has answer 1052 * tucked in there already. 1053 */ 1054 config_bool(ASSUME_ALWAYS_YES, &yes); 1055 if (!yes) { 1056 if (!isatty(fileno(stdin))) { 1057 fprintf(stderr, non_interactive_message); 1058 exit(EXIT_FAILURE); 1059 } 1060 1061 printf("%s", confirmation_message); 1062 if (pkg_query_yes_no() == 0) 1063 exit(EXIT_FAILURE); 1064 } 1065 if (bootstrap_pkg(force) != 0) 1066 exit(EXIT_FAILURE); 1067 config_finish(); 1068 1069 if (bootstrap_only) 1070 exit(EXIT_SUCCESS); 1071 } else if (bootstrap_only) { 1072 printf("pkg already bootstrapped at %s\n", pkgpath); 1073 exit(EXIT_SUCCESS); 1074 } 1075 1076 execv(pkgpath, argv); 1077 1078 /* NOT REACHED */ 1079 return (EXIT_FAILURE); 1080} 1081