summaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-29 15:58:50 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-29 15:58:50 +0000
commita35c9e91ba53073ff797d1d68d0d4e1836d934f0 (patch)
treea19543c721a5a98f9b96522303ca250b58d1bcca /networking
parent2425bdce34cd142b29eabad00927a9c473b05ecb (diff)
downloadbusybox-w32-a35c9e91ba53073ff797d1d68d0d4e1836d934f0.tar.gz
busybox-w32-a35c9e91ba53073ff797d1d68d0d4e1836d934f0.tar.bz2
busybox-w32-a35c9e91ba53073ff797d1d68d0d4e1836d934f0.zip
httpd: fix decode of '/' when called via -d
Diffstat (limited to 'networking')
-rw-r--r--networking/httpd.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index f95e0c06e..49c2c76be 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -671,43 +671,47 @@ static char *encodeString(const char *string)
671 * 671 *
672 * $Parameters: 672 * $Parameters:
673 * (char *) string . . . The first string to decode. 673 * (char *) string . . . The first string to decode.
674 * (int) flag . . . 1 if need to decode '+' as ' ' for CGI 674 * (int) option_d . . 1 if called for httpd -d
675 * 675 *
676 * $Return: (char *) . . . . A pointer to the decoded string (same as input). 676 * $Return: (char *) . . . . A pointer to the decoded string (same as input).
677 * 677 *
678 * $Errors: None 678 * $Errors: None
679 * 679 *
680 ****************************************************************************/ 680 ****************************************************************************/
681static char *decodeString(char *orig, int flag_plus_to_space) 681static char *decodeString(char *orig, int option_d)
682{ 682{
683 /* note that decoded string is always shorter than original */ 683 /* note that decoded string is always shorter than original */
684 char *string = orig; 684 char *string = orig;
685 char *ptr = string; 685 char *ptr = string;
686 char c;
686 687
687 while (*ptr) { 688 while ((c = *ptr++) != '\0') {
688 if (*ptr == '+' && flag_plus_to_space) { 689 unsigned value1, value2;
690
691 if (option_d && c == '+') {
689 *string++ = ' '; 692 *string++ = ' ';
690 ptr++; 693 continue;
691 } else if (*ptr != '%') { 694 }
692 *string++ = *ptr++; 695 if (c != '%') {
693 } else { 696 *string++ = c;
694 unsigned int value1, value2; 697 continue;
695 698 }
696 ptr++; 699 if (sscanf(ptr, "%1X", &value1) != 1
697 if (sscanf(ptr, "%1X", &value1) != 1 700 || sscanf(ptr+1, "%1X", &value2) != 1
698 || sscanf(ptr+1, "%1X", &value2) != 1 701 ) {
699 ) { 702 if (!option_d)
700 if (!flag_plus_to_space) 703 return NULL;
701 return NULL; 704 *string++ = '%';
702 *string++ = '%'; 705 continue;
703 } else { 706 }
704 value1 = value1 * 16 + value2; 707 value1 = value1 * 16 + value2;
705 if (value1 == '/' || value1 == 0) 708 if (!option_d && (value1 == '/' || value1 == '\0')) {
706 return orig+1; 709 /* caller takes it as indication of invalid
707 *string++ = value1; 710 * (dangerous wrt exploits) chars */
708 ptr += 2; 711 return orig + 1;
709 }
710 } 712 }
713 *string++ = value1;
714 ptr += 2;
711 } 715 }
712 *string = '\0'; 716 *string = '\0';
713 return orig; 717 return orig;
@@ -1510,8 +1514,8 @@ static void handleIncoming(void)
1510 test = decodeString(url, 0); 1514 test = decodeString(url, 0);
1511 if (test == NULL) 1515 if (test == NULL)
1512 goto BAD_REQUEST; 1516 goto BAD_REQUEST;
1513 /* FIXME: bug? should be "url+1"? */ 1517 if (test == url+1) {
1514 if (test == (buf+1)) { 1518 /* '/' or NUL is encoded */
1515 sendHeaders(HTTP_NOT_FOUND); 1519 sendHeaders(HTTP_NOT_FOUND);
1516 break; 1520 break;
1517 } 1521 }
@@ -1909,12 +1913,12 @@ int httpd_main(int argc, char *argv[])
1909 char *e; 1913 char *e;
1910 // FIXME: what the default group should be? 1914 // FIXME: what the default group should be?
1911 ugid.gid = -1; 1915 ugid.gid = -1;
1912 ugid.uid = strtoul(s_ugid, &e, 0); 1916 ugid.uid = bb_strtoul(s_ugid, &e, 0);
1913 if (*e == ':') { 1917 if (*e == ':') {
1914 e++; 1918 e++;
1915 ugid.gid = strtoul(e, &e, 0); 1919 ugid.gid = bb_strtoul(e, NULL, 0);
1916 } 1920 }
1917 if (*e != '\0') { 1921 if (errno) {
1918 /* not integer */ 1922 /* not integer */
1919 if (!uidgid_get(&ugid, s_ugid)) 1923 if (!uidgid_get(&ugid, s_ugid))
1920 bb_error_msg_and_die("unrecognized user[:group] " 1924 bb_error_msg_and_die("unrecognized user[:group] "
@@ -1942,9 +1946,7 @@ int httpd_main(int argc, char *argv[])
1942#if ENABLE_FEATURE_HTTPD_CGI 1946#if ENABLE_FEATURE_HTTPD_CGI
1943 { 1947 {
1944 char *p = getenv("PATH"); 1948 char *p = getenv("PATH");
1945 if (p) { 1949 p = xstrdup(p); /* if gets NULL, returns NULL */
1946 p = xstrdup(p);
1947 }
1948 clearenv(); 1950 clearenv();
1949 if (p) 1951 if (p)
1950 setenv1("PATH", p); 1952 setenv1("PATH", p);