Fix relative printelem with ? in name. - geomyidae - A small C-based gopherd. HTML git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit 6f22091df20685c8b7a8a89823aa31606bea2be0 DIR parent 42b52f54ede822d8e937025394d69702d5f910d3 HTML Author: Christoph Lohmann <20h@r-36.net> Date: Sun, 4 Apr 2021 20:57:28 +0200 Fix relative printelem with ? in name. * Thanks adc for reporting. * Add more comments in special selector request casing. Diffstat: M ind.c | 36 +++++++++++++++++++++----------- M main.c | 12 ++++++++++-- 2 files changed, 34 insertions(+), 14 deletions(-) --- DIR diff --git a/ind.c b/ind.c @@ -403,8 +403,8 @@ scanfile(char *fname) int printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port) { - char *path, *p, buf[PATH_MAX+1]; - int len; + char *path, *p, *argbase, buf[PATH_MAX+1]; + int len, blen; if (!strcmp(el->e[3], "server")) { free(el->e[3]); @@ -417,24 +417,36 @@ printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port) /* * Ignore if the path is from base, if it might be some h type with - * some URL and ignore various types that have different semantics but - * to point to some file or directory. + * some URL and ignore various types that have different semantics, + * do not point to some file or directory. + */ + /* + * FUTURE: If ever special requests with no beginning '/' are used in + * geomyidae, this is the place to control this. */ if ((el->e[2][0] != '\0' - && el->e[2][0] != '/' - && el->e[0][0] != 'i' - && el->e[0][0] != '2' - && el->e[0][0] != '3' - && el->e[0][0] != '8' - && el->e[0][0] != 'w' - && el->e[0][0] != 'T') && + && el->e[2][0] != '/' /* Absolute Request. */ + && el->e[0][0] != 'i' /* Informational item. */ + && el->e[0][0] != '2' /* CSO server */ + && el->e[0][0] != '3' /* Error */ + && el->e[0][0] != '8' /* Telnet */ + && el->e[0][0] != 'w' /* Selector is direct URI. */ + && el->e[0][0] != 'T') && /* tn3270 */ !(el->e[0][0] == 'h' && !strncmp(el->e[2], "URL:", 4))) { path = file + strlen(base); if ((p = strrchr(path, '/'))) len = p - path; else len = strlen(path); - snprintf(buf, sizeof(buf), "%s%.*s/%s", base, len, path, el->e[2]); + + argbase = strchr(el->e[2], '?'); + if (argbase != NULL) + blen = argbase - el->e[2]; + else + blen = strlen(el->e[2]); + + snprintf(buf, sizeof(buf), "%s%.*s/%.*s", base, len, + path, blen, el->e[2]); if ((path = realpath(buf, NULL)) && !strncmp(base, path, strlen(base))) { DIR diff --git a/main.c b/main.c @@ -177,6 +177,7 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, memmove(recvc, recvb, rlen+1); + /* Redirect to HTML redirecting to the specified URI. */ if (!strncmp(recvb, "URL:", 4)) { len = snprintf(path, sizeof(path), htredir, recvb + 4, recvb + 4, recvb + 4); @@ -189,8 +190,8 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, } /* - * Valid cases in gopher we overwrite here, but could be used for - * other geomyidae features: + * FUTURE: Valid cases in gopher we overwrite here, but could be used + * for other geomyidae features: * * request string = "?..." -> "/?..." * request string = "" -> "/" @@ -198,6 +199,9 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, * * Be careful, when you consider those special cases to be used * for some feature. You can easily do good and bad. + * + * Look at printelem() in ind.c for the counterpart of producing + * selectors. */ args = strchr(recvb, '?'); @@ -209,6 +213,10 @@ handlerequest(int sock, char *req, int rlen, char *base, char *ohost, recvb[1] = '\0'; } + /* + * Do not allow requests not beginning with '/' or which contain + * "..". + */ if (recvb[0] != '/' || strstr(recvb, "..")){ dprintf(sock, "%s", selinval); return;