This diff does a few things regarding MFT file and hash sequences:
- it validates the filename early on so that if considered valid it can
be printed by printf(%s) without problems.
- it assigns the file type (based on the file extension) early on and no
longer uses this information when comparing the file hash.
- Handle unknown files more like a soft error, the file hash still needs
to match but the content is totally ignored.
In other words it no longer rejects MFTs with unknown files in it.
Right now rpki-client is very strict in what is accepted and it will
become an some issue when ASPA is becomming more concrete.
--
:wq Claudio
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.114
diff -u -p -r1.114 extern.h
--- extern.h 23 Jan 2022 12:09:24 -0000 1.114
+++ extern.h 24 Jan 2022 14:53:52 -0000
@@ -422,7 +422,6 @@ struct mft *mft_parse(X509 **, const cha
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 *);
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.184
diff -u -p -r1.184 main.c
--- main.c 23 Jan 2022 18:40:55 -0000 1.184
+++ main.c 24 Jan 2022 15:05:59 -0000
@@ -376,7 +376,7 @@ queue_add_from_mft_set(const struct mft
case RTYPE_CRL:
continue;
default:
- logx("%s: unsupported file type: %s", name, f->file);
+ warnx("%s: unsupported file: %s", name, f->file);
}
}
}
Index: mft.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.50
diff -u -p -r1.50 mft.c
--- mft.c 22 Jan 2022 09:18:48 -0000 1.50
+++ mft.c 24 Jan 2022 14:50:40 -0000
@@ -152,22 +152,33 @@ rtype_from_file_extension(const char *fn
/*
* 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.
+ * permitted in draft-ietf-sidrops-6486bis section 4.2.2
*/
-enum rtype
-rtype_from_mftfile(const char *fn)
+static int
+valid_filename(const char *fn, size_t len)
{
- const unsigned char *c;
- enum rtype type;
+ const unsigned char *c;
+ size_t i;
- for (c = fn; *c != '\0'; ++c)
+ for (c = fn, i = 0; i < len; i++, c++)
if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
- return RTYPE_INVALID;
+ return 0;
- if (strchr(fn, '.') != strrchr(fn, '.'))
- return RTYPE_INVALID;
+ c = memchr(fn, '.', len);
+ if (c == NULL || c != memrchr(fn, '.', len))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Check that the file is a CER, CRL, GBR or a ROA.
+ * Returns corresponding rtype or RTYPE_INVALID on error.
+ */
+static enum rtype
+rtype_from_mftfile(const char *fn)
+{
+ enum rtype type;
type = rtype_from_file_extension(fn);
switch (type) {
@@ -217,15 +228,17 @@ mft_parse_filehash(struct parse *p, cons
p->fn, ASN1_tag2str(file->type), file->type);
goto out;
}
+ if (!valid_filename(file->value.ia5string->data,
+ file->value.ia5string->length)) {
+ warnx("%s: RFC 6486 section 4.2.2: bad filename", p->fn);
+ goto out;
+ }
fn = strndup((const char *)file->value.ia5string->data,
file->value.ia5string->length);
if (fn == NULL)
err(1, NULL);
- if ((type = rtype_from_mftfile(fn)) == RTYPE_INVALID) {
- warnx("%s: invalid filename: %s", p->fn, fn);
- goto out;
- }
+ type = rtype_from_mftfile(fn);
/* Now hash value. */
Index: parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
retrieving revision 1.53
diff -u -p -r1.53 parser.c
--- parser.c 23 Jan 2022 12:09:24 -0000 1.53
+++ parser.c 24 Jan 2022 15:26:08 -0000
@@ -304,21 +304,13 @@ static int
proc_parser_mft_check(const char *fn, struct mft *p)
{
size_t i;
- int fd, try, rc = 1;
- char *h, *path;
+ int rc = 1;
+ char *path;
for (i = 0; i < p->filesz; i++) {
const struct mftfile *m = &p->files[i];
- 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);
- free(h);
- continue;
- }
+ int fd = -1, try = 0;
- fd = -1;
- try = 0;
path = NULL;
do {
free(path);