Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/libpkg/pkg_repo.c
2065 views
1
/*-
2
* Copyright (c) 2011-2024 Baptiste Daroussin <[email protected]>
3
* Copyright (c) 2011-2012 Julien Laffaye <[email protected]>
4
* Copyright (c) 2011-2012 Marin Atanasov Nikolov <[email protected]>
5
* Copyright (c) 2012-2015 Matthew Seaman <[email protected]>
6
* Copyright (c) 2014 Vsevolod Stakhov <[email protected]>
7
* Copyright (c) 2023 Serenity Cyber Security, LLC
8
* Author: Gleb Popov <[email protected]>
9
*
10
* All rights reserved.
11
*
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
14
* are met:
15
* 1. Redistributions of source code must retain the above copyright
16
* notice, this list of conditions and the following disclaimer
17
* in this position and unchanged.
18
* 2. Redistributions in binary form must reproduce the above copyright
19
* notice, this list of conditions and the following disclaimer in the
20
* documentation and/or other materials provided with the distribution.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
23
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
26
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*/
33
34
#include <sys/types.h>
35
#include <sys/stat.h>
36
#include <sys/uio.h>
37
38
#include <archive_entry.h>
39
#include <assert.h>
40
#include <fts.h>
41
#include <libgen.h>
42
#include <sqlite3.h>
43
#include <string.h>
44
#include <dirent.h>
45
#define _WITH_GETLINE
46
#include <stdio.h>
47
#include <stdbool.h>
48
#include <unistd.h>
49
#include <errno.h>
50
#include <sys/mman.h>
51
#include <fcntl.h>
52
53
#include "pkg.h"
54
#include "private/event.h"
55
#include "private/utils.h"
56
#include "private/pkg.h"
57
#include "private/pkgdb.h"
58
#include "private/fetch.h"
59
#include "private/pkgsign.h"
60
61
struct sig_cert {
62
char name[MAXPATHLEN];
63
char *type;
64
char *sig;
65
int64_t siglen;
66
char *cert;
67
int64_t certlen;
68
bool cert_allocated;
69
bool trusted;
70
};
71
72
int
73
pkg_repo_fetch_remote_tmp(struct pkg_repo *repo,
74
const char *filename, const char *extension, time_t *t, int *rc, bool silent)
75
{
76
struct fetch_item fi;
77
char url[MAXPATHLEN];
78
char tmp[MAXPATHLEN];
79
int fd;
80
const char *tmpdir, *dot;
81
82
memset(&fi, 0, sizeof(struct fetch_item));
83
84
/*
85
* XXX: here we support old naming scheme, such as filename.yaml
86
*/
87
dot = strrchr(filename, '.');
88
if (dot != NULL) {
89
snprintf(tmp, MIN(sizeof(tmp), dot - filename + 1), "%s", filename);
90
snprintf(url, sizeof(url), "%s/%s.%s", pkg_repo_url(repo), tmp,
91
extension);
92
}
93
else {
94
snprintf(url, sizeof(url), "%s/%s.%s", pkg_repo_url(repo), filename,
95
extension);
96
}
97
98
tmpdir = getenv("TMPDIR");
99
if (tmpdir == NULL)
100
tmpdir = "/tmp";
101
pkg_mkdirs(tmpdir);
102
snprintf(tmp, sizeof(tmp), "%s/%s.%s.XXXXXX", tmpdir, filename, extension);
103
104
fd = mkstemp(tmp);
105
if (fd == -1) {
106
pkg_emit_error("Could not create temporary file %s, "
107
"aborting update.\n", tmp);
108
*rc = EPKG_FATAL;
109
return (-1);
110
}
111
(void)unlink(tmp);
112
113
fi.url = url;
114
fi.mtime = *t;
115
if ((*rc = pkg_fetch_file_to_fd(repo, fd, &fi, silent)) != EPKG_OK) {
116
close(fd);
117
fd = -1;
118
}
119
if (fd != -1)
120
*t = fi.mtime;
121
122
return (fd);
123
}
124
125
static bool
126
pkg_repo_file_has_ext(const char *path, const char *ext)
127
{
128
size_t n, l;
129
const char *p = NULL;
130
131
n = strlen(path);
132
l = strlen(ext);
133
p = &path[n - l];
134
135
if (STREQ(p, ext))
136
return (true);
137
138
return (false);
139
}
140
141
static bool
142
pkg_repo_check_fingerprint(struct pkg_repo *repo, pkghash *sc, bool fatal)
143
{
144
char *hash;
145
int nbgood = 0;
146
struct sig_cert *s = NULL;
147
struct pkg_repo_meta_key *mk = NULL;
148
pkghash_it it;
149
150
if (pkghash_count(sc) == 0) {
151
if (fatal)
152
pkg_emit_error("No signature found");
153
return (false);
154
}
155
156
/* load fingerprints */
157
if (repo->trusted_fp == NULL) {
158
if (pkg_repo_load_fingerprints(repo) != EPKG_OK)
159
return (false);
160
}
161
162
it = pkghash_iterator(sc);
163
while (pkghash_next(&it)) {
164
s = (struct sig_cert *) it.value;
165
if (s->sig != NULL && s->cert == NULL) {
166
/*
167
* We may want to check meta
168
*/
169
if (repo->meta != NULL && repo->meta->keys != NULL) {
170
mk = pkghash_get_value(repo->meta->keys, s->name);
171
}
172
173
if (mk != NULL && mk->pubkey != NULL) {
174
s->cert = mk->pubkey;
175
s->certlen = strlen(mk->pubkey);
176
}
177
else {
178
if (fatal)
179
pkg_emit_error("No key with name %s has been found", s->name);
180
return (false);
181
}
182
}
183
else if (s->sig == NULL) {
184
if (fatal)
185
pkg_emit_error("No signature with name %s has been found", s->name);
186
return (false);
187
}
188
189
s->trusted = false;
190
hash = pkg_checksum_data(s->cert, s->certlen,
191
PKG_HASH_TYPE_SHA256_HEX);
192
if (pkghash_get(repo->revoked_fp, hash) != NULL) {
193
if (fatal)
194
pkg_emit_error("At least one of the "
195
"certificates has been revoked");
196
197
free(hash);
198
return (false);
199
}
200
201
if (pkghash_get(repo->trusted_fp, hash) != NULL) {
202
nbgood++;
203
s->trusted = true;
204
}
205
free(hash);
206
}
207
208
if (nbgood == 0) {
209
if (fatal)
210
pkg_emit_error("No trusted public keys found");
211
212
return (false);
213
}
214
215
return (true);
216
}
217
218
static void
219
pkg_repo_signatures_free(pkghash *sc)
220
{
221
struct sig_cert *s;
222
pkghash_it it;
223
224
if (sc == NULL)
225
return;
226
it = pkghash_iterator(sc);
227
while (pkghash_next(&it)) {
228
s = (struct sig_cert *)it.value;
229
free(s->sig);
230
free(s->type);
231
if (s->cert_allocated)
232
free(s->cert);
233
free(s);
234
}
235
pkghash_destroy(sc);
236
}
237
238
239
struct pkg_extract_cbdata {
240
int afd;
241
int tfd;
242
const char *fname;
243
bool need_sig;
244
};
245
246
#define PKGSIGN_DEFAULT_IMPL "rsa"
247
248
static int
249
pkg_repo_write_sig_from_archive(struct archive *a, int fd, size_t siglen)
250
{
251
char sig[siglen];
252
253
if (archive_read_data(a, sig, siglen) == -1) {
254
pkg_emit_errno("pkg_repo_meta_extract_signature",
255
"archive_read_data failed");
256
return (EPKG_FATAL);
257
}
258
if (write(fd, sig, siglen) == -1) {
259
pkg_emit_errno("pkg_repo_meta_extract_signature",
260
"write failed");
261
return (EPKG_FATAL);
262
}
263
return (EPKG_OK);
264
}
265
266
static int
267
pkg_repo_meta_extract_signature_pubkey(int fd, void *ud)
268
{
269
struct archive *a = NULL;
270
struct archive_entry *ae = NULL;
271
struct pkg_extract_cbdata *cb = ud;
272
int siglen;
273
int rc = EPKG_FATAL;
274
275
pkg_debug(1, "PkgRepo: extracting signature of repo in a sandbox");
276
277
a = archive_read_new();
278
archive_read_support_filter_all(a);
279
archive_read_support_format_tar(a);
280
281
archive_read_open_fd(a, cb->afd, 4096);
282
283
while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
284
if (cb->need_sig && STREQ(archive_entry_pathname(ae), "signature")) {
285
siglen = archive_entry_size(ae);
286
rc = pkg_repo_write_sig_from_archive(a, fd, siglen);
287
if (rc != EPKG_OK)
288
break;
289
}
290
else if (STREQ(archive_entry_pathname(ae), cb->fname)) {
291
if (archive_read_data_into_fd(a, cb->tfd) != 0) {
292
pkg_emit_error("Error extracting the archive: '%s'", archive_error_string(a));
293
rc = EPKG_FATAL;
294
break;
295
}
296
else if (!cb->need_sig) {
297
rc = EPKG_OK;
298
}
299
}
300
}
301
302
close(cb->tfd);
303
/*
304
* XXX: do not free resources here since the sandbox is terminated anyway
305
*/
306
return (rc);
307
}
308
/*
309
* We use here the following format:
310
* <type(0|1)><namelen(int)><name><sigtypelen(int)><sigtype><datalen(int)><data>
311
*/
312
static int
313
pkg_repo_meta_extract_signature_fingerprints(int fd, void *ud)
314
{
315
struct archive *a = NULL;
316
struct archive_entry *ae = NULL;
317
struct pkg_extract_cbdata *cb = ud;
318
const char *type;
319
int siglen, keylen, typelen;
320
uint8_t *sig, *sigdata;
321
int rc = EPKG_FATAL;
322
char key[MAXPATHLEN], t;
323
struct iovec iov[7];
324
325
pkg_debug(1, "PkgRepo: extracting signature of repo in a sandbox");
326
327
a = archive_read_new();
328
archive_read_support_filter_all(a);
329
archive_read_support_format_tar(a);
330
331
archive_read_open_fd(a, cb->afd, 4096);
332
333
while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
334
if (pkg_repo_file_has_ext(archive_entry_pathname(ae), ".sig")) {
335
snprintf(key, sizeof(key), "%.*s",
336
(int) strlen(archive_entry_pathname(ae)) - 4,
337
archive_entry_pathname(ae));
338
type = NULL;
339
siglen = archive_entry_size(ae);
340
sigdata = sig = xmalloc(siglen);
341
if (archive_read_data(a, sig, siglen) == -1) {
342
pkg_emit_errno("pkg_repo_meta_extract_signature",
343
"archive_read_data failed");
344
free(sig);
345
return (EPKG_FATAL);
346
}
347
if (strncmp(sig, PKGSIGN_HEAD, strlen(PKGSIGN_HEAD)) == 0) {
348
type = sig + strlen(PKGSIGN_HEAD);
349
sigdata = memchr(type, '$', siglen - ((uint8_t *)type - sig));
350
if (sigdata != NULL) {
351
*sigdata++ = '\0';
352
353
siglen -= sigdata - sig;
354
} else {
355
/* Malformed, proceed as if no header at all. */
356
sigdata = sig;
357
type = NULL;
358
}
359
}
360
361
if (type == NULL)
362
type = "rsa";
363
typelen = strlen(type);
364
/* Signature type */
365
t = 0;
366
keylen = strlen(key);
367
iov[0].iov_base = &t;
368
iov[0].iov_len = sizeof(t);
369
iov[1].iov_base = &keylen;
370
iov[1].iov_len = sizeof(keylen);
371
iov[2].iov_base = key;
372
iov[2].iov_len = keylen;
373
iov[3].iov_base = &typelen;
374
iov[3].iov_len = sizeof(typelen);
375
iov[4].iov_base = __DECONST(void *, type);
376
iov[4].iov_len = typelen;
377
iov[5].iov_base = &siglen;
378
iov[5].iov_len = sizeof(siglen);
379
iov[6].iov_base = sigdata;
380
iov[6].iov_len = siglen;
381
if (writev(fd, iov, NELEM(iov)) == -1) {
382
pkg_emit_errno("pkg_repo_meta_extract_signature",
383
"writev failed");
384
free(sig);
385
return (EPKG_FATAL);
386
}
387
free(sig);
388
rc = EPKG_OK;
389
}
390
else if (pkg_repo_file_has_ext(archive_entry_pathname(ae), ".pub")) {
391
snprintf(key, sizeof(key), "%.*s",
392
(int) strlen(archive_entry_pathname(ae)) - 4,
393
archive_entry_pathname(ae));
394
type = NULL;
395
siglen = archive_entry_size(ae);
396
sigdata = sig = xmalloc(siglen);
397
if (archive_read_data(a, sig, siglen) == -1) {
398
pkg_emit_errno("pkg_repo_meta_extract_signature",
399
"archive_read_data failed");
400
free(sig);
401
return (EPKG_FATAL);
402
}
403
if (strncmp(sig, PKGSIGN_HEAD, strlen(PKGSIGN_HEAD)) == 0) {
404
type = sig + strlen(PKGSIGN_HEAD);
405
sigdata = memchr(type, '$', siglen - ((uint8_t *)type - sig));
406
if (sigdata != NULL) {
407
*sigdata++ = '\0';
408
409
siglen -= sigdata - sig;
410
} else {
411
/* Malformed, proceed as if no header at all. */
412
type = NULL;
413
sigdata = sig;
414
}
415
}
416
417
if (type == NULL)
418
type = "rsa";
419
typelen = strlen(type);
420
/* Pubkey type */
421
t = 1;
422
keylen = strlen(key);
423
iov[0].iov_base = &t;
424
iov[0].iov_len = sizeof(t);
425
iov[1].iov_base = &keylen;
426
iov[1].iov_len = sizeof(keylen);
427
iov[2].iov_base = key;
428
iov[2].iov_len = keylen;
429
iov[3].iov_base = &typelen;
430
iov[3].iov_len = sizeof(typelen);
431
iov[4].iov_base = __DECONST(char *, type);
432
iov[4].iov_len = typelen;
433
iov[5].iov_base = &siglen;
434
iov[5].iov_len = sizeof(siglen);
435
iov[6].iov_base = sigdata;
436
iov[6].iov_len = siglen;
437
if (writev(fd, iov, NELEM(iov)) == -1) {
438
pkg_emit_errno("pkg_repo_meta_extract_signature",
439
"writev failed");
440
free(sig);
441
return (EPKG_FATAL);
442
}
443
free(sig);
444
rc = EPKG_OK;
445
}
446
else {
447
if (STREQ(archive_entry_pathname(ae), cb->fname)) {
448
if (archive_read_data_into_fd(a, cb->tfd) != 0) {
449
pkg_emit_error("Error extracting the archive: '%s'", archive_error_string(a));
450
rc = EPKG_FATAL;
451
break;
452
}
453
}
454
}
455
}
456
close(cb->tfd);
457
/*
458
* XXX: do not free resources here since the sandbox is terminated anyway
459
*/
460
return (rc);
461
}
462
463
static int
464
pkg_repo_parse_sigkeys(const char *in, int inlen, pkghash **sc)
465
{
466
const char *p = in, *end = in + inlen;
467
int rc = EPKG_OK;
468
enum {
469
fp_parse_type,
470
fp_parse_flen,
471
fp_parse_file,
472
fp_parse_sigtypelen,
473
fp_parse_sigtype,
474
fp_parse_siglen,
475
fp_parse_sig
476
} state = fp_parse_type;
477
char type = 0;
478
unsigned char *sig;
479
int len = 0, sigtypelen = 0, tlen;
480
struct sig_cert *s = NULL;
481
bool new = false;
482
483
while (p < end) {
484
switch (state) {
485
case fp_parse_type:
486
type = *p;
487
if (type != 0 && type != 1) {
488
/* Invalid type */
489
pkg_emit_error("%d is not a valid type for signature_fingerprints"
490
" output", type);
491
return (EPKG_FATAL);
492
}
493
state = fp_parse_flen;
494
s = NULL;
495
p ++;
496
break;
497
case fp_parse_flen:
498
if (end - p < sizeof (int)) {
499
pkg_emit_error("truncated reply for signature_fingerprints"
500
" output");
501
return (EPKG_FATAL);
502
}
503
memcpy(&len, p, sizeof(int));
504
state = fp_parse_file;
505
p += sizeof(int);
506
s = NULL;
507
break;
508
case fp_parse_file:
509
if (end - p < len || len <= 0) {
510
pkg_emit_error("truncated reply for signature_fingerprints"
511
" output, wanted %d bytes", len);
512
return (EPKG_FATAL);
513
}
514
else if (len >= MAXPATHLEN) {
515
pkg_emit_error("filename is incorrect for signature_fingerprints"
516
" output: %d, wanted 5..%d bytes", type, len);
517
free(s);
518
return (EPKG_FATAL);
519
}
520
char *k = xstrndup(p, len);
521
s = pkghash_get_value(*sc, k);
522
free(k);
523
if ( s == NULL) {
524
s = xcalloc(1, sizeof(struct sig_cert));
525
tlen = MIN(len, sizeof(s->name) - 1);
526
memcpy(s->name, p, tlen);
527
s->name[tlen] = '\0';
528
new = true;
529
} else {
530
new = false;
531
}
532
state = fp_parse_sigtypelen;
533
p += len;
534
break;
535
case fp_parse_sigtypelen:
536
if (end - p < sizeof (int)) {
537
pkg_emit_error("truncated reply for signature_fingerprints"
538
" output");
539
return (EPKG_FATAL);
540
}
541
memcpy(&sigtypelen, p, sizeof(int));
542
state = fp_parse_sigtype;
543
p += sizeof(int);
544
break;
545
case fp_parse_sigtype:
546
if (s == NULL) {
547
pkg_emit_error("fatal state machine failure at pkg_repo_parse_sigkeys");
548
return (EPKG_FATAL);
549
}
550
if (end - p < sigtypelen || sigtypelen <= 0) {
551
pkg_emit_error("truncated reply for signature_fingerprints"
552
" output, wanted %d bytes", sigtypelen);
553
return (EPKG_FATAL);
554
}
555
s->type = xstrndup(p, sigtypelen);
556
state = fp_parse_siglen;
557
p += sigtypelen;
558
break;
559
case fp_parse_siglen:
560
if (s == NULL) {
561
pkg_emit_error("fatal state machine failure at pkg_repo_parse_sigkeys");
562
return (EPKG_FATAL);
563
}
564
if (end - p < sizeof (int)) {
565
pkg_emit_error("truncated reply for signature_fingerprints"
566
"output");
567
free(s);
568
return (EPKG_FATAL);
569
}
570
memcpy(&len, p, sizeof(int));
571
state = fp_parse_sig;
572
p += sizeof(int);
573
break;
574
case fp_parse_sig:
575
if (s == NULL) {
576
pkg_emit_error("fatal state machine failure at pkg_repo_parse_sigkeys");
577
return (EPKG_FATAL);
578
}
579
if (end - p < len || len <= 0) {
580
pkg_emit_error("truncated reply for signature_fingerprints"
581
"output, wanted %d bytes", len);
582
free(s);
583
return (EPKG_FATAL);
584
}
585
sig = xmalloc(len);
586
memcpy(sig, p, len);
587
if (type == 0) {
588
s->sig = sig;
589
s->siglen = len;
590
}
591
else {
592
s->cert = sig;
593
s->certlen = len;
594
s->cert_allocated = true;
595
}
596
state = fp_parse_type;
597
p += len;
598
599
if (new)
600
pkghash_safe_add(*sc, s->name, s, NULL);
601
602
break;
603
}
604
}
605
606
return (rc);
607
}
608
609
static int
610
pkg_repo_archive_extract_archive(int fd, const char *file,
611
struct pkg_repo *repo, int dest_fd,
612
pkghash **signatures)
613
{
614
struct pkghash *sc = NULL;
615
struct sig_cert *s;
616
struct pkg_extract_cbdata cbdata;
617
618
char *sig = NULL;
619
int rc = EPKG_OK;
620
int64_t siglen = 0;
621
622
623
pkg_debug(1, "PkgRepo: extracting %s of repo %s", file, pkg_repo_name(repo));
624
625
/* Seek to the begin of file */
626
(void)lseek(fd, 0, SEEK_SET);
627
628
cbdata.afd = fd;
629
cbdata.fname = file;
630
cbdata.tfd = dest_fd;
631
632
if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
633
cbdata.need_sig = true;
634
if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_signature_pubkey,
635
&cbdata, (char **)&sig, &siglen) == EPKG_OK && sig != NULL) {
636
s = xcalloc(1, sizeof(struct sig_cert));
637
if (strncmp(sig, PKGSIGN_HEAD, strlen(PKGSIGN_HEAD)) == 0) {
638
char *sigtype, *sigstart;
639
640
sigtype = sig + strlen(PKGSIGN_HEAD);
641
sigstart = memchr(sigtype, '$', siglen - (sigtype - sig));
642
if (sigstart != NULL) {
643
s->type = xstrndup(sigtype, sigstart - sigtype);
644
siglen -= (sigstart + 1) - sig;
645
memmove(sig, sigstart + 1, siglen);
646
}
647
}
648
if (s->type == NULL)
649
s->type = xstrdup("rsa");
650
s->sig = sig;
651
s->siglen = siglen;
652
strlcpy(s->name, "signature", sizeof(s->name));
653
pkghash_safe_add(sc, s->name, s, NULL);
654
}
655
}
656
else if (pkg_repo_signature_type(repo) == SIG_FINGERPRINT) {
657
if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_signature_fingerprints,
658
&cbdata, (char **)&sig, &siglen) == EPKG_OK && sig != NULL &&
659
siglen > 0) {
660
if (pkg_repo_parse_sigkeys(sig, siglen, &sc) == EPKG_FATAL) {
661
return (EPKG_FATAL);
662
}
663
free(sig);
664
if (!pkg_repo_check_fingerprint(repo, sc, true)) {
665
return (EPKG_FATAL);
666
}
667
}
668
else {
669
pkg_emit_error("No signature found");
670
return (EPKG_FATAL);
671
}
672
}
673
else {
674
cbdata.need_sig = false;
675
if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_signature_pubkey,
676
&cbdata, (char **)&sig, &siglen) == EPKG_OK) {
677
free(sig);
678
}
679
else {
680
pkg_emit_error("Repo extraction failed");
681
return (EPKG_FATAL);
682
}
683
}
684
(void)lseek(fd, 0, SEEK_SET);
685
if (dest_fd != -1)
686
(void)lseek(dest_fd, 0, SEEK_SET);
687
688
if (rc == EPKG_OK) {
689
if (signatures != NULL)
690
*signatures = sc;
691
else
692
pkg_repo_signatures_free(sc);
693
}
694
else {
695
pkg_repo_signatures_free(sc);
696
}
697
698
return rc;
699
}
700
701
static int
702
pkg_repo_archive_extract_check_archive(int fd, const char *file,
703
struct pkg_repo *repo, int dest_fd)
704
{
705
pkghash *sc = NULL;
706
struct sig_cert *s;
707
const struct pkgsign_ctx *sctx;
708
const char *rkey;
709
signature_t sigtype;
710
pkghash_it it;
711
int ret;
712
713
ret = EPKG_OK;
714
715
if (pkg_repo_archive_extract_archive(fd, file, repo, dest_fd, &sc)
716
!= EPKG_OK)
717
return (EPKG_FATAL);
718
719
sctx = NULL;
720
sigtype = pkg_repo_signature_type(repo);
721
722
if (sigtype == SIG_PUBKEY) {
723
rkey = pkg_repo_key(repo);
724
if (rkey == NULL) {
725
pkg_emit_error("No PUBKEY defined. Removing "
726
"repository.");
727
return (EPKG_FATAL);
728
}
729
if (sc == NULL) {
730
pkg_emit_error("No signature found in the repository. "
731
"Can not validate against %s key.", rkey);
732
return (EPKG_FATAL);
733
}
734
it = pkghash_iterator(sc);
735
pkghash_next(&it); /* check that there is content is already above */
736
s = (struct sig_cert *)it.value;
737
738
ret = pkgsign_new_verify(s->type, &sctx);
739
if (ret != EPKG_OK) {
740
pkg_emit_error("'%s' signer not found", s->type);
741
return (EPKG_FATAL);
742
}
743
744
/*
745
* Note that pkgsign_verify is not the same method or use-case
746
* as pkgsign_verify_cert.
747
*
748
* The primary difference is that pkgsign_verify takes a file
749
* to load the pubkey from, while pkgsign_verify_cert expects
750
* that the key will simply be passed in for it to verify
751
* against.
752
*
753
* Some versions of pkgsign_verify were also suboptimal, in the
754
* sense that they signed the hex encoding of a SHA256 checksum
755
* over the repo rather than raw. This required some kludges
756
* to work with, but future pkgsign_verify implementations
757
* should not follow in its path.
758
*/
759
ret = pkgsign_verify(sctx, rkey, s->sig, s->siglen, dest_fd);
760
if (ret != EPKG_OK) {
761
pkg_emit_error("Invalid signature, "
762
"removing repository.");
763
return (EPKG_FATAL);
764
}
765
}
766
else if (pkg_repo_signature_type(repo) == SIG_FINGERPRINT) {
767
const char *signer_name = NULL;
768
769
it = pkghash_iterator(sc);
770
while (pkghash_next(&it)) {
771
s = (struct sig_cert *)it.value;
772
773
/*
774
* Each signature may use a different signer, so we'll potentially
775
* grab a new context for each one. This is cheaper than it sounds,
776
* verifying contexts are stashed in a pkghash for re-use.
777
*/
778
if (sctx == NULL || !STREQ(s->type, signer_name)) {
779
ret = pkgsign_new_verify(s->type, &sctx);
780
if (ret != EPKG_OK) {
781
pkg_emit_error("'%s' signer not found", s->type);
782
return (EPKG_FATAL);
783
}
784
785
signer_name = pkgsign_impl_name(sctx);
786
}
787
788
ret = pkgsign_verify_cert(sctx, s->cert, s->certlen, s->sig,
789
s->siglen, dest_fd);
790
if (ret == EPKG_OK && s->trusted) {
791
break;
792
}
793
ret = EPKG_FATAL;
794
}
795
if (ret != EPKG_OK) {
796
pkg_emit_error("No trusted certificate has been used "
797
"to sign the repository");
798
return (EPKG_FATAL);
799
}
800
}
801
802
return (EPKG_OK);
803
}
804
805
int
806
pkg_repo_fetch_data_fd(struct pkg_repo *repo, struct pkg_repo_content *prc)
807
{
808
int fd;
809
const char *tmpdir;
810
char tmp[MAXPATHLEN];
811
struct stat st;
812
int rc = EPKG_OK;
813
814
fd = pkg_repo_fetch_remote_tmp(repo, repo->meta->data, "pkg", &prc->mtime, &rc, false);
815
if (fd == -1) {
816
if (rc == EPKG_UPTODATE)
817
return (rc);
818
fd = pkg_repo_fetch_remote_tmp(repo, repo->meta->data,
819
packing_format_to_string(repo->meta->packing_format), &prc->mtime, &rc, false);
820
if (fd == -1)
821
return (EPKG_FATAL);
822
}
823
824
tmpdir = getenv("TMPDIR");
825
if (tmpdir == NULL)
826
tmpdir = "/tmp";
827
snprintf(tmp, sizeof(tmp), "%s/%s.XXXXXX", tmpdir, repo->meta->data);
828
prc->data_fd = mkstemp(tmp);
829
if (prc->data_fd == -1) {
830
pkg_emit_error("Cound not create temporary file %s, "
831
"aborting update.\n", tmp);
832
close(fd);
833
return (EPKG_FATAL);
834
}
835
836
unlink(tmp);
837
if (pkg_repo_archive_extract_check_archive(fd, repo->meta->data, repo, prc->data_fd) != EPKG_OK) {
838
close(prc->data_fd);
839
close(fd);
840
return (EPKG_FATAL);
841
}
842
843
close(fd);
844
if (fstat(prc->data_fd, &st) == -1) {
845
close(prc->data_fd);
846
return (EPKG_FATAL);
847
}
848
849
return (EPKG_OK);
850
}
851
852
int
853
pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, struct pkg_repo_content *prc)
854
{
855
int fd;
856
const char *tmpdir;
857
char tmp[MAXPATHLEN];
858
struct stat st;
859
int rc = EPKG_OK;
860
861
fd = pkg_repo_fetch_remote_tmp(repo, repo->meta->manifests, "pkg", &prc->mtime, &rc, false);
862
if (fd == -1) {
863
if (rc == EPKG_UPTODATE)
864
return (rc);
865
866
fd = pkg_repo_fetch_remote_tmp(repo, repo->meta->manifests,
867
packing_format_to_string(repo->meta->packing_format), &prc->mtime, &rc, false);
868
if (fd == -1)
869
return (EPKG_FATAL);
870
}
871
872
tmpdir = getenv("TMPDIR");
873
if (tmpdir == NULL)
874
tmpdir = "/tmp";
875
snprintf(tmp, sizeof(tmp), "%s/%s.XXXXXX", tmpdir, repo->meta->manifests);
876
877
prc->manifest_fd = mkstemp(tmp);
878
if (prc->manifest_fd == -1) {
879
pkg_emit_error("Could not create temporary file %s, "
880
"aborting update.\n", tmp);
881
close(fd);
882
return (EPKG_FATAL);
883
}
884
885
(void)unlink(tmp);
886
if (pkg_repo_archive_extract_check_archive(fd, repo->meta->manifests, repo, prc->manifest_fd)
887
!= EPKG_OK) {
888
close(prc->manifest_fd);
889
close(fd);
890
return (EPKG_FATAL);
891
}
892
893
/* Thus removing archived file as well */
894
close(fd);
895
if (fstat(prc->manifest_fd, &st) == -1) {
896
close(prc->manifest_fd);
897
return (EPKG_FATAL);
898
}
899
900
prc->manifest_len = st.st_size;
901
902
return (EPKG_OK);
903
}
904
905
struct pkg_repo_check_cbdata {
906
unsigned char *map;
907
size_t len;
908
const char *name;
909
};
910
911
static int
912
pkg_repo_meta_extract_pubkey(int fd, void *ud)
913
{
914
struct pkg_repo_check_cbdata *cbdata = ud;
915
struct ucl_parser *parser;
916
ucl_object_t *top;
917
const ucl_object_t *obj, *cur, *elt;
918
ucl_object_iter_t iter = NULL;
919
struct iovec iov[2];
920
int rc = EPKG_OK;
921
int64_t res_len = 0;
922
923
parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
924
if (!ucl_parser_add_chunk(parser, cbdata->map, cbdata->len)) {
925
pkg_emit_error("cannot parse repository meta from %s",
926
ucl_parser_get_error(parser));
927
ucl_parser_free(parser);
928
return (EPKG_FATAL);
929
}
930
931
top = ucl_parser_get_object(parser);
932
ucl_parser_free(parser);
933
934
/* Now search for the required key */
935
obj = ucl_object_find_key(top, "cert");
936
if (obj == NULL) {
937
pkg_emit_error("cannot find key for signature %s in meta",
938
cbdata->name);
939
ucl_object_unref(top);
940
return (EPKG_FATAL);
941
}
942
while((cur = ucl_iterate_object(obj, &iter, false)) != NULL) {
943
elt = ucl_object_find_key(cur, "name");
944
if (elt == NULL || elt->type != UCL_STRING)
945
continue;
946
if (!STREQ(ucl_object_tostring(elt), cbdata->name))
947
continue;
948
elt = ucl_object_find_key(cur, "data");
949
if (elt == NULL || elt->type != UCL_STRING)
950
continue;
951
952
/* +1 to include \0 at the end */
953
res_len = elt->len + 1;
954
iov[0].iov_base = (void *)ucl_object_tostring(elt);
955
iov[0].iov_len = res_len;
956
if (writev(fd, iov, 1) == -1) {
957
pkg_emit_errno("pkg_repo_meta_extract_pubkey",
958
"writev error");
959
rc = EPKG_FATAL;
960
break;
961
}
962
}
963
964
ucl_object_unref(top);
965
966
return (rc);
967
}
968
969
int
970
pkg_repo_open(struct pkg_repo *repo)
971
{
972
int reposfd;
973
974
if (repo->dfd != -1)
975
return (EPKG_OK);
976
977
reposfd = pkg_get_reposdirfd();
978
if (reposfd == -1)
979
return (EPKG_FATAL);
980
981
repo->dfd = openat(reposfd, repo->name, O_DIRECTORY|O_CLOEXEC);
982
if (repo->dfd == -1) {
983
if (mkdirat(reposfd, repo->name, 0755) == -1)
984
return (EPKG_FATAL);
985
986
repo->dfd = openat(reposfd, repo->name, O_DIRECTORY|O_CLOEXEC);
987
if (repo->dfd == -1)
988
return (EPKG_FATAL);
989
}
990
991
return (EPKG_OK);
992
}
993
994
int
995
pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
996
{
997
char filepath[MAXPATHLEN];
998
struct pkg_repo_meta *nmeta;
999
const struct pkgsign_ctx *sctx;
1000
struct stat st;
1001
unsigned char *map = NULL;
1002
int fd, dbdirfd, metafd;
1003
int rc = EPKG_OK, ret;
1004
pkghash *sc = NULL;
1005
struct sig_cert *s;
1006
struct pkg_repo_check_cbdata cbdata;
1007
bool newscheme = false;
1008
pkghash_it it;
1009
1010
dbdirfd = pkg_get_dbdirfd();
1011
sctx = NULL;
1012
if (repo->dfd == -1) {
1013
if (pkg_repo_open(repo) == EPKG_FATAL)
1014
return (EPKG_FATAL);
1015
}
1016
fd = pkg_repo_fetch_remote_tmp(repo, "meta", "conf", t, &rc, true);
1017
if (fd != -1) {
1018
newscheme = true;
1019
metafd = fd;
1020
fd = openat(repo->dfd, "meta", O_RDWR|O_CREAT|O_TRUNC, 0644);
1021
if (fd == -1) {
1022
close(metafd);
1023
return (EPKG_FATAL);
1024
}
1025
goto load_meta;
1026
} else if (rc == EPKG_UPTODATE) {
1027
return (EPKG_UPTODATE);
1028
}
1029
1030
/* TODO: remove this backward compatibility some day */
1031
fd = pkg_repo_fetch_remote_tmp(repo, "meta", "txz", t, &rc, false);
1032
if (fd == -1)
1033
return (rc);
1034
1035
metafd = openat(repo->dfd, "meta", O_RDWR|O_CREAT|O_TRUNC, 0644);
1036
if (metafd == -1) {
1037
close(fd);
1038
return (EPKG_FATAL);
1039
}
1040
1041
if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
1042
if ((rc = pkg_repo_archive_extract_check_archive(fd, "meta", repo, metafd)) != EPKG_OK) {
1043
close (fd);
1044
return (rc);
1045
}
1046
goto load_meta;
1047
}
1048
1049
/*
1050
* For fingerprints we cannot just load pubkeys as they could be in metafile itself
1051
* To do it, we parse meta in sandbox and for each unloaded pubkey we try to return
1052
* a corresponding key from meta file.
1053
*/
1054
1055
if ((rc = pkg_repo_archive_extract_archive(fd, "meta", repo,
1056
metafd, &sc)) != EPKG_OK) {
1057
close(metafd);
1058
unlinkat(dbdirfd, filepath, 0);
1059
close (fd);
1060
return (rc);
1061
}
1062
close(metafd);
1063
close(fd);
1064
1065
if (repo->signature_type == SIG_FINGERPRINT && repo->trusted_fp == NULL) {
1066
if (pkg_repo_load_fingerprints(repo) != EPKG_OK)
1067
return (EPKG_FATAL);
1068
}
1069
1070
/* Map meta file for extracting pubkeys from it */
1071
if ((metafd = openat(repo->dfd, "meta", O_RDONLY)) == -1) {
1072
pkg_emit_errno("pkg_repo_fetch_meta", "cannot open meta fetched");
1073
rc = EPKG_FATAL;
1074
goto cleanup;
1075
}
1076
1077
if (fstat(metafd, &st) == -1) {
1078
pkg_emit_errno("pkg_repo_fetch_meta", "cannot stat meta fetched");
1079
rc = EPKG_FATAL;
1080
goto cleanup;
1081
}
1082
1083
map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
1084
if (map == MAP_FAILED) {
1085
pkg_emit_errno("pkg_repo_fetch_meta", "cannot mmap meta fetched");
1086
rc = EPKG_FATAL;
1087
goto cleanup;
1088
}
1089
1090
if (repo->signature_type == SIG_FINGERPRINT) {
1091
const char *signer_name = NULL;
1092
1093
cbdata.len = st.st_size;
1094
cbdata.map = map;
1095
it = pkghash_iterator(sc);
1096
while (pkghash_next(&it)) {
1097
s = (struct sig_cert *) it.value;
1098
if (s->siglen != 0 && s->certlen == 0) {
1099
/*
1100
* We need to load this pubkey from meta
1101
*/
1102
cbdata.name = s->name;
1103
if (pkg_emit_sandbox_get_string(pkg_repo_meta_extract_pubkey, &cbdata,
1104
(char **)&s->cert, &s->certlen) != EPKG_OK) {
1105
rc = EPKG_FATAL;
1106
goto cleanup;
1107
}
1108
s->cert_allocated = true;
1109
}
1110
}
1111
1112
if (!pkg_repo_check_fingerprint(repo, sc, true)) {
1113
rc = EPKG_FATAL;
1114
goto cleanup;
1115
}
1116
1117
ret = EPKG_FATAL;
1118
it = pkghash_iterator(sc);
1119
while (pkghash_next(&it)) {
1120
s = (struct sig_cert *) it.value;
1121
1122
/*
1123
* Just as above, each one may have a different type associated with
1124
* it, so grab a new one each time.
1125
*/
1126
if (sctx == NULL || !STREQ(s->type, signer_name)) {
1127
ret = pkgsign_new_verify(s->type, &sctx);
1128
if (ret != EPKG_OK) {
1129
pkg_emit_error("'%s' signer not found", s->type);
1130
rc = EPKG_FATAL;
1131
goto cleanup;
1132
}
1133
1134
signer_name = pkgsign_impl_name(sctx);
1135
}
1136
1137
ret = pkgsign_verify_cert(sctx, s->cert, s->certlen, s->sig, s->siglen,
1138
metafd);
1139
if (ret == EPKG_OK && s->trusted)
1140
break;
1141
ret = EPKG_FATAL;
1142
}
1143
if (ret != EPKG_OK) {
1144
pkg_emit_error("No trusted certificate has been used "
1145
"to sign the repository");
1146
rc = EPKG_FATAL;
1147
goto cleanup;
1148
}
1149
}
1150
1151
load_meta:
1152
if ((rc = pkg_repo_meta_load(metafd, &nmeta)) != EPKG_OK) {
1153
if (map != NULL)
1154
munmap(map, st.st_size);
1155
1156
return (rc);
1157
} else if (newscheme) {
1158
pkg_repo_meta_dump_fd(nmeta, fd);
1159
}
1160
1161
if (repo->meta != NULL)
1162
pkg_repo_meta_free(repo->meta);
1163
1164
repo->meta = nmeta;
1165
1166
cleanup:
1167
if (map != NULL)
1168
munmap(map, st.st_size);
1169
1170
if (sc != NULL)
1171
pkg_repo_signatures_free(sc);
1172
1173
if (rc != EPKG_OK)
1174
unlinkat(dbdirfd, filepath, 0);
1175
1176
return (rc);
1177
}
1178
1179
static struct fingerprint *
1180
pkg_repo_parse_fingerprint(ucl_object_t *obj)
1181
{
1182
const ucl_object_t *cur;
1183
ucl_object_iter_t it = NULL;
1184
const char *function = NULL, *fp = NULL;
1185
hash_t fct = HASH_UNKNOWN;
1186
struct fingerprint *f = NULL;
1187
const char *key;
1188
1189
while ((cur = ucl_iterate_object(obj, &it, true))) {
1190
key = ucl_object_key(cur);
1191
if (cur->type != UCL_STRING)
1192
continue;
1193
1194
if (STRIEQ(key, "function")) {
1195
function = ucl_object_tostring(cur);
1196
continue;
1197
}
1198
1199
if (STRIEQ(key, "fingerprint")) {
1200
fp = ucl_object_tostring(cur);
1201
continue;
1202
}
1203
}
1204
1205
if (fp == NULL || function == NULL)
1206
return (NULL);
1207
1208
if (STRIEQ(function, "sha256"))
1209
fct = HASH_SHA256;
1210
1211
if (fct == HASH_UNKNOWN) {
1212
pkg_emit_error("Unsupported hashing function: %s", function);
1213
return (NULL);
1214
}
1215
1216
f = xcalloc(1, sizeof(struct fingerprint));
1217
f->type = fct;
1218
strlcpy(f->hash, fp, sizeof(f->hash));
1219
1220
return (f);
1221
}
1222
1223
static struct fingerprint *
1224
pkg_repo_load_fingerprint(const char *dir, const char *filename)
1225
{
1226
ucl_object_t *obj = NULL;
1227
struct ucl_parser *p = NULL;
1228
char path[MAXPATHLEN];
1229
struct fingerprint *f = NULL;
1230
int fd;
1231
1232
snprintf(path, sizeof(path), "%s/%s", dir, filename);
1233
fd = openat(ctx.rootfd, RELATIVE_PATH(path), O_RDONLY);
1234
if (fd == -1) {
1235
pkg_emit_error("cannot load fingerprints from %s: %s",
1236
path, strerror(errno));
1237
return (NULL);
1238
}
1239
1240
p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
1241
1242
if (!ucl_parser_add_fd(p, fd)) {
1243
pkg_emit_error("cannot parse fingerprints: %s", ucl_parser_get_error(p));
1244
ucl_parser_free(p);
1245
close(fd);
1246
return (NULL);
1247
}
1248
1249
obj = ucl_parser_get_object(p);
1250
close(fd);
1251
1252
/* Silently return if obj is NULL */
1253
if (!obj)
1254
return(NULL);
1255
1256
if (obj->type == UCL_OBJECT)
1257
f = pkg_repo_parse_fingerprint(obj);
1258
1259
ucl_object_unref(obj);
1260
ucl_parser_free(p);
1261
1262
return (f);
1263
}
1264
1265
static int
1266
pkg_repo_load_fingerprints_from_path(const char *path, pkghash **f)
1267
{
1268
DIR *d;
1269
int fd;
1270
struct dirent *ent;
1271
struct fingerprint *finger = NULL;
1272
1273
*f = NULL;
1274
1275
if ((fd = openat(ctx.rootfd, RELATIVE_PATH(path), O_DIRECTORY)) == -1) {
1276
pkg_emit_error("Error opening the trusted directory %s", path);
1277
return (EPKG_FATAL);
1278
}
1279
if ((d = fdopendir(fd)) == NULL) {
1280
pkg_emit_error("Error fdopening the trusted directory %s", path);
1281
return (EPKG_FATAL);
1282
}
1283
1284
while ((ent = readdir(d))) {
1285
if (STREQ(ent->d_name, ".") ||
1286
STREQ(ent->d_name, ".."))
1287
continue;
1288
finger = pkg_repo_load_fingerprint(path, ent->d_name);
1289
if (finger != NULL)
1290
pkghash_safe_add(*f, finger->hash, finger, NULL);
1291
}
1292
1293
closedir(d);
1294
1295
return (EPKG_OK);
1296
}
1297
1298
int
1299
pkg_repo_load_fingerprints(struct pkg_repo *repo)
1300
{
1301
char path[MAXPATHLEN];
1302
struct stat st;
1303
1304
snprintf(path, sizeof(path), "%s/trusted", pkg_repo_fingerprints(repo));
1305
1306
if ((pkg_repo_load_fingerprints_from_path(path, &repo->trusted_fp)) != EPKG_OK) {
1307
pkg_emit_error("Error loading trusted certificates");
1308
return (EPKG_FATAL);
1309
}
1310
1311
if (pkghash_count(repo->trusted_fp) == 0) {
1312
pkg_emit_error("No trusted certificates");
1313
return (EPKG_FATAL);
1314
}
1315
1316
snprintf(path, sizeof(path), "%s/revoked", pkg_repo_fingerprints(repo));
1317
/* Absence of revoked certificates is not a fatal error */
1318
if (fstatat(ctx.rootfd, RELATIVE_PATH(path), &st, 0) != -1) {
1319
if ((pkg_repo_load_fingerprints_from_path(path, &repo->revoked_fp)) != EPKG_OK) {
1320
pkg_emit_error("Error loading revoked certificates");
1321
return (EPKG_FATAL);
1322
}
1323
}
1324
1325
return (EPKG_OK);
1326
}
1327
1328
1329
int
1330
pkg_repo_fetch_package(struct pkg *pkg)
1331
{
1332
struct pkg_repo *repo;
1333
1334
if (pkg->repo == NULL) {
1335
pkg_emit_error("Trying to fetch package without repository");
1336
return (EPKG_FATAL);
1337
}
1338
1339
repo = pkg->repo;
1340
if (repo->ops->fetch_pkg == NULL) {
1341
pkg_emit_error("Repository %s does not support fetching", repo->name);
1342
return (EPKG_FATAL);
1343
}
1344
1345
return (repo->ops->fetch_pkg(repo, pkg));
1346
}
1347
1348
int
1349
pkg_repo_mirror_package(struct pkg *pkg, const char *destdir)
1350
{
1351
struct pkg_repo *repo;
1352
1353
if (pkg->repo == NULL) {
1354
pkg_emit_error("Trying to mirror package without repository");
1355
return (EPKG_FATAL);
1356
}
1357
1358
repo = pkg->repo;
1359
if (repo->ops->mirror_pkg == NULL) {
1360
pkg_emit_error("Repository %s does not support mirroring", repo->name);
1361
return (EPKG_FATAL);
1362
}
1363
1364
return (repo->ops->mirror_pkg(repo, pkg, destdir));
1365
}
1366
1367
int
1368
pkg_repo_cached_name(struct pkg *pkg, char *dest, size_t destlen)
1369
{
1370
struct pkg_repo *repo;
1371
1372
if (pkg->repo == NULL)
1373
return (EPKG_FATAL);
1374
1375
repo = pkg->repo;
1376
if (repo->ops->get_cached_name == NULL)
1377
return (EPKG_FATAL);
1378
1379
return (repo->ops->get_cached_name(repo, pkg, dest, destlen));
1380
}
1381
1382