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);

Reply via email to