aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-07-09 04:41:55 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-07-09 05:54:53 +0200
commitb5282b23653b3a46ab6ae2d84049abadcc8a8a1d (patch)
tree182e9fd51ca2d9678089efd41439848d61aada23
parentfbd730754b83dd9ae95d9b308e29ba7e85001528 (diff)
downloadslcl-b5282b23653b3a46ab6ae2d84049abadcc8a8a1d.tar.gz
main.c: Disallow invalid filenames or directory names
- Relative paths must not be used for filenames or directory names, such as "..", "." or "dir/..". - Paths with asterisks ('*') must not be allowed, to avoid confusion with wildcard expressions.
-rw-r--r--main.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/main.c b/main.c
index 05e7d1b..2dee5f6 100644
--- a/main.c
+++ b/main.c
@@ -370,6 +370,21 @@ static bool path_isrel(const char *const path)
return false;
}
+static bool path_invalid(const char *const path)
+{
+ return path_isrel(path) || strchr(path, '*');
+}
+
+static bool filename_invalid(const char *const path)
+{
+ return path_invalid(path) || strchr(path, '/');
+}
+
+static bool dirname_invalid(const char *const path)
+{
+ return *path != '/' || path[strlen(path) - 1] != '/' || path_invalid(path);
+}
+
static int getpublic(const struct http_payload *const p,
struct http_response *const r, void *const user)
{
@@ -385,7 +400,7 @@ static int getpublic(const struct http_payload *const p,
fprintf(stderr, "%s: auth_dir failed\n", __func__);
goto end;
}
- else if (path_isrel(p->resource))
+ else if (path_invalid(p->resource))
{
fprintf(stderr, "%s: illegal relative path %s\n",
__func__, p->resource);
@@ -520,14 +535,14 @@ static int check_search_input(const struct http_payload *const p,
*f = page_bad_request;
goto end;
}
- else if (path_isrel(tdir) || *tdir != '/' || tdir[strlen(tdir) - 1] != '/')
+ else if (dirname_invalid(tdir))
{
fprintf(stderr, "%s: invalid directory %s\n", __func__, tdir);
ret = 1;
*f = page_bad_request;
goto end;
}
- else if (strchr(tres, '/') || path_isrel(tres))
+ else if (filename_invalid(tres))
{
fprintf(stderr, "%s: invalid resource %s\n", __func__, tres);
ret = 1;
@@ -741,7 +756,7 @@ static int share(const struct http_payload *const p,
const char *const path = forms->value, *const username = p->cookie.field;
- if (path_isrel(path))
+ if (path_invalid(path))
{
fprintf(stderr, "%s: invalid path %s\n", __func__, path);
ret = page_bad_request(r);
@@ -870,7 +885,7 @@ static int getnode(const struct http_payload *const p,
const char *const username = p->cookie.field,
*const resource = p->resource + strlen("/user/");
- if (path_isrel(resource))
+ if (path_invalid(resource))
{
fprintf(stderr, "%s: illegal relative path %s\n", __func__, resource);
return page_forbidden(r);
@@ -1124,6 +1139,11 @@ static int upload_files(const struct http_payload *const p,
return 0;
}
+ else if (dirname_invalid(dir))
+ {
+ fprintf(stderr, "%s: invalid directory %s\n", __func__, dir);
+ return page_bad_request(r);
+ }
for (size_t i = 0; i < po->n; i++)
{
@@ -1218,13 +1238,13 @@ static int createdir(const struct http_payload *const p,
ret = page_bad_request(r);
goto end;
}
- else if (path_isrel(name) || strpbrk(name, "/*"))
+ else if (filename_invalid(name))
{
fprintf(stderr, "%s: invalid directory name %s\n", __func__, dir);
ret = page_bad_request(r);
goto end;
}
- else if (path_isrel(dir) || strchr(dir, '*'))
+ else if (dirname_invalid(dir))
{
fprintf(stderr, "%s: invalid name %s\n", __func__, name);
ret = page_bad_request(r);
@@ -1318,6 +1338,15 @@ static int check_rm_input(const struct form *const forms, const size_t n,
}
else if (!strcmp(f->key, "path"))
{
+ const char *const path = f->value;
+
+ if (path_isrel(path))
+ {
+ fprintf(stderr, "%s: invalid path %s\n", __func__, rm->dir);
+ *cb = page_bad_request;
+ return 1;
+ }
+
const char **tmp = realloc(rm->items, (rm->n + 1) * sizeof *tmp);
if (!tmp)
@@ -1327,7 +1356,7 @@ static int check_rm_input(const struct form *const forms, const size_t n,
return -1;
}
- tmp[rm->n++] = f->value;
+ tmp[rm->n++] = path;
rm->items = tmp;
}
}
@@ -1338,7 +1367,7 @@ static int check_rm_input(const struct form *const forms, const size_t n,
*cb = page_bad_request;
return 1;
}
- else if (*rm->dir != '/' || path_isrel(rm->dir))
+ else if (dirname_invalid(rm->dir))
{
fprintf(stderr, "%s: invalid directory %s\n", __func__, rm->dir);
*cb = page_bad_request;
@@ -1526,10 +1555,20 @@ static int do_rm(const struct form *const forms, const size_t n,
{
const struct form *const f = &forms[i];
- if (!strcmp(f->key, "path") && rm_item(dir, f->value))
+ if (!strcmp(f->key, "path"))
{
- fprintf(stderr, "%s: rm_item failed\n", __func__);
- return -1;
+ const char *const path = f->value;
+
+ if (path_isrel(path))
+ {
+ fprintf(stderr, "%s: invalid path %s\n", __func__, path);
+ return 1;
+ }
+ else if (rm_item(dir, f->value))
+ {
+ fprintf(stderr, "%s: rm_item failed\n", __func__);
+ return -1;
+ }
}
}
@@ -1580,7 +1619,7 @@ static int rm(const struct http_payload *const p,
ret = f(r);
goto end;
}
- else if (*dir != '/' || path_isrel(dir))
+ else if (dirname_invalid(dir))
{
fprintf(stderr, "%s: invalid directory %s\n", __func__, dir);
ret = page_bad_request(r);