summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--README.md7
-rw-r--r--browse.c13
-rw-r--r--config.c51
-rw-r--r--config.h17
-rw-r--r--download.c14
-rw-r--r--file.c8
-rw-r--r--main.c7
-rw-r--r--url.c16
9 files changed, 112 insertions, 27 deletions
diff --git a/Makefile b/Makefile
index 7e84eea..0c485c0 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ LDFLAGS=-static $(LDFLAGS_DEPS)
.if make(debug) || make(test)
PWD!=pwd
-CFLAGS+=-O0 -g -W -Wall -Wextra -DDATA_DIR='"$(PWD)/test-data"' -DTEMPLATE_DIR='"template"'
+CFLAGS+=-O0 -g -W -Wall -Wextra -DTEMPLATE_DIR='"template"'
.else
CFLAGS+=-O2
.endif
@@ -47,10 +47,10 @@ all: main
.c.o:
$(CC) -o $@ -c $< $(CFLAGS)
-main: str.o mime.o url.o template.o file.o http.o download.o browse.o main.o
+main: str.o config.o mime.o url.o template.o file.o http.o download.o browse.o main.o
$(CC) -o $@ $> $(LDFLAGS)
-test: str.o mime.o url.o template.o file.o http.o download.o browse.o test.o
+test: str.o config.o mime.o url.o template.o file.o http.o download.o browse.o test.o
$(CC) -o $@ $> $(LDFLAGS)
env: env.o
diff --git a/README.md b/README.md
index 512453c..a140bc0 100644
--- a/README.md
+++ b/README.md
@@ -34,9 +34,10 @@ By default on OpenBSD, the `slowcgi(8)` daemon allows a timeout of 2 minutes for
server "server" {
listen on * port 80
connection timeout 540
- location "/cgi-bin/vault/*" {
- fastcgi
- root "/"
+ location "/vault/*" {
+ root "/cgi-bin/vault"
+ fastcgi param VAULT_DATA_DIR "/vault-data"
+ request strip 1
}
location "/static/*" {
root "/vault-static"
diff --git a/browse.c b/browse.c
index 51f41dd..868388f 100644
--- a/browse.c
+++ b/browse.c
@@ -208,6 +208,7 @@ browse(struct kreq * r)
{
size_t url_len;
char current_dir[PATH_MAX];
+ char *data_dir;
struct file *file;
struct page_template *tmpl;
struct http_ret ret;
@@ -223,6 +224,16 @@ browse(struct kreq * r)
KHTTP_200, ""
};
+ /* check that data dir is configured */
+ data_dir = config_data_dir();
+ if (data_dir == NULL) {
+ ret = (struct http_ret) {
+ KHTTP_400,
+ "browse: data dir is not configured"
+ };
+ goto end;
+ }
+
/* check that the requested URL can be safely processed */
if (!check_request_path(r->path, r->suffix)) {
ret = (struct http_ret) {
@@ -232,7 +243,7 @@ browse(struct kreq * r)
goto end;
}
/* list requested directory content */
- url_len = url_build(current_dir, PATH_MAX, DATA_DIR, r->path,
+ url_len = url_build(current_dir, PATH_MAX, data_dir, r->path,
NULL);
if (url_len == 0) {
ret = (struct http_ret) {
diff --git a/config.c b/config.c
new file mode 100644
index 0000000..4401d31
--- /dev/null
+++ b/config.c
@@ -0,0 +1,51 @@
+/*
+ * 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 <string.h>
+
+#include "config.h"
+
+extern char **environ;
+
+char *
+config_data_dir()
+{
+ char *key;
+
+ key = "VAULT_DATA_DIR";
+ for (char **var = environ; *var; var++) {
+ if (strncmp(key, *var, strlen(key)) == 0) {
+ if (strlen(*var) <= strlen(key))
+ return NULL;
+ return *var + strlen(key) + 1;
+ }
+ }
+ return NULL;
+}
diff --git a/config.h b/config.h
index 3f58258..edb494b 100644
--- a/config.h
+++ b/config.h
@@ -32,15 +32,6 @@
#define CONFIG_H
/*
- * The directory that will be browseable through vault. The vault process
- * should have full read/write access to this folder and any subfolders and
- * files.
- */
-#ifndef DATA_DIR
-#define DATA_DIR "/vault-data"
-#endif
-
-/*
* The log file. The vault process needs write permissions to this file,
* otherwise it will quit with an error.
*/
@@ -53,4 +44,12 @@
#define TEMPLATE_DIR "/usr/share/vault/template"
#endif
+/*
+ * The directory that will be browseable through vault. It is read from the env
+ * variable VAULT_DATA_DIR. The vault process should have full read/write
+ * access to this folder and any subfolders and files.
+ */
+char *
+config_data_dir();
+
#endif /* CONFIG_H */
diff --git a/download.c b/download.c
index bff1dd6..a8f5947 100644
--- a/download.c
+++ b/download.c
@@ -79,7 +79,7 @@ build_download_url(struct kreq * r, struct file * file)
struct http_ret
download(struct kreq * r)
{
- char *file_name;
+ char *file_name, *data_dir;
void *buffer;
struct file *f;
int fd;
@@ -93,6 +93,16 @@ download(struct kreq * r)
KHTTP_200, ""
};
+ /* check that data dir is configured */
+ data_dir = config_data_dir();
+ if (data_dir == NULL) {
+ ret = (struct http_ret) {
+ KHTTP_400,
+ "download: data dir not configured"
+ };
+ goto end;
+ }
+
/* check that the requested URL can be safely processed */
if (strlen(r->path) == 0 || !check_request_path(r->path, r->suffix)) {
ret = (struct http_ret) {
@@ -122,7 +132,7 @@ download(struct kreq * r)
}
}
- path_size = url_build(file_path, PATH_MAX, DATA_DIR, request_path,
+ path_size = url_build(file_path, PATH_MAX, data_dir, request_path,
NULL);
if (path_size == 0) {
ret = (struct http_ret) {
diff --git a/file.c b/file.c
index be044ca..5785805 100644
--- a/file.c
+++ b/file.c
@@ -64,16 +64,20 @@ file_free(struct file * file)
static bool
fill_metadata(struct file * f)
{
- char *ext;
+ char *ext, *data_dir;
char path[PATH_MAX];
struct stat sb;
size_t path_len;
+ data_dir = config_data_dir();
+ if (data_dir == NULL)
+ return false;
+
/* default mime */
f->mime = MIME__MAX;
/* check if it is a directory */
- path_len = url_build(path, PATH_MAX, DATA_DIR, f->path, f->name, NULL);
+ path_len = url_build(path, PATH_MAX, data_dir, f->path, f->name, NULL);
if (path_len == 0 || path_len >= PATH_MAX)
return false;
diff --git a/main.c b/main.c
index 0b8e867..1561a09 100644
--- a/main.c
+++ b/main.c
@@ -53,6 +53,7 @@ static const char *const pages[PAGE__MAX] = {
int
main(void)
{
+ char *data_dir;
enum kcgi_err parse_err;
struct kreq r;
struct http_ret ret;
@@ -65,8 +66,12 @@ main(void)
http_exit(NULL, KHTTP_500, "Unable to parse request: %s",
kcgi_strerror(parse_err));
+ data_dir = config_data_dir();
+ if (data_dir == NULL)
+ http_exit(NULL, KHTTP_500, "Data dir not configured");
+
/* A bit of security cannot hurt */
- if (-1 == unveil(DATA_DIR, "r")
+ if (-1 == unveil(data_dir, "r")
|| -1 == unveil(TEMPLATE_DIR, "r")
|| -1 == unveil(NULL, NULL))
http_exit(&r, KHTTP_500, "Unveil failed: %s", strerror(errno));
diff --git a/url.c b/url.c
index 228efeb..3e82821 100644
--- a/url.c
+++ b/url.c
@@ -41,10 +41,14 @@ bool
check_request_path(char *path, char *suffix)
{
char p[PATH_MAX], resolved[PATH_MAX];
- char *rp;
+ char *rp, *data_dir;
+
+ data_dir = config_data_dir();
+ if (data_dir == NULL)
+ return false;
/* build absolute path from DATA_DIR */
- if (strlcpy(p, DATA_DIR, sizeof(p)) >= sizeof(p))
+ if (strlcpy(p, data_dir, sizeof(p)) >= sizeof(p))
return false;
if (strlcat(p, "/", sizeof(p)) >= sizeof(p))
return false;
@@ -52,9 +56,9 @@ check_request_path(char *path, char *suffix)
return false;
if (strlen(suffix) > 0) {
/* add suffix */
- if(strlcat(p, ".", sizeof(p)) >= sizeof(p))
+ if (strlcat(p, ".", sizeof(p)) >= sizeof(p))
return false;
- if(strlcat(p, suffix, sizeof(p)) >= sizeof(p))
+ if (strlcat(p, suffix, sizeof(p)) >= sizeof(p))
return false;
}
@@ -65,7 +69,7 @@ check_request_path(char *path, char *suffix)
/* path must start with DATA_DIR */
rp[PATH_MAX - 1] = '\0';
- if (strstr(rp, DATA_DIR) != rp)
+ if (strstr(rp, data_dir) != rp)
return false;
return true;
@@ -92,7 +96,7 @@ url_build(char *dst, size_t dst_size,...)
if (path[0] == '.' && path[1] == '\0')
continue;
- if (path[0] != '/' && dst[w_size - 1] != '/')
+ if (path[0] != '/' && w_size > 0 && dst[w_size - 1] != '/')
strlcat(dst, "/", dst_size);
w_size = strlcat(dst, path, dst_size);