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;
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
(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) {
|
if (srvroot_len + 1 > PBUF_SIZE) {
|
||||||
fprintf(stderr, "Path buffer is too small\n");
|
fprintf(stderr, "Path buffer is too small\n");
|
||||||
@ -260,8 +313,7 @@ int main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (retrying_write(cfd, rbuf, n) != n) {
|
if (retrying_write(cfd, rbuf, n) != n) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Error sending respose line to client\n");
|
||||||
"Error sending respose line to client\n");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user