Adjust code to handle unsupported file types a bit more graceful.
authorclaudio <claudio@openbsd.org>
Mon, 24 Jan 2022 17:29:37 +0000 (17:29 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 24 Jan 2022 17:29:37 +0000 (17:29 +0000)
The file still needs to match its hash to make the MFT valid but then
there will only be a warning printed. Parsing of other files from that
MFT are not influenced.
OK tb@

usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/main.c
usr.sbin/rpki-client/mft.c
usr.sbin/rpki-client/parser.c

index 66a460c..d4f0f18 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.114 2022/01/23 12:09:24 claudio Exp $ */
+/*     $OpenBSD: extern.h,v 1.115 2022/01/24 17:29:37 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -422,7 +422,6 @@ 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 *);
index 3955c77..7259662 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.184 2022/01/23 18:40:55 jmc Exp $ */
+/*     $OpenBSD: main.c,v 1.185 2022/01/24 17:29:37 claudio Exp $ */
 /*
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -376,7 +376,7 @@ queue_add_from_mft_set(const struct mft *mft, const char *name, struct repo *rp)
                case RTYPE_CRL:
                        continue;
                default:
-                       logx("%s: unsupported file type: %s", name, f->file);
+                       warnx("%s: unsupported file: %s", name, f->file);
                }
        }
 }
index 39feafd..d1e6c1e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mft.c,v 1.50 2022/01/22 09:18:48 tb Exp $ */
+/*     $OpenBSD: mft.c,v 1.51 2022/01/24 17:29:37 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -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) {
@@ -191,7 +202,6 @@ mft_parse_filehash(struct parse *p, const ASN1_OCTET_STRING *os)
        ASN1_SEQUENCE_ANY       *seq;
        const ASN1_TYPE         *file, *hash;
        char                    *fn = NULL;
-       enum rtype               type;
        const unsigned char     *d = os->data;
        size_t                   dsz = os->length;
        int                      rc = 0;
@@ -217,16 +227,16 @@ mft_parse_filehash(struct parse *p, const ASN1_OCTET_STRING *os)
                    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;
-       }
-
        /* Now hash value. */
 
        hash = sk_ASN1_TYPE_value(seq, 1);
@@ -247,8 +257,8 @@ mft_parse_filehash(struct parse *p, const ASN1_OCTET_STRING *os)
        /* Insert the filename and hash value. */
        fent = &p->res->files[p->res->filesz++];
 
+       fent->type = rtype_from_mftfile(fn);
        fent->file = fn;
-       fent->type = type;
        fn = NULL;
        memcpy(fent->hash, hash->value.bit_string->data, SHA256_DIGEST_LENGTH);
 
index 17d6c26..0e249a1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.c,v 1.53 2022/01/23 12:09:24 claudio Exp $ */
+/*     $OpenBSD: parser.c,v 1.54 2022/01/24 17:29:37 claudio Exp $ */
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -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);