From 2674db3c388a942572a81b2d43b6afca7da11c4b Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 7 Jun 2024 08:22:53 +0000 Subject: [PATCH] Download new TA files into a temporary place (.ta/) so that the parser can decide which of the two files to use. With and OK tb@ --- usr.sbin/rpki-client/main.c | 4 +-- usr.sbin/rpki-client/repo.c | 67 +++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index ffd01001361..8546861a310 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.258 2024/05/20 15:51:43 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.259 2024/06/07 08:22:53 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -481,7 +481,7 @@ queue_add_from_tal(struct tal *tal) /* steal the pkey from the tal structure */ data = tal->pkey; tal->pkey = NULL; - entityq_add(NULL, nfile, RTYPE_CER, DIR_VALID, repo, data, + entityq_add(NULL, nfile, RTYPE_CER, DIR_UNKNOWN, repo, data, tal->pkeysz, tal->id, tal->id, NULL); } diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c index 15ff513f00a..0dd47cd0bb0 100644 --- a/usr.sbin/rpki-client/repo.c +++ b/usr.sbin/rpki-client/repo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: repo.c,v 1.59 2024/05/30 12:33:15 claudio Exp $ */ +/* $OpenBSD: repo.c,v 1.60 2024/06/07 08:22:53 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -78,7 +78,6 @@ struct tarepo { SLIST_ENTRY(tarepo) entry; char *descr; char *basedir; - char *temp; char **uri; size_t urisz; size_t uriidx; @@ -322,7 +321,7 @@ repo_done(const void *vp, int ok) * If temp is set add Xs for mkostemp. */ static char * -ta_filename(const struct tarepo *tr, int temp) +ta_filename(const struct tarepo *tr) { const char *file; char *nfile; @@ -331,8 +330,7 @@ ta_filename(const struct tarepo *tr, int temp) file = strrchr(tr->uri[0], '/'); assert(file); - if (asprintf(&nfile, "%s%s%s", tr->basedir, file, - temp ? ".XXXXXXXX" : "") == -1) + if (asprintf(&nfile, "%s%s", tr->basedir, file) == -1) err(1, NULL); return nfile; @@ -367,18 +365,21 @@ ta_fetch(struct tarepo *tr) */ rsync_fetch(tr->id, tr->uri[tr->uriidx], tr->basedir, NULL); } else { + char *temp; int fd; - tr->temp = ta_filename(tr, 1); - fd = mkostemp(tr->temp, O_CLOEXEC); + temp = ta_filename(tr); + fd = open(temp, + O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd == -1) { - warn("mkostemp: %s", tr->temp); + warn("open: %s", temp); + free(temp); http_finish(tr->id, HTTP_FAILED, NULL); return; } - if (fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) - warn("fchmod: %s", tr->temp); + free(temp); http_fetch(tr->id, tr->uri[tr->uriidx], NULL, fd); } } @@ -392,12 +393,21 @@ ta_get(struct tal *tal) if ((tr = calloc(1, sizeof(*tr))) == NULL) err(1, NULL); + tr->id = ++repoid; SLIST_INSERT_HEAD(&tarepos, tr, entry); if ((tr->descr = strdup(tal->descr)) == NULL) err(1, NULL); - tr->basedir = repo_dir(tal->descr, "ta", 0); + tr->basedir = repo_dir(tal->descr, ".ta", 0); + + /* create base directory */ + if (mkpath(tr->basedir) == -1) { + warn("mkpath %s", tr->basedir); + tr->state = REPO_FAILED; + repo_done(tr, 0); + return tr; + } /* steal URI information from TAL */ tr->urisz = tal->urisz; @@ -430,7 +440,6 @@ ta_free(void) SLIST_REMOVE_HEAD(&tarepos, entry); free(tr->descr); free(tr->basedir); - free(tr->temp); free(tr->uri); free(tr); } @@ -1070,20 +1079,12 @@ http_finish(unsigned int id, enum http_result res, const char *last_mod) /* Move downloaded TA file into place, or unlink on failure. */ if (res == HTTP_OK) { - char *file; - - file = ta_filename(tr, 0); - if (rename(tr->temp, file) == -1) - warn("rename to %s", file); - free(file); - logx("ta/%s: loaded from network", tr->descr); tr->state = REPO_DONE; stats.http_repos++; repo_done(tr, 1); } else { - if (unlink(tr->temp) == -1 && errno != ENOENT) - warn("unlink %s", tr->temp); + remove_contents(tr->basedir); tr->uriidx++; warnx("ta/%s: load from network failed", tr->descr); @@ -1632,15 +1633,19 @@ repo_move_valid(struct filepath_tree *tree) struct filepath *fp, *nfp; size_t rsyncsz = strlen(".rsync/"); size_t rrdpsz = strlen(".rrdp/"); + size_t tasz = strlen(".ta/"); char *fn, *base; RB_FOREACH_SAFE(fp, filepath_tree, tree, nfp) { if (strncmp(fp->file, ".rsync/", rsyncsz) != 0 && - strncmp(fp->file, ".rrdp/", rrdpsz) != 0) + strncmp(fp->file, ".rrdp/", rrdpsz) != 0 && + strncmp(fp->file, ".ta/", tasz) != 0) continue; /* not a temporary file path */ if (strncmp(fp->file, ".rsync/", rsyncsz) == 0) { fn = fp->file + rsyncsz; + } else if (strncmp(fp->file, ".ta/", tasz) == 0) { + fn = fp->file + 1; /* just skip the '.' */ } else { base = strchr(fp->file + rrdpsz, '/'); assert(base != NULL); @@ -1690,8 +1695,8 @@ repo_move_valid(struct filepath_tree *tree) } struct fts_state { - enum { BASE_DIR, RSYNC_DIR, RRDP_DIR } type; - struct repo *rp; + enum { BASE_DIR, RSYNC_DIR, TA_DIR, RRDP_DIR } type; + struct repo *rp; } fts_state; static const struct rrdprepo * @@ -1768,8 +1773,9 @@ repo_cleanup_entry(FTSENT *e, struct filepath_tree *tree, int cachefd) unlink: if (unlink(e->fts_accpath) == -1) { warn("unlink %s", path); - } else if (fts_state.type == RSYNC_DIR) { - /* no need to keep rsync files */ + } else if (fts_state.type == RSYNC_DIR || + fts_state.type == TA_DIR) { + /* no need to keep rsync or ta files */ if (verbose > 1) logx("deleted superfluous %s", path); if (fts_state.rp != NULL) @@ -1792,9 +1798,11 @@ repo_cleanup_entry(FTSENT *e, struct filepath_tree *tree, int cachefd) fts_state.rp = NULL; } if (e->fts_level == 1) { - /* rpki.example.org or .rrdp / .rsync */ + /* rpki.example.org or .rrdp / .rsync / .ta */ if (strcmp(".rsync", e->fts_name) == 0) fts_state.type = RSYNC_DIR; + else if (strcmp(".ta", e->fts_name) == 0) + fts_state.type = TA_DIR; else if (strcmp(".rrdp", e->fts_name) == 0) fts_state.type = RRDP_DIR; else @@ -1805,6 +1813,8 @@ repo_cleanup_entry(FTSENT *e, struct filepath_tree *tree, int cachefd) /* rpki.example.org/repository or .rrdp/hashdir */ if (fts_state.type == BASE_DIR) fts_state.rp = repo_bypath(path); + if (fts_state.type == TA_DIR) + fts_state.rp = repo_bypath(path + 1); /* * special handling for rrdp directories, * clear them if they are not used anymore but @@ -1826,7 +1836,8 @@ repo_cleanup_entry(FTSENT *e, struct filepath_tree *tree, int cachefd) /* do not remove .rsync and .rrdp */ fts_state.rp = NULL; if (fts_state.type == RRDP_DIR || - fts_state.type == RSYNC_DIR) + fts_state.type == RSYNC_DIR || + fts_state.type == TA_DIR) break; } -- 2.20.1