summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Douillet <vincent@vdouillet.fr>2023-07-26 09:41:28 +0200
committerVincent Douillet <vincent@vdouillet.fr>2023-08-01 18:14:47 +0200
commit89a76cdd3fa168902d83f4c043d2cc6629b40024 (patch)
treed09e916129894e64010ae5d8f6dbe68ef842d02f
parent519194a2199af44b157812705aa8838068a97bc8 (diff)
browse folders
-rw-r--r--.indent.pro1
-rw-r--r--Makefile2
-rw-r--r--browse.c83
-rw-r--r--browse.h2
-rw-r--r--config.h37
-rw-r--r--error.h5
-rw-r--r--main.c2
-rw-r--r--url.c70
-rw-r--r--url.h42
9 files changed, 228 insertions, 16 deletions
diff --git a/.indent.pro b/.indent.pro
index 1f1db9f..5be652a 100644
--- a/.indent.pro
+++ b/.indent.pro
@@ -3,6 +3,7 @@
-ce
-ci4
-cli0
+-di8
-d0
-i8
-ip
diff --git a/Makefile b/Makefile
index 45c1133..5489720 100644
--- a/Makefile
+++ b/Makefile
@@ -38,7 +38,7 @@ all: main
.c.o:
$(CC) -o $@ -c $< $(CFLAGS)
-main: http.o browse.o main.o
+main: url.o http.o browse.o main.o
$(CC) -o $@ $> $(LDFLAGS)
env: env.o
diff --git a/browse.c b/browse.c
index 1cd635f..65e3c5a 100644
--- a/browse.c
+++ b/browse.c
@@ -31,21 +31,78 @@
#include <dirent.h>
#include <kcgi.h>
#include <kcgihtml.h>
+#include <stdbool.h>
#include <string.h>
#include "browse.h"
#include "config.h"
#include "error.h"
#include "http.h"
+#include "url.h"
+
+#define URL_LENGTH_MAX 8192
+
+/*
+ * Checks that the path can be safely processed. Namely, it should not contain "..", which denotes an attempt to get out of the DATA_DIR root folder.
+ */
+static bool
+check_request_path(char *path)
+{
+ char *p_found;
+
+ p_found = strstr(path, "/..");
+ if (p_found != NULL)
+ return false;
+
+ p_found = strstr(path, "../");
+ return p_found == NULL;
+}
+
+/*
+ * file url = r->pname / r->pagename / r->path / file_name
+ */
+static size_t
+build_browse_url(struct kreq * r, char *url, size_t url_size, const char *file)
+{
+ char *page_name;
+
+ page_name = strlen(r->pagename) == 0 ? BROWSE_URL : r->pagename;
+ return url_build(url, url_size, 4, r->pname, page_name, r->path, file);
+}
int
browse(struct kreq * r)
{
- struct dirent *current_dir;
- DIR *data_dir;
- char *dir_name;
+ struct dirent *dir;
+ DIR *data_dir;
+ char *file_name;
+ size_t url_size;
+ char url[URL_LENGTH_MAX], current_dir[URL_LENGTH_MAX];
struct khtmlreq html;
+ /* check that the requested URL can be safely processed */
+ if (strlen(r->path) >= URL_LENGTH_MAX) {
+ http_open(r, KHTTP_414);
+ return VAULT_URI_ERROR;
+ }
+ if (!check_request_path(r->path)) {
+ http_open(r, KHTTP_400);
+ return VAULT_URI_ERROR;
+ }
+ /* list requested directory content */
+ url_size = url_build(current_dir, URL_LENGTH_MAX, 2, DATA_DIR, r->path);
+ if (url_size == 0) {
+ http_open(r, KHTTP_404);
+ return VAULT_IO_ERROR;
+ } else if (url_size >= URL_LENGTH_MAX) {
+ http_open(r, KHTTP_414);
+ return VAULT_URI_ERROR;
+ }
+ data_dir = opendir(current_dir);
+ if (NULL == data_dir) {
+ http_open(r, KHTTP_404);
+ return VAULT_IO_ERROR;
+ }
http_open(r, KHTTP_200);
if (KCGI_OK != khtml_open(&html, r, 0))
@@ -53,25 +110,27 @@ browse(struct kreq * r)
/* build basic html page */
khtml_elem(&html, KELEM_DOCTYPE);
+ khtml_elem(&html, KELEM_HEAD);
+ khtml_attr(&html, KELEM_META, KATTR_CHARSET, "utf-8", KATTR__MAX);
khtml_elem(&html, KELEM_HTML);
khtml_elem(&html, KELEM_BODY);
khtml_elem(&html, KELEM_P);
khtml_puts(&html, "/");
khtml_closeelem(&html, 1);
- /* list data directory content */
- data_dir = opendir(DATA_DIR);
- if (NULL == data_dir)
- return VAULT_IO_ERROR;
khtml_elem(&html, KELEM_UL);
- while ((current_dir = readdir(data_dir)) != NULL) {
+ while ((dir = readdir(data_dir)) != NULL) {
/* ignore special . and .. folders */
- dir_name = current_dir->d_name;
- if (strcmp(".", dir_name) == 0 || strcmp("..", dir_name) == 0)
+ file_name = dir->d_name;
+ if (strcmp(".", file_name) == 0 || strcmp("..", file_name) == 0)
+ continue;
+ url_size = build_browse_url(r, url, URL_LENGTH_MAX, file_name);
+ if (url_size == 0 || url_size >= URL_LENGTH_MAX)
continue;
khtml_elem(&html, KELEM_LI);
- khtml_puts(&html, current_dir->d_name);
- khtml_closeelem(&html, 1);
+ khtml_attr(&html, KELEM_A, KATTR_HREF, url, KATTR__MAX);
+ khtml_puts(&html, dir->d_name);
+ khtml_closeelem(&html, 2);
}
khtml_close(&html);
closedir(data_dir);
diff --git a/browse.h b/browse.h
index 888cbc7..3d34d94 100644
--- a/browse.h
+++ b/browse.h
@@ -33,6 +33,8 @@
#include <kcgi.h>
+#define BROWSE_URL "browse"
+
/*
* browse page allows to browse through the folder hierarchy under DATA_DIR,
* returns 0 in case of success, an error code otherwise
diff --git a/config.h b/config.h
index e69de29..0db9f43 100644
--- a/config.h
+++ b/config.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2023, Vincent Douillet <vincent@vdouillet.fr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VAULT_CONFIG_H
+#define VAULT_CONFIG_H
+
+#define DATA_DIR "/var/www/vault-data"
+
+#endif /* VAULT_CONFIG_H */
+
diff --git a/error.h b/error.h
index e95b38f..ce96418 100644
--- a/error.h
+++ b/error.h
@@ -32,7 +32,8 @@
#define VAULT_ERROR_H
#define VAULT_SUCCESS 0
-#define VAULT_CGI_ERROR -1
-#define VAULT_IO_ERROR -2
+#define VAULT_CGI_ERROR 1
+#define VAULT_IO_ERROR 2
+#define VAULT_URI_ERROR 3
#endif /* VAULT_ERROR_H */
diff --git a/main.c b/main.c
index e323683..6abcbc5 100644
--- a/main.c
+++ b/main.c
@@ -41,7 +41,7 @@ enum page {
};
static const char *const pages[PAGE__MAX] = {
- "browse",
+ BROWSE_URL
};
int
diff --git a/url.c b/url.c
new file mode 100644
index 0000000..b4c30a6
--- /dev/null
+++ b/url.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2023, Vincent Douillet <vincent@vdouillet.fr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "url.h"
+
+size_t
+url_build(char *dst, size_t dst_size, int count,...)
+{
+ va_list path_list;
+ const char *path;
+ int path_index;
+ size_t w_size;
+
+ dst[0] = '\0';
+ w_size = 0;
+ va_start(path_list, count);
+ for (path_index = 0; path_index < count; path_index++) {
+ /* no more space in dst buffer */
+ if (w_size >= dst_size)
+ break;
+
+ path = va_arg(path_list, char *);
+
+ assert(path != NULL);
+ if (path[0] == '\0')
+ continue;
+
+ if (path[0] == '.' && path[1] == '\0')
+ continue;
+
+ if (path[0] != '/' && dst[w_size - 1] != '/')
+ w_size = strlcat(dst, "/", dst_size);
+
+ w_size = strlcat(dst, path, dst_size);
+ }
+
+ va_end(path_list);
+ return w_size;
+}
diff --git a/url.h b/url.h
new file mode 100644
index 0000000..b60f548
--- /dev/null
+++ b/url.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023, Vincent Douillet <vincent@vdouillet.fr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VAULT_URL_H
+#define VAULT_URL_H
+
+#include <stdio.h>
+
+/*
+ * Build an URL from the provided components.
+ */
+size_t
+url_build(char *, size_t, int,...);
+
+#endif /* VAULT_URL_H */