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