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