diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2025-01-23 23:21:44 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2025-01-23 23:37:39 +0100 |
| commit | 9752843329a257542c34798d65e829a6cff7764b (patch) | |
| tree | b834d2d3dd4c27cae03f3d2c663644ecae3d1a8d | |
| parent | 5c4e226ddcd132c0dfa9a9cf096d3b3f8fc3c171 (diff) | |
| download | slcl-9752843329a257542c34798d65e829a6cff7764b.tar.gz | |
main.c: Forbid sharing non-existing files
So far, slcl would allow to share literally any directory or file, even
if they did not exist, as long as valid credentials were given.
Now, directories cannot be shared, since this is already restricted by
the web interface. This is now considered an invalid request.
On the other hand, attempting to share non-existing files shall now
return a 404 Not Found response to the user.
| -rw-r--r-- | main.c | 41 | ||||
| -rw-r--r-- | page.c | 2 | ||||
| -rw-r--r-- | page.h | 1 |
3 files changed, 31 insertions, 13 deletions
@@ -487,15 +487,13 @@ end: return ret; } -static char *create_symlink(const char *const username, const char *const dir, - const char *const path) +static char *create_symlink(const char *const dir, const char *user) { char *ret = NULL; unsigned char buf[16]; char dbuf[1 + 2 * sizeof buf]; - struct dynstr user, abs, rel; + struct dynstr abs, rel; - dynstr_init(&user); dynstr_init(&abs); dynstr_init(&rel); @@ -510,11 +508,6 @@ static char *create_symlink(const char *const username, const char *const dir, fprintf(stderr, "%s: hex_encode failed\n", __func__); goto end; } - else if (dynstr_append(&user, "%s/user/%s%s", dir, username, path)) - { - fprintf(stderr, "%s: dynstr_append user failed\n", __func__); - goto end; - } else if (dynstr_append(&rel, "/public/%s", dbuf)) { fprintf(stderr, "%s: dynstr_append rel failed\n", __func__); @@ -525,7 +518,7 @@ static char *create_symlink(const char *const username, const char *const dir, fprintf(stderr, "%s: dynstr_append abs failed\n", __func__); goto end; } - else if (symlink(user.str, abs.str)) + else if (symlink(user, abs.str)) { fprintf(stderr, "%s: symlink(2): %s\n", __func__, strerror(errno)); goto end; @@ -534,7 +527,6 @@ static char *create_symlink(const char *const username, const char *const dir, ret = rel.str; end: - dynstr_free(&user); dynstr_free(&abs); if (!ret) @@ -806,6 +798,9 @@ static int share(const struct http_payload *const p, struct form *forms = NULL; size_t n = 0; char *sympath = NULL; + struct dynstr userpath; + + dynstr_init(&userpath); if ((ret = get_forms(p, &forms, &n))) { @@ -824,6 +819,7 @@ static int share(const struct http_payload *const p, } const char *const path = forms->value, *const username = p->cookie.field; + struct stat sb; if (path_invalid(path)) { @@ -831,7 +827,27 @@ static int share(const struct http_payload *const p, ret = page_bad_request(r); goto end; } - else if (!(sympath = create_symlink(username, adir, path))) + else if (dynstr_append(&userpath, "%s/user/%s%s", adir, username, path)) + { + fprintf(stderr, "%s: dynstr_append user failed\n", __func__); + goto end; + } + else if (stat(userpath.str, &sb)) + { + fprintf(stderr, "%s: stat(2) %s: %s\n", __func__, userpath.str, + strerror(errno)); + + if (errno == ENOENT || errno == ENOTDIR) + ret = page_not_found(r); + + goto end; + } + else if (!S_ISREG(sb.st_mode)) + { + ret = page_bad_request(r); + goto end; + } + else if (!(sympath = create_symlink(adir, userpath.str))) { fprintf(stderr, "%s: create_symlink failed\n", __func__); goto end; @@ -847,6 +863,7 @@ static int share(const struct http_payload *const p, end: forms_free(forms, n); free(sympath); + dynstr_free(&userpath); return ret; } @@ -1626,7 +1626,7 @@ end: return ret; } -static int page_not_found(struct http_response *const r) +int page_not_found(struct http_response *const r) { static const char body[] = DOCTYPE_TAG @@ -42,6 +42,7 @@ int page_style(struct http_response *r, const char *path); int page_failed_login(struct http_response *r); int page_forbidden(struct http_response *r); int page_bad_request(struct http_response *r); +int page_not_found(struct http_response *r); int page_resource(const struct page_resource *r); int page_head_resource(struct http_response *r, const char *res); int page_public(struct http_response *r, const char *res); |
