xref: /freebsd/usr.sbin/pkg/pkg.c (revision 76039bc84fae9915788b54ff28fe0cc4876952d2)
1 /*-
2  * Copyright (c) 2012-2013 Baptiste Daroussin <bapt@FreeBSD.org>
3  * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/queue.h>
33 #include <sys/types.h>
34 #include <sys/sbuf.h>
35 #include <sys/wait.h>
36 
37 #define _WITH_GETLINE
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 <paths.h>
46 #include <stdbool.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <time.h>
51 #include <unistd.h>
52 #include <yaml.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 typedef enum {
70        HASH_UNKNOWN,
71        HASH_SHA256,
72 } hash_t;
73 
74 struct fingerprint {
75        hash_t type;
76        char *name;
77        char hash[BUFSIZ];
78        STAILQ_ENTRY(fingerprint) next;
79 };
80 
81 STAILQ_HEAD(fingerprint_list, fingerprint);
82 
83 static int
84 extract_pkg_static(int fd, char *p, int sz)
85 {
86 	struct archive *a;
87 	struct archive_entry *ae;
88 	char *end;
89 	int ret, r;
90 
91 	ret = -1;
92 	a = archive_read_new();
93 	if (a == NULL) {
94 		warn("archive_read_new");
95 		return (ret);
96 	}
97 	archive_read_support_filter_all(a);
98 	archive_read_support_format_tar(a);
99 
100 	if (lseek(fd, 0, 0) == -1) {
101 		warn("lseek");
102 		goto cleanup;
103 	}
104 
105 	if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) {
106 		warnx("archive_read_open_fd: %s", archive_error_string(a));
107 		goto cleanup;
108 	}
109 
110 	ae = NULL;
111 	while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) {
112 		end = strrchr(archive_entry_pathname(ae), '/');
113 		if (end == NULL)
114 			continue;
115 
116 		if (strcmp(end, "/pkg-static") == 0) {
117 			r = archive_read_extract(a, ae,
118 			    ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM |
119 			    ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL |
120 			    ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR);
121 			strlcpy(p, archive_entry_pathname(ae), sz);
122 			break;
123 		}
124 	}
125 
126 	if (r == ARCHIVE_OK)
127 		ret = 0;
128 	else
129 		warnx("fail to extract pkg-static");
130 
131 cleanup:
132 	archive_read_free(a);
133 	return (ret);
134 
135 }
136 
137 static int
138 install_pkg_static(const char *path, const char *pkgpath)
139 {
140 	int pstat;
141 	pid_t pid;
142 
143 	switch ((pid = fork())) {
144 	case -1:
145 		return (-1);
146 	case 0:
147 		execl(path, "pkg-static", "add", pkgpath, (char *)NULL);
148 		_exit(1);
149 	default:
150 		break;
151 	}
152 
153 	while (waitpid(pid, &pstat, 0) == -1)
154 		if (errno != EINTR)
155 			return (-1);
156 
157 	if (WEXITSTATUS(pstat))
158 		return (WEXITSTATUS(pstat));
159 	else if (WIFSIGNALED(pstat))
160 		return (128 & (WTERMSIG(pstat)));
161 	return (pstat);
162 }
163 
164 static int
165 fetch_to_fd(const char *url, char *path)
166 {
167 	struct url *u;
168 	struct dns_srvinfo *mirrors, *current;
169 	struct url_stat st;
170 	FILE *remote;
171 	/* To store _https._tcp. + hostname + \0 */
172 	int fd;
173 	int retry, max_retry;
174 	off_t done, r;
175 	time_t now, last;
176 	char buf[10240];
177 	char zone[MAXHOSTNAMELEN + 13];
178 	static const char *mirror_type = NULL;
179 
180 	done = 0;
181 	last = 0;
182 	max_retry = 3;
183 	current = mirrors = NULL;
184 	remote = NULL;
185 
186 	if (mirror_type == NULL && config_string(MIRROR_TYPE, &mirror_type)
187 	    != 0) {
188 		warnx("No MIRROR_TYPE defined");
189 		return (-1);
190 	}
191 
192 	if ((fd = mkstemp(path)) == -1) {
193 		warn("mkstemp()");
194 		return (-1);
195 	}
196 
197 	retry = max_retry;
198 
199 	u = fetchParseURL(url);
200 	while (remote == NULL) {
201 		if (retry == max_retry) {
202 			if (strcmp(u->scheme, "file") != 0 &&
203 			    strcasecmp(mirror_type, "srv") == 0) {
204 				snprintf(zone, sizeof(zone),
205 				    "_%s._tcp.%s", u->scheme, u->host);
206 				mirrors = dns_getsrvinfo(zone);
207 				current = mirrors;
208 			}
209 		}
210 
211 		if (mirrors != NULL) {
212 			strlcpy(u->host, current->host, sizeof(u->host));
213 			u->port = current->port;
214 		}
215 
216 		remote = fetchXGet(u, &st, "");
217 		if (remote == NULL) {
218 			--retry;
219 			if (retry <= 0)
220 				goto fetchfail;
221 			if (mirrors == NULL) {
222 				sleep(1);
223 			} else {
224 				current = current->next;
225 				if (current == NULL)
226 					current = mirrors;
227 			}
228 		}
229 	}
230 
231 	if (remote == NULL)
232 		goto fetchfail;
233 
234 	while (done < st.size) {
235 		if ((r = fread(buf, 1, sizeof(buf), remote)) < 1)
236 			break;
237 
238 		if (write(fd, buf, r) != r) {
239 			warn("write()");
240 			goto fetchfail;
241 		}
242 
243 		done += r;
244 		now = time(NULL);
245 		if (now > last || done == st.size)
246 			last = now;
247 	}
248 
249 	if (ferror(remote))
250 		goto fetchfail;
251 
252 	goto cleanup;
253 
254 fetchfail:
255 	if (fd != -1) {
256 		close(fd);
257 		fd = -1;
258 		unlink(path);
259 	}
260 
261 cleanup:
262 	if (remote != NULL)
263 		fclose(remote);
264 
265 	return fd;
266 }
267 
268 static struct fingerprint *
269 parse_fingerprint(yaml_document_t *doc, yaml_node_t *node)
270 {
271 	yaml_node_pair_t *pair;
272 	yaml_char_t *function, *fp;
273 	struct fingerprint *f;
274 	hash_t fct = HASH_UNKNOWN;
275 
276 	function = fp = NULL;
277 
278 	pair = node->data.mapping.pairs.start;
279 	while (pair < node->data.mapping.pairs.top) {
280 		yaml_node_t *key = yaml_document_get_node(doc, pair->key);
281 		yaml_node_t *val = yaml_document_get_node(doc, pair->value);
282 
283 		if (key->data.scalar.length <= 0) {
284 			++pair;
285 			continue;
286 		}
287 
288 		if (val->type != YAML_SCALAR_NODE) {
289 			++pair;
290 			continue;
291 		}
292 
293 		if (strcasecmp(key->data.scalar.value, "function") == 0)
294 			function = val->data.scalar.value;
295 		else if (strcasecmp(key->data.scalar.value, "fingerprint")
296 		    == 0)
297 			fp = val->data.scalar.value;
298 
299 		++pair;
300 		continue;
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 		fprintf(stderr, "Unsupported hashing function: %s\n", 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;
325 
326 	STAILQ_FOREACH(fingerprint, list, next) {
327 		if (fingerprint->name)
328 			free(fingerprint->name);
329 		free(fingerprint);
330 	}
331 	free(list);
332 }
333 
334 static struct fingerprint *
335 load_fingerprint(const char *dir, const char *filename)
336 {
337 	yaml_parser_t parser;
338 	yaml_document_t doc;
339 	yaml_node_t *node;
340 	FILE *fp;
341 	struct fingerprint *f;
342 	char path[MAXPATHLEN];
343 
344 	f = NULL;
345 
346 	snprintf(path, MAXPATHLEN, "%s/%s", dir, filename);
347 
348 	if ((fp = fopen(path, "r")) == NULL)
349 		return (NULL);
350 
351 	yaml_parser_initialize(&parser);
352 	yaml_parser_set_input_file(&parser, fp);
353 	yaml_parser_load(&parser, &doc);
354 
355 	node = yaml_document_get_root_node(&doc);
356 	if (node == NULL || node->type != YAML_MAPPING_NODE)
357 		goto out;
358 
359 	f = parse_fingerprint(&doc, node);
360 	f->name = strdup(filename);
361 
362 out:
363 	yaml_document_delete(&doc);
364 	yaml_parser_delete(&parser);
365 	fclose(fp);
366 
367 	return (f);
368 }
369 
370 static struct fingerprint_list *
371 load_fingerprints(const char *path, int *count)
372 {
373 	DIR *d;
374 	struct dirent *ent;
375 	struct fingerprint *finger;
376 	struct fingerprint_list *fingerprints;
377 
378 	*count = 0;
379 
380 	fingerprints = calloc(1, sizeof(struct fingerprint_list));
381 	if (fingerprints == NULL)
382 		return (NULL);
383 	STAILQ_INIT(fingerprints);
384 
385 	if ((d = opendir(path)) == NULL)
386 		return (NULL);
387 
388 	while ((ent = readdir(d))) {
389 		if (strcmp(ent->d_name, ".") == 0 ||
390 		    strcmp(ent->d_name, "..") == 0)
391 			continue;
392 		finger = load_fingerprint(path, ent->d_name);
393 		if (finger != NULL) {
394 			STAILQ_INSERT_TAIL(fingerprints, finger, next);
395 			++(*count);
396 		}
397 	}
398 
399 	closedir(d);
400 
401 	return (fingerprints);
402 }
403 
404 static void
405 sha256_hash(unsigned char hash[SHA256_DIGEST_LENGTH],
406     char out[SHA256_DIGEST_LENGTH * 2 + 1])
407 {
408 	int i;
409 
410 	for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
411 		sprintf(out + (i * 2), "%02x", hash[i]);
412 
413 	out[SHA256_DIGEST_LENGTH * 2] = '\0';
414 }
415 
416 static void
417 sha256_buf(char *buf, size_t len, char out[SHA256_DIGEST_LENGTH * 2 + 1])
418 {
419 	unsigned char hash[SHA256_DIGEST_LENGTH];
420 	SHA256_CTX sha256;
421 
422 	out[0] = '\0';
423 
424 	SHA256_Init(&sha256);
425 	SHA256_Update(&sha256, buf, len);
426 	SHA256_Final(hash, &sha256);
427 	sha256_hash(hash, out);
428 }
429 
430 static int
431 sha256_fd(int fd, char out[SHA256_DIGEST_LENGTH * 2 + 1])
432 {
433 	int my_fd;
434 	FILE *fp;
435 	char buffer[BUFSIZ];
436 	unsigned char hash[SHA256_DIGEST_LENGTH];
437 	size_t r;
438 	int ret;
439 	SHA256_CTX sha256;
440 
441 	my_fd = -1;
442 	fp = NULL;
443 	r = 0;
444 	ret = 1;
445 
446 	out[0] = '\0';
447 
448 	/* Duplicate the fd so that fclose(3) does not close it. */
449 	if ((my_fd = dup(fd)) == -1) {
450 		warnx("dup");
451 		goto cleanup;
452 	}
453 
454 	if ((fp = fdopen(my_fd, "rb")) == NULL) {
455 		warnx("fdopen");
456 		goto cleanup;
457 	}
458 
459 	SHA256_Init(&sha256);
460 
461 	while ((r = fread(buffer, 1, BUFSIZ, fp)) > 0)
462 		SHA256_Update(&sha256, buffer, r);
463 
464 	if (ferror(fp) != 0) {
465 		warnx("fread");
466 		goto cleanup;
467 	}
468 
469 	SHA256_Final(hash, &sha256);
470 	sha256_hash(hash, out);
471 	ret = 0;
472 
473 cleanup:
474 	if (fp != NULL)
475 		fclose(fp);
476 	else if (my_fd != -1)
477 		close(my_fd);
478 	(void)lseek(fd, 0, SEEK_SET);
479 
480 	return (ret);
481 }
482 
483 static EVP_PKEY *
484 load_public_key_buf(const unsigned char *cert, int certlen)
485 {
486 	EVP_PKEY *pkey;
487 	BIO *bp;
488 	char errbuf[1024];
489 
490 	bp = BIO_new_mem_buf((void *)cert, certlen);
491 
492 	if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL)
493 		warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
494 
495 	BIO_free(bp);
496 
497 	return (pkey);
498 }
499 
500 static bool
501 rsa_verify_cert(int fd, const unsigned char *key, int keylen,
502     unsigned char *sig, int siglen)
503 {
504 	EVP_MD_CTX *mdctx;
505 	EVP_PKEY *pkey;
506 	char sha256[(SHA256_DIGEST_LENGTH * 2) + 2];
507 	char errbuf[1024];
508 	bool ret;
509 
510 	pkey = NULL;
511 	mdctx = NULL;
512 	ret = false;
513 
514 	/* Compute SHA256 of the package. */
515 	if (lseek(fd, 0, 0) == -1) {
516 		warn("lseek");
517 		goto cleanup;
518 	}
519 	if ((sha256_fd(fd, sha256)) == -1) {
520 		warnx("Error creating SHA256 hash for package");
521 		goto cleanup;
522 	}
523 
524 	if ((pkey = load_public_key_buf(key, keylen)) == NULL) {
525 		warnx("Error reading public key");
526 		goto cleanup;
527 	}
528 
529 	/* Verify signature of the SHA256(pkg) is valid. */
530 	if ((mdctx = EVP_MD_CTX_create()) == NULL) {
531 		warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
532 		goto error;
533 	}
534 
535 	if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
536 		warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
537 		goto error;
538 	}
539 	if (EVP_DigestVerifyUpdate(mdctx, sha256, strlen(sha256)) != 1) {
540 		warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
541 		goto error;
542 	}
543 
544 	if (EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) {
545 		warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
546 		goto error;
547 	}
548 
549 	ret = true;
550 	printf("done\n");
551 	goto cleanup;
552 
553 error:
554 	printf("failed\n");
555 
556 cleanup:
557 	if (pkey)
558 		EVP_PKEY_free(pkey);
559 	if (mdctx)
560 		EVP_MD_CTX_destroy(mdctx);
561 	ERR_free_strings();
562 
563 	return (ret);
564 }
565 
566 static struct sig_cert *
567 parse_cert(int fd) {
568 	int my_fd;
569 	struct sig_cert *sc;
570 	FILE *fp;
571 	struct sbuf *buf, *sig, *cert;
572 	char *line;
573 	size_t linecap;
574 	ssize_t linelen;
575 
576 	my_fd = -1;
577 	sc = NULL;
578 	line = NULL;
579 	linecap = 0;
580 
581 	if (lseek(fd, 0, 0) == -1) {
582 		warn("lseek");
583 		return (NULL);
584 	}
585 
586 	/* Duplicate the fd so that fclose(3) does not close it. */
587 	if ((my_fd = dup(fd)) == -1) {
588 		warnx("dup");
589 		return (NULL);
590 	}
591 
592 	if ((fp = fdopen(my_fd, "rb")) == NULL) {
593 		warn("fdopen");
594 		close(my_fd);
595 		return (NULL);
596 	}
597 
598 	sig = sbuf_new_auto();
599 	cert = sbuf_new_auto();
600 
601 	while ((linelen = getline(&line, &linecap, fp)) > 0) {
602 		if (strcmp(line, "SIGNATURE\n") == 0) {
603 			buf = sig;
604 			continue;
605 		} else if (strcmp(line, "CERT\n") == 0) {
606 			buf = cert;
607 			continue;
608 		} else if (strcmp(line, "END\n") == 0) {
609 			break;
610 		}
611 		if (buf != NULL)
612 			sbuf_bcat(buf, line, linelen);
613 	}
614 
615 	fclose(fp);
616 
617 	/* Trim out unrelated trailing newline */
618 	sbuf_setpos(sig, sbuf_len(sig) - 1);
619 
620 	sbuf_finish(sig);
621 	sbuf_finish(cert);
622 
623 	sc = calloc(1, sizeof(struct sig_cert));
624 	sc->siglen = sbuf_len(sig);
625 	sc->sig = calloc(1, sc->siglen);
626 	memcpy(sc->sig, sbuf_data(sig), sc->siglen);
627 
628 	sc->certlen = sbuf_len(cert);
629 	sc->cert = strdup(sbuf_data(cert));
630 
631 	sbuf_delete(sig);
632 	sbuf_delete(cert);
633 
634 	return (sc);
635 }
636 
637 static bool
638 verify_signature(int fd_pkg, int fd_sig)
639 {
640 	struct fingerprint_list *trusted, *revoked;
641 	struct fingerprint *fingerprint;
642 	struct sig_cert *sc;
643 	bool ret;
644 	int trusted_count, revoked_count;
645 	const char *fingerprints;
646 	char path[MAXPATHLEN];
647 	char hash[SHA256_DIGEST_LENGTH * 2 + 1];
648 
649 	sc = NULL;
650 	trusted = revoked = NULL;
651 	ret = false;
652 
653 	/* Read and parse fingerprints. */
654 	if (config_string(FINGERPRINTS, &fingerprints) != 0) {
655 		warnx("No CONFIG_FINGERPRINTS defined");
656 		goto cleanup;
657 	}
658 
659 	snprintf(path, MAXPATHLEN, "%s/trusted", fingerprints);
660 	if ((trusted = load_fingerprints(path, &trusted_count)) == NULL) {
661 		warnx("Error loading trusted certificates");
662 		goto cleanup;
663 	}
664 
665 	if (trusted_count == 0 || trusted == NULL) {
666 		fprintf(stderr, "No trusted certificates found.\n");
667 		goto cleanup;
668 	}
669 
670 	snprintf(path, MAXPATHLEN, "%s/revoked", fingerprints);
671 	if ((revoked = load_fingerprints(path, &revoked_count)) == NULL) {
672 		warnx("Error loading revoked certificates");
673 		goto cleanup;
674 	}
675 
676 	/* Read certificate and signature in. */
677 	if ((sc = parse_cert(fd_sig)) == NULL) {
678 		warnx("Error parsing certificate");
679 		goto cleanup;
680 	}
681 	/* Explicitly mark as non-trusted until proven otherwise. */
682 	sc->trusted = false;
683 
684 	/* Parse signature and pubkey out of the certificate */
685 	sha256_buf(sc->cert, sc->certlen, hash);
686 
687 	/* Check if this hash is revoked */
688 	if (revoked != NULL) {
689 		STAILQ_FOREACH(fingerprint, revoked, next) {
690 			if (strcasecmp(fingerprint->hash, hash) == 0) {
691 				fprintf(stderr, "The package was signed with "
692 				    "revoked certificate %s\n",
693 				    fingerprint->name);
694 				goto cleanup;
695 			}
696 		}
697 	}
698 
699 	STAILQ_FOREACH(fingerprint, trusted, next) {
700 		if (strcasecmp(fingerprint->hash, hash) == 0) {
701 			sc->trusted = true;
702 			sc->name = strdup(fingerprint->name);
703 			break;
704 		}
705 	}
706 
707 	if (sc->trusted == false) {
708 		fprintf(stderr, "No trusted fingerprint found matching "
709 		    "package's certificate\n");
710 		goto cleanup;
711 	}
712 
713 	/* Verify the signature. */
714 	printf("Verifying signature with trusted certificate %s... ", sc->name);
715 	if (rsa_verify_cert(fd_pkg, sc->cert, sc->certlen, sc->sig,
716 	    sc->siglen) == false) {
717 		fprintf(stderr, "Signature is not valid\n");
718 		goto cleanup;
719 	}
720 
721 	ret = true;
722 
723 cleanup:
724 	if (trusted)
725 		free_fingerprint_list(trusted);
726 	if (revoked)
727 		free_fingerprint_list(revoked);
728 	if (sc) {
729 		if (sc->cert)
730 			free(sc->cert);
731 		if (sc->sig)
732 			free(sc->sig);
733 		if (sc->name)
734 			free(sc->name);
735 		free(sc);
736 	}
737 
738 	return (ret);
739 }
740 
741 static int
742 bootstrap_pkg(void)
743 {
744 	FILE *config;
745 	int fd_pkg, fd_sig;
746 	int ret;
747 	char *site;
748 	char url[MAXPATHLEN];
749 	char conf[MAXPATHLEN];
750 	char tmppkg[MAXPATHLEN];
751 	char tmpsig[MAXPATHLEN];
752 	const char *packagesite;
753 	const char *signature_type;
754 	char pkgstatic[MAXPATHLEN];
755 
756 	fd_sig = -1;
757 	ret = -1;
758 	config = NULL;
759 
760 	if (config_string(PACKAGESITE, &packagesite) != 0) {
761 		warnx("No PACKAGESITE defined");
762 		return (-1);
763 	}
764 
765 	if (config_string(SIGNATURE_TYPE, &signature_type) != 0) {
766 		warnx("Error looking up SIGNATURE_TYPE");
767 		return (-1);
768 	}
769 
770 	printf("Bootstrapping pkg from %s, please wait...\n", packagesite);
771 
772 	/* Support pkg+http:// for PACKAGESITE which is the new format
773 	   in 1.2 to avoid confusion on why http://pkg.FreeBSD.org has
774 	   no A record. */
775 	if (strncmp(URL_SCHEME_PREFIX, packagesite,
776 	    strlen(URL_SCHEME_PREFIX)) == 0)
777 		packagesite += strlen(URL_SCHEME_PREFIX);
778 	snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", packagesite);
779 
780 	snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX",
781 	    getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP);
782 
783 	if ((fd_pkg = fetch_to_fd(url, tmppkg)) == -1)
784 		goto fetchfail;
785 
786 	if (signature_type != NULL &&
787 	    strcasecmp(signature_type, "FINGERPRINTS") == 0) {
788 		snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX",
789 		    getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP);
790 		snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig",
791 		    packagesite);
792 
793 		if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) {
794 			fprintf(stderr, "Signature for pkg not available.\n");
795 			goto fetchfail;
796 		}
797 
798 		if (verify_signature(fd_pkg, fd_sig) == false)
799 			goto cleanup;
800 	}
801 
802 	if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
803 		ret = install_pkg_static(pkgstatic, tmppkg);
804 
805 	snprintf(conf, MAXPATHLEN, "%s/etc/pkg.conf",
806 	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
807 
808 	if (access(conf, R_OK) == -1) {
809 		site = strrchr(url, '/');
810 		if (site == NULL)
811 			goto cleanup;
812 		site[0] = '\0';
813 		site = strrchr(url, '/');
814 		if (site == NULL)
815 			goto cleanup;
816 		site[0] = '\0';
817 
818 		config = fopen(conf, "w+");
819 		if (config == NULL)
820 			goto cleanup;
821 		fprintf(config, "packagesite: %s\n", url);
822 		fclose(config);
823 	}
824 
825 	goto cleanup;
826 
827 fetchfail:
828 	warnx("Error fetching %s: %s", url, fetchLastErrString);
829 	fprintf(stderr, "A pre-built version of pkg could not be found for "
830 	    "your system.\n");
831 	fprintf(stderr, "Consider changing PACKAGESITE or installing it from "
832 	    "ports: 'ports-mgmt/pkg'.\n");
833 
834 cleanup:
835 	if (fd_sig != -1) {
836 		close(fd_sig);
837 		unlink(tmpsig);
838 	}
839 	close(fd_pkg);
840 	unlink(tmppkg);
841 
842 	return (ret);
843 }
844 
845 static const char confirmation_message[] =
846 "The package management tool is not yet installed on your system.\n"
847 "Do you want to fetch and install it now? [y/N]: ";
848 
849 static int
850 pkg_query_yes_no(void)
851 {
852 	int ret, c;
853 
854 	c = getchar();
855 
856 	if (c == 'y' || c == 'Y')
857 		ret = 1;
858 	else
859 		ret = 0;
860 
861 	while (c != '\n' && c != EOF)
862 		c = getchar();
863 
864 	return (ret);
865 }
866 
867 static int
868 bootstrap_pkg_local(const char *pkgpath)
869 {
870 	char path[MAXPATHLEN];
871 	char pkgstatic[MAXPATHLEN];
872 	const char *signature_type;
873 	int fd_pkg, fd_sig, ret;
874 
875 	fd_sig = -1;
876 	ret = -1;
877 
878 	fd_pkg = open(pkgpath, O_RDONLY);
879 	if (fd_pkg == -1)
880 		err(EXIT_FAILURE, "Unable to open %s", pkgpath);
881 
882 	if (config_string(SIGNATURE_TYPE, &signature_type) != 0) {
883 		warnx("Error looking up SIGNATURE_TYPE");
884 		return (-1);
885 	}
886 	if (signature_type != NULL &&
887 	    strcasecmp(signature_type, "FINGERPRINTS") == 0) {
888 		snprintf(path, sizeof(path), "%s.sig", pkgpath);
889 
890 		if ((fd_sig = open(path, O_RDONLY)) == -1) {
891 			fprintf(stderr, "Signature for pkg not available.\n");
892 			goto cleanup;
893 		}
894 
895 		if (verify_signature(fd_pkg, fd_sig) == false)
896 			goto cleanup;
897 	}
898 
899 	if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
900 		ret = install_pkg_static(pkgstatic, pkgpath);
901 
902 cleanup:
903 	close(fd_pkg);
904 	if (fd_sig != -1)
905 		close(fd_sig);
906 
907 	return (ret);
908 }
909 
910 int
911 main(__unused int argc, char *argv[])
912 {
913 	char pkgpath[MAXPATHLEN];
914 	bool yes = false;
915 
916 	snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg",
917 	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
918 
919 	if (access(pkgpath, X_OK) == -1) {
920 		/*
921 		 * To allow 'pkg -N' to be used as a reliable test for whether
922 		 * a system is configured to use pkg, don't bootstrap pkg
923 		 * when that argument is given as argv[1].
924 		 */
925 		if (argv[1] != NULL && strcmp(argv[1], "-N") == 0)
926 			errx(EXIT_FAILURE, "pkg is not installed");
927 
928 		config_init();
929 
930 		if (argc > 2 && strcmp(argv[1], "add") == 0 &&
931 		    access(argv[2], R_OK) == 0) {
932 			if (bootstrap_pkg_local(argv[2]) != 0)
933 				exit(EXIT_FAILURE);
934 			exit(EXIT_SUCCESS);
935 		}
936 		/*
937 		 * Do not ask for confirmation if either of stdin or stdout is
938 		 * not tty. Check the environment to see if user has answer
939 		 * tucked in there already.
940 		 */
941 		config_bool(ASSUME_ALWAYS_YES, &yes);
942 		if (!yes) {
943 			printf("%s", confirmation_message);
944 			if (!isatty(fileno(stdin)))
945 				exit(EXIT_FAILURE);
946 
947 			if (pkg_query_yes_no() == 0)
948 				exit(EXIT_FAILURE);
949 		}
950 		if (bootstrap_pkg() != 0)
951 			exit(EXIT_FAILURE);
952 		config_finish();
953 	}
954 
955 	execv(pkgpath, argv);
956 
957 	/* NOT REACHED */
958 	return (EXIT_FAILURE);
959 }
960