mirror of
https://github.com/sheumann/hush.git
synced 2025-01-03 00:31:16 +00:00
httpd: fix decode of '/' when called via -d
This commit is contained in:
parent
2425bdce34
commit
a35c9e91ba
@ -671,44 +671,48 @@ static char *encodeString(const char *string)
|
|||||||
*
|
*
|
||||||
* $Parameters:
|
* $Parameters:
|
||||||
* (char *) string . . . The first string to decode.
|
* (char *) string . . . The first string to decode.
|
||||||
* (int) flag . . . 1 if need to decode '+' as ' ' for CGI
|
* (int) option_d . . 1 if called for httpd -d
|
||||||
*
|
*
|
||||||
* $Return: (char *) . . . . A pointer to the decoded string (same as input).
|
* $Return: (char *) . . . . A pointer to the decoded string (same as input).
|
||||||
*
|
*
|
||||||
* $Errors: None
|
* $Errors: None
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static char *decodeString(char *orig, int flag_plus_to_space)
|
static char *decodeString(char *orig, int option_d)
|
||||||
{
|
{
|
||||||
/* note that decoded string is always shorter than original */
|
/* note that decoded string is always shorter than original */
|
||||||
char *string = orig;
|
char *string = orig;
|
||||||
char *ptr = string;
|
char *ptr = string;
|
||||||
|
char c;
|
||||||
|
|
||||||
while (*ptr) {
|
while ((c = *ptr++) != '\0') {
|
||||||
if (*ptr == '+' && flag_plus_to_space) {
|
unsigned value1, value2;
|
||||||
|
|
||||||
|
if (option_d && c == '+') {
|
||||||
*string++ = ' ';
|
*string++ = ' ';
|
||||||
ptr++;
|
continue;
|
||||||
} else if (*ptr != '%') {
|
}
|
||||||
*string++ = *ptr++;
|
if (c != '%') {
|
||||||
} else {
|
*string++ = c;
|
||||||
unsigned int value1, value2;
|
continue;
|
||||||
|
}
|
||||||
ptr++;
|
|
||||||
if (sscanf(ptr, "%1X", &value1) != 1
|
if (sscanf(ptr, "%1X", &value1) != 1
|
||||||
|| sscanf(ptr+1, "%1X", &value2) != 1
|
|| sscanf(ptr+1, "%1X", &value2) != 1
|
||||||
) {
|
) {
|
||||||
if (!flag_plus_to_space)
|
if (!option_d)
|
||||||
return NULL;
|
return NULL;
|
||||||
*string++ = '%';
|
*string++ = '%';
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
value1 = value1 * 16 + value2;
|
value1 = value1 * 16 + value2;
|
||||||
if (value1 == '/' || value1 == 0)
|
if (!option_d && (value1 == '/' || value1 == '\0')) {
|
||||||
return orig+1;
|
/* caller takes it as indication of invalid
|
||||||
|
* (dangerous wrt exploits) chars */
|
||||||
|
return orig + 1;
|
||||||
|
}
|
||||||
*string++ = value1;
|
*string++ = value1;
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
*string = '\0';
|
*string = '\0';
|
||||||
return orig;
|
return orig;
|
||||||
}
|
}
|
||||||
@ -1510,8 +1514,8 @@ static void handleIncoming(void)
|
|||||||
test = decodeString(url, 0);
|
test = decodeString(url, 0);
|
||||||
if (test == NULL)
|
if (test == NULL)
|
||||||
goto BAD_REQUEST;
|
goto BAD_REQUEST;
|
||||||
/* FIXME: bug? should be "url+1"? */
|
if (test == url+1) {
|
||||||
if (test == (buf+1)) {
|
/* '/' or NUL is encoded */
|
||||||
sendHeaders(HTTP_NOT_FOUND);
|
sendHeaders(HTTP_NOT_FOUND);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1909,12 +1913,12 @@ int httpd_main(int argc, char *argv[])
|
|||||||
char *e;
|
char *e;
|
||||||
// FIXME: what the default group should be?
|
// FIXME: what the default group should be?
|
||||||
ugid.gid = -1;
|
ugid.gid = -1;
|
||||||
ugid.uid = strtoul(s_ugid, &e, 0);
|
ugid.uid = bb_strtoul(s_ugid, &e, 0);
|
||||||
if (*e == ':') {
|
if (*e == ':') {
|
||||||
e++;
|
e++;
|
||||||
ugid.gid = strtoul(e, &e, 0);
|
ugid.gid = bb_strtoul(e, NULL, 0);
|
||||||
}
|
}
|
||||||
if (*e != '\0') {
|
if (errno) {
|
||||||
/* not integer */
|
/* not integer */
|
||||||
if (!uidgid_get(&ugid, s_ugid))
|
if (!uidgid_get(&ugid, s_ugid))
|
||||||
bb_error_msg_and_die("unrecognized user[:group] "
|
bb_error_msg_and_die("unrecognized user[:group] "
|
||||||
@ -1942,9 +1946,7 @@ int httpd_main(int argc, char *argv[])
|
|||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
{
|
{
|
||||||
char *p = getenv("PATH");
|
char *p = getenv("PATH");
|
||||||
if (p) {
|
p = xstrdup(p); /* if gets NULL, returns NULL */
|
||||||
p = xstrdup(p);
|
|
||||||
}
|
|
||||||
clearenv();
|
clearenv();
|
||||||
if (p)
|
if (p)
|
||||||
setenv1("PATH", p);
|
setenv1("PATH", p);
|
||||||
|
Loading…
Reference in New Issue
Block a user