On Wed, Jan 26, 2022 at 10:06:37AM +0100, Claudio Jeker wrote: > This diff removes the valid/ subdir in favor of a more direct directory > layout for all valid CA repository files. > It moves rrdp and rsync to .rsync and .rrdp but keeps ta/ because trust > anchors are special. > > The biggest change is probably in the FTS code to cleanup the repo since > the traversing now starts at ".". Apart from that removing valid results > in some simplified code (esp. in -f mode). > > This diff is mostly from job@, I just did fixed the FTS bits so the > cleanup works again.
If I do a full run with this diff, I run into rpki-client: both possibilities of file present Instrumenting this error (should it include fn?) it turns out to be pki-repo.registro.br/repo/A2x6icaKpVWP5uUBzJQzRvEpjvS7PV2qt1Ct/1/3230302e3138392e34302e302f32332d3234203d3e20313roa I have not yet figured out why. One tiny nit inline. > -- > :wq Claudio > > Index: parser.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v > retrieving revision 1.54 > diff -u -p -r1.54 parser.c > --- parser.c 24 Jan 2022 17:29:37 -0000 1.54 > +++ parser.c 25 Jan 2022 16:36:12 -0000 > @@ -737,9 +737,9 @@ parse_entity(struct entityq *q, struct m > * verification. > */ > static void > -parse_load_crl(const char *uri) > +parse_load_crl(char *uri) > { > - char *nfile, *f; > + char *f; > size_t flen; > > if (uri == NULL) > @@ -750,19 +750,14 @@ parse_load_crl(const char *uri) > } > uri += strlen("rsync://"); > > - if (asprintf(&nfile, "valid/%s", uri) == -1) > - err(1, NULL); > - > - f = load_file(nfile, &flen); > + f = load_file(uri, &flen); > if (f == NULL) { > - warn("parse file %s", nfile); > - goto done; > + warn("parse file %s", uri); > + return; > } > > - proc_parser_crl(nfile, f, flen); > + proc_parser_crl(uri, f, flen); > > -done: > - free(nfile); > free(f); > } > > @@ -773,10 +768,10 @@ done: > * necessary certs were loaded. Returns NULL on failure. > */ > static struct cert * > -parse_load_cert(const char *uri) > +parse_load_cert(char *uri) > { > struct cert *cert = NULL; > - char *nfile, *f; > + char *f; > size_t flen; > > if (uri == NULL) > @@ -788,33 +783,28 @@ parse_load_cert(const char *uri) > } > uri += strlen("rsync://"); > > - if (asprintf(&nfile, "valid/%s", uri) == -1) > - err(1, NULL); > - > - f = load_file(nfile, &flen); > + f = load_file(uri, &flen); > if (f == NULL) { > - warn("parse file %s", nfile); > + warn("parse file %s", uri); > goto done; > } > > - cert = cert_parse(nfile, f, flen); > + cert = cert_parse(uri, f, flen); > free(f); > > if (cert == NULL) > goto done; > if (cert->purpose != CERT_PURPOSE_CA) { > - warnx("AIA reference to bgpsec cert %s", nfile); > + warnx("AIA reference to bgpsec cert %s", uri); > goto done; > } > /* try to load the CRL of this cert */ > parse_load_crl(cert->crl); > > - free(nfile); > return cert; > > -done: > + done: > cert_free(cert); > - free(nfile); > return NULL; > } > > Index: repo.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/repo.c,v > retrieving revision 1.27 > diff -u -p -r1.27 repo.c > --- repo.c 24 Jan 2022 15:50:34 -0000 1.27 > +++ repo.c 26 Jan 2022 08:39:07 -0000 > @@ -224,8 +224,14 @@ repo_dir(const char *uri, const char *di > local = uri; > } > > - if (asprintf(&out, "%s/%s", dir, local) == -1) > - err(1, NULL); > + if (dir == NULL) { > + if ((out = strdup(local)) == NULL) > + err(1, NULL); > + } else { > + if (asprintf(&out, "%s/%s", dir, local) == -1) > + err(1, NULL); > + } > + > free(hdir); > return out; > } > @@ -436,7 +442,7 @@ rsync_get(const char *uri, const char *v > SLIST_INSERT_HEAD(&rsyncrepos, rr, entry); > > rr->repouri = repo; > - rr->basedir = repo_dir(repo, "rsync", 0); > + rr->basedir = repo_dir(repo, ".rsync", 0); > > /* create base directory */ > if (mkpath(rr->basedir) == -1) { > @@ -484,13 +490,16 @@ rrdp_filename(const struct rrdprepo *rr, > char *nfile; > const char *dir = rr->basedir; > > - if (valid) > - dir = "valid"; > if (!valid_uri(uri, strlen(uri), "rsync://")) > errx(1, "%s: bad URI %s", rr->basedir, uri); > uri += strlen("rsync://"); /* skip proto */ > - if (asprintf(&nfile, "%s/%s", dir, uri) == -1) > - err(1, NULL); > + if (valid) { > + if ((nfile = strdup(uri)) == NULL) > + err(1, NULL); > + } else { > + if (asprintf(&nfile, "%s/%s", dir, uri) == -1) > + err(1, NULL); > + } > return nfile; > } > > @@ -734,7 +743,7 @@ rrdp_get(const char *uri) > > if ((rr->notifyuri = strdup(uri)) == NULL) > err(1, NULL); > - rr->basedir = repo_dir(uri, "rrdp", 1); > + rr->basedir = repo_dir(uri, ".rrdp", 1); > > RB_INIT(&rr->deleted); > > @@ -1058,7 +1067,7 @@ repo_lookup(int talid, const char *uri, > } > > rp = repo_alloc(talid); > - rp->basedir = repo_dir(repouri, "valid", 0); > + rp->basedir = repo_dir(repouri, NULL, 0); > rp->repouri = repouri; > if (notify != NULL) > if ((rp->notifyuri = strdup(notify)) == NULL) > @@ -1270,40 +1279,38 @@ static void > repo_move_valid(struct filepath_tree *tree) > { > struct filepath *fp, *nfp; > - size_t rsyncsz = strlen("rsync/"); > - size_t rrdpsz = strlen("rrdp/"); > + size_t rsyncsz = strlen(".rsync/"); > + size_t rrdpsz = strlen(".rrdp/"); > char *fn, *base; > > RB_FOREACH_SAFE(fp, filepath_tree, tree, nfp) { > - if (strncmp(fp->file, "rsync/", rsyncsz) != 0 && > - strncmp(fp->file, "rrdp/", rrdpsz) != 0) > + if (strncmp(fp->file, ".rsync/", rsyncsz) != 0 && > + strncmp(fp->file, ".rrdp/", rrdpsz) != 0) > continue; /* not a temporary file path */ > > - if (strncmp(fp->file, "rsync/", rsyncsz) == 0) { > - if (asprintf(&fn, "valid/%s", fp->file + rsyncsz) == -1) > - err(1, NULL); > + if (strncmp(fp->file, ".rsync/", rsyncsz) == 0) { > + fn = fp->file + rsyncsz; > } else { > base = strchr(fp->file + rrdpsz, '/'); > assert(base != NULL); > - if (asprintf(&fn, "valid/%s", base + 1) == -1) > - err(1, NULL); > + fn = base + 1; > } > > if (repo_mkpath(fn) == -1) { > - free(fn); > continue; > } > > if (rename(fp->file, fn) == -1) { > warn("rename %s", fp->file); > - free(fn); > continue; > } > > /* switch filepath node to new path */ > RB_REMOVE(filepath_tree, tree, fp); > - free(fp->file); > - fp->file = fn; > + base = fp->file; > + if ((fp->file = strdup(fn)) == NULL) > + err(1, NULL); > + free(base); The dance with base is not necessary: free(fp->file) if ((fp->file = strdup(fn)) == NULL) err(1, NULL); > if (RB_INSERT(filepath_tree, tree, fp) != NULL) > errx(1, "both possibilities of file present"); > } > @@ -1313,12 +1320,20 @@ repo_move_valid(struct filepath_tree *tr > #define RSYNC_DIR (void *)0x73796e63 > #define RRDP_DIR (void *)0x52524450 > > +static inline char * > +skip_dotslash(char *in) > +{ > + if (memcmp(in, "./", 2) == 0) > + return in + 2; > + return in; > +} > + > void > repo_cleanup(struct filepath_tree *tree) > { > size_t i, cnt, delsz = 0, dirsz = 0; > char **del = NULL, **dir = NULL; > - char *argv[5] = { "ta", "rsync", "rrdp", "valid", NULL }; > + char *argv[2] = { ".", NULL }; > FTS *fts; > FTSENT *e; > > @@ -1331,38 +1346,38 @@ repo_cleanup(struct filepath_tree *tree) > err(1, "fts_open"); > errno = 0; > while ((e = fts_read(fts)) != NULL) { > + char *path = skip_dotslash(e->fts_path); > switch (e->fts_info) { > case FTS_NSOK: > - /* handle rrdp .state files explicitly */ > - if (e->fts_parent->fts_pointer == RRDP_DIR && > - e->fts_level == 2 && > - strcmp(e->fts_name, ".state") == 0) { > + if (filepath_exists(tree, path)) { > e->fts_parent->fts_number++; > - } else if (filepath_exists(tree, e->fts_path)) { > + break; > + } > + if (e->fts_parent->fts_pointer == RRDP_DIR) { > e->fts_parent->fts_number++; > - } else if (e->fts_parent->fts_pointer == RRDP_DIR) { > + /* handle rrdp .state files explicitly */ > + if (e->fts_level == 3 && > + strcmp(e->fts_name, ".state") == 0) > + break; > /* can't delete these extra files */ > - e->fts_parent->fts_number++; > stats.extra_files++; > if (verbose > 1) > - logx("superfluous %s", e->fts_path); > - } else { > - if (e->fts_parent->fts_pointer == RSYNC_DIR) { > - /* no need to keep rsync files */ > - stats.extra_files++; > - if (verbose > 1) > - logx("superfluous %s", > - e->fts_path); > - } > - del = add_to_del(del, &delsz, > - e->fts_path); > + logx("superfluous %s", path); > + break; > + } > + if (e->fts_parent->fts_pointer == RSYNC_DIR) { > + /* no need to keep rsync files */ > + stats.extra_files++; > + if (verbose > 1) > + logx("superfluous %s", path); > } > + del = add_to_del(del, &delsz, path); > break; > case FTS_D: > - if (e->fts_level == FTS_ROOTLEVEL) { > - if (strcmp("rsync", e->fts_path) == 0) > + if (e->fts_level == 1) { > + if (strcmp(".rsync", e->fts_name) == 0) > e->fts_pointer = RSYNC_DIR; > - else if (strcmp("rrdp", e->fts_path) == 0) > + else if (strcmp(".rrdp", e->fts_name) == 0) > e->fts_pointer = RRDP_DIR; > else > e->fts_pointer = BASE_DIR; > @@ -1375,8 +1390,8 @@ repo_cleanup(struct filepath_tree *tree) > * only if rrdp is active. > */ > if (e->fts_pointer == RRDP_DIR && !noop && rrdpon && > - e->fts_level == 1) { > - if (!rrdp_is_active(e->fts_path)) > + e->fts_level == 2) { > + if (!rrdp_is_active(path)) > e->fts_pointer = NULL; > } > break; > @@ -1384,26 +1399,26 @@ repo_cleanup(struct filepath_tree *tree) > if (e->fts_level == FTS_ROOTLEVEL) > break; > if (e->fts_number == 0) > - dir = add_to_del(dir, &dirsz, e->fts_path); > + dir = add_to_del(dir, &dirsz, path); > > e->fts_parent->fts_number += e->fts_number; > break; > case FTS_SL: > case FTS_SLNONE: > - warnx("symlink %s", e->fts_path); > - del = add_to_del(del, &delsz, e->fts_path); > + warnx("symlink %s", path); > + del = add_to_del(del, &delsz, path); > break; > case FTS_NS: > case FTS_ERR: > if (e->fts_errno == ENOENT && > e->fts_level == FTS_ROOTLEVEL) > continue; > - warnx("fts_read %s: %s", e->fts_path, > + warnx("fts_read %s: %s", path, > strerror(e->fts_errno)); > break; > default: > - warnx("unhandled[%x] %s", e->fts_info, > - e->fts_path); > + warnx("fts_read %s: unhandled[%x]", path, > + e->fts_info); > break; > } > >