diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-12-15 10:35:41 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-12-15 10:35:41 +0000 |
commit | d2959364ef8d6bc948474a8facf497788b4e768b (patch) | |
tree | e1459c1c94e9b7556c21c0b43d7144a162601b0a /src | |
parent | 66844097454a8f2b4eddec64d4f276602c4cdd3a (diff) | |
download | tipidee-d2959364ef8d6bc948474a8facf497788b4e768b.tar.xz |
Prepare for 0.0.3.0; add XXX_no_translate
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/config/defaults.c | 1 | ||||
-rw-r--r-- | src/config/lexparse.c | 1 | ||||
-rw-r--r-- | src/tipideed/deps-exe/tipideed | 1 | ||||
-rw-r--r-- | src/tipideed/responses.c | 41 | ||||
-rw-r--r-- | src/tipideed/tipideed-internal.h | 9 | ||||
-rw-r--r-- | src/tipideed/tipideed.c | 18 | ||||
-rw-r--r-- | src/tipideed/util.c | 29 |
7 files changed, 69 insertions, 31 deletions
diff --git a/src/config/defaults.c b/src/config/defaults.c index 7dbab8a..18dfa7e 100644 --- a/src/config/defaults.c +++ b/src/config/defaults.c @@ -25,6 +25,7 @@ static struct defaults_s const defaults[] = RECU32("G:max_cgi_body_length", 4194304), RECU32("G:logv", TIPIDEE_LOG_DEFAULT), RECU32("G:executable_means_cgi", 0), + RECU32("G:XXX_no_translate", 0), RECS("G:index-file", "index.html"), RECS("T:html", "text/html"), diff --git a/src/config/lexparse.c b/src/config/lexparse.c index 99eeaa0..d5fcf6d 100644 --- a/src/config/lexparse.c +++ b/src/config/lexparse.c @@ -97,6 +97,7 @@ static inline void parse_global (char const *s, size_t const *word, size_t n, md { static char const *const globalkeys[] = { + "XXX_no_translate", "cgi_timeout", "executable_means_cgi", "max_cgi_body_length", 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 ; +} |