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