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