mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-24 09:03:30 +01:00
Implement /api/downloads
This commit is contained in:
parent
e5404b10e1
commit
7659765116
@ -27,6 +27,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h> // daemonizing
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <wordexp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bio.h> /* base64 encode/decode */
|
||||
@ -1636,6 +1639,101 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in, const char * const use
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
weblog(200, wsthread_handler_id, 0, origip, ip, user, 1, origpath, strlen(buf));
|
||||
|
||||
ret = 1;
|
||||
} else entry("/api/downloads") {
|
||||
char subpath[PATH_MAX] = "", startpath[PATH_MAX] = "~/Downloads", allpath[PATH_MAX];
|
||||
param = parse_get(args, "path", &len);
|
||||
if (len) {
|
||||
memcpy(buf, param, len);
|
||||
buf[len] = '\0';
|
||||
percent_decode(buf, subpath, 0);
|
||||
|
||||
if (strstr(subpath, "../")) {
|
||||
handler_msg("Attempted directory traversal in /api/downloads\n");
|
||||
goto nope;
|
||||
}
|
||||
}
|
||||
|
||||
wordexp_t wexp;
|
||||
if (!wordexp(startpath, &wexp, WRDE_NOCMD))
|
||||
strcpy(startpath, wexp.we_wordv[0]);
|
||||
else
|
||||
goto nope;
|
||||
wordfree(&wexp);
|
||||
|
||||
snprintf(allpath, PATH_MAX, "%s/%s", startpath, subpath);
|
||||
allpath[PATH_MAX - 1] = '\0';
|
||||
|
||||
DIR *dir = opendir(allpath);
|
||||
if (!dir) {
|
||||
handler_msg("Requested dir does not exist\n");
|
||||
goto nope;
|
||||
}
|
||||
|
||||
sprintf(buf, "HTTP/1.1 200 OK\r\n"
|
||||
"Server: KasmVNC/4.0\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-type: text/json\r\n"
|
||||
"%s"
|
||||
"\r\n", extra_headers ? extra_headers : "");
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
len = 15;
|
||||
|
||||
ws_send(ws_ctx, "{ \"files\": [\n", 13);
|
||||
|
||||
struct dirent *ent;
|
||||
unsigned char sent = 0;
|
||||
while ((ent = readdir(dir))) {
|
||||
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||
continue;
|
||||
|
||||
sprintf(path, "%s/%s", allpath, ent->d_name);
|
||||
struct stat st;
|
||||
if (lstat(path, &st))
|
||||
continue;
|
||||
|
||||
char own[LOGIN_NAME_MAX], grp[LOGIN_NAME_MAX], perms[32];
|
||||
sprintf(perms, "%o", st.st_mode & 0777);
|
||||
|
||||
struct passwd pwdt, *pwdptr;
|
||||
if (getpwuid_r(st.st_uid, &pwdt, buf, sizeof(buf), &pwdptr)) {
|
||||
sprintf(own, "(unknown uid %u)", st.st_uid);
|
||||
} else {
|
||||
strcpy(own, pwdt.pw_name);
|
||||
}
|
||||
|
||||
struct group grpt, *grpptr;
|
||||
if (getgrgid_r(st.st_gid, &grpt, buf, sizeof(buf), &grpptr)) {
|
||||
sprintf(grp, "(unknown gid %u)", st.st_gid);
|
||||
} else {
|
||||
strcpy(grp, grpt.gr_name);
|
||||
}
|
||||
|
||||
sprintf(buf, "%s{ \"filename\": \"%s\", "
|
||||
"\"date_modified\": %lu, "
|
||||
"\"date_created\": %lu, "
|
||||
"\"is_dir\": %s, "
|
||||
"\"owner\": \"%s\", "
|
||||
"\"group\": \"%s\", "
|
||||
"\"perms\": \"%s\" }",
|
||||
sent ? ",\n" : "",
|
||||
ent->d_name,
|
||||
st.st_mtime,
|
||||
st.st_ctime,
|
||||
S_ISDIR(st.st_mode) ? "true" : "false",
|
||||
own,
|
||||
grp,
|
||||
perms);
|
||||
sent = 1;
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
len += strlen(buf);
|
||||
}
|
||||
|
||||
ws_send(ws_ctx, "]}", 2);
|
||||
|
||||
closedir(dir);
|
||||
weblog(200, wsthread_handler_id, 0, origip, ip, user, 1, origpath, len);
|
||||
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user