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