[BusyBox] httpd patches
Vladimir N. Oleynik
dzo at simtreas.ru
Mon Apr 7 04:41:22 UTC 2003
Glenn,
> > I found restore old algorithms for addEnvCgi(), base64ToBin[] and many
> > others :(
>
> addEnvCgi() I didn't change unless it was formatting.
What for you add non-standard features?
Your code easily turns out inside the CGI script.
CGI_ARGLIST_=`env | sed "{
s/^CGI_\(..*\)=.*/\1/
t ok
/.*/d
: ok
}
> base64ToBin() was broken for certain combinations of input.
I found problem. I ignored '=' padding, but require set as '\0';
> Rather than
> debug the new version I put in the old one. The old one was smaller code
> size
Only 3 bytes.
New version base64ToBin() have size:
text data bss dec hex filename
172 0 0 172 ac b64_vodz.o
189 0 0 189 bd b64_glen.o
with my old algorithm without your ascii comparing:
if ((newch < '+') || (newch > 'z'))
> >
> > You removed my sorting and my not trivial logic from conf_parse :(
> >
>
> The sorting is still there and should behave the same as your version.
Example:
global conf (administrative) have:
A:10.
D:*
subdir conf (users) have:
A:10.
A:172.20.
D:*
My result:
A:10.
D:*
Your result:
A:10.
A:172.20 # open by user!
x:*
--w
vodz
-------------- next part --------------
diff -ru busybox.orig/networking/httpd.c busybox/networking/httpd.c
--- busybox.orig/networking/httpd.c Wed Mar 19 12:12:37 2003
+++ busybox/networking/httpd.c Mon Apr 7 08:31:56 2003
@@ -42,7 +42,7 @@
* The server can also be invoked as a url arg decoder and html text encoder
* as follows:
* foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World"
- * bar=`httpd -e "<Hello World>"` # encode as "%3CHello%20World%3E"
+ * bar=`httpd -e "<Hello World>"` # encode as "<Hello World>"
*
* httpd.conf has the following format:
@@ -120,30 +120,29 @@
#include "busybox.h"
-static const char httpdVersion[] = "busybox httpd/1.20 31-Jan-2003";
-static const char default_patch_httpd_conf[] = "/etc";
+static const char httpdVersion[] = "busybox httpd/1.22 05-Apr-2003";
+static const char default_path_httpd_conf[] = "/etc";
static const char httpd_conf[] = "httpd.conf";
static const char home[] = "/www";
-// Note: xfuncs are not used because we want the server to keep running
+// Note: bussybox xfuncs are not used because we want the server to keep running
// if something bad happens due to a malformed user request.
// As a result, all memory allocation after daemonize
// is checked rigorously
//#define DEBUG 1
-/* Configure options, disabled by default as nonstandart httpd feature */
+/* Configure options, disabled by default as custom httpd feature */
+
+/* disabled as optional features */
//#define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
//#define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
-//#define CONFIG_FEATURE_HTTPD_DECODE_URL_STR
-
-/* disabled as not necessary feature */
//#define CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
//#define CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
//#define CONFIG_FEATURE_HTTPD_SETUID
//#define CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
-/* If seted this you can use this server from internet superserver only */
+/* If set, use this server from internet superserver only */
//#define CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
/* You can use this server as standalone, require libbb.a for linking */
@@ -160,7 +159,6 @@
#undef CONFIG_FEATURE_HTTPD_BASIC_AUTH
#undef CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
#undef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
-#undef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
#undef CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
#undef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
#undef CONFIG_FEATURE_HTTPD_CGI
@@ -170,7 +168,6 @@
#define CONFIG_FEATURE_HTTPD_BASIC_AUTH
#define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
#define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
-#define CONFIG_FEATURE_HTTPD_DECODE_URL_STR
#define CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
#define CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
#define CONFIG_FEATURE_HTTPD_CGI
@@ -183,7 +180,7 @@
void bb_show_usage(void)
{
fprintf(stderr, "Usage: %s [-p <port>] [-c configFile] [-d/-e <string>] "
- "[-r realm] [-u user]\n", bb_applet_name);
+ "[-r realm] [-u user] [-h homedir ]\n", bb_applet_name);
exit(1);
}
#endif
@@ -423,7 +420,7 @@
cf = p0 = alloca(strlen(path) + sizeof(httpd_conf) + 2);
if(p0 == NULL) {
if(flag == FIRST_PARSE)
- bb_error_msg_and_die(bb_msg_memory_exhausted);
+ bb_error_msg_and_die(bb_memory_exhausted);
return;
}
sprintf(p0, "%s/%s", path, httpd_conf);
@@ -432,7 +429,7 @@
while((f = fopen(cf, "r")) == NULL) {
if(flag != FIRST_PARSE)
return; /* subdir config not found */
- if(p0 == NULL) /* if -c option gived */
+ if(p0 == NULL) /* if -c option given */
bb_perror_msg_and_die("%s", cf);
p0 = NULL;
cf = httpd_conf; /* set -c ./httpd_conf */
@@ -459,7 +456,7 @@
}
}
- /* This could stand some work */
+ /* This could stand some work */
while ( (p0 = fgets(buf, 80, f)) != NULL) {
char *p;
char *colon;
@@ -543,7 +540,7 @@
pcur = alloca((n + 1) * sizeof(Htaccess *));
if(pcur == NULL) {
if(flag == FIRST_PARSE)
- bb_error_msg_and_die(bb_msg_memory_exhausted);
+ bb_error_msg_and_die(bb_memory_exhausted);
return;
}
n = 0;
@@ -602,7 +599,6 @@
}
#endif /* CONFIG_FEATURE_HTTPD_ENCODE_URL_STR */
-#ifdef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
/****************************************************************************
*
> $Function: decodeString()
@@ -615,20 +611,21 @@
*
* $Parameters:
* (char *) string . . . The first string to decode.
+ * (int) flag . . . 1 if require decode '+' as ' ' for CGI
*
* $Return: (char *) . . . . A pointer to the decoded string (same as input).
*
* $Errors: None
*
****************************************************************************/
-static char *decodeString(char *string)
+static char *decodeString(char *string, int flag_plus_to_space)
{
/* note that decoded string is always shorter than original */
char *orig = string;
char *ptr = string;
while (*ptr)
{
- if (*ptr == '+') { *string++ = ' '; ptr++; }
+ if (*ptr == '+' && flag_plus_to_space) { *string++ = ' '; ptr++; }
else if (*ptr != '%') *string++ = *ptr++;
else {
unsigned int value;
@@ -640,7 +637,6 @@
*string = '\0';
return orig;
}
-#endif /* CONFIG_FEATURE_HTTPD_DECODE_URL_STR */
#ifdef CONFIG_FEATURE_HTTPD_CGI
@@ -730,7 +726,7 @@
args = strchr(value, '&');
if (args)
*args++ = 0;
- addEnv("CGI", name, decodeString(value));
+ addEnv("CGI", name, decodeString(value, 1));
}
free(memargs);
}
@@ -758,33 +754,28 @@
****************************************************************************/
static void decodeBase64(char *Data)
{
- int i = 0;
static const char base64ToBin[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const unsigned char *in = Data;
// The decoded size will be at most 3/4 the size of the encoded
unsigned long ch = 0;
+ int i = 0;
while (*in) {
- unsigned char conv = 0;
-
- while (*in) {
- const char *p64;
+ const char *p64 = strchr(base64ToBin, *in++);
- p64 = strchr(base64ToBin, *in++);
- if(p64 == NULL)
- continue;
- conv = (p64 - base64ToBin);
- break;
- }
- ch = (ch << 6) | conv;
- i++;
- if (i== 4) {
- *Data++ = (char) (ch >> 16);
- *Data++ = (char) (ch >> 8);
- *Data++ = (char) ch;
- i = 0;
+ if(p64) {
+ if(*p64 == '=') /* padding, set 0 */
+ p64 = base64ToBin;
+ ch = (ch << 6) | (p64 - base64ToBin);
+ i++;
+ if (i == 4) {
+ *Data++ = (char) (ch >> 16);
+ *Data++ = (char) (ch >> 8);
+ *Data++ = (char) ch;
+ i = 0;
+ }
}
}
*Data = 0;
@@ -882,12 +873,10 @@
"Date: %s\r\nConnection: close\r\n",
responseNum, responseString, config->found_mime_type, timeStr);
-#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
if (responseNum == HTTP_UNAUTHORIZED) {
len += sprintf(buf+len, "WWW-Authenticate: Basic realm=\"%s\"\r\n",
config->realm);
}
-#endif
if (config->ContentLength != -1) { /* file */
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&config->last_mod));
len += sprintf(buf+len, "Last-Modified: %s\r\n%s %ld\r\n",
@@ -1382,6 +1371,7 @@
*purl = ' ';
count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank);
+ decodeString(buf, 0);
if (count < 1 || buf[0] != '/') {
/* Garbled request/URL */
goto BAD_REQUEST;
@@ -1394,10 +1384,8 @@
strcpy(url, buf);
/* extract url args if present */
urlArgs = strchr(url, '?');
- if (urlArgs) {
- *urlArgs++ = 0; /* next code can set '/' to this pointer,
- but CGI script can`t be a directory */
- }
+ if (urlArgs)
+ *urlArgs++ = 0;
/* algorithm stolen from libbb bb_simplify_path(),
but don`t strdup and reducing trailing slash */
@@ -1644,6 +1632,9 @@
exit(0);
}
close(s);
+#ifdef TEST
+ return 0; // exit after processing one request
+#endif
}
}
} // while (1)
@@ -1682,7 +1673,7 @@
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, NULL);
- parse_conf(default_patch_httpd_conf,
+ parse_conf(default_path_httpd_conf,
sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE);
}
#endif
@@ -1694,6 +1685,10 @@
#endif
{
const char *home_httpd = home;
+#ifdef TEST
+ const char *testArg1 = 0;
+ const char *testArg2 = 0;
+#endif
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
int server;
@@ -1716,22 +1711,22 @@
/* check if user supplied a port number */
for (;;) {
- int c = getopt( argc, argv, "c:h:"
+ int c = getopt( argc, argv, "c:d:h:"
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
"p:v"
#endif
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
"e:"
#endif
-#ifdef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
- "d:"
-#endif
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
"r:"
#endif
#ifdef CONFIG_FEATURE_HTTPD_SETUID
"u:"
#endif
+#ifdef TEST
+ "t:"
+#endif
);
if (c == EOF) break;
switch (c) {
@@ -1751,11 +1746,9 @@
bb_error_msg_and_die("invalid %s for -p", optarg);
break;
#endif
-#ifdef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
case 'd':
- printf("%s", decodeString(optarg));
+ printf("%s", decodeString(optarg, 1));
return 0;
-#endif
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
case 'e':
printf("%s", encodeString(optarg));
@@ -1779,6 +1772,12 @@
}
break;
#endif
+#ifdef TEST
+ case 't':
+ if (testArg1 == 0) testArg1 = optarg;
+ else testArg2 = optarg;
+ break;
+#endif
default:
bb_error_msg("%s", httpdVersion);
bb_show_usage();
@@ -1803,8 +1802,16 @@
#ifdef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
sighup_handler(0);
#else
- parse_conf(default_patch_httpd_conf, FIRST_PARSE);
+ parse_conf(default_path_httpd_conf, FIRST_PARSE);
#endif
+
+#ifdef TEST
+ if (testArg1) {
+ if (strcmp(testArg1,"ip") == 0)
+ testArg1 = 0;
+ return printf("%d\n", checkPerm(testArg1, testArg2));
+ }
+ #endif
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
if (!config->debugHttpd) {
More information about the busybox
mailing list