From d1ca3911d29c9fb2147695b6622d9a088041a534 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Thu, 21 Jan 2021 22:44:41 +0000 Subject: [PATCH] fix redirects make sure redirect starts with /. This also requires a tweak in check_path, in the case we go open_file -> send_dir -> open_file -> check-path and the path starts with a slash. --- server.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/server.c b/server.c index c1ccbce..2d80dcb 100644 --- a/server.c +++ b/server.c @@ -33,10 +33,20 @@ int check_path(struct client *c, const char *path, int *fd) { struct stat sb; + const char *p; assert(path != NULL); - if ((*fd = openat(c->host->dirfd, *path ? path : ".", - O_RDONLY | O_NOFOLLOW)) == -1) { + + if (*path == '\0') + p = "."; + else if (*path == '/') + /* in send_dir we add an initial / (to be + * redirect-friendly), but here we want to skip it */ + p = path+1; + else + p = path; + + if ((*fd = openat(c->host->dirfd, p, O_RDONLY | O_NOFOLLOW)) == -1) { return FILE_MISSING; } @@ -395,10 +405,12 @@ send_dir(struct pollfd *fds, struct client *c) return; } + strlcpy(c->sbuf, "/", sizeof(c->sbuf)); + len = strlen(c->iri.path); if (len > 0 && c->iri.path[len-1] != '/') { /* redirect to url with the trailing / */ - strlcpy(c->sbuf, c->iri.path, sizeof(c->sbuf)); + strlcat(c->sbuf, c->iri.path, sizeof(c->sbuf)); strlcat(c->sbuf, "/", sizeof(c->sbuf)); if (!start_reply(fds, c, TEMP_REDIRECT, c->sbuf)) return; @@ -406,9 +418,11 @@ send_dir(struct pollfd *fds, struct client *c) return; } - strlcpy(c->sbuf, c->iri.path, sizeof(c->sbuf)); - if (len != 0) + strlcat(c->sbuf, c->iri.path, sizeof(c->sbuf)); + + if (!ends_with(c->sbuf, "/")) strlcat(c->sbuf, "/", sizeof(c->sbuf)); + len = strlcat(c->sbuf, "index.gmi", sizeof(c->sbuf)); if (len >= sizeof(c->sbuf)) {