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