geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

commit 27c94c92d5fdf7294ee1905c381d0ce2f4ccebca
parent fdd8c5b2210b2c3719bce020dfec54bbe36adb49
Author: Christoph Lohmann <20h@r-36.net>
Date:   Sun,  3 Apr 2022 09:55:45 +0200

Optimize new path fallthrough feature to only serve dynamic content.

Diffstat:
main.c | 29+++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/main.c b/main.c @@ -139,10 +139,14 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, struct stat dir; char recvc[1025], recvb[1025], path[1025], args[1025], argsc[1025], *sear, *c, *sep, *pathp, *recvbp; - int len = 0, fd, i, maxrecv; + int len = 0, fd, i, maxrecv, pathfallthrough = 0; filetype *type; if (!istls) { + /* + * If sticky bit is set on base dir and encryption is not + * used, do not serve. + */ if (stat(base, &dir) == -1) return; if (dir.st_mode & S_ISVTX) { @@ -284,12 +288,16 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, ); } /* path fallthrough */ + pathfallthrough = 1; break; } } } if (stat(path, &dir) != -1) { + /* + * If sticky bit is set, only serve if this is encrypted. + */ if ((dir.st_mode & S_ISVTX) && !istls) { dprintf(sock, tlserr, recvc); if (loglvl & ERRORS) { @@ -340,6 +348,19 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, if (c == NULL) c = path; type = gettype(c); + + /* + * If we had to traverse the path to find some, only + * allow index.dcgi and index.cgi as handlers. + */ + if (pathfallthrough && + !(type->f == handledcgi || type->f == handlecgi)) { + dprintf(sock, notfounderr, recvc); + if (loglvl & ERRORS) + logentry(clienth, clientp, recvc, "not found"); + return; + } + if (nocgi && (type->f == handledcgi || type->f == handlecgi)) { dprintf(sock, nocgierr, recvc); if (loglvl & ERRORS) @@ -349,7 +370,11 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, clienth, istls); } } else { - if (S_ISDIR(dir.st_mode)) { + /* + * If we had to traverse the path, do not allow directory + * listings, only dynamic content. + */ + if (!pathfallthrough && S_ISDIR(dir.st_mode)) { handledir(sock, path, port, base, args, sear, ohost, clienth, istls); if (loglvl & DIRS) {