Restrict the characterset for filenames on Manifests
authorjob <job@openbsd.org>
Sun, 24 Oct 2021 12:06:16 +0000 (12:06 +0000)
committerjob <job@openbsd.org>
Sun, 24 Oct 2021 12:06:16 +0000 (12:06 +0000)
feedback from benno@

OK claudio@

usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/mft.c
usr.sbin/rpki-client/validate.c

index fbaf8d9..4a0bc62 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.75 2021/10/23 20:01:16 claudio Exp $ */
+/*     $OpenBSD: extern.h,v 1.76 2021/10/24 12:06:16 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -437,6 +437,7 @@ int          valid_ta(const char *, struct auth_tree *,
 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(const char *, const char *, size_t);
 int             valid_uri(const char *, size_t, const char *);
 
index 0fc6f00..b0fd40c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mft.c,v 1.39 2021/10/23 16:06:04 claudio Exp $ */
+/*     $OpenBSD: mft.c,v 1.40 2021/10/24 12:06:16 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -489,7 +489,7 @@ mft_check(const char *fn, struct mft *p)
 {
        size_t  i;
        int     rc = 1;
-       char    *cp, *path = NULL;
+       char    *cp, *h, *path = NULL;
 
        /* Check hash of file now, but first build path for it */
        cp = strrchr(fn, '/');
@@ -498,6 +498,13 @@ mft_check(const char *fn, struct mft *p)
 
        for (i = 0; i < p->filesz; i++) {
                const struct mftfile *m = &p->files[i];
+               if (!valid_filename(m->file)) {
+                       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;
+               }
                if (asprintf(&path, "%.*s/%s", (int)(cp - fn), fn,
                    m->file) == -1)
                        err(1, NULL);
index d249ba9..f511edc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: validate.c,v 1.16 2021/10/11 16:50:03 job Exp $ */
+/*     $OpenBSD: validate.c,v 1.17 2021/10/24 12:06:16 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -245,6 +245,40 @@ valid_roa(const char *fn, struct auth_tree *auths, struct roa *roa)
        return 1;
 }
 
+/*
+ * 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)
+{
+       size_t                   sz;
+       const unsigned char     *c;
+
+       sz = strlen(fn);
+       if (sz < 5)
+               return 0;
+
+       for (c = fn; *c != '\0'; ++c)
+               if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
+                       return 0;
+
+       if (strchr(fn, '.') != strrchr(fn, '.'))
+               return 0;
+
+       if (strcasecmp(fn + sz - 4, ".cer") == 0)
+               return 1;
+       if (strcasecmp(fn + sz - 4, ".crl") == 0)
+               return 1;
+       if (strcasecmp(fn + sz - 4, ".gbr") == 0)
+               return 1;
+       if (strcasecmp(fn + sz - 4, ".roa") == 0)
+               return 1;
+
+       return 0;
+}
+
 /*
  * Validate a file by verifying the SHA256 hash of that file.
  * Returns 1 if valid, 0 otherwise.