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