summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL4
-rw-r--r--doc/index.html6
-rw-r--r--doc/tipidee.conf.html31
-rw-r--r--doc/upgrade.html10
-rw-r--r--package/deps.mak3
-rw-r--r--package/info2
-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
13 files changed, 118 insertions, 38 deletions
diff --git a/INSTALL b/INSTALL
index 5e148af..e1ca77e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,8 +6,8 @@ Build Instructions
- A POSIX-compliant C development environment
- GNU make version 3.81 or later
- - skalibs version 2.14.0.1 or later: https://skarnet.org/software/skalibs/
- - (optional but recommended): s6-networking version 2.7.0.0 or later:
+ - skalibs version 2.14.1.0 or later: https://skarnet.org/software/skalibs/
+ - (optional but recommended): s6-networking version 2.7.0.1 or later:
https://skarnet.org/software/s6-networking/
This software will run on any operating system that implements
diff --git a/doc/index.html b/doc/index.html
index 0db88cd..2aef76b 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -111,11 +111,11 @@ make it shorter. Just like the code.
<li> A POSIX-compliant system with a standard C development environment </li>
<li> GNU make, version 3.81 or later </li>
<li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version
-2.14.0.1 or later. It's a build-time requirement. It's also a run-time
+2.14.1.0 or later. It's a build-time requirement. It's also a run-time
requirement if you link against the shared version of the skalibs
library. </li>
<li> Recommended at run-time: <a href="//skarnet.org/software/s6-networking/">s6-networking</a> version
-2.7.0.0 or later. It's not a strict requirement, but tipidee relies on a super-server such as
+2.7.0.1 or later. It's not a strict requirement, but tipidee relies on a super-server such as
<a href="//skarnet.org/software/s6-networking/s6-tcpserver.html">s6-tcpserver</a>
to listen to the network and provide connection
information via environment variables. It also defers to tools such as
@@ -143,7 +143,7 @@ Don't take my word for it; try it out for yourself. </li>
<ul>
<li> The current released version of tipidee is
-<a href="tipidee-0.0.2.0.tar.gz">0.0.2.0</a>. </li>
+<a href="tipidee-0.0.3.0.tar.gz">0.0.3.0</a>. </li>
<li> You can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/tipidee/">tipidee
git repository</a>:
diff --git a/doc/tipidee.conf.html b/doc/tipidee.conf.html
index 691ac94..17c1a4f 100644
--- a/doc/tipidee.conf.html
+++ b/doc/tipidee.conf.html
@@ -302,6 +302,37 @@ a directive can protect dynamically managed content that is restricted
to a given hierarchy. </li>
</ul>
+<div id="XXX_no_translate">
+<h4> <tt>XXX_no_translate</tt> </h4>
+</div>
+
+<p>
+ <code> global XXX_no_translate <em>value</em> </code>
+</p>
+
+<ul>
+ <li> This directive is dangerous and significantly changes the behaviour of tipideed,
+which is why it is marked with the <tt>XXX_</tt> prefix. If you are not 100% certain
+that you need it, do not use it. </li>
+ <li> <em>value</em> is a non-negative integer. If it is nonzero, then:
+ <ul>
+ <li> Symbolic links are <em>not resolved</em> when tipidee looks for resources
+or error pages. This means that host names and resource paths will be looked up
+in the configuration database as they are given by the client, not as they appear
+in the filesystem. </li>
+ <ul>
+ <li> In particular, a same resource could have different attributes depending on how
+it is accessed: it could be seen as a CGI script from one URI and as a regular file from
+another. </li>
+ <li> This also means that if your configuration file needs local directives, you must
+specify them for every host/port combination your server is listening on. </li>
+ </ul> </li>
+ <li> If tipideed is not chrooted, symbolic links <em>may</em> point outside of the
+server root: this will not be checked. This allows you to serve data from other parts
+of the filesystem. </li>
+ </ul> </li>
+</ul>
+
<div id="index-file">
<h3> The <tt>index-file</tt> directive </h3>
</div>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 74f7594..f2a6880 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,16 @@
<h1> What has changed in tipidee </h1>
+<h2> in.0.0.3.0 </h2>
+
+<ul>
+ <li> <a href="//skarnet.org/software/skalibs/">skalibs</a>
+dependency bumped to 2.14.1.0 </li>
+ <li> <a href="//skarnet.org/software/s6-networking/">s6-networking</a>
+recommendation bumped to 2.7.0.1 </li>
+ <li> New <tt>global XXX_no_translate</tt> configuration directive. </li>
+</ul>
+
<h2> in.0.0.2.0 </h2>
<ul>
diff --git a/package/deps.mak b/package/deps.mak
index 9ef8eed..cd49648 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -67,6 +67,7 @@ src/tipideed/responses.o src/tipideed/responses.lo: src/tipideed/responses.c src
src/tipideed/send_file.o src/tipideed/send_file.lo: src/tipideed/send_file.c src/tipideed/tipideed-internal.h
src/tipideed/tipideed.o src/tipideed/tipideed.lo: src/tipideed/tipideed.c src/include/tipidee/tipidee.h src/tipideed/tipideed-internal.h
src/tipideed/trace.o src/tipideed/trace.lo: src/tipideed/trace.c src/include/tipidee/log.h src/include/tipidee/method.h src/include/tipidee/response.h src/tipideed/tipideed-internal.h
+src/tipideed/util.o src/tipideed/util.lo: src/tipideed/util.c src/tipideed/tipideed-internal.h
tipidee-config: EXTRA_LIBS := -lskarnet ${SPAWN_LIB}
tipidee-config: src/config/tipidee-config.o src/config/util.o src/config/node.o src/config/repo.o src/config/conftree.o src/config/headers.o src/config/defaults.o src/config/lexparse.o
@@ -80,5 +81,5 @@ endif
libtipidee.so.xyzzy: EXTRA_LIBS := -lskarnet
libtipidee.so.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_errorfile.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_resattr.lo src/libtipidee/tipidee_conf_get_resattr1.lo src/libtipidee/tipidee_conf_get_responseheaders.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_log_answer.lo src/libtipidee/tipidee_log_exit.lo src/libtipidee/tipidee_log_resource.lo src/libtipidee/tipidee_log_request.lo src/libtipidee/tipidee_log_start.lo src/libtipidee/tipidee_method.lo src/libtipidee/tipidee_response_error_nofile.lo src/libtipidee/tipidee_response_error_nofile_G.lo src/libtipidee/tipidee_response_file.lo src/libtipidee/tipidee_response_file_G.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_G.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_header_preparebuiltin.lo src/libtipidee/tipidee_response_header_writeall.lo src/libtipidee/tipidee_response_header_writeall_G.lo src/libtipidee/tipidee_response_header_writemerge.lo src/libtipidee/tipidee_response_header_writemerge_G.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_defaulttext.lo src/libtipidee/tipidee_util_httpdate.lo
tipideed: EXTRA_LIBS := -lskarnet
-tipideed: src/tipideed/tipideed.o src/tipideed/cgi.o src/tipideed/harden.o src/tipideed/options.o src/tipideed/regular.o src/tipideed/responses.o src/tipideed/send_file.o src/tipideed/trace.o libtipidee.a.xyzzy
+tipideed: src/tipideed/tipideed.o src/tipideed/cgi.o src/tipideed/harden.o src/tipideed/options.o src/tipideed/regular.o src/tipideed/responses.o src/tipideed/send_file.o src/tipideed/trace.o src/tipideed/util.o libtipidee.a.xyzzy
INTERNAL_LIBS :=
diff --git a/package/info b/package/info
index 3492464..a525420 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=tipidee
-version=0.0.2.0
+version=0.0.3.0
category=web
package_macro_name=TIPIDEE
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 ;
+}