|
|
@ -111,7 +111,7 @@ static const char *parse_get(const char * const in, const char * const opt, unsi
|
|
|
|
return "";
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void percent_decode(const char *src, char *dst) {
|
|
|
|
static void percent_decode(const char *src, char *dst, const uint8_t filter) {
|
|
|
|
while (1) {
|
|
|
|
while (1) {
|
|
|
|
if (!*src)
|
|
|
|
if (!*src)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -127,7 +127,15 @@ static void percent_decode(const char *src, char *dst) {
|
|
|
|
hex[2] = '\0';
|
|
|
|
hex[2] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
src += 2;
|
|
|
|
src += 2;
|
|
|
|
*dst++ = strtol(hex, NULL, 16);
|
|
|
|
*dst = strtol(hex, NULL, 16);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (filter) {
|
|
|
|
|
|
|
|
// Avoid directory traversal
|
|
|
|
|
|
|
|
if (*dst == '/')
|
|
|
|
|
|
|
|
*dst = '_';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dst++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -842,7 +850,7 @@ static void servefile(ws_ctx_t *ws_ctx, const char *in) {
|
|
|
|
len = strlen(path);
|
|
|
|
len = strlen(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
percent_decode(path, buf);
|
|
|
|
percent_decode(path, buf, 1);
|
|
|
|
|
|
|
|
|
|
|
|
wserr("Requested file '%s'\n", buf);
|
|
|
|
wserr("Requested file '%s'\n", buf);
|
|
|
|
sprintf(fullpath, "%s/%s", settings.httpdir, buf);
|
|
|
|
sprintf(fullpath, "%s/%s", settings.httpdir, buf);
|
|
|
@ -998,14 +1006,14 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|
|
|
if (len) {
|
|
|
|
if (len) {
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
buf[len] = '\0';
|
|
|
|
buf[len] = '\0';
|
|
|
|
percent_decode(buf, decname);
|
|
|
|
percent_decode(buf, decname, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
param = parse_get(args, "password", &len);
|
|
|
|
param = parse_get(args, "password", &len);
|
|
|
|
if (len) {
|
|
|
|
if (len) {
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
buf[len] = '\0';
|
|
|
|
buf[len] = '\0';
|
|
|
|
percent_decode(buf, decpw);
|
|
|
|
percent_decode(buf, decpw, 0);
|
|
|
|
|
|
|
|
|
|
|
|
struct crypt_data cdata;
|
|
|
|
struct crypt_data cdata;
|
|
|
|
cdata.initialized = 0;
|
|
|
|
cdata.initialized = 0;
|
|
|
@ -1045,7 +1053,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|
|
|
if (len) {
|
|
|
|
if (len) {
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
buf[len] = '\0';
|
|
|
|
buf[len] = '\0';
|
|
|
|
percent_decode(buf, decname);
|
|
|
|
percent_decode(buf, decname, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!decname[0])
|
|
|
|
if (!decname[0])
|
|
|
@ -1074,7 +1082,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|
|
|
if (len) {
|
|
|
|
if (len) {
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
buf[len] = '\0';
|
|
|
|
buf[len] = '\0';
|
|
|
|
percent_decode(buf, decname);
|
|
|
|
percent_decode(buf, decname, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!decname[0])
|
|
|
|
if (!decname[0])
|
|
|
@ -1119,7 +1127,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|
|
|
if (len) {
|
|
|
|
if (len) {
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
memcpy(buf, param, len);
|
|
|
|
buf[len] = '\0';
|
|
|
|
buf[len] = '\0';
|
|
|
|
percent_decode(buf, decname);
|
|
|
|
percent_decode(buf, decname, 0);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
wserr("client param required\n");
|
|
|
|
wserr("client param required\n");
|
|
|
|
goto nope;
|
|
|
|
goto nope;
|
|
|
|