Construct full path of requested resource
Also detects .. in the selector string, as this could be used to see files outside of srvroot, otherwise.
This commit is contained in:
parent
f6871a7922
commit
a3cdde2c34
60
main.c
60
main.c
@ -61,6 +61,26 @@ static int retrying_write(int fd, const char *buf, size_t len)
|
||||
return n;
|
||||
}
|
||||
|
||||
static int append_selector_part(const char *part, size_t partlen, char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
if (partlen == 0)
|
||||
return 0;
|
||||
|
||||
if (strncmp(part, "..", partlen) == 0) {
|
||||
fprintf(stderr, "Selector string contains \"..\"\n");
|
||||
return -1;
|
||||
} else if (partlen + 1 > bufsize) {
|
||||
fprintf(stderr, "Path buffer too small\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*buf++ = '/';
|
||||
memcpy(buf, part, partlen);
|
||||
|
||||
return partlen + 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
(void)argc;
|
||||
@ -190,9 +210,42 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the requested resource.
|
||||
* Construct the full path to the requested resource.
|
||||
*
|
||||
* For now, this is just opening srvroot.
|
||||
* This is needed in order to pass it to stat() and open() or
|
||||
* opendir() later. It must be null-terminated. We also need
|
||||
* to make sure that none of the path's parts are "..", as
|
||||
* this could be used to escape the srvroot directory.
|
||||
*/
|
||||
char *sp = sbuf;
|
||||
unsigned splen = 0, ppos = srvroot_len;
|
||||
for (unsigned i = 0; i < slen; ++i) {
|
||||
if (sbuf[i] != '/') {
|
||||
++splen;
|
||||
continue;
|
||||
}
|
||||
n = append_selector_part(sp, splen, &pbuf[ppos], PBUF_SIZE - ppos);
|
||||
if (n == -1)
|
||||
goto close_client_socket;
|
||||
ppos += n;
|
||||
sp = &sbuf[i + 1];
|
||||
splen = 0;
|
||||
}
|
||||
n = append_selector_part(sp, splen, &pbuf[ppos], PBUF_SIZE - ppos);
|
||||
if (n == -1)
|
||||
goto close_client_socket;
|
||||
ppos += n;
|
||||
|
||||
// UNSAFE!
|
||||
pbuf[ppos] = '\0';
|
||||
printf("Requested path: %s\n", pbuf);
|
||||
|
||||
/*
|
||||
* Determine the resource's type.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Open the resource.
|
||||
*/
|
||||
if (srvroot_len + 1 > PBUF_SIZE) {
|
||||
fprintf(stderr, "Path buffer is too small\n");
|
||||
@ -260,8 +313,7 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
if (retrying_write(cfd, rbuf, n) != n) {
|
||||
fprintf(stderr,
|
||||
"Error sending respose line to client\n");
|
||||
fprintf(stderr, "Error sending respose line to client\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user