diff options
Diffstat (limited to 'usr.sbin/rpki-client')
-rw-r--r-- | usr.sbin/rpki-client/extern.h | 5 | ||||
-rw-r--r-- | usr.sbin/rpki-client/filemode.c | 4 | ||||
-rw-r--r-- | usr.sbin/rpki-client/main.c | 6 | ||||
-rw-r--r-- | usr.sbin/rpki-client/parser.c | 59 | ||||
-rw-r--r-- | usr.sbin/rpki-client/repo.c | 30 |
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) |