about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-12-15 10:35:41 +0000
committerLaurent Bercot <ska@appnovation.com>2023-12-15 10:35:41 +0000
commitd2959364ef8d6bc948474a8facf497788b4e768b (patch)
treee1459c1c94e9b7556c21c0b43d7144a162601b0a /src
parent66844097454a8f2b4eddec64d4f276602c4cdd3a (diff)
downloadtipidee-d2959364ef8d6bc948474a8facf497788b4e768b.tar.gz
tipidee-d2959364ef8d6bc948474a8facf497788b4e768b.tar.xz
tipidee-d2959364ef8d6bc948474a8facf497788b4e768b.zip
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.c1
-rw-r--r--src/config/lexparse.c1
-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
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 ;
+}