I like that.. LGTM
ok beck@ On Fri, Jan 21, 2022 at 08:37:27PM +0100, Theo Buehler wrote: > > Lets start with that and optimize this in tree. I think we can rename the > > function to something like rtype_from_mftfile(). In that case I would move > > the function as well... > > Like this? > > Index: extern.h > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v > retrieving revision 1.111 > diff -u -p -r1.111 extern.h > --- extern.h 21 Jan 2022 18:49:44 -0000 1.111 > +++ extern.h 21 Jan 2022 19:36:09 -0000 > @@ -421,6 +421,8 @@ void mft_free(struct mft *); > struct mft *mft_parse(X509 **, const char *, const unsigned char *, > size_t); > struct mft *mft_read(struct ibuf *); > +enum rtype rtype_from_file_extension(const char *); > +enum rtype rtype_from_mftfile(const char *); > > void roa_buffer(struct ibuf *, const struct roa *); > void roa_free(struct roa *); > @@ -447,12 +449,9 @@ int valid_ta(const char *, struct auth > int valid_cert(const char *, struct auth_tree *, > const struct cert *); > int valid_roa(const char *, struct auth_tree *, struct roa *); > -int valid_filename(const char *); > int valid_filehash(int, const char *, size_t); > int valid_uri(const char *, size_t, const char *); > int valid_origin(const char *, const char *); > - > -enum rtype rtype_from_file_extension(const char *); > > /* Working with CMS. */ > unsigned char *cms_parse_validate(X509 **, const char *, > Index: mft.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v > retrieving revision 1.49 > diff -u -p -r1.49 mft.c > --- mft.c 21 Jan 2022 18:49:44 -0000 1.49 > +++ mft.c 21 Jan 2022 19:36:10 -0000 > @@ -16,6 +16,7 @@ > */ > > #include <assert.h> > +#include <ctype.h> > #include <err.h> > #include <limits.h> > #include <stdarg.h> > @@ -121,6 +122,66 @@ check_validity(const ASN1_GENERALIZEDTIM > } > > /* > + * Determine rtype corresponding to file extension. Returns RTYPE_INVALID > + * on error or unkown extension. > + */ > +enum rtype > +rtype_from_file_extension(const char *fn) > +{ > + size_t sz; > + > + sz = strlen(fn); > + if (sz < 5) > + return RTYPE_INVALID; > + > + if (strcasecmp(fn + sz - 4, ".tal") == 0) > + return RTYPE_TAL; > + if (strcasecmp(fn + sz - 4, ".cer") == 0) > + return RTYPE_CER; > + if (strcasecmp(fn + sz - 4, ".crl") == 0) > + return RTYPE_CRL; > + if (strcasecmp(fn + sz - 4, ".mft") == 0) > + return RTYPE_MFT; > + if (strcasecmp(fn + sz - 4, ".roa") == 0) > + return RTYPE_ROA; > + if (strcasecmp(fn + sz - 4, ".gbr") == 0) > + return RTYPE_GBR; > + > + return RTYPE_INVALID; > +} > + > +/* > + * Validate that a filename listed on a Manifest only contains characters > + * permitted in draft-ietf-sidrops-6486bis section 4.2.2 and check that > + * it's a CER, CRL, GBR or a ROA. > + * Returns corresponding rtype or RTYPE_INVALID on error. > + */ > +enum rtype > +rtype_from_mftfile(const char *fn) > +{ > + const unsigned char *c; > + enum rtype type; > + > + for (c = fn; *c != '\0'; ++c) > + if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.') > + return RTYPE_INVALID; > + > + if (strchr(fn, '.') != strrchr(fn, '.')) > + return RTYPE_INVALID; > + > + type = rtype_from_file_extension(fn); > + switch (type) { > + case RTYPE_CER: > + case RTYPE_CRL: > + case RTYPE_GBR: > + case RTYPE_ROA: > + return type; > + default: > + return RTYPE_INVALID; > + } > +} > + > +/* > * Parse an individual "FileAndHash", RFC 6486, sec. 4.2. > * Return zero on failure, non-zero on success. > */ > @@ -161,12 +222,10 @@ mft_parse_filehash(struct parse *p, cons > if (fn == NULL) > err(1, NULL); > > - if (!valid_filename(fn)) { > + if ((type = rtype_from_mftfile(fn)) == RTYPE_INVALID) { > warnx("%s: invalid filename: %s", p->fn, fn); > goto out; > } > - > - type = rtype_from_file_extension(fn); > > /* Now hash value. */ > > Index: parser.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v > retrieving revision 1.49 > diff -u -p -r1.49 parser.c > --- parser.c 21 Jan 2022 18:49:44 -0000 1.49 > +++ parser.c 21 Jan 2022 19:36:10 -0000 > @@ -307,7 +307,7 @@ proc_parser_mft_check(const char *fn, st > > for (i = 0; i < p->filesz; i++) { > const struct mftfile *m = &p->files[i]; > - if (!valid_filename(m->file)) { > + if (rtype_from_mftfile(m->file) == RTYPE_INVALID) { > if (base64_encode(m->hash, sizeof(m->hash), &h) == -1) > errx(1, "base64_encode failed in %s", __func__); > warnx("%s: unsupported filename for %s", fn, h); > Index: validate.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v > retrieving revision 1.25 > diff -u -p -r1.25 validate.c > --- validate.c 21 Jan 2022 18:49:44 -0000 1.25 > +++ validate.c 21 Jan 2022 19:36:10 -0000 > @@ -234,63 +234,6 @@ valid_roa(const char *fn, struct auth_tr > } > > /* > - * Determine rtype corresponding to file extension. Returns RTYPE_INVALID > - * on error or unkown extension. > - */ > -enum rtype > -rtype_from_file_extension(const char *fn) > -{ > - size_t sz; > - > - sz = strlen(fn); > - if (sz < 5) > - return RTYPE_INVALID; > - > - if (strcasecmp(fn + sz - 4, ".tal") == 0) > - return RTYPE_TAL; > - if (strcasecmp(fn + sz - 4, ".cer") == 0) > - return RTYPE_CER; > - if (strcasecmp(fn + sz - 4, ".crl") == 0) > - return RTYPE_CRL; > - if (strcasecmp(fn + sz - 4, ".mft") == 0) > - return RTYPE_MFT; > - if (strcasecmp(fn + sz - 4, ".roa") == 0) > - return RTYPE_ROA; > - if (strcasecmp(fn + sz - 4, ".gbr") == 0) > - return RTYPE_GBR; > - > - return RTYPE_INVALID; > -} > - > -/* > - * Validate a filename listed on a Manifest. > - * draft-ietf-sidrops-6486bis section 4.2.2 > - * Returns 1 if filename is valid, otherwise 0. > - */ > -int > -valid_filename(const char *fn) > -{ > - const unsigned char *c; > - > - for (c = fn; *c != '\0'; ++c) > - if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.') > - return 0; > - > - if (strchr(fn, '.') != strrchr(fn, '.')) > - return 0; > - > - switch (rtype_from_file_extension(fn)) { > - case RTYPE_CER: > - case RTYPE_CRL: > - case RTYPE_GBR: > - case RTYPE_ROA: > - return 1; > - default: > - return 0; > - } > -} > - > -/* > * Validate a file by verifying the SHA256 hash of that file. > * The file to check is passed as a file descriptor. > * Returns 1 if hash matched, 0 otherwise. Closes fd when done. >