xref: /freebsd/usr.sbin/pkg/pkg.c (revision 77a1348b3c1cfe8547be49a121b56299a1e18b69)
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 	fprintf(stderr, "A pre-built version of pkg could not be found for "
919 	    "your system.\n");
920 	fprintf(stderr, "Consider changing PACKAGESITE or installing it from "
921 	    "ports: 'ports-mgmt/pkg'.\n");
922 
923 cleanup:
924 	if (fd_sig != -1) {
925 		close(fd_sig);
926 		unlink(tmpsig);
927 	}
928 
929 	if (fd_pkg != -1) {
930 		close(fd_pkg);
931 		unlink(tmppkg);
932 	}
933 
934 	return (ret);
935 }
936 
937 static const char confirmation_message[] =
938 "The package management tool is not yet installed on your system.\n"
939 "Do you want to fetch and install it now? [y/N]: ";
940 
941 static const char non_interactive_message[] =
942 "The package management tool is not yet installed on your system.\n"
943 "Please set ASSUME_ALWAYS_YES=yes environment variable to be able to bootstrap "
944 "in non-interactive (stdin not being a tty)\n";
945 
946 static int
947 pkg_query_yes_no(void)
948 {
949 	int ret, c;
950 
951 	fflush(stdout);
952 	c = getchar();
953 
954 	if (c == 'y' || c == 'Y')
955 		ret = 1;
956 	else
957 		ret = 0;
958 
959 	while (c != '\n' && c != EOF)
960 		c = getchar();
961 
962 	return (ret);
963 }
964 
965 static int
966 bootstrap_pkg_local(const char *pkgpath, bool force)
967 {
968 	char path[MAXPATHLEN];
969 	char pkgstatic[MAXPATHLEN];
970 	const char *signature_type;
971 	int fd_pkg, fd_sig, ret;
972 
973 	fd_sig = -1;
974 	ret = -1;
975 
976 	fd_pkg = open(pkgpath, O_RDONLY);
977 	if (fd_pkg == -1)
978 		err(EXIT_FAILURE, "Unable to open %s", pkgpath);
979 
980 	if (config_string(SIGNATURE_TYPE, &signature_type) != 0) {
981 		warnx("Error looking up SIGNATURE_TYPE");
982 		goto cleanup;
983 	}
984 	if (signature_type != NULL &&
985 	    strcasecmp(signature_type, "NONE") != 0) {
986 		if (strcasecmp(signature_type, "FINGERPRINTS") == 0) {
987 
988 			snprintf(path, sizeof(path), "%s.sig", pkgpath);
989 
990 			if ((fd_sig = open(path, O_RDONLY)) == -1) {
991 				fprintf(stderr, "Signature for pkg not "
992 				    "available.\n");
993 				goto cleanup;
994 			}
995 
996 			if (verify_signature(fd_pkg, fd_sig) == false)
997 				goto cleanup;
998 
999 		} else if (strcasecmp(signature_type, "PUBKEY") == 0) {
1000 
1001 			snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath);
1002 
1003 			if ((fd_sig = open(path, O_RDONLY)) == -1) {
1004 				fprintf(stderr, "Signature for pkg not "
1005 				    "available.\n");
1006 				goto cleanup;
1007 			}
1008 
1009 			if (verify_pubsignature(fd_pkg, fd_sig) == false)
1010 				goto cleanup;
1011 
1012 		} else {
1013 			warnx("Signature type %s is not supported for "
1014 			    "bootstrapping.", signature_type);
1015 			goto cleanup;
1016 		}
1017 	}
1018 
1019 	if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
1020 		ret = install_pkg_static(pkgstatic, pkgpath, force);
1021 
1022 cleanup:
1023 	close(fd_pkg);
1024 	if (fd_sig != -1)
1025 		close(fd_sig);
1026 
1027 	return (ret);
1028 }
1029 
1030 int
1031 main(int argc, char *argv[])
1032 {
1033 	char pkgpath[MAXPATHLEN];
1034 	const char *pkgarg;
1035 	int i;
1036 	bool bootstrap_only, force, yes;
1037 
1038 	bootstrap_only = false;
1039 	force = false;
1040 	pkgarg = NULL;
1041 	yes = false;
1042 
1043 	snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg",
1044 	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
1045 
1046 	if (argc > 1 && strcmp(argv[1], "bootstrap") == 0) {
1047 		bootstrap_only = true;
1048 		if (argc == 3 && strcmp(argv[2], "-f") == 0)
1049 			force = true;
1050 	}
1051 
1052 	if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) {
1053 		/*
1054 		 * To allow 'pkg -N' to be used as a reliable test for whether
1055 		 * a system is configured to use pkg, don't bootstrap pkg
1056 		 * when that argument is given as argv[1].
1057 		 */
1058 		if (argv[1] != NULL && strcmp(argv[1], "-N") == 0)
1059 			errx(EXIT_FAILURE, "pkg is not installed");
1060 
1061 		config_init();
1062 
1063 		if (argc > 1 && strcmp(argv[1], "add") == 0) {
1064 			if (argc > 2 && strcmp(argv[2], "-f") == 0) {
1065 				force = true;
1066 				pkgarg = argv[3];
1067 			} else
1068 				pkgarg = argv[2];
1069 			if (pkgarg == NULL) {
1070 				fprintf(stderr, "Path to pkg.txz required\n");
1071 				exit(EXIT_FAILURE);
1072 			}
1073 			if (access(pkgarg, R_OK) == -1) {
1074 				fprintf(stderr, "No such file: %s\n", pkgarg);
1075 				exit(EXIT_FAILURE);
1076 			}
1077 			if (bootstrap_pkg_local(pkgarg, force) != 0)
1078 				exit(EXIT_FAILURE);
1079 			exit(EXIT_SUCCESS);
1080 		}
1081 		/*
1082 		 * Do not ask for confirmation if either of stdin or stdout is
1083 		 * not tty. Check the environment to see if user has answer
1084 		 * tucked in there already.
1085 		 */
1086 		config_bool(ASSUME_ALWAYS_YES, &yes);
1087 		if (!yes) {
1088 			for (i = 1; i < argc; i++) {
1089 				if (strcmp(argv[i], "-y") == 0 ||
1090 				    strcmp(argv[i], "--yes") == 0) {
1091 					yes = true;
1092 					break;
1093 				}
1094 			}
1095 		}
1096 		if (!yes) {
1097 			if (!isatty(fileno(stdin))) {
1098 				fprintf(stderr, non_interactive_message);
1099 				exit(EXIT_FAILURE);
1100 			}
1101 
1102 			printf("%s", confirmation_message);
1103 			if (pkg_query_yes_no() == 0)
1104 				exit(EXIT_FAILURE);
1105 		}
1106 		if (bootstrap_pkg(force) != 0)
1107 			exit(EXIT_FAILURE);
1108 		config_finish();
1109 
1110 		if (bootstrap_only)
1111 			exit(EXIT_SUCCESS);
1112 	} else if (bootstrap_only) {
1113 		printf("pkg already bootstrapped at %s\n", pkgpath);
1114 		exit(EXIT_SUCCESS);
1115 	}
1116 
1117 	execv(pkgpath, argv);
1118 
1119 	/* NOT REACHED */
1120 	return (EXIT_FAILURE);
1121 }
1122