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