summaryrefslogtreecommitdiff
path: root/usr.sbin/rpki-client
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/rpki-client')
-rw-r--r--usr.sbin/rpki-client/extern.h5
-rw-r--r--usr.sbin/rpki-client/filemode.c4
-rw-r--r--usr.sbin/rpki-client/main.c6
-rw-r--r--usr.sbin/rpki-client/parser.c59
-rw-r--r--usr.sbin/rpki-client/repo.c30
5 files changed, 86 insertions, 18 deletions
diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h
index 64c75cc87e0..c3e3be89ce6 100644
--- a/usr.sbin/rpki-client/extern.h
+++ b/usr.sbin/rpki-client/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.182 2023/05/30 12:14:48 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.183 2023/05/30 16:02:28 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -348,6 +348,7 @@ struct gbr {
time_t notbefore; /* EE cert's Not Before */
time_t notafter; /* Not After of the GBR EE */
time_t expires; /* when the signature path expires */
+ int talid; /* TAL the GBR is chained up to */
};
struct aspa_provider {
@@ -755,7 +756,7 @@ void proc_http(char *, int) __attribute__((noreturn));
void proc_rrdp(int) __attribute__((noreturn));
/* Repository handling */
-int filepath_add(struct filepath_tree *, char *);
+int filepath_add(struct filepath_tree *, char *, time_t);
void rrdp_clear(unsigned int);
void rrdp_save_state(unsigned int, struct rrdp_session *);
int rrdp_handle_file(unsigned int, enum publish_type, char *,
diff --git a/usr.sbin/rpki-client/filemode.c b/usr.sbin/rpki-client/filemode.c
index 0acb2385c60..6a0cbecbd51 100644
--- a/usr.sbin/rpki-client/filemode.c
+++ b/usr.sbin/rpki-client/filemode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: filemode.c,v 1.32 2023/05/30 12:02:22 claudio Exp $ */
+/* $OpenBSD: filemode.c,v 1.33 2023/05/30 16:02:28 job Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -589,6 +589,7 @@ parse_file(struct entityq *q, struct msgbuf *msgq)
struct entity *entp;
struct ibuf *b;
struct tal *tal;
+ time_t dummy = 0;
while ((entp = TAILQ_FIRST(q)) != NULL) {
TAILQ_REMOVE(q, entp, entries);
@@ -615,6 +616,7 @@ parse_file(struct entityq *q, struct msgbuf *msgq)
io_simple_buffer(b, &entp->repoid, sizeof(entp->repoid));
io_simple_buffer(b, &entp->talid, sizeof(entp->talid));
io_str_buffer(b, entp->file);
+ io_simple_buffer(b, &dummy, sizeof(dummy));
io_close_buffer(msgq, b);
entity_free(entp);
}
diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c
index 22c1c34001d..1982e2747be 100644
--- a/usr.sbin/rpki-client/main.c
+++ b/usr.sbin/rpki-client/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.240 2023/05/30 12:14:48 claudio Exp $ */
+/* $OpenBSD: main.c,v 1.241 2023/05/30 16:02:28 job Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -559,6 +559,7 @@ entity_process(struct ibuf *b, struct stats *st, struct vrp_tree *tree,
struct aspa *aspa;
struct repo *rp;
char *file;
+ time_t mtime;
unsigned int id;
int talid;
int c;
@@ -573,12 +574,13 @@ entity_process(struct ibuf *b, struct stats *st, struct vrp_tree *tree,
io_read_buf(b, &id, sizeof(id));
io_read_buf(b, &talid, sizeof(talid));
io_read_str(b, &file);
+ io_read_buf(b, &mtime, sizeof(mtime));
/* in filemode messages can be ignored, only the accounting matters */
if (filemode)
goto done;
- if (filepath_add(&fpt, file) == 0) {
+ if (filepath_add(&fpt, file, mtime) == 0) {
warnx("%s: File already visited", file);
goto done;
}
diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c
index 93c0eca95b8..107375fc2ce 100644
--- a/usr.sbin/rpki-client/parser.c
+++ b/usr.sbin/rpki-client/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.95 2023/05/30 12:14:48 claudio Exp $ */
+/* $OpenBSD: parser.c,v 1.96 2023/05/30 16:02:28 job Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -352,7 +352,8 @@ proc_parser_mft_post(char *file, struct mft *mft, const char *path,
* Load the most recent MFT by opening both options and comparing the two.
*/
static char *
-proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile)
+proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile,
+ time_t *crlmtime)
{
struct mft *mft1 = NULL, *mft2 = NULL;
struct crl *crl, *crl1, *crl2;
@@ -360,6 +361,7 @@ proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile)
const char *err1, *err2;
*mp = NULL;
+ *crlmtime = 0;
mft1 = proc_parser_mft_pre(entp, DIR_VALID, &file1, &crl1, &crl1file,
&err1);
@@ -392,6 +394,7 @@ proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile)
}
if (*mp != NULL) {
+ *crlmtime = crl->lastupdate;
if (!crl_insert(&crlt, crl)) {
warnx("%s: duplicate AKI %s", file, crl->aki);
crl_free(crl);
@@ -488,7 +491,7 @@ proc_parser_root_cert(char *file, const unsigned char *der, size_t len,
/*
* Parse a ghostbuster record
*/
-static void
+static struct gbr *
proc_parser_gbr(char *file, const unsigned char *der, size_t len,
const char *mftaki)
{
@@ -499,17 +502,23 @@ proc_parser_gbr(char *file, const unsigned char *der, size_t len,
const char *errstr;
if ((gbr = gbr_parse(&x509, file, der, len)) == NULL)
- return;
+ return NULL;
a = valid_ski_aki(file, &auths, gbr->ski, gbr->aki, mftaki);
crl = crl_get(&crlt, a);
/* return value can be ignored since nothing happens here */
- if (!valid_x509(file, ctx, x509, a, crl, &errstr))
+ if (!valid_x509(file, ctx, x509, a, crl, &errstr)) {
warnx("%s: %s", file, errstr);
-
+ X509_free(x509);
+ gbr_free(gbr);
+ return NULL;
+ }
X509_free(x509);
- gbr_free(gbr);
+
+ gbr->talid = a->cert->talid;
+
+ return gbr;
}
/*
@@ -618,8 +627,11 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
struct mft *mft;
struct roa *roa;
struct aspa *aspa;
+ struct gbr *gbr;
+ struct tak *tak;
struct ibuf *b;
unsigned char *f;
+ time_t mtime, crlmtime;
size_t flen;
char *file, *crlfile;
int c;
@@ -642,9 +654,13 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
file = NULL;
f = NULL;
+ mtime = 0;
+ crlmtime = 0;
+
switch (entp->type) {
case RTYPE_TAL:
io_str_buffer(b, entp->file);
+ io_simple_buffer(b, &mtime, sizeof(mtime));
if ((tal = tal_parse(entp->file, entp->data,
entp->datasz)) == NULL)
errx(1, "%s: could not parse tal file",
@@ -663,6 +679,9 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
else
cert = proc_parser_cert(file, f, flen,
entp->mftaki);
+ if (cert != NULL)
+ mtime = cert->notbefore;
+ io_simple_buffer(b, &mtime, sizeof(mtime));
c = (cert != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (cert != NULL) {
@@ -676,8 +695,11 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
*/
break;
case RTYPE_MFT:
- file = proc_parser_mft(entp, &mft, &crlfile);
+ file = proc_parser_mft(entp, &mft, &crlfile, &crlmtime);
io_str_buffer(b, file);
+ if (mft != NULL)
+ mtime = mft->signtime;
+ io_simple_buffer(b, &mtime, sizeof(mtime));
c = (mft != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (mft != NULL)
@@ -696,6 +718,8 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
io_simple_buffer(b2, &entp->talid,
sizeof(entp->talid));
io_str_buffer(b2, crlfile);
+ io_simple_buffer(b2, &crlmtime,
+ sizeof(crlmtime));
free(crlfile);
io_close_buffer(msgq, b2);
@@ -706,6 +730,9 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
file = parse_load_file(entp, &f, &flen);
io_str_buffer(b, file);
roa = proc_parser_roa(file, f, flen, entp->mftaki);
+ if (roa != NULL)
+ mtime = roa->signtime;
+ io_simple_buffer(b, &mtime, sizeof(mtime));
c = (roa != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (roa != NULL)
@@ -715,12 +742,19 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
case RTYPE_GBR:
file = parse_load_file(entp, &f, &flen);
io_str_buffer(b, file);
- proc_parser_gbr(file, f, flen, entp->mftaki);
+ gbr = proc_parser_gbr(file, f, flen, entp->mftaki);
+ if (gbr != NULL)
+ mtime = gbr->signtime;
+ io_simple_buffer(b, &mtime, sizeof(mtime));
+ gbr_free(gbr);
break;
case RTYPE_ASPA:
file = parse_load_file(entp, &f, &flen);
io_str_buffer(b, file);
aspa = proc_parser_aspa(file, f, flen, entp->mftaki);
+ if (aspa != NULL)
+ mtime = aspa->signtime;
+ io_simple_buffer(b, &mtime, sizeof(mtime));
c = (aspa != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (aspa != NULL)
@@ -730,13 +764,18 @@ parse_entity(struct entityq *q, struct msgbuf *msgq)
case RTYPE_TAK:
file = parse_load_file(entp, &f, &flen);
io_str_buffer(b, file);
- proc_parser_tak(file, f, flen, entp->mftaki);
+ tak = proc_parser_tak(file, f, flen, entp->mftaki);
+ if (tak != NULL)
+ mtime = tak->signtime;
+ io_simple_buffer(b, &mtime, sizeof(mtime));
+ tak_free(tak);
break;
case RTYPE_CRL:
default:
file = parse_filepath(entp->repoid, entp->path,
entp->file, entp->location);
io_str_buffer(b, file);
+ io_simple_buffer(b, &mtime, sizeof(mtime));
warnx("%s: unhandled type %d", file, entp->type);
break;
}
diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c
index ee79b1e3195..009ce254613 100644
--- a/usr.sbin/rpki-client/repo.c
+++ b/usr.sbin/rpki-client/repo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: repo.c,v 1.46 2023/05/25 12:49:39 claudio Exp $ */
+/* $OpenBSD: repo.c,v 1.47 2023/05/30 16:02:28 job Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -119,6 +119,7 @@ static void remove_contents(char *);
struct filepath {
RB_ENTRY(filepath) entry;
char *file;
+ time_t mtime;
};
static inline int
@@ -133,12 +134,13 @@ RB_PROTOTYPE(filepath_tree, filepath, entry, filepathcmp);
* Functions to lookup which files have been accessed during computation.
*/
int
-filepath_add(struct filepath_tree *tree, char *file)
+filepath_add(struct filepath_tree *tree, char *file, time_t mtime)
{
struct filepath *fp;
if ((fp = malloc(sizeof(*fp))) == NULL)
err(1, NULL);
+ fp->mtime = mtime;
if ((fp->file = strdup(file)) == NULL)
err(1, NULL);
@@ -838,7 +840,7 @@ rrdp_handle_file(unsigned int id, enum publish_type pt, char *uri,
/* write new content or mark uri as deleted. */
if (pt == PUB_DEL) {
- filepath_add(&rr->deleted, uri);
+ filepath_add(&rr->deleted, uri, 0);
} else {
fp = filepath_find(&rr->deleted, uri);
if (fp != NULL)
@@ -1536,6 +1538,28 @@ repo_move_valid(struct filepath_tree *tree)
base = strchr(fp->file + rrdpsz, '/');
assert(base != NULL);
fn = base + 1;
+
+ /*
+ * Adjust file last modification time in order to
+ * minimize RSYNC synchronization load after transport
+ * failover.
+ * While serializing RRDP datastructures to disk, set
+ * the last modified timestamp to the CMS signing-time,
+ * the X.509 notBefore, or CRL lastUpdate timestamp.
+ */
+ if (fp->mtime != 0) {
+ int ret;
+ struct timespec ts[2];
+
+ ts[0].tv_nsec = UTIME_OMIT;
+ ts[1].tv_sec = fp->mtime;
+ ts[1].tv_nsec = 0;
+ ret = utimensat(AT_FDCWD, fp->file, ts, 0);
+ if (ret == -1) {
+ warn("utimensat %s", fp->file);
+ continue;
+ }
+ }
}
if (repo_mkpath(AT_FDCWD, fn) == -1)