xref: /freebsd/usr.sbin/pkg/pkg.c (revision 3a3af6b2a160bea72509a9d5ef84e25906b0478a)
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