1 /*-
2 * Copyright (c) 2011-2019 Baptiste Daroussin <bapt@FreeBSD.org>
3 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
5 * Copyright (c) 2012-2015 Matthew Seaman <matthew@FreeBSD.org>
6 * Copyright (c) 2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer
15 * in this position and unchanged.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/uio.h>
35
36 #include <archive_entry.h>
37 #include <assert.h>
38 #include <fts.h>
39 #include <libgen.h>
40 #include <sqlite3.h>
41 #include <string.h>
42 #include <dirent.h>
43 #define _WITH_GETLINE
44 #include <stdio.h>
45 #include <stdbool.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <sys/mman.h>
49 #include <fcntl.h>
50
51 #include "pkg.h"
52 #include "private/event.h"
53 #include "private/utils.h"
54 #include "private/pkg.h"
55 #include "private/pkgdb.h"
56
57 struct sig_cert {
58 char name[MAXPATHLEN];
59 char *sig;
60 int64_t siglen;
61 char *cert;
62 int64_t certlen;
63 bool cert_allocated;
64 UT_hash_handle hh;
65 bool trusted;
66 };
67
68 static int
pkg_repo_fetch_remote_tmp(struct pkg_repo * repo,const char * filename,const char * extension,time_t * t,int * rc,bool silent)69 pkg_repo_fetch_remote_tmp(struct pkg_repo *repo,
70 const char *filename, const char *extension, time_t *t, int *rc, bool silent)
71 {
72 char url[MAXPATHLEN];
73 char tmp[MAXPATHLEN];
74 int fd;
75 const char *tmpdir, *dot;
76
77 /*
78 * XXX: here we support old naming scheme, such as filename.yaml
79 */
80 dot = strrchr(filename, '.');
81 if (dot != NULL) {
82 snprintf(tmp, MIN(sizeof(tmp), dot - filename + 1), "%s", filename);
83 snprintf(url, sizeof(url), "%s/%s.%s", pkg_repo_url(repo), tmp,
84 extension);
85 }
86 else {
87 snprintf(url, sizeof(url), "%s/%s.%s", pkg_repo_url(repo), filename,
88 extension);
89 }
90
91 tmpdir = getenv("TMPDIR");
92 if (tmpdir == NULL)
93 tmpdir = "/tmp";
94 mkdirs(tmpdir);
95 snprintf(tmp, sizeof(tmp), "%s/%s.%s.XXXXXX", tmpdir, filename, extension);
96
97 fd = mkstemp(tmp);
98 if (fd == -1) {
99 pkg_emit_error("Could not create temporary file %s, "
100 "aborting update.\n", tmp);
101 *rc = EPKG_FATAL;
102 return (-1);
103 }
104 (void)unlink(tmp);
105
106 if ((*rc = pkg_fetch_file_to_fd(repo, url, fd, t, -1, 0, silent)) != EPKG_OK) {
107 close(fd);
108 fd = -1;
109 }
110
111 return (fd);
112 }
113
114 static bool
pkg_repo_file_has_ext(const char * path,const char * ext)115 pkg_repo_file_has_ext(const char *path, const char *ext)
116 {
117 size_t n, l;
118 const char *p = NULL;
119
120 n = strlen(path);
121 l = strlen(ext);
122 p = &path[n - l];
123
124 if (strcmp(p, ext) == 0)
125 return (true);
126
127 return (false);
128 }
129
130 static bool
pkg_repo_check_fingerprint(struct pkg_repo * repo,struct sig_cert * sc,bool fatal)131 pkg_repo_check_fingerprint(struct pkg_repo *repo, struct sig_cert *sc, bool fatal)
132 {
133 struct fingerprint *f = NULL;
134 char *hash;
135 int nbgood = 0;
136 struct sig_cert *s = NULL, *stmp = NULL;
137 struct pkg_repo_meta_key *mk = NULL;
138
139 if (HASH_COUNT(sc) == 0) {
140 if (fatal)
141 pkg_emit_error("No signature found");
142 return (false);
143 }
144
145 /* load fingerprints */
146 if (repo->trusted_fp == NULL) {
147 if (pkg_repo_load_fingerprints(repo) != EPKG_OK)
148 return (false);
149 }
150
151 HASH_ITER(hh, sc, s, stmp) {
152 if (s->sig != NULL && s->cert == NULL) {
153 /*
154 * We may want to check meta
155 */
156 if (repo->meta != NULL && repo->meta->keys != NULL)
157 HASH_FIND_STR(repo->meta->keys, s->name, mk);
158
159 if (mk != NULL && mk->pubkey != NULL) {
160 s->cert = mk->pubkey;
161 s->certlen = strlen(mk->pubkey);
162 }
163 else {
164 if (fatal)
165 pkg_emit_error("No key with name %s has been found", s->name);
166 return (false);
167 }
168 }
169 else if (s->sig == NULL) {
170 if (fatal)
171 pkg_emit_error("No signature with name %s has been found", s->name);
172 return (false);
173 }
174
175 s->trusted = false;
176 hash = pkg_checksum_data(s->cert, s->certlen,
177 PKG_HASH_TYPE_SHA256_HEX);
178 HASH_FIND_STR(repo->revoked_fp, hash, f);
179 if (f != NULL) {
180 if (fatal)
181 pkg_emit_error("At least one of the "
182 "certificates has been revoked");
183
184 free(hash);
185 return (false);
186 }
187
188 HASH_FIND_STR(repo->trusted_fp, hash, f);
189 free(hash);
190 if (f != NULL) {
191 nbgood++;
192 s->trusted = true;
193 }
194 }
195
196 if (nbgood == 0) {
197 if (fatal)
198 pkg_emit_error("No trusted public keys found");
199
200 return (false);
201 }
202
203 return (true);
204 }
205
206 static void
pkg_repo_signatures_free(struct sig_cert * sc)207 pkg_repo_signatures_free(struct sig_cert *sc)
208 {
209 struct sig_cert *s, *stmp;
210
211 HASH_ITER(hh, sc, s, stmp) {
212 HASH_DELETE(hh, sc, s);
213 free(s->sig);
214 if (s->cert_allocated)
215 free(s->cert);
216 free(s);
217 }
218 }
219
220
221 struct pkg_extract_cbdata {
222 int afd;
223 int tfd;
224 const char *fname;
225 bool need_sig;
226 };
227
228 static int
pkg_repo_write_sig_from_archive(struct archive * a,int fd,size_t siglen)229 pkg_repo_write_sig_from_archive(struct archive *a, int fd, size_t siglen)
230 {
231 char sig[siglen];
232
233 if (archive_read_data(a, sig, siglen) == -1) {
234 pkg_emit_errno("pkg_repo_meta_extract_signature",
235 "archive_read_data failed");
236 return (EPKG_FATAL);
237 }
238 if (write(fd, sig, siglen) == -1) {
239 pkg_emit_errno("pkg_repo_meta_extract_signature",
240 "write failed");
241 return (EPKG_FATAL);
242 }
243 return (EPKG_OK);
244 }
245
246 static int
pkg_repo_meta_extract_signature_pubkey(int fd,void * ud)247 pkg_repo_meta_extract_signature_pubkey(int fd, void *ud)
248 {
249 struct archive *a = NULL;
250 struct archive_entry *ae = NULL;
251 struct pkg_extract_cbdata *cb = ud;
252 int siglen;
253 int rc = EPKG_FATAL;
254
255 pkg_debug(1, "PkgRepo: extracting signature of repo in a sandbox");
256
257 a = archive_read_new();
258 archive_read_support_filter_all(a);
259 archive_read_support_format_tar(a);
260
261 archive_read_open_fd(a, cb->afd, 4096);
262
263 while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
264 if (cb->need_sig && strcmp(archive_entry_pathname(ae), "signature") == 0) {
265 siglen = archive_entry_size(ae);
266 rc = pkg_repo_write_sig_from_archive(a, fd, siglen);
267 if (rc != EPKG_OK)
268 break;
269 }
270 else if (strcmp(archive_entry_pathname(ae), cb->fname) == 0) {
271 if (archive_read_data_into_fd(a, cb->tfd) != 0) {
272 pkg_emit_errno("archive_read_extract", "extract error");
273 rc = EPKG_FATAL;
274 break;
275 }
276 else if (!cb->need_sig) {
277 rc = EPKG_OK;
278 }
279 }
280 }
281
282 close(cb->tfd);
283 /*
284 * XXX: do not free resources here since the sandbox is terminated anyway
285 */
286 return (rc);
287 }
288 /*
289 * We use here the following format:
290 * <type(0|1)><namelen(int)><name><datalen(int)><data>
291 */
292 static int
pkg_repo_meta_extract_signature_fingerprints(int fd,void * ud)293 pkg_repo_meta_extract_signature_fingerprints(int fd, void *ud)
294 {
295 struct archive *a = NULL;
296 struct archive_entry *ae = NULL;
297 struct pkg_extract_cbdata *cb = ud;
298 int siglen, keylen;
299 void *sig;
300 int rc = EPKG_FATAL;
301 char key[MAXPATHLEN], t;
302 struct iovec iov[5];
303
304 pkg_debug(1, "PkgRepo: extracting signature of repo in a sandbox");
305
306 a = archive_read_new();
307 archive_read_support_filter_all(a);
308 archive_read_support_format_tar(a);
309
310 archive_read_open_fd(a, cb->afd, 4096);
311
312 while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
313 if (pkg_repo_file_has_ext(archive_entry_pathname(ae), ".sig")) {
314 snprintf(key, sizeof(key), "%.*s",
315 (int) strlen(archive_entry_pathname(ae)) - 4,
316 archive_entry_pathname(ae));
317 siglen = archive_entry_size(ae);
318 sig = xmalloc(siglen);
319 if (archive_read_data(a, sig, siglen) == -1) {
320 pkg_emit_errno("pkg_repo_meta_extract_signature",
321 "archive_read_data failed");
322 free(sig);
323 return (EPKG_FATAL);
324 }
325 /* Signature type */
326 t = 0;
327 keylen = strlen(key);
328 iov[0].iov_base = &t;
329 iov[0].iov_len = sizeof(t);
330 iov[1].iov_base = &keylen;
331 iov[1].iov_len = sizeof(keylen);
332 iov[2].iov_base = key;
333 iov[2].iov_len = keylen;
334 iov[3].iov_base = &siglen;
335 iov[3].iov_len = sizeof(siglen);
336 iov[4].iov_base = sig;
337 iov[4].iov_len = siglen;
338 if (writev(fd, iov, NELEM(iov)) == -1) {
339 pkg_emit_errno("pkg_repo_meta_extract_signature",
340 "writev failed");
341 free(sig);
342 return (EPKG_FATAL);
343 }
344 free(sig);
345 rc = EPKG_OK;
346 }
347 else if (pkg_repo_file_has_ext(archive_entry_pathname(ae), ".pub")) {
348 snprintf(key, sizeof(key), "%.*s",
349 (int) strlen(archive_entry_pathname(ae)) - 4,
350 archive_entry_pathname(ae));
351 siglen = archive_entry_size(ae);
352 sig = xmalloc(siglen);
353 if (archive_read_data(a, sig, siglen) == -1) {
354 pkg_emit_errno("pkg_repo_meta_extract_signature",
355 "archive_read_data failed");
356 free(sig);
357 return (EPKG_FATAL);
358 }
359 /* Pubkey type */
360 t = 1;
361 keylen = strlen(key);
362 iov[0].iov_base = &t;
363 iov[0].iov_len = sizeof(t);
364 iov[1].iov_base = &keylen;
365 iov[1].iov_len = sizeof(keylen);
366 iov[2].iov_base = key;
367 iov[2].iov_len = keylen;
368 iov[3].iov_base = &siglen;
369 iov[3].iov_len = sizeof(siglen);
370 iov[4].iov_base = sig;
371 iov[4].iov_len = siglen;
372 if (writev(fd, iov, NELEM(iov)) == -1) {
373 pkg_emit_errno("pkg_repo_meta_extract_signature",
374 "writev failed");
375 free(sig);
376 return (EPKG_FATAL);
377 }
378 free(sig);
379 rc = EPKG_OK;
380 }
381 else {
382 if (strcmp(archive_entry_pathname(ae), cb->fname) == 0) {
383 if (archive_read_data_into_fd(a, cb->tfd) != 0) {
384 pkg_emit_errno("archive_read_extract", "extract error");
385 rc = EPKG_FATAL;
386 break;
387 }
388 }
389 }
390 }
391 close(cb->tfd);
392 /*
393 * XXX: do not free resources here since the sandbox is terminated anyway
394 */
395 return (rc);
396 }
397
398 static int
pkg_repo_parse_sigkeys(const char * in,int inlen,struct sig_cert ** sc)399 pkg_repo_parse_sigkeys(const char *in, int inlen, struct sig_cert **sc)
400 {
401 const char *p = in, *end = in + inlen;
402 int rc = EPKG_OK;
403 enum {
404 fp_parse_type,
405 fp_parse_flen,
406 fp_parse_file,
407 fp_parse_siglen,
408 fp_parse_sig
409 } state = fp_parse_type;
410 char type = 0;
411 unsigned char *sig;
412 int len = 0, tlen;
413 struct sig_cert *s = NULL;
414 bool new = false;
415
416 while (p < end) {
417 switch (state) {
418 case fp_parse_type:
419 type = *p;
420 if (type != 0 && type != 1) {
421 /* Invalid type */
422 pkg_emit_error("%d is not a valid type for signature_fingerprints"
423 " output", type);
424 return (EPKG_FATAL);
425 }
426 state = fp_parse_flen;
427 s = NULL;
428 p ++;
429 break;
430 case fp_parse_flen:
431 if (end - p < sizeof (int)) {
432 pkg_emit_error("truncated reply for signature_fingerprints"
433 " output");
434 return (EPKG_FATAL);
435 }
436 memcpy(&len, p, sizeof(int));
437 state = fp_parse_file;
438 p += sizeof(int);
439 s = NULL;
440 break;
441 case fp_parse_file:
442 if (end - p < len || len <= 0) {
443 pkg_emit_error("truncated reply for signature_fingerprints"
444 " output, wanted %d bytes", len);
445 return (EPKG_FATAL);
446 }
447 else if (len >= MAXPATHLEN) {
448 pkg_emit_error("filename is incorrect for signature_fingerprints"
449 " output: %d, wanted 5..%d bytes", type, len);
450 free(s);
451 return (EPKG_FATAL);
452 }
453 HASH_FIND(hh, *sc, p, len, s);
454 if (s == NULL) {
455 s = xcalloc(1, sizeof(struct sig_cert));
456 tlen = MIN(len, sizeof(s->name) - 1);
457 memcpy(s->name, p, tlen);
458 s->name[tlen] = '\0';
459 new = true;
460 }
461 else {
462 new = false;
463 }
464 state = fp_parse_siglen;
465 p += len;
466 break;
467 case fp_parse_siglen:
468 if (s == NULL) {
469 pkg_emit_error("fatal state machine failure at pkg_repo_parse_sigkeys");
470 return (EPKG_FATAL);
471 }
472 if (end - p < sizeof (int)) {
473 pkg_emit_error("truncated reply for signature_fingerprints"
474 "output");
475 free(s);
476 return (EPKG_FATAL);
477 }
478 memcpy(&len, p, sizeof(int));
479 state = fp_parse_sig;
480 p += sizeof(int);
481 break;
482 case fp_parse_sig:
483 if (s == NULL) {
484 pkg_emit_error("fatal state machine failure at pkg_repo_parse_sigkeys");
485 return (EPKG_FATAL);
486 }
487 if (end - p < len || len <= 0) {
488 pkg_emit_error("truncated reply for signature_fingerprints"
489 "output, wanted %d bytes", len);
490 free(s);
491 return (EPKG_FATAL);
492 }
493 sig = xmalloc(len);
494 memcpy(sig, p, len);
495 if (type == 0) {
496 s->sig = sig;
497 s->siglen = len;
498 }
499 else {
500 s->cert = sig;
501 s->certlen = len;
502 s->cert_allocated = true;
503 }
504 state = fp_parse_type;
505 p += len;
506
507 if (new)
508 HASH_ADD_STR(*sc, name, s);
509
510 break;
511 }
512 }
513
514 return (rc);
515 }
516
517 static int
pkg_repo_archive_extract_archive(int fd,const char * file,struct pkg_repo * repo,int dest_fd,struct sig_cert ** signatures)518 pkg_repo_archive_extract_archive(int fd, const char *file,
519 struct pkg_repo *repo, int dest_fd,
520 struct sig_cert **signatures)
521 {
522 struct sig_cert *sc = NULL, *s;
523 struct pkg_extract_cbdata cbdata;
524
525 char *sig = NULL;
526 int rc = EPKG_OK;
527 int64_t siglen = 0;
528
529
530 pkg_debug(1, "PkgRepo: extracting %s of repo %s", file, pkg_repo_name(repo));
531
532 /* Seek to the begin of file */
533 (void)lseek(fd, 0, SEEK_SET);
534
535 cbdata.afd = fd;
536 cbdata.fname = file;
537 cbdata.tfd = dest_fd;
538
539 if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
540 cbdata.need_sig = true;
541 if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_signature_pubkey,
542 &cbdata, (char **)&sig, &siglen) == EPKG_OK && sig != NULL) {
543 s = xcalloc(1, sizeof(struct sig_cert));
544 s->sig = sig;
545 s->siglen = siglen;
546 strlcpy(s->name, "signature", sizeof(s->name));
547 HASH_ADD_STR(sc, name, s);
548 }
549 }
550 else if (pkg_repo_signature_type(repo) == SIG_FINGERPRINT) {
551 if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_signature_fingerprints,
552 &cbdata, (char **)&sig, &siglen) == EPKG_OK && sig != NULL &&
553 siglen > 0) {
554 if (pkg_repo_parse_sigkeys(sig, siglen, &sc) == EPKG_FATAL) {
555 return (EPKG_FATAL);
556 }
557 free(sig);
558 if (!pkg_repo_check_fingerprint(repo, sc, true)) {
559 return (EPKG_FATAL);
560 }
561 }
562 else {
563 pkg_emit_error("No signature found");
564 return (EPKG_FATAL);
565 }
566 }
567 else {
568 cbdata.need_sig = false;
569 if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_signature_pubkey,
570 &cbdata, (char **)&sig, &siglen) == EPKG_OK) {
571 free(sig);
572 }
573 else {
574 pkg_emit_error("Repo extraction failed");
575 return (EPKG_FATAL);
576 }
577 }
578 (void)lseek(fd, 0, SEEK_SET);
579 if (dest_fd != -1)
580 (void)lseek(dest_fd, 0, SEEK_SET);
581
582 if (rc == EPKG_OK) {
583 if (signatures != NULL)
584 *signatures = sc;
585 else
586 pkg_repo_signatures_free(sc);
587 }
588 else {
589 pkg_repo_signatures_free(sc);
590 }
591
592 return rc;
593 }
594
595 static int
pkg_repo_archive_extract_check_archive(int fd,const char * file,struct pkg_repo * repo,int dest_fd)596 pkg_repo_archive_extract_check_archive(int fd, const char *file,
597 struct pkg_repo *repo, int dest_fd)
598 {
599 struct sig_cert *sc = NULL, *s, *stmp;
600 int ret, rc;
601
602 ret = rc = EPKG_OK;
603
604 if (pkg_repo_archive_extract_archive(fd, file, repo, dest_fd, &sc)
605 != EPKG_OK)
606 return (EPKG_FATAL);
607
608 if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
609 if (pkg_repo_key(repo) == NULL) {
610 pkg_emit_error("No PUBKEY defined. Removing "
611 "repository.");
612 rc = EPKG_FATAL;
613 goto out;
614 }
615 if (sc == NULL) {
616 pkg_emit_error("No signature found in the repository. "
617 "Can not validate against %s key.", pkg_repo_key(repo));
618 rc = EPKG_FATAL;
619 goto out;
620 }
621 /*
622 * Here are dragons:
623 * 1) rsa_verify is NOT rsa_verify_cert
624 * 2) siglen must be reduced by one to match how pkg_repo_finish()
625 * packs the signature in.
626 *
627 * by @bdrewery
628 */
629 ret = rsa_verify(pkg_repo_key(repo), sc->sig, sc->siglen - 1,
630 dest_fd);
631 if (ret != EPKG_OK) {
632 pkg_emit_error("Invalid signature, "
633 "removing repository.");
634 rc = EPKG_FATAL;
635 goto out;
636 }
637 }
638 else if (pkg_repo_signature_type(repo) == SIG_FINGERPRINT) {
639 HASH_ITER(hh, sc, s, stmp) {
640 ret = rsa_verify_cert(s->cert, s->certlen, s->sig, s->siglen,
641 dest_fd);
642 if (ret == EPKG_OK && s->trusted) {
643 break;
644 }
645 ret = EPKG_FATAL;
646 }
647 if (ret != EPKG_OK) {
648 pkg_emit_error("No trusted certificate has been used "
649 "to sign the repository");
650 rc = EPKG_FATAL;
651 goto out;
652 }
653 }
654
655 out:
656 return rc;
657 }
658
659 int
pkg_repo_fetch_remote_extract_fd(struct pkg_repo * repo,const char * filename,time_t * t,int * rc,size_t * sz)660 pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, const char *filename,
661 time_t *t, int *rc, size_t *sz)
662 {
663 int fd, dest_fd;
664 const char *tmpdir;
665 char tmp[MAXPATHLEN];
666 struct stat st;
667
668 fd = pkg_repo_fetch_remote_tmp(repo, filename, "pkg", t, rc, false);
669 if (fd == -1) {
670 fd = pkg_repo_fetch_remote_tmp(repo, filename,
671 packing_format_to_string(repo->meta->packing_format), t, rc, false);
672 }
673 if (fd == -1)
674 return (-1);
675
676 tmpdir = getenv("TMPDIR");
677 if (tmpdir == NULL)
678 tmpdir = "/tmp";
679 snprintf(tmp, sizeof(tmp), "%s/%s.XXXXXX", tmpdir, filename);
680
681 dest_fd = mkstemp(tmp);
682 if (dest_fd == -1) {
683 pkg_emit_error("Could not create temporary file %s, "
684 "aborting update.\n", tmp);
685 close(fd);
686 *rc = EPKG_FATAL;
687 return (-1);
688 }
689
690 (void)unlink(tmp);
691 if (pkg_repo_archive_extract_check_archive(fd, filename, repo, dest_fd)
692 != EPKG_OK) {
693 *rc = EPKG_FATAL;
694 close(dest_fd);
695 close(fd);
696 return (-1);
697 }
698
699 /* Thus removing archived file as well */
700 close(fd);
701 if (fstat(dest_fd, &st) == -1) {
702 close(dest_fd);
703 return (-1);
704 }
705
706 *sz = st.st_size;
707
708 return (dest_fd);
709 }
710
711 struct pkg_repo_check_cbdata {
712 unsigned char *map;
713 size_t len;
714 const char *name;
715 };
716
717 static int
pkg_repo_meta_extract_pubkey(int fd,void * ud)718 pkg_repo_meta_extract_pubkey(int fd, void *ud)
719 {
720 struct pkg_repo_check_cbdata *cbdata = ud;
721 struct ucl_parser *parser;
722 ucl_object_t *top;
723 const ucl_object_t *obj, *cur, *elt;
724 ucl_object_iter_t iter = NULL;
725 struct iovec iov[2];
726 int rc = EPKG_OK;
727 int64_t res_len = 0;
728
729 parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
730 if (!ucl_parser_add_chunk(parser, cbdata->map, cbdata->len)) {
731 pkg_emit_error("cannot parse repository meta from %s",
732 ucl_parser_get_error(parser));
733 ucl_parser_free(parser);
734 return (EPKG_FATAL);
735 }
736
737 top = ucl_parser_get_object(parser);
738 ucl_parser_free(parser);
739
740 /* Now search for the required key */
741 obj = ucl_object_find_key(top, "cert");
742 if (obj == NULL) {
743 pkg_emit_error("cannot find key for signature %s in meta",
744 cbdata->name);
745 ucl_object_unref(top);
746 return (EPKG_FATAL);
747 }
748 while((cur = ucl_iterate_object(obj, &iter, false)) != NULL) {
749 elt = ucl_object_find_key(cur, "name");
750 if (elt == NULL || elt->type != UCL_STRING)
751 continue;
752 if (strcmp(ucl_object_tostring(elt), cbdata->name) != 0)
753 continue;
754 elt = ucl_object_find_key(cur, "data");
755 if (elt == NULL || elt->type != UCL_STRING)
756 continue;
757
758 /* +1 to include \0 at the end */
759 res_len = elt->len + 1;
760 iov[0].iov_base = (void *)ucl_object_tostring(elt);
761 iov[0].iov_len = res_len;
762 if (writev(fd, iov, 1) == -1) {
763 pkg_emit_errno("pkg_repo_meta_extract_pubkey",
764 "writev error");
765 rc = EPKG_FATAL;
766 break;
767 }
768 }
769
770 ucl_object_unref(top);
771
772 return (rc);
773 }
774
775 int
pkg_repo_fetch_meta(struct pkg_repo * repo,time_t * t)776 pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
777 {
778 char filepath[MAXPATHLEN];
779 struct pkg_repo_meta *nmeta;
780 struct stat st;
781 unsigned char *map = NULL;
782 int fd, dbdirfd, metafd;
783 int rc = EPKG_OK, ret;
784 struct sig_cert *sc = NULL, *s, *stmp;
785 struct pkg_repo_check_cbdata cbdata;
786 bool newscheme = false;
787
788 dbdirfd = pkg_get_dbdirfd();
789 snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));
790 fd = pkg_repo_fetch_remote_tmp(repo, "meta", "conf", t, &rc, true);
791 if (fd != -1) {
792 newscheme = true;
793 metafd = fd;
794 fd = openat(dbdirfd, filepath, O_RDWR|O_CREAT|O_TRUNC, 0644);
795 if (fd == -1) {
796 close(metafd);
797 return (EPKG_FATAL);
798 }
799 goto load_meta;
800 } else if (rc == EPKG_UPTODATE) {
801 return (EPKG_UPTODATE);
802 }
803
804 /* TODO: remove this backward compatibility some day */
805 fd = pkg_repo_fetch_remote_tmp(repo, "meta", "txz", t, &rc, false);
806 if (fd == -1)
807 return (rc);
808
809 metafd = openat(dbdirfd, filepath, O_RDWR|O_CREAT|O_TRUNC, 0644);
810 if (metafd == -1) {
811 close(fd);
812 return (EPKG_FATAL);
813 }
814
815 if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
816 if ((rc = pkg_repo_archive_extract_check_archive(fd, "meta", repo, metafd)) != EPKG_OK) {
817 close (fd);
818 return (rc);
819 }
820 goto load_meta;
821 }
822
823 /*
824 * For fingerprints we cannot just load pubkeys as they could be in metafile itself
825 * To do it, we parse meta in sandbox and for each unloaded pubkey we try to return
826 * a corresponding key from meta file.
827 */
828
829 if ((rc = pkg_repo_archive_extract_archive(fd, "meta", repo,
830 metafd, &sc)) != EPKG_OK) {
831 close(metafd);
832 unlinkat(dbdirfd, filepath, 0);
833 close (fd);
834 return (rc);
835 }
836 close(metafd);
837 close(fd);
838
839 if (repo->signature_type == SIG_FINGERPRINT && repo->trusted_fp == NULL) {
840 if (pkg_repo_load_fingerprints(repo) != EPKG_OK)
841 return (EPKG_FATAL);
842 }
843
844 /* Map meta file for extracting pubkeys from it */
845 if ((metafd = openat(dbdirfd, filepath, O_RDONLY)) == -1) {
846 pkg_emit_errno("pkg_repo_fetch_meta", "cannot open meta fetched");
847 rc = EPKG_FATAL;
848 goto cleanup;
849 }
850
851 if (fstat(metafd, &st) == -1) {
852 pkg_emit_errno("pkg_repo_fetch_meta", "cannot stat meta fetched");
853 rc = EPKG_FATAL;
854 goto cleanup;
855 }
856
857 map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
858 if (map == MAP_FAILED) {
859 pkg_emit_errno("pkg_repo_fetch_meta", "cannot mmap meta fetched");
860 rc = EPKG_FATAL;
861 goto cleanup;
862 }
863
864 if (repo->signature_type == SIG_FINGERPRINT) {
865 cbdata.len = st.st_size;
866 cbdata.map = map;
867 HASH_ITER(hh, sc, s, stmp) {
868 if (s->siglen != 0 && s->certlen == 0) {
869 /*
870 * We need to load this pubkey from meta
871 */
872 cbdata.name = s->name;
873 if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_pubkey, &cbdata,
874 (char **)&s->cert, &s->certlen) != EPKG_OK) {
875 rc = EPKG_FATAL;
876 goto cleanup;
877 }
878 s->cert_allocated = true;
879 }
880 }
881
882 if (!pkg_repo_check_fingerprint(repo, sc, true)) {
883 rc = EPKG_FATAL;
884 goto cleanup;
885 }
886
887 HASH_ITER(hh, sc, s, stmp) {
888 ret = rsa_verify_cert(s->cert, s->certlen, s->sig, s->siglen,
889 metafd);
890 if (ret == EPKG_OK && s->trusted)
891 break;
892
893 ret = EPKG_FATAL;
894 }
895 if (ret != EPKG_OK) {
896 pkg_emit_error("No trusted certificate has been used "
897 "to sign the repository");
898 rc = EPKG_FATAL;
899 goto cleanup;
900 }
901 }
902
903 load_meta:
904 if ((rc = pkg_repo_meta_load(metafd, &nmeta)) != EPKG_OK) {
905 if (map != NULL)
906 munmap(map, st.st_size);
907
908 return (rc);
909 } else if (newscheme) {
910 pkg_repo_meta_dump_fd(nmeta, fd);
911 }
912
913 if (repo->meta != NULL)
914 pkg_repo_meta_free(repo->meta);
915
916 repo->meta = nmeta;
917
918 cleanup:
919 if (map != NULL)
920 munmap(map, st.st_size);
921
922 if (sc != NULL)
923 pkg_repo_signatures_free(sc);
924
925 if (rc != EPKG_OK)
926 unlinkat(dbdirfd, filepath, 0);
927
928 return (rc);
929 }
930
931 static struct fingerprint *
pkg_repo_parse_fingerprint(ucl_object_t * obj)932 pkg_repo_parse_fingerprint(ucl_object_t *obj)
933 {
934 const ucl_object_t *cur;
935 ucl_object_iter_t it = NULL;
936 const char *function = NULL, *fp = NULL;
937 hash_t fct = HASH_UNKNOWN;
938 struct fingerprint *f = NULL;
939 const char *key;
940
941 while ((cur = ucl_iterate_object(obj, &it, true))) {
942 key = ucl_object_key(cur);
943 if (cur->type != UCL_STRING)
944 continue;
945
946 if (strcasecmp(key, "function") == 0) {
947 function = ucl_object_tostring(cur);
948 continue;
949 }
950
951 if (strcasecmp(key, "fingerprint") == 0) {
952 fp = ucl_object_tostring(cur);
953 continue;
954 }
955 }
956
957 if (fp == NULL || function == NULL)
958 return (NULL);
959
960 if (strcasecmp(function, "sha256") == 0)
961 fct = HASH_SHA256;
962
963 if (fct == HASH_UNKNOWN) {
964 pkg_emit_error("Unsupported hashing function: %s", function);
965 return (NULL);
966 }
967
968 f = xcalloc(1, sizeof(struct fingerprint));
969 f->type = fct;
970 strlcpy(f->hash, fp, sizeof(f->hash));
971
972 return (f);
973 }
974
975 static struct fingerprint *
pkg_repo_load_fingerprint(const char * dir,const char * filename)976 pkg_repo_load_fingerprint(const char *dir, const char *filename)
977 {
978 ucl_object_t *obj = NULL;
979 struct ucl_parser *p = NULL;
980 char path[MAXPATHLEN];
981 struct fingerprint *f = NULL;
982 int fd;
983
984 snprintf(path, sizeof(path), "%s/%s", dir, filename);
985 fd = openat(ctx.rootfd, RELATIVE_PATH(path), O_RDONLY);
986 if (fd == -1) {
987 pkg_emit_error("cannot load fingerprints from %s: %s",
988 path, strerror(errno));
989 return (NULL);
990 }
991
992 p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
993
994 if (!ucl_parser_add_fd(p, fd)) {
995 pkg_emit_error("cannot parse fingerprints: %s", ucl_parser_get_error(p));
996 ucl_parser_free(p);
997 close(fd);
998 return (NULL);
999 }
1000
1001 obj = ucl_parser_get_object(p);
1002 close(fd);
1003
1004 /* Silently return if obj is NULL */
1005 if (!obj)
1006 return(NULL);
1007
1008 if (obj->type == UCL_OBJECT)
1009 f = pkg_repo_parse_fingerprint(obj);
1010
1011 ucl_object_unref(obj);
1012 ucl_parser_free(p);
1013
1014 return (f);
1015 }
1016
1017 static int
pkg_repo_load_fingerprints_from_path(const char * path,struct fingerprint ** f)1018 pkg_repo_load_fingerprints_from_path(const char *path, struct fingerprint **f)
1019 {
1020 DIR *d;
1021 int fd;
1022 struct dirent *ent;
1023 struct fingerprint *finger = NULL;
1024
1025 *f = NULL;
1026
1027 if ((fd = openat(ctx.rootfd, RELATIVE_PATH(path), O_DIRECTORY)) == -1) {
1028 pkg_emit_error("Error opening the trusted directory %s", path);
1029 return (EPKG_FATAL);
1030 }
1031 if ((d = fdopendir(fd)) == NULL) {
1032 pkg_emit_error("Error fdopening the trusted directory %s", path);
1033 return (EPKG_FATAL);
1034 }
1035
1036 while ((ent = readdir(d))) {
1037 if (strcmp(ent->d_name, ".") == 0 ||
1038 strcmp(ent->d_name, "..") == 0)
1039 continue;
1040 finger = pkg_repo_load_fingerprint(path, ent->d_name);
1041 if (finger != NULL)
1042 HASH_ADD_STR(*f, hash, finger);
1043 }
1044
1045 closedir(d);
1046
1047 return (EPKG_OK);
1048 }
1049
1050 int
pkg_repo_load_fingerprints(struct pkg_repo * repo)1051 pkg_repo_load_fingerprints(struct pkg_repo *repo)
1052 {
1053 char path[MAXPATHLEN];
1054 struct stat st;
1055
1056 snprintf(path, sizeof(path), "%s/trusted", pkg_repo_fingerprints(repo));
1057
1058 if ((pkg_repo_load_fingerprints_from_path(path, &repo->trusted_fp)) != EPKG_OK) {
1059 pkg_emit_error("Error loading trusted certificates");
1060 return (EPKG_FATAL);
1061 }
1062
1063 if (HASH_COUNT(repo->trusted_fp) == 0) {
1064 pkg_emit_error("No trusted certificates");
1065 return (EPKG_FATAL);
1066 }
1067
1068 snprintf(path, sizeof(path), "%s/revoked", pkg_repo_fingerprints(repo));
1069 /* Absence of revoked certificates is not a fatal error */
1070 if (fstatat(ctx.rootfd, RELATIVE_PATH(path), &st, 0) != -1) {
1071 if ((pkg_repo_load_fingerprints_from_path(path, &repo->revoked_fp)) != EPKG_OK) {
1072 pkg_emit_error("Error loading revoked certificates");
1073 return (EPKG_FATAL);
1074 }
1075 }
1076
1077 return (EPKG_OK);
1078 }
1079
1080
1081 int
pkg_repo_fetch_package(struct pkg * pkg)1082 pkg_repo_fetch_package(struct pkg *pkg)
1083 {
1084 struct pkg_repo *repo;
1085
1086 if (pkg->repo == NULL) {
1087 pkg_emit_error("Trying to fetch package without repository");
1088 return (EPKG_FATAL);
1089 }
1090
1091 repo = pkg->repo;
1092 if (repo->ops->fetch_pkg == NULL) {
1093 pkg_emit_error("Repository %s does not support fetching", repo->name);
1094 return (EPKG_FATAL);
1095 }
1096
1097 return (repo->ops->fetch_pkg(repo, pkg));
1098 }
1099
1100 int
pkg_repo_mirror_package(struct pkg * pkg,const char * destdir)1101 pkg_repo_mirror_package(struct pkg *pkg, const char *destdir)
1102 {
1103 struct pkg_repo *repo;
1104
1105 if (pkg->repo == NULL) {
1106 pkg_emit_error("Trying to mirror package without repository");
1107 return (EPKG_FATAL);
1108 }
1109
1110 repo = pkg->repo;
1111 if (repo->ops->mirror_pkg == NULL) {
1112 pkg_emit_error("Repository %s does not support mirroring", repo->name);
1113 return (EPKG_FATAL);
1114 }
1115
1116 return (repo->ops->mirror_pkg(repo, pkg, destdir));
1117 }
1118
1119 int
pkg_repo_cached_name(struct pkg * pkg,char * dest,size_t destlen)1120 pkg_repo_cached_name(struct pkg *pkg, char *dest, size_t destlen)
1121 {
1122 struct pkg_repo *repo;
1123
1124 if (pkg->repo == NULL)
1125 return (EPKG_FATAL);
1126
1127 repo = pkg->repo;
1128 if (repo->ops->get_cached_name == NULL)
1129 return (EPKG_FATAL);
1130
1131 return (repo->ops->get_cached_name(repo, pkg, dest, destlen));
1132 }
1133