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