]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/pkg/pkg.c
libfido2: update to 1.13.0
[FreeBSD/FreeBSD.git] / usr.sbin / pkg / pkg.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 #include <sys/param.h>
32 #include <sys/queue.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
35
36 #include <archive.h>
37 #include <archive_entry.h>
38 #include <dirent.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <fetch.h>
43 #include <getopt.h>
44 #include <libutil.h>
45 #include <paths.h>
46 #include <stdbool.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <ucl.h>
51
52 #include <openssl/err.h>
53 #include <openssl/ssl.h>
54
55 #include "dns_utils.h"
56 #include "config.h"
57 #include "hash.h"
58
59 struct sig_cert {
60         char *name;
61         unsigned char *sig;
62         int siglen;
63         unsigned char *cert;
64         int certlen;
65         bool trusted;
66 };
67
68 struct pubkey {
69         unsigned char *sig;
70         int siglen;
71 };
72
73 typedef enum {
74         HASH_UNKNOWN,
75         HASH_SHA256,
76 } hash_t;
77
78 struct fingerprint {
79         hash_t type;
80         char *name;
81         char hash[BUFSIZ];
82         STAILQ_ENTRY(fingerprint) next;
83 };
84
85 static const char *bootstrap_names []  = {
86         "pkg.pkg",
87         "pkg.txz",
88         NULL
89 };
90
91 STAILQ_HEAD(fingerprint_list, fingerprint);
92
93 static int debug;
94
95 static int
96 extract_pkg_static(int fd, char *p, int sz)
97 {
98         struct archive *a;
99         struct archive_entry *ae;
100         char *end;
101         int ret, r;
102
103         ret = -1;
104         a = archive_read_new();
105         if (a == NULL) {
106                 warn("archive_read_new");
107                 return (ret);
108         }
109         archive_read_support_filter_all(a);
110         archive_read_support_format_tar(a);
111
112         if (lseek(fd, 0, 0) == -1) {
113                 warn("lseek");
114                 goto cleanup;
115         }
116
117         if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) {
118                 warnx("archive_read_open_fd: %s", archive_error_string(a));
119                 goto cleanup;
120         }
121
122         ae = NULL;
123         while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) {
124                 end = strrchr(archive_entry_pathname(ae), '/');
125                 if (end == NULL)
126                         continue;
127
128                 if (strcmp(end, "/pkg-static") == 0) {
129                         r = archive_read_extract(a, ae,
130                             ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM |
131                             ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL |
132                             ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR);
133                         strlcpy(p, archive_entry_pathname(ae), sz);
134                         break;
135                 }
136         }
137
138         if (r == ARCHIVE_OK)
139                 ret = 0;
140         else
141                 warnx("failed to extract pkg-static: %s",
142                     archive_error_string(a));
143
144 cleanup:
145         archive_read_free(a);
146         return (ret);
147
148 }
149
150 static int
151 install_pkg_static(const char *path, const char *pkgpath, bool force)
152 {
153         int pstat;
154         pid_t pid;
155
156         switch ((pid = fork())) {
157         case -1:
158                 return (-1);
159         case 0:
160                 if (force)
161                         execl(path, "pkg-static", "add", "-f", pkgpath,
162                             (char *)NULL);
163                 else
164                         execl(path, "pkg-static", "add", pkgpath,
165                             (char *)NULL);
166                 _exit(1);
167         default:
168                 break;
169         }
170
171         while (waitpid(pid, &pstat, 0) == -1)
172                 if (errno != EINTR)
173                         return (-1);
174
175         if (WEXITSTATUS(pstat))
176                 return (WEXITSTATUS(pstat));
177         else if (WIFSIGNALED(pstat))
178                 return (128 & (WTERMSIG(pstat)));
179         return (pstat);
180 }
181
182 static int
183 fetch_to_fd(const char *url, char *path, const char *fetchOpts)
184 {
185         struct url *u;
186         struct dns_srvinfo *mirrors, *current;
187         struct url_stat st;
188         FILE *remote;
189         /* To store _https._tcp. + hostname + \0 */
190         int fd;
191         int retry, max_retry;
192         ssize_t r;
193         char buf[10240];
194         char zone[MAXHOSTNAMELEN + 13];
195         static const char *mirror_type = NULL;
196
197         max_retry = 3;
198         current = mirrors = NULL;
199         remote = NULL;
200
201         if (mirror_type == NULL && config_string(MIRROR_TYPE, &mirror_type)
202             != 0) {
203                 warnx("No MIRROR_TYPE defined");
204                 return (-1);
205         }
206
207         if ((fd = mkstemp(path)) == -1) {
208                 warn("mkstemp()");
209                 return (-1);
210         }
211
212         retry = max_retry;
213
214         if ((u = fetchParseURL(url)) == NULL) {
215                 warn("fetchParseURL('%s')", url);
216                 return (-1);
217         }
218
219         while (remote == NULL) {
220                 if (retry == max_retry) {
221                         if (strcmp(u->scheme, "file") != 0 &&
222                             strcasecmp(mirror_type, "srv") == 0) {
223                                 snprintf(zone, sizeof(zone),
224                                     "_%s._tcp.%s", u->scheme, u->host);
225                                 mirrors = dns_getsrvinfo(zone);
226                                 current = mirrors;
227                         }
228                 }
229
230                 if (mirrors != NULL) {
231                         strlcpy(u->host, current->host, sizeof(u->host));
232                         u->port = current->port;
233                 }
234
235                 remote = fetchXGet(u, &st, fetchOpts);
236                 if (remote == NULL) {
237                         --retry;
238                         if (retry <= 0)
239                                 goto fetchfail;
240                         if (mirrors != NULL) {
241                                 current = current->next;
242                                 if (current == NULL)
243                                         current = mirrors;
244                         }
245                 }
246         }
247
248         while ((r = fread(buf, 1, sizeof(buf), remote)) > 0) {
249                 if (write(fd, buf, r) != r) {
250                         warn("write()");
251                         goto fetchfail;
252                 }
253         }
254
255         if (r != 0) {
256                 warn("An error occurred while fetching pkg(8)");
257                 goto fetchfail;
258         }
259
260         if (ferror(remote))
261                 goto fetchfail;
262
263         goto cleanup;
264
265 fetchfail:
266         if (fd != -1) {
267                 close(fd);
268                 fd = -1;
269                 unlink(path);
270         }
271
272 cleanup:
273         if (remote != NULL)
274                 fclose(remote);
275
276         return fd;
277 }
278
279 static struct fingerprint *
280 parse_fingerprint(ucl_object_t *obj)
281 {
282         const ucl_object_t *cur;
283         ucl_object_iter_t it = NULL;
284         const char *function, *fp, *key;
285         struct fingerprint *f;
286         hash_t fct = HASH_UNKNOWN;
287
288         function = fp = NULL;
289
290         while ((cur = ucl_iterate_object(obj, &it, true))) {
291                 key = ucl_object_key(cur);
292                 if (cur->type != UCL_STRING)
293                         continue;
294                 if (strcasecmp(key, "function") == 0) {
295                         function = ucl_object_tostring(cur);
296                         continue;
297                 }
298                 if (strcasecmp(key, "fingerprint") == 0) {
299                         fp = ucl_object_tostring(cur);
300                         continue;
301                 }
302         }
303
304         if (fp == NULL || function == NULL)
305                 return (NULL);
306
307         if (strcasecmp(function, "sha256") == 0)
308                 fct = HASH_SHA256;
309
310         if (fct == HASH_UNKNOWN) {
311                 warnx("Unsupported hashing function: %s", function);
312                 return (NULL);
313         }
314
315         f = calloc(1, sizeof(struct fingerprint));
316         f->type = fct;
317         strlcpy(f->hash, fp, sizeof(f->hash));
318
319         return (f);
320 }
321
322 static void
323 free_fingerprint_list(struct fingerprint_list* list)
324 {
325         struct fingerprint *fingerprint, *tmp;
326
327         STAILQ_FOREACH_SAFE(fingerprint, list, next, tmp) {
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         ucl_object_t *obj = NULL;
338         struct ucl_parser *p = NULL;
339         struct fingerprint *f;
340         char path[MAXPATHLEN];
341
342         f = NULL;
343
344         snprintf(path, MAXPATHLEN, "%s/%s", dir, filename);
345
346         p = ucl_parser_new(0);
347         if (!ucl_parser_add_file(p, path)) {
348                 warnx("%s: %s", path, ucl_parser_get_error(p));
349                 ucl_parser_free(p);
350                 return (NULL);
351         }
352
353         obj = ucl_parser_get_object(p);
354
355         if (obj->type == UCL_OBJECT)
356                 f = parse_fingerprint(obj);
357
358         if (f != NULL)
359                 f->name = strdup(filename);
360
361         ucl_object_unref(obj);
362         ucl_parser_free(p);
363
364         return (f);
365 }
366
367 static struct fingerprint_list *
368 load_fingerprints(const char *path, int *count)
369 {
370         DIR *d;
371         struct dirent *ent;
372         struct fingerprint *finger;
373         struct fingerprint_list *fingerprints;
374
375         *count = 0;
376
377         fingerprints = calloc(1, sizeof(struct fingerprint_list));
378         if (fingerprints == NULL)
379                 return (NULL);
380         STAILQ_INIT(fingerprints);
381
382         if ((d = opendir(path)) == NULL) {
383                 free(fingerprints);
384
385                 return (NULL);
386         }
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 EVP_PKEY *
405 load_public_key_file(const char *file)
406 {
407         EVP_PKEY *pkey;
408         BIO *bp;
409         char errbuf[1024];
410
411         bp = BIO_new_file(file, "r");
412         if (!bp)
413                 errx(EXIT_FAILURE, "Unable to read %s", file);
414
415         if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL)
416                 warnx("ici: %s", ERR_error_string(ERR_get_error(), errbuf));
417
418         BIO_free(bp);
419
420         return (pkey);
421 }
422
423 static EVP_PKEY *
424 load_public_key_buf(const unsigned char *cert, int certlen)
425 {
426         EVP_PKEY *pkey;
427         BIO *bp;
428         char errbuf[1024];
429
430         bp = BIO_new_mem_buf(__DECONST(void *, cert), certlen);
431
432         if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL)
433                 warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
434
435         BIO_free(bp);
436
437         return (pkey);
438 }
439
440 static bool
441 rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key,
442     int keylen, unsigned char *sig, int siglen)
443 {
444         EVP_MD_CTX *mdctx;
445         EVP_PKEY *pkey;
446         char *sha256;
447         char errbuf[1024];
448         bool ret;
449
450         sha256 = NULL;
451         pkey = NULL;
452         mdctx = NULL;
453         ret = false;
454
455         SSL_load_error_strings();
456
457         /* Compute SHA256 of the package. */
458         if (lseek(fd, 0, 0) == -1) {
459                 warn("lseek");
460                 goto cleanup;
461         }
462         if ((sha256 = sha256_fd(fd)) == NULL) {
463                 warnx("Error creating SHA256 hash for package");
464                 goto cleanup;
465         }
466
467         if (sigfile != NULL) {
468                 if ((pkey = load_public_key_file(sigfile)) == NULL) {
469                         warnx("Error reading public key");
470                         goto cleanup;
471                 }
472         } else {
473                 if ((pkey = load_public_key_buf(key, keylen)) == NULL) {
474                         warnx("Error reading public key");
475                         goto cleanup;
476                 }
477         }
478
479         /* Verify signature of the SHA256(pkg) is valid. */
480         if ((mdctx = EVP_MD_CTX_create()) == NULL) {
481                 warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
482                 goto error;
483         }
484
485         if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
486                 warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
487                 goto error;
488         }
489         if (EVP_DigestVerifyUpdate(mdctx, sha256, strlen(sha256)) != 1) {
490                 warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
491                 goto error;
492         }
493
494         if (EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) {
495                 warnx("%s", ERR_error_string(ERR_get_error(), errbuf));
496                 goto error;
497         }
498
499         ret = true;
500         printf("done\n");
501         goto cleanup;
502
503 error:
504         printf("failed\n");
505
506 cleanup:
507         free(sha256);
508         if (pkey)
509                 EVP_PKEY_free(pkey);
510         if (mdctx)
511                 EVP_MD_CTX_destroy(mdctx);
512         ERR_free_strings();
513
514         return (ret);
515 }
516
517 static struct pubkey *
518 read_pubkey(int fd)
519 {
520         struct pubkey *pk;
521         char *sigb;
522         size_t sigsz;
523         FILE *sig;
524         char buf[4096];
525         int r;
526
527         if (lseek(fd, 0, 0) == -1) {
528                 warn("lseek");
529                 return (NULL);
530         }
531
532         sigsz = 0;
533         sigb = NULL;
534         sig = open_memstream(&sigb, &sigsz);
535         if (sig == NULL)
536                 err(EXIT_FAILURE, "open_memstream()");
537
538         while ((r = read(fd, buf, sizeof(buf))) >0) {
539                 fwrite(buf, 1, r, sig);
540         }
541
542         fclose(sig);
543         pk = calloc(1, sizeof(struct pubkey));
544         pk->siglen = sigsz;
545         pk->sig = calloc(1, pk->siglen);
546         memcpy(pk->sig, sigb, pk->siglen);
547         free(sigb);
548
549         return (pk);
550 }
551
552 static struct sig_cert *
553 parse_cert(int fd) {
554         int my_fd;
555         struct sig_cert *sc;
556         FILE *fp, *sigfp, *certfp, *tmpfp;
557         char *line;
558         char *sig, *cert;
559         size_t linecap, sigsz, certsz;
560         ssize_t linelen;
561
562         sc = NULL;
563         line = NULL;
564         linecap = 0;
565         sig = cert = NULL;
566         sigfp = certfp = tmpfp = NULL;
567
568         if (lseek(fd, 0, 0) == -1) {
569                 warn("lseek");
570                 return (NULL);
571         }
572
573         /* Duplicate the fd so that fclose(3) does not close it. */
574         if ((my_fd = dup(fd)) == -1) {
575                 warnx("dup");
576                 return (NULL);
577         }
578
579         if ((fp = fdopen(my_fd, "rb")) == NULL) {
580                 warn("fdopen");
581                 close(my_fd);
582                 return (NULL);
583         }
584
585         sigsz = certsz = 0;
586         sigfp = open_memstream(&sig, &sigsz);
587         if (sigfp == NULL)
588                 err(EXIT_FAILURE, "open_memstream()");
589         certfp = open_memstream(&cert, &certsz);
590         if (certfp == NULL)
591                 err(EXIT_FAILURE, "open_memstream()");
592
593         while ((linelen = getline(&line, &linecap, fp)) > 0) {
594                 if (strcmp(line, "SIGNATURE\n") == 0) {
595                         tmpfp = sigfp;
596                         continue;
597                 } else if (strcmp(line, "CERT\n") == 0) {
598                         tmpfp = certfp;
599                         continue;
600                 } else if (strcmp(line, "END\n") == 0) {
601                         break;
602                 }
603                 if (tmpfp != NULL)
604                         fwrite(line, 1, linelen, tmpfp);
605         }
606
607         fclose(fp);
608         fclose(sigfp);
609         fclose(certfp);
610
611         sc = calloc(1, sizeof(struct sig_cert));
612         sc->siglen = sigsz -1; /* Trim out unrelated trailing newline */
613         sc->sig = sig;
614
615         sc->certlen = certsz;
616         sc->cert = cert;
617
618         return (sc);
619 }
620
621 static bool
622 verify_pubsignature(int fd_pkg, int fd_sig)
623 {
624         struct pubkey *pk;
625         const char *pubkey;
626         bool ret;
627
628         pk = NULL;
629         pubkey = NULL;
630         ret = false;
631         if (config_string(PUBKEY, &pubkey) != 0) {
632                 warnx("No CONFIG_PUBKEY defined");
633                 goto cleanup;
634         }
635
636         if ((pk = read_pubkey(fd_sig)) == NULL) {
637                 warnx("Error reading signature");
638                 goto cleanup;
639         }
640
641         /* Verify the signature. */
642         printf("Verifying signature with public key %s... ", pubkey);
643         if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig,
644             pk->siglen) == false) {
645                 fprintf(stderr, "Signature is not valid\n");
646                 goto cleanup;
647         }
648
649         ret = true;
650
651 cleanup:
652         if (pk) {
653                 free(pk->sig);
654                 free(pk);
655         }
656
657         return (ret);
658 }
659
660 static bool
661 verify_signature(int fd_pkg, int fd_sig)
662 {
663         struct fingerprint_list *trusted, *revoked;
664         struct fingerprint *fingerprint;
665         struct sig_cert *sc;
666         bool ret;
667         int trusted_count, revoked_count;
668         const char *fingerprints;
669         char path[MAXPATHLEN];
670         char *hash;
671
672         hash = NULL;
673         sc = NULL;
674         trusted = revoked = NULL;
675         ret = false;
676
677         /* Read and parse fingerprints. */
678         if (config_string(FINGERPRINTS, &fingerprints) != 0) {
679                 warnx("No CONFIG_FINGERPRINTS defined");
680                 goto cleanup;
681         }
682
683         snprintf(path, MAXPATHLEN, "%s/trusted", fingerprints);
684         if ((trusted = load_fingerprints(path, &trusted_count)) == NULL) {
685                 warnx("Error loading trusted certificates");
686                 goto cleanup;
687         }
688
689         if (trusted_count == 0 || trusted == NULL) {
690                 fprintf(stderr, "No trusted certificates found.\n");
691                 goto cleanup;
692         }
693
694         snprintf(path, MAXPATHLEN, "%s/revoked", fingerprints);
695         if ((revoked = load_fingerprints(path, &revoked_count)) == NULL) {
696                 warnx("Error loading revoked certificates");
697                 goto cleanup;
698         }
699
700         /* Read certificate and signature in. */
701         if ((sc = parse_cert(fd_sig)) == NULL) {
702                 warnx("Error parsing certificate");
703                 goto cleanup;
704         }
705         /* Explicitly mark as non-trusted until proven otherwise. */
706         sc->trusted = false;
707
708         /* Parse signature and pubkey out of the certificate */
709         hash = sha256_buf(sc->cert, sc->certlen);
710
711         /* Check if this hash is revoked */
712         if (revoked != NULL) {
713                 STAILQ_FOREACH(fingerprint, revoked, next) {
714                         if (strcasecmp(fingerprint->hash, hash) == 0) {
715                                 fprintf(stderr, "The package was signed with "
716                                     "revoked certificate %s\n",
717                                     fingerprint->name);
718                                 goto cleanup;
719                         }
720                 }
721         }
722
723         STAILQ_FOREACH(fingerprint, trusted, next) {
724                 if (strcasecmp(fingerprint->hash, hash) == 0) {
725                         sc->trusted = true;
726                         sc->name = strdup(fingerprint->name);
727                         break;
728                 }
729         }
730
731         if (sc->trusted == false) {
732                 fprintf(stderr, "No trusted fingerprint found matching "
733                     "package's certificate\n");
734                 goto cleanup;
735         }
736
737         /* Verify the signature. */
738         printf("Verifying signature with trusted certificate %s... ", sc->name);
739         if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig,
740             sc->siglen) == false) {
741                 fprintf(stderr, "Signature is not valid\n");
742                 goto cleanup;
743         }
744
745         ret = true;
746
747 cleanup:
748         free(hash);
749         if (trusted)
750                 free_fingerprint_list(trusted);
751         if (revoked)
752                 free_fingerprint_list(revoked);
753         if (sc) {
754                 free(sc->cert);
755                 free(sc->sig);
756                 free(sc->name);
757                 free(sc);
758         }
759
760         return (ret);
761 }
762
763 static int
764 bootstrap_pkg(bool force, const char *fetchOpts)
765 {
766         int fd_pkg, fd_sig;
767         int ret;
768         char url[MAXPATHLEN];
769         char tmppkg[MAXPATHLEN];
770         char tmpsig[MAXPATHLEN];
771         const char *packagesite;
772         const char *signature_type;
773         char pkgstatic[MAXPATHLEN];
774         const char *bootstrap_name;
775
776         fd_sig = -1;
777         ret = -1;
778
779         if (config_string(PACKAGESITE, &packagesite) != 0) {
780                 warnx("No PACKAGESITE defined");
781                 return (-1);
782         }
783
784         if (config_string(SIGNATURE_TYPE, &signature_type) != 0) {
785                 warnx("Error looking up SIGNATURE_TYPE");
786                 return (-1);
787         }
788
789         printf("Bootstrapping pkg from %s, please wait...\n", packagesite);
790
791         /* Support pkg+http:// for PACKAGESITE which is the new format
792            in 1.2 to avoid confusion on why http://pkg.FreeBSD.org has
793            no A record. */
794         if (strncmp(URL_SCHEME_PREFIX, packagesite,
795             strlen(URL_SCHEME_PREFIX)) == 0)
796                 packagesite += strlen(URL_SCHEME_PREFIX);
797         for (int j = 0; bootstrap_names[j] != NULL; j++) {
798                 bootstrap_name = bootstrap_names[j];
799
800                 snprintf(url, MAXPATHLEN, "%s/Latest/%s", packagesite, bootstrap_name);
801                 snprintf(tmppkg, MAXPATHLEN, "%s/%s.XXXXXX",
802                     getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
803                     bootstrap_name);
804                 if ((fd_pkg = fetch_to_fd(url, tmppkg, fetchOpts)) != -1)
805                         break;
806                 bootstrap_name = NULL;
807         }
808         if (bootstrap_name == NULL)
809                 goto fetchfail;
810
811         if (signature_type != NULL &&
812             strcasecmp(signature_type, "NONE") != 0) {
813                 if (strcasecmp(signature_type, "FINGERPRINTS") == 0) {
814
815                         snprintf(tmpsig, MAXPATHLEN, "%s/%s.sig.XXXXXX",
816                             getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
817                             bootstrap_name);
818                         snprintf(url, MAXPATHLEN, "%s/Latest/%s.sig",
819                             packagesite, bootstrap_name);
820
821                         if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) {
822                                 fprintf(stderr, "Signature for pkg not "
823                                     "available.\n");
824                                 goto fetchfail;
825                         }
826
827                         if (verify_signature(fd_pkg, fd_sig) == false)
828                                 goto cleanup;
829                 } else if (strcasecmp(signature_type, "PUBKEY") == 0) {
830
831                         snprintf(tmpsig, MAXPATHLEN,
832                             "%s/%s.pubkeysig.XXXXXX",
833                             getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
834                             bootstrap_name);
835                         snprintf(url, MAXPATHLEN, "%s/Latest/%s.pubkeysig",
836                             packagesite, bootstrap_name);
837
838                         if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) {
839                                 fprintf(stderr, "Signature for pkg not "
840                                     "available.\n");
841                                 goto fetchfail;
842                         }
843
844                         if (verify_pubsignature(fd_pkg, fd_sig) == false)
845                                 goto cleanup;
846                 } else {
847                         warnx("Signature type %s is not supported for "
848                             "bootstrapping.", signature_type);
849                         goto cleanup;
850                 }
851         }
852
853         if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
854                 ret = install_pkg_static(pkgstatic, tmppkg, force);
855
856         goto cleanup;
857
858 fetchfail:
859         warnx("Error fetching %s: %s", url, fetchLastErrString);
860         if (fetchLastErrCode == FETCH_RESOLV) {
861                 fprintf(stderr, "Address resolution failed for %s.\n", packagesite);
862                 fprintf(stderr, "Consider changing PACKAGESITE.\n");
863         } else {
864                 fprintf(stderr, "A pre-built version of pkg could not be found for "
865                     "your system.\n");
866                 fprintf(stderr, "Consider changing PACKAGESITE or installing it from "
867                     "ports: 'ports-mgmt/pkg'.\n");
868         }
869
870 cleanup:
871         if (fd_sig != -1) {
872                 close(fd_sig);
873                 unlink(tmpsig);
874         }
875
876         if (fd_pkg != -1) {
877                 close(fd_pkg);
878                 unlink(tmppkg);
879         }
880
881         return (ret);
882 }
883
884 static const char confirmation_message[] =
885 "The package management tool is not yet installed on your system.\n"
886 "Do you want to fetch and install it now? [y/N]: ";
887
888 static const char non_interactive_message[] =
889 "The package management tool is not yet installed on your system.\n"
890 "Please set ASSUME_ALWAYS_YES=yes environment variable to be able to bootstrap "
891 "in non-interactive (stdin not being a tty)\n";
892
893 static const char args_bootstrap_message[] =
894 "Too many arguments\n"
895 "Usage: pkg [-4|-6] bootstrap [-f] [-y]\n";
896
897 static const char args_add_message[] =
898 "Too many arguments\n"
899 "Usage: pkg add [-f] [-y] {pkg.txz}\n";
900
901 static int
902 pkg_query_yes_no(void)
903 {
904         int ret, c;
905
906         fflush(stdout);
907         c = getchar();
908
909         if (c == 'y' || c == 'Y')
910                 ret = 1;
911         else
912                 ret = 0;
913
914         while (c != '\n' && c != EOF)
915                 c = getchar();
916
917         return (ret);
918 }
919
920 static int
921 bootstrap_pkg_local(const char *pkgpath, bool force)
922 {
923         char path[MAXPATHLEN];
924         char pkgstatic[MAXPATHLEN];
925         const char *signature_type;
926         int fd_pkg, fd_sig, ret;
927
928         fd_sig = -1;
929         ret = -1;
930
931         fd_pkg = open(pkgpath, O_RDONLY);
932         if (fd_pkg == -1)
933                 err(EXIT_FAILURE, "Unable to open %s", pkgpath);
934
935         if (config_string(SIGNATURE_TYPE, &signature_type) != 0) {
936                 warnx("Error looking up SIGNATURE_TYPE");
937                 goto cleanup;
938         }
939         if (signature_type != NULL &&
940             strcasecmp(signature_type, "NONE") != 0) {
941                 if (strcasecmp(signature_type, "FINGERPRINTS") == 0) {
942
943                         snprintf(path, sizeof(path), "%s.sig", pkgpath);
944
945                         if ((fd_sig = open(path, O_RDONLY)) == -1) {
946                                 fprintf(stderr, "Signature for pkg not "
947                                     "available.\n");
948                                 goto cleanup;
949                         }
950
951                         if (verify_signature(fd_pkg, fd_sig) == false)
952                                 goto cleanup;
953
954                 } else if (strcasecmp(signature_type, "PUBKEY") == 0) {
955
956                         snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath);
957
958                         if ((fd_sig = open(path, O_RDONLY)) == -1) {
959                                 fprintf(stderr, "Signature for pkg not "
960                                     "available.\n");
961                                 goto cleanup;
962                         }
963
964                         if (verify_pubsignature(fd_pkg, fd_sig) == false)
965                                 goto cleanup;
966
967                 } else {
968                         warnx("Signature type %s is not supported for "
969                             "bootstrapping.", signature_type);
970                         goto cleanup;
971                 }
972         }
973
974         if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
975                 ret = install_pkg_static(pkgstatic, pkgpath, force);
976
977 cleanup:
978         close(fd_pkg);
979         if (fd_sig != -1)
980                 close(fd_sig);
981
982         return (ret);
983 }
984
985 #define PKG_NAME        "pkg"
986 #define PKG_DEVEL_NAME  PKG_NAME "-devel"
987 #define PKG_PKG         PKG_NAME "."
988
989 static bool
990 pkg_is_pkg_pkg(const char *pkg)
991 {
992         char *vstart, *basename;
993         size_t namelen;
994
995         /* Strip path. */
996         if ((basename = strrchr(pkg, '/')) != NULL)
997                 pkg = basename + 1;
998
999         /*
1000          * Chop off the final "-" (version delimiter) and check the name that
1001          * precedes it.  If we didn't have a version delimiter, it must be the
1002          * pkg.$archive short form but we'll check it anyways.  pkg-devel short
1003          * form will look like a pkg archive with 'devel' version, but that's
1004          * OK.  We otherwise assumed that non-pkg packages will always have a
1005          * version component.
1006          */
1007         vstart = strrchr(pkg, '-');
1008         if (vstart == NULL) {
1009                 return (strlen(pkg) > sizeof(PKG_PKG) - 1 &&
1010                     strncmp(pkg, PKG_PKG, sizeof(PKG_PKG) - 1) == 0);
1011         }
1012
1013         namelen = vstart - pkg;
1014         if (namelen == sizeof(PKG_NAME) - 1 &&
1015             strncmp(pkg, PKG_NAME, sizeof(PKG_NAME) - 1) == 0)
1016                 return (true);
1017         if (namelen == sizeof(PKG_DEVEL_NAME) - 1 &&
1018             strncmp(pkg, PKG_DEVEL_NAME, sizeof(PKG_DEVEL_NAME) - 1) == 0)
1019                 return (true);
1020         return (false);
1021 }
1022
1023 int
1024 main(int argc, char *argv[])
1025 {
1026         char pkgpath[MAXPATHLEN];
1027         const char *pkgarg, *repo_name;
1028         bool activation_test, add_pkg, bootstrap_only, force, yes;
1029         signed char ch;
1030         const char *fetchOpts;
1031         char *command;
1032
1033         activation_test = false;
1034         add_pkg = false;
1035         bootstrap_only = false;
1036         command = NULL;
1037         fetchOpts = "";
1038         force = false;
1039         pkgarg = NULL;
1040         repo_name = NULL;
1041         yes = false;
1042
1043         struct option longopts[] = {
1044                 { "debug",              no_argument,            NULL,   'd' },
1045                 { "force",              no_argument,            NULL,   'f' },
1046                 { "only-ipv4",          no_argument,            NULL,   '4' },
1047                 { "only-ipv6",          no_argument,            NULL,   '6' },
1048                 { "yes",                no_argument,            NULL,   'y' },
1049                 { NULL,                 0,                      NULL,   0   },
1050         };
1051
1052         snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", getlocalbase());
1053
1054         while ((ch = getopt_long(argc, argv, "-:dfr::yN46", longopts, NULL)) != -1) {
1055                 switch (ch) {
1056                 case 'd':
1057                         debug++;
1058                         break;
1059                 case 'f':
1060                         force = true;
1061                         break;
1062                 case 'N':
1063                         activation_test = true;
1064                         break;
1065                 case 'y':
1066                         yes = true;
1067                         break;
1068                 case '4':
1069                         fetchOpts = "4";
1070                         break;
1071                 case '6':
1072                         fetchOpts = "6";
1073                         break;
1074                 case 'r':
1075                         /*
1076                          * The repository can only be specified for an explicit
1077                          * bootstrap request at this time, so that we don't
1078                          * confuse the user if they're trying to use a verb that
1079                          * has some other conflicting meaning but we need to
1080                          * bootstrap.
1081                          *
1082                          * For that reason, we specify that -r has an optional
1083                          * argument above and process the next index ourselves.
1084                          * This is mostly significant because getopt(3) will
1085                          * otherwise eat the next argument, which could be
1086                          * something we need to try and make sense of.
1087                          *
1088                          * At worst this gets us false positives that we ignore
1089                          * in other contexts, and we have to do a little fudging
1090                          * in order to support separating -r from the reponame
1091                          * with a space since it's not actually optional in
1092                          * the bootstrap/add sense.
1093                          */
1094                         if (add_pkg || bootstrap_only) {
1095                                 if (optarg != NULL) {
1096                                         repo_name = optarg;
1097                                 } else if (optind < argc) {
1098                                         repo_name = argv[optind];
1099                                 }
1100
1101                                 if (repo_name == NULL || *repo_name == '\0') {
1102                                         fprintf(stderr,
1103                                             "Must specify a repository with -r!\n");
1104                                         exit(EXIT_FAILURE);
1105                                 }
1106
1107                                 if (optarg == NULL) {
1108                                         /* Advance past repo name. */
1109                                         optreset = 1;
1110                                         optind++;
1111                                 }
1112                         }
1113                         break;
1114                 case 1:
1115                         // Non-option arguments, first one is the command
1116                         if (command == NULL) {
1117                                 command = argv[optind-1];
1118                                 if (strcmp(command, "add") == 0) {
1119                                         add_pkg = true;
1120                                 }
1121                                 else if (strcmp(command, "bootstrap") == 0) {
1122                                         bootstrap_only = true;
1123                                 }
1124                         }
1125                         // bootstrap doesn't accept other arguments
1126                         else if (bootstrap_only) {
1127                                 fprintf(stderr, args_bootstrap_message);
1128                                 exit(EXIT_FAILURE);
1129                         }
1130                         else if (add_pkg && pkgarg != NULL) {
1131                                 /*
1132                                  * Additional arguments also means it's not a
1133                                  * local bootstrap request.
1134                                  */
1135                                 add_pkg = false;
1136                         }
1137                         else if (add_pkg) {
1138                                 /*
1139                                  * If it's not a request for pkg or pkg-devel,
1140                                  * then we must assume they were trying to
1141                                  * install some other local package and we
1142                                  * should try to bootstrap from the repo.
1143                                  */
1144                                 if (!pkg_is_pkg_pkg(argv[optind-1])) {
1145                                         add_pkg = false;
1146                                 } else {
1147                                         pkgarg = argv[optind-1];
1148                                 }
1149                         }
1150                         break;
1151                 default:
1152                         break;
1153                 }
1154         }
1155         if (debug > 1)
1156                 fetchDebug = 1;
1157
1158         if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) {
1159                 /*
1160                  * To allow 'pkg -N' to be used as a reliable test for whether
1161                  * a system is configured to use pkg, don't bootstrap pkg
1162                  * when that option is passed.
1163                  */
1164                 if (activation_test)
1165                         errx(EXIT_FAILURE, "pkg is not installed");
1166
1167                 config_init(repo_name);
1168
1169                 if (add_pkg) {
1170                         if (pkgarg == NULL) {
1171                                 fprintf(stderr, "Path to pkg.txz required\n");
1172                                 exit(EXIT_FAILURE);
1173                         }
1174                         if (access(pkgarg, R_OK) == -1) {
1175                                 fprintf(stderr, "No such file: %s\n", pkgarg);
1176                                 exit(EXIT_FAILURE);
1177                         }
1178                         if (bootstrap_pkg_local(pkgarg, force) != 0)
1179                                 exit(EXIT_FAILURE);
1180                         exit(EXIT_SUCCESS);
1181                 }
1182                 /*
1183                  * Do not ask for confirmation if either of stdin or stdout is
1184                  * not tty. Check the environment to see if user has answer
1185                  * tucked in there already.
1186                  */
1187                 if (!yes)
1188                         config_bool(ASSUME_ALWAYS_YES, &yes);
1189                 if (!yes) {
1190                         if (!isatty(fileno(stdin))) {
1191                                 fprintf(stderr, non_interactive_message);
1192                                 exit(EXIT_FAILURE);
1193                         }
1194
1195                         printf("%s", confirmation_message);
1196                         if (pkg_query_yes_no() == 0)
1197                                 exit(EXIT_FAILURE);
1198                 }
1199                 if (bootstrap_pkg(force, fetchOpts) != 0)
1200                         exit(EXIT_FAILURE);
1201                 config_finish();
1202
1203                 if (bootstrap_only)
1204                         exit(EXIT_SUCCESS);
1205         } else if (bootstrap_only) {
1206                 printf("pkg already bootstrapped at %s\n", pkgpath);
1207                 exit(EXIT_SUCCESS);
1208         }
1209
1210         execv(pkgpath, argv);
1211
1212         /* NOT REACHED */
1213         return (EXIT_FAILURE);
1214 }