iFirst rework of path handling. - geomyidae - A small C-based gopherd. Err bitreich.org 70 hgit clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ URL:git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ bitreich.org 70 1Log /scm/geomyidae/log.gph bitreich.org 70 1Files /scm/geomyidae/files.gph bitreich.org 70 1Refs /scm/geomyidae/refs.gph bitreich.org 70 1Tags /scm/geomyidae/tag bitreich.org 70 1README /scm/geomyidae/file/README.gph bitreich.org 70 1LICENSE /scm/geomyidae/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit b12a77acd24fc170b1ad047986ffaf13592fb326 /scm/geomyidae/commit/b12a77acd24fc170b1ad047986ffaf13592fb326.gph bitreich.org 70 1parent f66a8a67b9471909016d6f24ce93f39584130a67 /scm/geomyidae/commit/f66a8a67b9471909016d6f24ce93f39584130a67.gph bitreich.org 70 hAuthor: Christoph Lohmann <20h@r-36.net> URL:mailto:20h@r-36.net bitreich.org 70 iDate: Thu, 20 Jul 2023 06:30:24 +0200 Err bitreich.org 70 i Err bitreich.org 70 iFirst rework of path handling. Err bitreich.org 70 i Err bitreich.org 70 i* Renaming the gph functions. Err bitreich.org 70 i* Beware, still full of debug functions. Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M handlr.c | 112 +++++++++++++++++-------------- Err bitreich.org 70 i M handlr.h | 25 ++++++++++++++++++++----- Err bitreich.org 70 i M ind.c | 133 ++++++++++++++++--------------- Err bitreich.org 70 i M ind.h | 41 ++++++++++++++++--------------- Err bitreich.org 70 i M index.gph | 4 +++- Err bitreich.org 70 i M main.c | 144 ++++++++++++++++++++++--------- Err bitreich.org 70 i Err bitreich.org 70 i6 files changed, 277 insertions(+), 182 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/handlr.c b/handlr.c /scm/geomyidae/file/handlr.c.gph bitreich.org 70 i@@ -17,6 +17,7 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #include "ind.h" Err bitreich.org 70 i #include "arg.h" Err bitreich.org 70 i@@ -25,7 +26,7 @@ void Err bitreich.org 70 i handledir(int sock, char *path, char *port, char *base, char *args, Err bitreich.org 70 i char *sear, char *ohost, char *chost, char *bhost, int istls) Err bitreich.org 70 i { Err bitreich.org 70 i- char *pa, *file, *e, *par, *b; Err bitreich.org 70 i+ char *pa, *file, *e, *par; Err bitreich.org 70 i struct dirent **dirent; Err bitreich.org 70 i int ndir, i, ret = 0; Err bitreich.org 70 i struct stat st; Err bitreich.org 70 i@@ -35,22 +36,25 @@ handledir(int sock, char *path, char *port, char *base, char *args, Err bitreich.org 70 i USED(sear); Err bitreich.org 70 i USED(bhost); Err bitreich.org 70 i Err bitreich.org 70 i- pa = xstrdup(path); Err bitreich.org 70 i- e = pa + strlen(pa) - 1; Err bitreich.org 70 i- if (e > pa && e[0] == '/') Err bitreich.org 70 i- *e = '\0'; Err bitreich.org 70 i+ printf("handledir:\n"); Err bitreich.org 70 i+ printf("sock = %d; path = %s; port = %s; base = %s; args = %s;\n", Err bitreich.org 70 i+ sock, path, port, base, args); Err bitreich.org 70 i+ printf("sear = %s; ohost = %s; chost = %s; bhost = %s; istls = %d;\n", Err bitreich.org 70 i+ sear, ohost, chost, bhost, istls); Err bitreich.org 70 i Err bitreich.org 70 i- par = xstrdup(pa); Err bitreich.org 70 i+ pa = xstrdup(path); Err bitreich.org 70 i Err bitreich.org 70 i- b = strrchr(makebasepath(par, base), '/'); Err bitreich.org 70 i- if (b != NULL) { Err bitreich.org 70 i- *b = '\0'; Err bitreich.org 70 i+ /* Is there any directory below the request? */ Err bitreich.org 70 i+ if (strlen(pa+strlen(base)) > 1) { Err bitreich.org 70 i+ par = xstrdup(pa+strlen(base)); Err bitreich.org 70 i+ e = strrchr(par, '/'); Err bitreich.org 70 i+ *e = '\0'; Err bitreich.org 70 i dprintf(sock, "1..\t%s\t%s\t%s\r\n", Err bitreich.org 70 i- makebasepath(par, base), ohost, port); Err bitreich.org 70 i+ par, ohost, port); Err bitreich.org 70 i+ free(par); Err bitreich.org 70 i } Err bitreich.org 70 i- free(par); Err bitreich.org 70 i Err bitreich.org 70 i- ndir = scandir(pa[0] ? pa : ".", &dirent, 0, alphasort); Err bitreich.org 70 i+ ndir = scandir(pa, &dirent, 0, alphasort); Err bitreich.org 70 i if (ndir < 0) { Err bitreich.org 70 i perror("scandir"); Err bitreich.org 70 i free(pa); Err bitreich.org 70 i@@ -61,19 +65,21 @@ handledir(int sock, char *path, char *port, char *base, char *args, Err bitreich.org 70 i continue; Err bitreich.org 70 i Err bitreich.org 70 i type = gettype(dirent[i]->d_name); Err bitreich.org 70 i- file = smprintf("%s%s%s", pa, Err bitreich.org 70 i- pa[0] == '/' && pa[1] == '\0' ? "" : "/", Err bitreich.org 70 i+ Err bitreich.org 70 i+ file = smprintf("%s%s%s", Err bitreich.org 70 i+ pa, Err bitreich.org 70 i+ pa[strlen(pa)-1] == '/'? "" : "/", Err bitreich.org 70 i dirent[i]->d_name); Err bitreich.org 70 i+ printf("handledir: smprintf file = %s\n", file); Err bitreich.org 70 i if (stat(file, &st) >= 0 && S_ISDIR(st.st_mode)) Err bitreich.org 70 i type = gettype("index.gph"); Err bitreich.org 70 i- e = makebasepath(file, base); Err bitreich.org 70 i ret = dprintf(sock, Err bitreich.org 70 i "%c%-50.50s %10s %16s\t%s\t%s\t%s\r\n", Err bitreich.org 70 i *type->type, Err bitreich.org 70 i dirent[i]->d_name, Err bitreich.org 70 i humansize(st.st_size), Err bitreich.org 70 i humantime(&(st.st_mtime)), Err bitreich.org 70 i- e, ohost, port); Err bitreich.org 70 i+ file + strlen(base), ohost, port); Err bitreich.org 70 i free(file); Err bitreich.org 70 i } Err bitreich.org 70 i for (i = 0; i < ndir; i++) Err bitreich.org 70 i@@ -89,24 +95,30 @@ void Err bitreich.org 70 i handlegph(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i char *sear, char *ohost, char *chost, char *bhost, int istls) Err bitreich.org 70 i { Err bitreich.org 70 i- Indexs *act; Err bitreich.org 70 i+ gphindex *act; Err bitreich.org 70 i int i, ret = 0; Err bitreich.org 70 i Err bitreich.org 70 i USED(args); Err bitreich.org 70 i USED(sear); Err bitreich.org 70 i USED(bhost); Err bitreich.org 70 i Err bitreich.org 70 i- act = scanfile(file); Err bitreich.org 70 i+ printf("handlegph:\n"); Err bitreich.org 70 i+ printf("sock = %d; file = %s; port = %s; base = %s; args = %s;\n", Err bitreich.org 70 i+ sock, file, port, base, args); Err bitreich.org 70 i+ printf("sear = %s; ohost = %s; chost = %s; bhost = %s; istls = %d;\n", Err bitreich.org 70 i+ sear, ohost, chost, bhost, istls); Err bitreich.org 70 i+ Err bitreich.org 70 i+ act = gph_scanfile(file); Err bitreich.org 70 i if (act != NULL) { Err bitreich.org 70 i for (i = 0; i < act->num && ret >= 0; i++) Err bitreich.org 70 i- ret = printelem(sock, act->n[i], file, base, ohost, port); Err bitreich.org 70 i+ ret = gph_printelem(sock, act->n[i], file, base, ohost, port); Err bitreich.org 70 i dprintf(sock, ".\r\n"); Err bitreich.org 70 i Err bitreich.org 70 i for (i = 0; i < act->num; i++) { Err bitreich.org 70 i- freeelem(act->n[i]); Err bitreich.org 70 i+ gph_freeelem(act->n[i]); Err bitreich.org 70 i act->n[i] = NULL; Err bitreich.org 70 i } Err bitreich.org 70 i- freeindex(act); Err bitreich.org 70 i+ gph_freeindex(act); Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -135,21 +147,22 @@ void Err bitreich.org 70 i handlecgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i char *sear, char *ohost, char *chost, char *bhost, int istls) Err bitreich.org 70 i { Err bitreich.org 70 i- char *p, *path; Err bitreich.org 70 i+ char *script, *path; Err bitreich.org 70 i Err bitreich.org 70 i USED(base); Err bitreich.org 70 i USED(port); Err bitreich.org 70 i Err bitreich.org 70 i- path = xstrdup(file); Err bitreich.org 70 i- p = strrchr(path, '/'); Err bitreich.org 70 i- if (p != NULL) Err bitreich.org 70 i- p[1] = '\0'; Err bitreich.org 70 i- else { Err bitreich.org 70 i- free(path); Err bitreich.org 70 i- path = NULL; Err bitreich.org 70 i- } Err bitreich.org 70 i+ printf("handlecgi:\n"); Err bitreich.org 70 i+ printf("sock = %d; file = %s; port = %s; base = %s; args = %s;\n", Err bitreich.org 70 i+ sock, file, port, base, args); Err bitreich.org 70 i+ printf("sear = %s; ohost = %s; chost = %s; bhost = %s; istls = %d;\n", Err bitreich.org 70 i+ sear, ohost, chost, bhost, istls); Err bitreich.org 70 i Err bitreich.org 70 i- p = makebasepath(file, base); Err bitreich.org 70 i+ path = xstrdup(file); Err bitreich.org 70 i+ path = dirname(path); Err bitreich.org 70 i+ script = path + strlen(path) + 1; Err bitreich.org 70 i+ printf("path = %s\n", path); Err bitreich.org 70 i+ printf("script = %s\n", script); Err bitreich.org 70 i Err bitreich.org 70 i if (sear == NULL) Err bitreich.org 70 i sear = ""; Err bitreich.org 70 i@@ -166,10 +179,10 @@ handlecgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i break; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- setcgienviron(p, file, port, base, args, sear, ohost, chost, Err bitreich.org 70 i+ setcgienviron(script, file, port, base, args, sear, ohost, chost, Err bitreich.org 70 i bhost, istls); Err bitreich.org 70 i Err bitreich.org 70 i- if (execl(file, p, sear, args, ohost, port, Err bitreich.org 70 i+ if (execl(file, script, sear, args, ohost, port, Err bitreich.org 70 i (char *)NULL) == -1) { Err bitreich.org 70 i perror("execl"); Err bitreich.org 70 i _exit(1); Err bitreich.org 70 i@@ -189,25 +202,24 @@ handledcgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i char *sear, char *ohost, char *chost, char *bhost, int istls) Err bitreich.org 70 i { Err bitreich.org 70 i FILE *fp; Err bitreich.org 70 i- char *p, *path, *ln = NULL; Err bitreich.org 70 i+ char *script, *path, *ln = NULL; Err bitreich.org 70 i size_t linesiz = 0; Err bitreich.org 70 i ssize_t n; Err bitreich.org 70 i int outsocks[2], ret = 0; Err bitreich.org 70 i- Elems *el; Err bitreich.org 70 i+ gphelem *el; Err bitreich.org 70 i+ Err bitreich.org 70 i+ printf("handledcgi:\n"); Err bitreich.org 70 i+ printf("sock = %d; file = %s; port = %s; base = %s; args = %s;\n", Err bitreich.org 70 i+ sock, file, port, base, args); Err bitreich.org 70 i+ printf("sear = %s; ohost = %s; chost = %s; bhost = %s; istls = %d;\n", Err bitreich.org 70 i+ sear, ohost, chost, bhost, istls); Err bitreich.org 70 i Err bitreich.org 70 i if (socketpair(AF_LOCAL, SOCK_STREAM, 0, outsocks) < 0) Err bitreich.org 70 i return; Err bitreich.org 70 i Err bitreich.org 70 i path = xstrdup(file); Err bitreich.org 70 i- p = strrchr(path, '/'); Err bitreich.org 70 i- if (p != NULL) Err bitreich.org 70 i- p[1] = '\0'; Err bitreich.org 70 i- else { Err bitreich.org 70 i- free(path); Err bitreich.org 70 i- path = NULL; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- p = makebasepath(file, base); Err bitreich.org 70 i+ path = dirname(path); Err bitreich.org 70 i+ script = path + strlen(path) + 1; Err bitreich.org 70 i Err bitreich.org 70 i if (sear == NULL) Err bitreich.org 70 i sear = ""; Err bitreich.org 70 i@@ -225,10 +237,10 @@ handledcgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i break; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- setcgienviron(p, file, port, base, args, sear, ohost, chost, Err bitreich.org 70 i+ setcgienviron(script, file, port, base, args, sear, ohost, chost, Err bitreich.org 70 i bhost, istls); Err bitreich.org 70 i Err bitreich.org 70 i- if (execl(file, p, sear, args, ohost, port, Err bitreich.org 70 i+ if (execl(file, script, sear, args, ohost, port, Err bitreich.org 70 i (char *)NULL) == -1) { Err bitreich.org 70 i perror("execl"); Err bitreich.org 70 i _exit(1); Err bitreich.org 70 i@@ -251,21 +263,21 @@ handledcgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i if (ln[n - 1] == '\n') Err bitreich.org 70 i ln[--n] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i- el = getadv(ln); Err bitreich.org 70 i+ el = gph_getadv(ln); Err bitreich.org 70 i if (el == NULL) Err bitreich.org 70 i continue; Err bitreich.org 70 i Err bitreich.org 70 i- ret = printelem(sock, el, file, base, ohost, port); Err bitreich.org 70 i- freeelem(el); Err bitreich.org 70 i+ ret = gph_printelem(sock, el, file, base, ohost, port); Err bitreich.org 70 i+ gph_freeelem(el); Err bitreich.org 70 i } Err bitreich.org 70 i if (ferror(fp)) Err bitreich.org 70 i perror("getline"); Err bitreich.org 70 i dprintf(sock, ".\r\n"); Err bitreich.org 70 i Err bitreich.org 70 i free(ln); Err bitreich.org 70 i- free(path); Err bitreich.org 70 i fclose(fp); Err bitreich.org 70 i wait(NULL); Err bitreich.org 70 i+ free(path); Err bitreich.org 70 i break; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/handlr.h b/handlr.h /scm/geomyidae/file/handlr.h.gph bitreich.org 70 i@@ -9,16 +9,31 @@ Err bitreich.org 70 i /* Err bitreich.org 70 i * Handler API definition Err bitreich.org 70 i * Err bitreich.org 70 i- * path .... absolute path to the script Err bitreich.org 70 i+ * Sample: /get/some/script/with/dirs////?key=value\tsearch what?\r\n Err bitreich.org 70 i+ * * in /get/some/script is a file "index.dcgi" Err bitreich.org 70 i+ * * request to bitreich.org on port 70 using TLS Err bitreich.org 70 i+ * * base is in /var/gopher Err bitreich.org 70 i+ * * client from 85.65.4.2 Err bitreich.org 70 i+ * Err bitreich.org 70 i+ * path/file absolute path to the script/directory, always starts with '/' Err bitreich.org 70 i+ * Sample: /var/gopher/get/some/script/index.dcgi Err bitreich.org 70 i * port .... port which the script should use when defining menu items Err bitreich.org 70 i * (See -o and -p in geomyidae(8)) Err bitreich.org 70 i- * base .... base path of geomyidae ("" in case of chroot) Err bitreich.org 70 i- * args .... query string parsed after »script?query« Err bitreich.org 70 i- * sear .... search part of request (»selector\tsearch\r\n«) Err bitreich.org 70 i- * ohost ... host of geomiydae (See -h in geomyidae(8)) Err bitreich.org 70 i+ * Sample: 70 Err bitreich.org 70 i+ * base .... base path of geomyidae, never ends in '/', so chroot is '' Err bitreich.org 70 i+ * Sample: /var/gopher Err bitreich.org 70 i+ * args .... Gives all variable input from the selector in some way. Err bitreich.org 70 i+ * Sample: /with/dirs////?key=value Err bitreich.org 70 i+ * sear .... search part of request Err bitreich.org 70 i+ * Sample: search what? Err bitreich.org 70 i+ * ohost ... host of geomyidae (See -h in geomyidae(8)) Err bitreich.org 70 i+ * Sample: bitreich.org Err bitreich.org 70 i * chost ... IP of the client sending a request Err bitreich.org 70 i+ * Sample: 85.65.4.2 Err bitreich.org 70 i * bhost ... server IP the server received the connection to Err bitreich.org 70 i+ * Sample: 78.46.175.99 Err bitreich.org 70 i * istls ... set to 1, if TLS was used for thr request Err bitreich.org 70 i+ * Sample: 1 Err bitreich.org 70 i */ Err bitreich.org 70 i Err bitreich.org 70 i void handledir(int sock, char *path, char *port, char *base, char *args, Err bitreich.org 70 1diff --git a/ind.c b/ind.c /scm/geomyidae/file/ind.c.gph bitreich.org 70 i@@ -24,6 +24,7 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #define PAGE_SHIFT 12 Err bitreich.org 70 i #define PAGE_SIZE (1UL << PAGE_SHIFT) Err bitreich.org 70 i@@ -258,7 +259,7 @@ gettype(char *filename) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-freeelem(Elems *e) Err bitreich.org 70 i+gph_freeelem(gphelem *e) Err bitreich.org 70 i { Err bitreich.org 70 i if (e != NULL) { Err bitreich.org 70 i if (e->e != NULL) { Err bitreich.org 70 i@@ -273,12 +274,12 @@ freeelem(Elems *e) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-freeindex(Indexs *i) Err bitreich.org 70 i+gph_freeindex(gphindex *i) Err bitreich.org 70 i { Err bitreich.org 70 i if (i != NULL) { Err bitreich.org 70 i if (i->n != NULL) { Err bitreich.org 70 i for (;i->num > 0; i->num--) Err bitreich.org 70 i- freeelem(i->n[i->num - 1]); Err bitreich.org 70 i+ gph_freeelem(i->n[i->num - 1]); Err bitreich.org 70 i free(i->n); Err bitreich.org 70 i } Err bitreich.org 70 i free(i); Err bitreich.org 70 i@@ -288,7 +289,7 @@ freeindex(Indexs *i) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-addelem(Elems *e, char *s) Err bitreich.org 70 i+gph_addelem(gphelem *e, char *s) Err bitreich.org 70 i { Err bitreich.org 70 i e->num++; Err bitreich.org 70 i e->e = xrealloc(e->e, sizeof(char *) * e->num); Err bitreich.org 70 i@@ -297,23 +298,23 @@ addelem(Elems *e, char *s) Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-Elems * Err bitreich.org 70 i-getadv(char *str) Err bitreich.org 70 i+gphelem * Err bitreich.org 70 i+gph_getadv(char *str) Err bitreich.org 70 i { Err bitreich.org 70 i char *b, *e, *o, *bo; Err bitreich.org 70 i- Elems *ret; Err bitreich.org 70 i+ gphelem *ret; Err bitreich.org 70 i Err bitreich.org 70 i- ret = xcalloc(1, sizeof(Elems)); Err bitreich.org 70 i+ ret = xcalloc(1, sizeof(gphelem)); Err bitreich.org 70 i Err bitreich.org 70 i if (strchr(str, '\t')) { Err bitreich.org 70 i- addelem(ret, "i"); Err bitreich.org 70 i- addelem(ret, "Happy helping ☃ here: You tried to " Err bitreich.org 70 i+ gph_addelem(ret, "i"); Err bitreich.org 70 i+ gph_addelem(ret, "Happy helping ☃ here: You tried to " Err bitreich.org 70 i "output a spurious TAB character. This will " Err bitreich.org 70 i "break gopher. Please review your scripts. " Err bitreich.org 70 i "Have a nice day!"); Err bitreich.org 70 i- addelem(ret, "Err"); Err bitreich.org 70 i- addelem(ret, "server"); Err bitreich.org 70 i- addelem(ret, "port"); Err bitreich.org 70 i+ gph_addelem(ret, "Err"); Err bitreich.org 70 i+ gph_addelem(ret, "server"); Err bitreich.org 70 i+ gph_addelem(ret, "port"); Err bitreich.org 70 i Err bitreich.org 70 i return ret; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -331,7 +332,7 @@ getadv(char *str) Err bitreich.org 70 i } Err bitreich.org 70 i *e = '\0'; Err bitreich.org 70 i e++; Err bitreich.org 70 i- addelem(ret, b); Err bitreich.org 70 i+ gph_addelem(ret, b); Err bitreich.org 70 i b = e; Err bitreich.org 70 i bo = b; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -339,7 +340,7 @@ getadv(char *str) Err bitreich.org 70 i e = strchr(b, ']'); Err bitreich.org 70 i if (e != NULL) { Err bitreich.org 70 i *e = '\0'; Err bitreich.org 70 i- addelem(ret, b); Err bitreich.org 70 i+ gph_addelem(ret, b); Err bitreich.org 70 i } Err bitreich.org 70 i free(o); Err bitreich.org 70 i Err bitreich.org 70 i@@ -349,55 +350,55 @@ getadv(char *str) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* Invalid entry: Give back the whole line. */ Err bitreich.org 70 i- freeelem(ret); Err bitreich.org 70 i- ret = xcalloc(1, sizeof(Elems)); Err bitreich.org 70 i+ gph_freeelem(ret); Err bitreich.org 70 i+ ret = xcalloc(1, sizeof(gphelem)); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- addelem(ret, "i"); Err bitreich.org 70 i+ gph_addelem(ret, "i"); Err bitreich.org 70 i /* Jump over escape sequence. */ Err bitreich.org 70 i if (str[0] == '[' && str[1] == '|') Err bitreich.org 70 i str += 2; Err bitreich.org 70 i- addelem(ret, str); Err bitreich.org 70 i- addelem(ret, "Err"); Err bitreich.org 70 i- addelem(ret, "server"); Err bitreich.org 70 i- addelem(ret, "port"); Err bitreich.org 70 i+ gph_addelem(ret, str); Err bitreich.org 70 i+ gph_addelem(ret, "Err"); Err bitreich.org 70 i+ gph_addelem(ret, "server"); Err bitreich.org 70 i+ gph_addelem(ret, "port"); Err bitreich.org 70 i Err bitreich.org 70 i return ret; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-addindexs(Indexs *idx, Elems *el) Err bitreich.org 70 i+gph_addindex(gphindex *idx, gphelem *el) Err bitreich.org 70 i { Err bitreich.org 70 i idx->num++; Err bitreich.org 70 i- idx->n = xrealloc(idx->n, sizeof(Elems) * idx->num); Err bitreich.org 70 i+ idx->n = xrealloc(idx->n, sizeof(gphelem *) * idx->num); Err bitreich.org 70 i idx->n[idx->num - 1] = el; Err bitreich.org 70 i Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-Indexs * Err bitreich.org 70 i-scanfile(char *fname) Err bitreich.org 70 i+gphindex * Err bitreich.org 70 i+gph_scanfile(char *fname) Err bitreich.org 70 i { Err bitreich.org 70 i char *ln = NULL; Err bitreich.org 70 i size_t linesiz = 0; Err bitreich.org 70 i ssize_t n; Err bitreich.org 70 i FILE *fp; Err bitreich.org 70 i- Indexs *ret; Err bitreich.org 70 i- Elems *el; Err bitreich.org 70 i+ gphindex *ret; Err bitreich.org 70 i+ gphelem *el; Err bitreich.org 70 i Err bitreich.org 70 i if (!(fp = fopen(fname, "r"))) Err bitreich.org 70 i return NULL; Err bitreich.org 70 i Err bitreich.org 70 i- ret = xcalloc(1, sizeof(Indexs)); Err bitreich.org 70 i+ ret = xcalloc(1, sizeof(gphindex)); Err bitreich.org 70 i Err bitreich.org 70 i while ((n = getline(&ln, &linesiz, fp)) > 0) { Err bitreich.org 70 i if (ln[n - 1] == '\n') Err bitreich.org 70 i ln[--n] = '\0'; Err bitreich.org 70 i- el = getadv(ln); Err bitreich.org 70 i+ el = gph_getadv(ln); Err bitreich.org 70 i if (el == NULL) Err bitreich.org 70 i continue; Err bitreich.org 70 i Err bitreich.org 70 i- addindexs(ret, el); Err bitreich.org 70 i+ gph_addindex(ret, el); Err bitreich.org 70 i } Err bitreich.org 70 i if (ferror(fp)) Err bitreich.org 70 i perror("getline"); Err bitreich.org 70 i@@ -413,9 +414,9 @@ scanfile(char *fname) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port) Err bitreich.org 70 i+gph_printelem(int fd, gphelem *el, char *file, char *base, char *addr, char *port) Err bitreich.org 70 i { Err bitreich.org 70 i- char *path, *p, *argbase, buf[PATH_MAX+1], *argp, *realbase; Err bitreich.org 70 i+ char *path, *p, *argbase, buf[PATH_MAX+1], *argp, *realbase, *rpath; Err bitreich.org 70 i int len, blen; Err bitreich.org 70 i Err bitreich.org 70 i if (!strcmp(el->e[3], "server")) { Err bitreich.org 70 i@@ -432,10 +433,6 @@ printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port) Err bitreich.org 70 i * some URL and ignore various types that have different semantics, Err bitreich.org 70 i * do not point to some file or directory. Err bitreich.org 70 i */ Err bitreich.org 70 i- /* Err bitreich.org 70 i- * FUTURE: If ever special requests with no beginning '/' are used in Err bitreich.org 70 i- * geomyidae, this is the place to control this. Err bitreich.org 70 i- */ Err bitreich.org 70 i if ((el->e[2][0] != '\0' Err bitreich.org 70 i && el->e[2][0] != '/' /* Absolute Request. */ Err bitreich.org 70 i && el->e[0][0] != 'i' /* Informational item. */ Err bitreich.org 70 i@@ -446,45 +443,50 @@ printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port) Err bitreich.org 70 i && el->e[0][0] != 'T') && /* tn3270 */ Err bitreich.org 70 i !(el->e[0][0] == 'h' && !strncmp(el->e[2], "URL:", 4))) { Err bitreich.org 70 i path = file + strlen(base); Err bitreich.org 70 i- if ((p = strrchr(path, '/'))) Err bitreich.org 70 i- len = p - path; Err bitreich.org 70 i- else Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Strip off original gph file name. */ Err bitreich.org 70 i+ if ((p = strrchr(path, '/'))) { Err bitreich.org 70 i+ len = strlen(path) - strlen(basename(path)); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i len = strlen(path); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i /* Strip off arguments for realpath. */ Err bitreich.org 70 i argbase = strchr(el->e[2], '?'); Err bitreich.org 70 i- if (argbase != NULL) Err bitreich.org 70 i+ if (argbase != NULL) { Err bitreich.org 70 i blen = argbase - el->e[2]; Err bitreich.org 70 i- else Err bitreich.org 70 i+ } else { Err bitreich.org 70 i blen = strlen(el->e[2]); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i- snprintf(buf, sizeof(buf), "%s%.*s/%.*s", base, len, Err bitreich.org 70 i+ /* Err bitreich.org 70 i+ * Print everything together. Realpath will resolve it. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+ snprintf(buf, sizeof(buf), "%s%.*s%.*s", base, len, Err bitreich.org 70 i path, blen, el->e[2]); Err bitreich.org 70 i Err bitreich.org 70 i- if ((path = realpath(buf, NULL)) && Err bitreich.org 70 i- (realbase = realpath(base, NULL)) && Err bitreich.org 70 i- !strncmp(realbase, path, strlen(realbase))) { Err bitreich.org 70 i- p = path + strlen(realbase); Err bitreich.org 70 i+ if ((rpath = realpath(buf, NULL)) && Err bitreich.org 70 i+ (realbase = realpath(*base? base : "/", NULL)) && Err bitreich.org 70 i+ !strncmp(realbase, rpath, strlen(realbase))) { Err bitreich.org 70 i+ p = rpath + (*base? strlen(realbase) : 0); Err bitreich.org 70 i Err bitreich.org 70 i /* Err bitreich.org 70 i- * Do not forget to readd arguments which were Err bitreich.org 70 i+ * Do not forget to re-add arguments which were Err bitreich.org 70 i * stripped off. Err bitreich.org 70 i */ Err bitreich.org 70 i- if (argbase != NULL) Err bitreich.org 70 i- argp = smprintf("%s%s", p[0]? p : "/", argbase); Err bitreich.org 70 i- else Err bitreich.org 70 i- argp = xstrdup(p[0]? p : "/"); Err bitreich.org 70 i+ argp = smprintf("%s%s", *p? p : "/", argbase? argbase : ""); Err bitreich.org 70 i Err bitreich.org 70 i free(el->e[2]); Err bitreich.org 70 i el->e[2] = argp; Err bitreich.org 70 i free(realbase); Err bitreich.org 70 i } Err bitreich.org 70 i- free(path); Err bitreich.org 70 i+ if (rpath != NULL) Err bitreich.org 70 i+ free(rpath); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i if (dprintf(fd, "%.1s%s\t%s\t%s\t%s\r\n", el->e[0], el->e[1], el->e[2], Err bitreich.org 70 i el->e[3], el->e[4]) < 0) { Err bitreich.org 70 i- perror("printelem: dprintf"); Err bitreich.org 70 i+ perror("printgphelem: dprintf"); Err bitreich.org 70 i return -1; Err bitreich.org 70 i } Err bitreich.org 70 i return 0; Err bitreich.org 70 i@@ -545,19 +547,26 @@ setcgienviron(char *file, char *path, char *port, char *base, char *args, Err bitreich.org 70 i setenv("GATEWAY_INTERFACE", "CGI/1.1", 1); Err bitreich.org 70 i /* TODO: Separate, if run like rest.dcgi. */ Err bitreich.org 70 i setenv("PATH_INFO", file, 1); Err bitreich.org 70 i+ printf("PATH_INFO = %s\n", file); Err bitreich.org 70 i setenv("PATH_TRANSLATED", path, 1); Err bitreich.org 70 i+ printf("PATH_TRANSLATED = %s\n", path); Err bitreich.org 70 i Err bitreich.org 70 i setenv("QUERY_STRING", args, 1); Err bitreich.org 70 i+ printf("QUERY_STRING = %s\n", args); Err bitreich.org 70 i /* legacy compatibility */ Err bitreich.org 70 i setenv("SELECTOR", args, 1); Err bitreich.org 70 i+ printf("SELECTOR = %s\n", args); Err bitreich.org 70 i setenv("REQUEST", args, 1); Err bitreich.org 70 i+ printf("REQUEST = %s\n", args); Err bitreich.org 70 i Err bitreich.org 70 i setenv("REMOTE_ADDR", chost, 1); Err bitreich.org 70 i+ printf("REMOTE_ADDR = %s\n", chost); Err bitreich.org 70 i /* Err bitreich.org 70 i * Don't do a reverse lookup on every call. Only do when needed, in Err bitreich.org 70 i * the script. The RFC allows us to set the IP to the value. Err bitreich.org 70 i */ Err bitreich.org 70 i setenv("REMOTE_HOST", chost, 1); Err bitreich.org 70 i+ printf("REMOTE_HOST = %s\n", chost); Err bitreich.org 70 i /* Please do not implement identd here. */ Err bitreich.org 70 i unsetenv("REMOTE_IDENT"); Err bitreich.org 70 i unsetenv("REMOTE_USER"); Err bitreich.org 70 i@@ -569,9 +578,12 @@ setcgienviron(char *file, char *path, char *port, char *base, char *args, Err bitreich.org 70 i */ Err bitreich.org 70 i setenv("REQUEST_METHOD", "GET", 1); Err bitreich.org 70 i setenv("SCRIPT_NAME", file, 1); Err bitreich.org 70 i+ printf("SCRIPT_NAME = %s\n", file); Err bitreich.org 70 i setenv("SERVER_NAME", ohost, 1); Err bitreich.org 70 i+ printf("SERVER_PORT = %s\n", port); Err bitreich.org 70 i setenv("SERVER_PORT", port, 1); Err bitreich.org 70 i setenv("SERVER_LISTEN_NAME", bhost, 1); Err bitreich.org 70 i+ printf("SERVER_LISTEN_NAME = %s\n", bhost); Err bitreich.org 70 i if (istls) { Err bitreich.org 70 i setenv("SERVER_PROTOCOL", "gophers/1.0", 1); Err bitreich.org 70 i } else { Err bitreich.org 70 i@@ -580,8 +592,10 @@ setcgienviron(char *file, char *path, char *port, char *base, char *args, Err bitreich.org 70 i setenv("SERVER_SOFTWARE", "geomyidae", 1); Err bitreich.org 70 i Err bitreich.org 70 i setenv("X_GOPHER_SEARCH", sear, 1); Err bitreich.org 70 i+ printf("X_GOPHER_SEARCH = %s\n", sear); Err bitreich.org 70 i /* legacy compatibility */ Err bitreich.org 70 i setenv("SEARCHREQUEST", sear, 1); Err bitreich.org 70 i+ printf("SEARCHREQUEST = %s\n", sear); Err bitreich.org 70 i Err bitreich.org 70 i if (istls) { Err bitreich.org 70 i setenv("GOPHERS", "on", 1); Err bitreich.org 70 i@@ -626,14 +640,3 @@ humantime(const time_t *clock) Err bitreich.org 70 i return buf; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-char * Err bitreich.org 70 i-makebasepath(char *path, char *base) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (!(base[0] == '/' && base[1] == '\0') && Err bitreich.org 70 i- strlen(path) > strlen(base)) { Err bitreich.org 70 i- return path + strlen(base); Err bitreich.org 70 i- } else { Err bitreich.org 70 i- return path; Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 1diff --git a/ind.h b/ind.h /scm/geomyidae/file/ind.h.gph bitreich.org 70 i@@ -10,18 +10,6 @@ Err bitreich.org 70 i Err bitreich.org 70 i extern int glfd; Err bitreich.org 70 i Err bitreich.org 70 i-typedef struct Elems Elems; Err bitreich.org 70 i-struct Elems { Err bitreich.org 70 i- char **e; Err bitreich.org 70 i- int num; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-typedef struct Indexs Indexs; Err bitreich.org 70 i-struct Indexs { Err bitreich.org 70 i- Elems **n; Err bitreich.org 70 i- int num; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i typedef struct filetype filetype; Err bitreich.org 70 i struct filetype { Err bitreich.org 70 i char *end; Err bitreich.org 70 i@@ -31,20 +19,34 @@ struct filetype { Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i filetype *gettype(char *filename); Err bitreich.org 70 i+ Err bitreich.org 70 i+typedef struct gphelem gphelem; Err bitreich.org 70 i+struct gphelem { Err bitreich.org 70 i+ char **e; Err bitreich.org 70 i+ int num; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+typedef struct gphindex gphindex; Err bitreich.org 70 i+struct gphindex { Err bitreich.org 70 i+ gphelem **n; Err bitreich.org 70 i+ int num; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+gphindex *gph_scanfile(char *fname); Err bitreich.org 70 i+gphelem *gph_getadv(char *str); Err bitreich.org 70 i+int gph_printelem(int fd, gphelem *el, char *file, char *base, char *addr, char *port); Err bitreich.org 70 i+void gph_addindex(gphindex *idx, gphelem *el); Err bitreich.org 70 i+void gph_addelem(gphelem *e, char *s); Err bitreich.org 70 i+void gph_freeindex(gphindex *i); Err bitreich.org 70 i+void gph_freeelem(gphelem *e); Err bitreich.org 70 i+ Err bitreich.org 70 i void *xcalloc(size_t, size_t); Err bitreich.org 70 i void *xmalloc(size_t); Err bitreich.org 70 i void *xrealloc(void *, size_t); Err bitreich.org 70 i char *xstrdup(const char *str); Err bitreich.org 70 i int xsendfile(int, int); Err bitreich.org 70 i-Indexs *scanfile(char *fname); Err bitreich.org 70 i-Elems *getadv(char *str); Err bitreich.org 70 i int pendingbytes(int sock); Err bitreich.org 70 i void waitforpendingbytes(int sock); Err bitreich.org 70 i-int printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port); Err bitreich.org 70 i-void addindexs(Indexs *idx, Elems *el); Err bitreich.org 70 i-void addelem(Elems *e, char *s); Err bitreich.org 70 i-void freeindex(Indexs *i); Err bitreich.org 70 i-void freeelem(Elems *e); Err bitreich.org 70 i char *smprintf(char *fmt, ...); Err bitreich.org 70 i char *reverselookup(char *host); Err bitreich.org 70 i void setcgienviron(char *file, char *path, char *port, char *base, Err bitreich.org 70 i@@ -52,7 +54,6 @@ void setcgienviron(char *file, char *path, char *port, char *base, Err bitreich.org 70 i char *bhost, int istls); Err bitreich.org 70 i char *humansize(off_t n); Err bitreich.org 70 i char *humantime(const time_t *clock); Err bitreich.org 70 i-char *makebasepath(char *path, char *base); Err bitreich.org 70 i Err bitreich.org 70 i #endif Err bitreich.org 70 i Err bitreich.org 70 1diff --git a/index.gph b/index.gph /scm/geomyidae/file/index.gph.gph bitreich.org 70 i@@ -3,9 +3,11 @@ tcomment (old style comment) Err bitreich.org 70 i [1|R-36|/|server|port] Err bitreich.org 70 i [0|file - comment|/file.txt|server|port] Err bitreich.org 70 i [h|http://www.heise.de|URL:http://www.heise.de|server|port] Err bitreich.org 70 i-[0|some \| escape and [ special characters ] test|error|server|port] Err bitreich.org 70 i+[0|some \| escape and [ special characters ] test|Err|server|port] Err bitreich.org 70 i [9|binary data file|/file.dat|server|port] Err bitreich.org 70 i [9|unclosed entry|/file.dat|server|port Err bitreich.org 70 i+[9|some relative path with args|./legacy/caps.txt?key=value|server|port] Err bitreich.org 70 i+[9|some other relative path|legacy/caps.txt|server|port] Err bitreich.org 70 i [|empty type||server|port] Err bitreich.org 70 i [|Escape something, [| is skipped. Err bitreich.org 70 i some invalid line Err bitreich.org 70 1diff --git a/main.c b/main.c /scm/geomyidae/file/main.c.gph bitreich.org 70 i@@ -59,7 +59,7 @@ int nlistfds = 0; Err bitreich.org 70 i char *argv0; Err bitreich.org 70 i char stdbase[] = "/var/gopher"; Err bitreich.org 70 i char *stdport = "70"; Err bitreich.org 70 i-char *indexf[] = {"/index.gph", "/index.cgi", "/index.dcgi", "/index.bob", "/index.bin"}; Err bitreich.org 70 i+char *indexf[] = {"index.gph", "index.cgi", "index.dcgi", "index.bob", "index.bin"}; Err bitreich.org 70 i char *nocgierr = "3Sorry, execution of the token '%s' was requested, but this " Err bitreich.org 70 i "is disabled in the server configuration.\tErr" Err bitreich.org 70 i "\tlocalhost\t70\r\n"; Err bitreich.org 70 i@@ -83,7 +83,7 @@ char *htredir = "\n" Err bitreich.org 70 i " \n" Err bitreich.org 70 i "\n"; Err bitreich.org 70 i char *selinval ="3Happy helping ☃ here: " Err bitreich.org 70 i- "Sorry, your selector does not start with / or contains '..'. " Err bitreich.org 70 i+ "Sorry, your selector does contains '..'. " Err bitreich.org 70 i "That's illegal here.\tErr\tlocalhost\t70\r\n.\r\n\r\n"; Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i@@ -142,12 +142,20 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i int len = 0, fd, i, maxrecv, pathfallthrough = 0; Err bitreich.org 70 i filetype *type; Err bitreich.org 70 i Err bitreich.org 70 i+ printf("handlerequest:\n"); Err bitreich.org 70 i+ printf("sock = %d; req = '%s';\n", sock, req); Err bitreich.org 70 i+ printf("rlen = %d; base = '%s'; ohost = '%s'; port = %s;\n", rlen, Err bitreich.org 70 i+ base, ohost, port); Err bitreich.org 70 i+ printf("clienth = %s; clientp = %s; serverh = %s; serverp = %s;\n", Err bitreich.org 70 i+ clienth, clientp, serverh, serverp); Err bitreich.org 70 i+ printf("nocgi = %d; istls = %d;\n", nocgi, istls); Err bitreich.org 70 i+ Err bitreich.org 70 i if (!istls) { Err bitreich.org 70 i /* Err bitreich.org 70 i * If sticky bit is set on base dir and encryption is not Err bitreich.org 70 i * used, do not serve. Err bitreich.org 70 i */ Err bitreich.org 70 i- if (stat(base, &dir) == -1) Err bitreich.org 70 i+ if (stat(*base? base : "/", &dir) == -1) Err bitreich.org 70 i return; Err bitreich.org 70 i if (dir.st_mode & S_ISVTX) { Err bitreich.org 70 i dprintf(sock, tlserr, recvc); Err bitreich.org 70 i@@ -176,6 +184,7 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i c = strchr(recvb, '\n'); Err bitreich.org 70 i if (c) Err bitreich.org 70 i c[0] = '\0'; Err bitreich.org 70 i+ Err bitreich.org 70 i sear = strchr(recvb, '\t'); Err bitreich.org 70 i if (sear != NULL) { Err bitreich.org 70 i *sear++ = '\0'; Err bitreich.org 70 i@@ -228,29 +237,32 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i * selectors. Err bitreich.org 70 i */ Err bitreich.org 70 i Err bitreich.org 70 i+ /* Strip off the arguments of req?args style. */ Err bitreich.org 70 i c = strchr(recvb, '?'); Err bitreich.org 70 i if (c != NULL) { Err bitreich.org 70 i *c++ = '\0'; Err bitreich.org 70 i- snprintf(args, sizeof(args), "%s", c); Err bitreich.org 70 i+ snprintf(args, sizeof(args), "?%s", c); Err bitreich.org 70 i } Err bitreich.org 70 i+ printf("args = %s\n", args); Err bitreich.org 70 i+ printf("recvb = %s\n", recvb); Err bitreich.org 70 i Err bitreich.org 70 i- if (recvb[0] == '\0') { Err bitreich.org 70 i- recvb[0] = '/'; Err bitreich.org 70 i- recvb[1] = '\0'; Err bitreich.org 70 i+ /* Strip '/' at the end of the request. */ Err bitreich.org 70 i+ for (c = recvb + strlen(recvb) - 1; c >= recvb && c[0] == '/'; c--) { Err bitreich.org 70 i+ /* Prepend to args. */ Err bitreich.org 70 i+ snprintf(args, sizeof(args), "/%s", args); Err bitreich.org 70 i+ c[0] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i+ printf("args = %s\n", args); Err bitreich.org 70 i Err bitreich.org 70 i- /* Err bitreich.org 70 i- * Do not allow requests not beginning with '/' or which contain Err bitreich.org 70 i- * "..". Err bitreich.org 70 i- */ Err bitreich.org 70 i- if (recvb[0] != '/' || strstr(recvb, "..")){ Err bitreich.org 70 i+ /* Do not allow requests including "..". */ Err bitreich.org 70 i+ if (strstr(recvb, "..")) { Err bitreich.org 70 i dprintf(sock, "%s", selinval); Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- /* append base to request path (always starting with /), if base is a chroot don't append '/' */ Err bitreich.org 70 i- if (snprintf(path, sizeof(path), "%s%s", Err bitreich.org 70 i- base[0] == '/' && base[1] == '\0' ? "" : base, Err bitreich.org 70 i+ printf("recvb = %s\n", recvb); Err bitreich.org 70 i+ if (snprintf(path, sizeof(path), "%s%s%s", base, Err bitreich.org 70 i+ (*recvb != '/')? "/" : "", Err bitreich.org 70 i recvb) > sizeof(path)) { Err bitreich.org 70 i if (loglvl & ERRORS) { Err bitreich.org 70 i logentry(clienth, clientp, recvc, Err bitreich.org 70 i@@ -259,6 +271,8 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i dprintf(sock, toolongerr, recvc); Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i+ /* path is now always at least '/' */ Err bitreich.org 70 i+ printf("path = %s\n", path); Err bitreich.org 70 i Err bitreich.org 70 i fd = -1; Err bitreich.org 70 i /* Err bitreich.org 70 i@@ -270,33 +284,54 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i * $args = $rest_of_path + "?" + $args Err bitreich.org 70 i */ Err bitreich.org 70 i if (stat(path, &dir) == -1) { Err bitreich.org 70 i+ printf("Not found. Try backtraversal.\n"); Err bitreich.org 70 i memmove(argsc, args, strlen(args)); Err bitreich.org 70 i snprintf(path, sizeof(path), "%s", base); Err bitreich.org 70 i- recvbp = recvb + 1; Err bitreich.org 70 i+ recvbp = recvb; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Err bitreich.org 70 i+ * Walk into the selector until some directory or file Err bitreich.org 70 i+ * does not exist. Then reconstruct the args, selector Err bitreich.org 70 i+ * etc. Err bitreich.org 70 i+ */ Err bitreich.org 70 i while (recvbp != NULL) { Err bitreich.org 70 i- sep = strsep(&recvbp, "/"); Err bitreich.org 70 i+ /* Traverse multiple / in selector. */ Err bitreich.org 70 i+ for (sep = recvbp; sep != recvbp && sep != recvbp+1; Err bitreich.org 70 i+ sep = strsep(&recvbp, "/")); Err bitreich.org 70 i+ printf("traversal directory = %s\n", sep); Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Append found directory to path. */ Err bitreich.org 70 i snprintf(path+strlen(path), sizeof(path)-strlen(path), Err bitreich.org 70 i "/%s", sep); Err bitreich.org 70 i+ /* path is now always at least '/' */ Err bitreich.org 70 i+ printf("full traversal path = %s\n", path); Err bitreich.org 70 i+ Err bitreich.org 70 i if (stat(path, &dir) == -1) { Err bitreich.org 70 i+ /* Err bitreich.org 70 i+ * Current try was not found. Go back one Err bitreich.org 70 i+ * step and finish. Err bitreich.org 70 i+ */ Err bitreich.org 70 i c = strrchr(path, '/'); Err bitreich.org 70 i if (c != NULL) { Err bitreich.org 70 i *c++ = '\0'; Err bitreich.org 70 i snprintf(args, sizeof(args), Err bitreich.org 70 i- "/%s%s%s%s%s", Err bitreich.org 70 i+ "/%s%s%s%s", Err bitreich.org 70 i c, Err bitreich.org 70 i (recvbp != NULL)? "/" : "", Err bitreich.org 70 i (recvbp != NULL)? recvbp : "", Err bitreich.org 70 i- (argsc[0] != '\0')? "?" : "", Err bitreich.org 70 i (argsc[0] != '\0')? argsc : "" Err bitreich.org 70 i ); Err bitreich.org 70 i+ printf("args = %s\n", args); Err bitreich.org 70 i } Err bitreich.org 70 i /* path fallthrough */ Err bitreich.org 70 i pathfallthrough = 1; Err bitreich.org 70 i+ printf("pathfallthrough = 1\n"); Err bitreich.org 70 i break; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ printf("path = %s\n", path); Err bitreich.org 70 i if (stat(path, &dir) != -1) { Err bitreich.org 70 i /* Err bitreich.org 70 i * If sticky bit is set, only serve if this is encrypted. Err bitreich.org 70 i@@ -311,9 +346,11 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i if (S_ISDIR(dir.st_mode)) { Err bitreich.org 70 i+ printf("S_ISDIR\n"); Err bitreich.org 70 i for (i = 0; i < sizeof(indexf)/sizeof(indexf[0]); Err bitreich.org 70 i i++) { Err bitreich.org 70 i- if (strlen(path) + strlen(indexf[i]) Err bitreich.org 70 i+ len = strlen(path); Err bitreich.org 70 i+ if (len + strlen(indexf[i]) + (path[len-1] == '/')? 0 : 1 Err bitreich.org 70 i >= sizeof(path)) { Err bitreich.org 70 i if (loglvl & ERRORS) { Err bitreich.org 70 i logentry(clienth, clientp, Err bitreich.org 70 i@@ -322,12 +359,18 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i } Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i- strncat(path, indexf[i], Err bitreich.org 70 i- sizeof(path)-strlen(path)-1); Err bitreich.org 70 i+ sprintf(path, "%s%s%s", Err bitreich.org 70 i+ path, Err bitreich.org 70 i+ (path[len-1] == '/')? "" : "/", Err bitreich.org 70 i+ indexf[i]); Err bitreich.org 70 i+ printf("path index = %s\n", path); Err bitreich.org 70 i fd = open(path, O_RDONLY); Err bitreich.org 70 i if (fd >= 0) Err bitreich.org 70 i break; Err bitreich.org 70 i- path[strlen(path)-strlen(indexf[i])] = '\0'; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Not found. Clear path from indexf. */ Err bitreich.org 70 i+ printf("len = %d\n", len); Err bitreich.org 70 i+ path[len] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i } else { Err bitreich.org 70 i fd = open(path, O_RDONLY); Err bitreich.org 70 i@@ -342,10 +385,9 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ /* Some file was opened. Serve it. */ Err bitreich.org 70 i if (fd >= 0) { Err bitreich.org 70 i close(fd); Err bitreich.org 70 i- if (loglvl & FILES) Err bitreich.org 70 i- logentry(clienth, clientp, recvc, "serving"); Err bitreich.org 70 i Err bitreich.org 70 i c = strrchr(path, '/'); Err bitreich.org 70 i if (c == NULL) Err bitreich.org 70 i@@ -359,8 +401,10 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i if (pathfallthrough && Err bitreich.org 70 i !(type->f == handledcgi || type->f == handlecgi)) { Err bitreich.org 70 i dprintf(sock, notfounderr, recvc); Err bitreich.org 70 i- if (loglvl & ERRORS) Err bitreich.org 70 i- logentry(clienth, clientp, recvc, "not found"); Err bitreich.org 70 i+ if (loglvl & ERRORS) { Err bitreich.org 70 i+ logentry(clienth, clientp, recvc, Err bitreich.org 70 i+ "handler in path fallthrough not allowed"); Err bitreich.org 70 i+ } Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -369,14 +413,21 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i if (loglvl & ERRORS) Err bitreich.org 70 i logentry(clienth, clientp, recvc, "nocgi error"); Err bitreich.org 70 i } else { Err bitreich.org 70 i+ if (loglvl & FILES) Err bitreich.org 70 i+ logentry(clienth, clientp, recvc, "serving"); Err bitreich.org 70 i+ Err bitreich.org 70 i type->f(sock, path, port, base, args, sear, ohost, Err bitreich.org 70 i clienth, serverh, istls); Err bitreich.org 70 i } Err bitreich.org 70 i } else { Err bitreich.org 70 i- /* Err bitreich.org 70 i- * If we had to traverse the path, do not allow directory Err bitreich.org 70 i- * listings, only dynamic content. Err bitreich.org 70 i- */ Err bitreich.org 70 i+ if (pathfallthrough && S_ISDIR(dir.st_mode)) { Err bitreich.org 70 i+ if (loglvl & ERRORS) { Err bitreich.org 70 i+ logentry(clienth, clientp, recvc, Err bitreich.org 70 i+ "directory listing in traversal not allowed"); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i if (!pathfallthrough && S_ISDIR(dir.st_mode)) { Err bitreich.org 70 i handledir(sock, path, port, base, args, sear, ohost, Err bitreich.org 70 i clienth, serverh, istls); Err bitreich.org 70 i@@ -791,7 +842,7 @@ main(int argc, char *argv[]) Err bitreich.org 70 i perror("chdir"); Err bitreich.org 70 i return 1; Err bitreich.org 70 i } Err bitreich.org 70 i- base = "/"; Err bitreich.org 70 i+ base = ""; Err bitreich.org 70 i if (chroot(".") < 0) { Err bitreich.org 70 i perror("chroot"); Err bitreich.org 70 i return 1; Err bitreich.org 70 i@@ -801,9 +852,9 @@ main(int argc, char *argv[]) Err bitreich.org 70 i return 1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- /* strip / at the end, except if it is "/" */ Err bitreich.org 70 i- for (p = base + strlen(base); p > base + 1 && p[-1] == '/'; --p) Err bitreich.org 70 i- p[-1] = '\0'; Err bitreich.org 70 i+ /* strip / at the end of base */ Err bitreich.org 70 i+ for (p = base + strlen(base) - 1; p >= base && p[0] == '/'; --p) Err bitreich.org 70 i+ p[0] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i if (dropprivileges(gr, us) < 0) { Err bitreich.org 70 i perror("dropprivileges"); Err bitreich.org 70 i@@ -1063,21 +1114,32 @@ read_selector_again: Err bitreich.org 70 i close(tlssocks[tlsclientreader? 1 : 0]); Err bitreich.org 70 i do { Err bitreich.org 70 i if (tlsclientreader) { Err bitreich.org 70 i- shuflen = read(tlssocks[0], shufbuf, sizeof(shufbuf)-1); Err bitreich.org 70 i+ shuflen = read(tlssocks[0], Err bitreich.org 70 i+ shufbuf, Err bitreich.org 70 i+ sizeof(shufbuf)-1); Err bitreich.org 70 i } else { Err bitreich.org 70 i- shuflen = tls_read(tlsclientctx, shufbuf, sizeof(shufbuf)-1); Err bitreich.org 70 i+ shuflen = tls_read(tlsclientctx, Err bitreich.org 70 i+ shufbuf, Err bitreich.org 70 i+ sizeof(shufbuf)-1); Err bitreich.org 70 i } Err bitreich.org 70 i if (shuflen == -1 && errno == EINTR) Err bitreich.org 70 i continue; Err bitreich.org 70 i- for (shufpos = 0; shufpos < shuflen; shufpos += wlen) { Err bitreich.org 70 i+ for (shufpos = 0; shufpos < shuflen; Err bitreich.org 70 i+ shufpos += wlen) { Err bitreich.org 70 i if (tlsclientreader) { Err bitreich.org 70 i- wlen = tls_write(tlsclientctx, shufbuf+shufpos, shuflen-shufpos); Err bitreich.org 70 i+ wlen = tls_write(tlsclientctx, Err bitreich.org 70 i+ shufbuf+shufpos, Err bitreich.org 70 i+ shuflen-shufpos); Err bitreich.org 70 i if (wlen < 0) { Err bitreich.org 70 i- fprintf(stderr, "tls_write failed: %s\n", tls_error(tlsclientctx)); Err bitreich.org 70 i+ fprintf(stderr, Err bitreich.org 70 i+ "tls_write failed: %s\n", Err bitreich.org 70 i+ tls_error(tlsclientctx)); Err bitreich.org 70 i return 1; Err bitreich.org 70 i } Err bitreich.org 70 i } else { Err bitreich.org 70 i- wlen = write(tlssocks[1], shufbuf+shufpos, shuflen-shufpos); Err bitreich.org 70 i+ wlen = write(tlssocks[1], Err bitreich.org 70 i+ shufbuf+shufpos, Err bitreich.org 70 i+ shuflen-shufpos); Err bitreich.org 70 i if (wlen < 0) { Err bitreich.org 70 i perror("write"); Err bitreich.org 70 i return 1; Err bitreich.org 70 .