summaryrefslogtreecommitdiff
path: root/src/tipideed
diff options
context:
space:
mode:
Diffstat (limited to 'src/tipideed')
-rw-r--r--src/tipideed/deps-exe/tipideed1
-rw-r--r--src/tipideed/responses.c41
-rw-r--r--src/tipideed/tipideed-internal.h9
-rw-r--r--src/tipideed/tipideed.c18
-rw-r--r--src/tipideed/util.c29
5 files changed, 67 insertions, 31 deletions
diff --git a/src/tipideed/deps-exe/tipideed b/src/tipideed/deps-exe/tipideed
index e1a6c0a..8e5263e 100644
--- a/src/tipideed/deps-exe/tipideed
+++ b/src/tipideed/deps-exe/tipideed
@@ -5,5 +5,6 @@ regular.o
responses.o
send_file.o
trace.o
+util.o
libtipidee.a.xyzzy
-lskarnet
diff --git a/src/tipideed/responses.c b/src/tipideed/responses.c
index ad53351..6e32ea9 100644
--- a/src/tipideed/responses.c
+++ b/src/tipideed/responses.c
@@ -40,21 +40,14 @@ void response_error (tipidee_rql const *rql, char const *docroot, unsigned int s
{
tain deadline ;
tipidee_defaulttext dt ;
- char const *file = 0;
- size_t salen = g.sa.len ;
+ char const *file = 0 ;
+ size_t pos = translate_path(docroot) ;
- if (sarealpath(&g.sa, docroot) == -1)
- {
- if (errno != ENOENT) strerr_diefu2sys(111, "realpath ", docroot) ;
- }
- else
- {
- if (!stralloc_0(&g.sa)) strerr_diefu1sys(111, "build response") ;
- if (strncmp(g.sa.s + salen, g.sa.s, g.cwdlen) || g.sa.s[salen + g.cwdlen] != '/')
- strerr_dief4x(102, "layout error: ", "docroot ", docroot, " points outside of the server's root") ;
- file = tipidee_conf_get_errorfile(&g.conf, g.sa.s + salen + g.cwdlen + 1, status) ;
- g.sa.len = salen ;
- }
+ if (pos) file = tipidee_conf_get_errorfile(&g.conf, g.sa.s + pos , status) ;
+ else if (errno == EPERM)
+ strerr_dief4x(102, "layout error: ", "docroot ", docroot, " points outside of the server's root") ;
+ else if (errno != ENOENT)
+ strerr_diefu2sys(111, "translate_path ", docroot) ;
if (!tipidee_util_defaulttext(status, &dt))
{
@@ -65,13 +58,17 @@ void response_error (tipidee_rql const *rql, char const *docroot, unsigned int s
if (file)
{
- if (sarealpath(&g.sa, file) == -1 || !stralloc_0(&g.sa))
- strerr_warnwu3sys("realpath ", "custom response file ", file) ;
- else if (strncmp(g.sa.s + salen, g.sa.s, g.cwdlen) || g.sa.s[salen + g.cwdlen] != '/')
- strerr_warnw4x("layout error: ", "custom response file ", file, " points outside of the server's root") ;
+ pos = translate_path(file) ;
+ if (!pos)
+ {
+ if (errno == EPERM)
+ strerr_warnw4x("layout error: ", "custom response file ", file, " points outside of the server's root") ;
+ else
+ strerr_warnwu3sys("translate_path ", "custom response file ", file) ;
+ }
else
{
- int fd = open_read(g.sa.s + salen + g.cwdlen + 1) ;
+ int fd = open_read(g.sa.s + pos) ;
if (fd == -1) strerr_warnwu3sys("open ", "custom response file ", file) ;
else
{
@@ -88,16 +85,14 @@ void response_error (tipidee_rql const *rql, char const *docroot, unsigned int s
}
else
{
- tipidee_response_file_G(buffer_1, rql, status, dt.reason, &st, tipidee_conf_get_content_type(&g.conf, g.sa.s + salen + g.cwdlen + 1), g.rhdr, g.rhdrn, options) ;
+ tipidee_response_file_G(buffer_1, rql, status, dt.reason, &st, tipidee_conf_get_content_type(&g.conf, g.sa.s + pos), g.rhdr, g.rhdrn, options) ;
tipidee_log_answer(g.logv, rql, status, st.st_size) ;
- send_file(fd, st.st_size, g.sa.s + salen + g.cwdlen + 1) ;
+ send_file(fd, st.st_size, g.sa.s + pos) ;
fd_close(fd) ;
- g.sa.len = salen ;
return ;
}
}
}
- g.sa.len = salen ;
}
tipidee_response_error_nofile_G(buffer_1, rql, status, dt.reason, dt.text, g.rhdr, g.rhdrn, options & 1 || !g.cont) ;
diff --git a/src/tipideed/tipideed-internal.h b/src/tipideed/tipideed-internal.h
index 8b0e114..8631861 100644
--- a/src/tipideed/tipideed-internal.h
+++ b/src/tipideed/tipideed-internal.h
@@ -41,6 +41,7 @@ struct global_s
uint16_t cont : 2 ;
uint16_t ssl : 1 ;
uint16_t xiscgi : 1 ;
+ uint8_t flagnoxlate : 1 ;
} ;
#define GLOBAL_ZERO \
{ \
@@ -64,7 +65,8 @@ struct global_s
.indexn = 0, \
.cont = 1, \
.ssl = 0, \
- .xiscgi = 0 \
+ .xiscgi = 0, \
+ .flagnoxlate = 0 \
}
extern struct global_s g ;
@@ -138,6 +140,11 @@ extern int respond_304 (tipidee_rql const *, char const *, struct stat const *)
extern int respond_cgi (tipidee_rql *, char const *, char const *, size_t, char const *, char *, tipidee_headers const *, tipidee_resattr const *, char const *, size_t) ;
+ /* util */
+
+extern size_t translate_path (char const *) ;
+
+
/* main */
extern void log_and_exit (int) gccattr_noreturn ;
diff --git a/src/tipideed/tipideed.c b/src/tipideed/tipideed.c
index 0f5d44c..8323db1 100644
--- a/src/tipideed/tipideed.c
+++ b/src/tipideed/tipideed.c
@@ -195,13 +195,16 @@ static inline unsigned int indexify (tipidee_rql const *rql, char const *docroot
static inline void get_resattr (tipidee_rql const *rql, char const *docroot, char const *res, tipidee_resattr *ra)
{
- size_t pos = g.sa.len ;
- if (sarealpath(&g.sa, res) == -1 || !stralloc_0(&g.sa)) die500sys(rql, 111, docroot, "realpath ", res) ;
- if (strncmp(g.sa.s + pos, g.sa.s, g.cwdlen) || g.sa.s[pos + g.cwdlen] != '/')
- die500x(rql, 102, docroot, "resource ", res, " points outside of the server's root") ;
- if (!tipidee_conf_get_resattr(&g.conf, g.sa.s + pos + g.cwdlen + 1, ra))
- die500sys(rql, 102, docroot, "look up resource attributes for ", g.sa.s + pos + g.cwdlen + 1) ;
- g.sa.len = pos ;
+ size_t pos = translate_path(res) ;
+ if (!pos)
+ {
+ if (errno == EPERM)
+ die500x(rql, 102, docroot, "resource ", res, " points outside of the server's root") ;
+ else
+ die500sys(rql, 111, docroot, "path_canonicalize ", res) ;
+ }
+ if (!tipidee_conf_get_resattr(&g.conf, g.sa.s + pos, ra))
+ die500sys(rql, 102, docroot, "look up resource attributes for ", g.sa.s + pos) ;
}
static inline void force_redirect (tipidee_rql const *rql, char const *fn)
@@ -353,6 +356,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
g.maxcgibody = get_uint32("G:max_cgi_body_length") ;
g.logv = get_uint32("G:logv") ;
g.xiscgi = !!get_uint32("G:executable_means_cgi") ;
+ g.flagnoxlate = !!get_uint32("G:XXX_no_translate") ;
n = tipidee_conf_get_argv(&g.conf, "G:index-file", g.indexnames, 16, &g.indexlen) ;
if (!n) strerr_dief3x(102, "bad", " config value for ", "G:index_file") ;
g.indexn = n-1 ;
diff --git a/src/tipideed/util.c b/src/tipideed/util.c
new file mode 100644
index 0000000..2891306
--- /dev/null
+++ b/src/tipideed/util.c
@@ -0,0 +1,29 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <string.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#include "tipideed-internal.h"
+
+size_t translate_path (char const *path)
+{
+ size_t n = g.sa.len ;
+ if (g.flagnoxlate)
+ {
+ if (!stralloc_readyplus(&g.sa, strlen(path) + 2)) return 0 ;
+ path_canonicalize(g.sa.s + n, path, 0) ;
+ return n ;
+ }
+ if (sarealpath(&g.sa, path) == -1 || !stralloc_0(&g.sa))
+ {
+ g.sa.len = n ;
+ return 0 ;
+ }
+ g.sa.len = n ;
+ if (strncmp(g.sa.s + n, g.sa.s, g.cwdlen) || g.sa.s[n + g.cwdlen] != '/')
+ return (errno = EPERM, 0) ;
+ return n + g.cwdlen + 1 ;
+}