diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-12-19 12:30:34 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-12-19 12:30:34 +0100 |
commit | 03419aa037ce37d1c3accb0df52fdc456b360541 (patch) | |
tree | 6f96d1d0bdaafd2e197c9651dde789a8451c09b9 /networking/httpd.c | |
parent | 93b4a605263612cf32ad9de746a4fafaf4515115 (diff) | |
download | busybox-w32-03419aa037ce37d1c3accb0df52fdc456b360541.tar.gz busybox-w32-03419aa037ce37d1c3accb0df52fdc456b360541.tar.bz2 busybox-w32-03419aa037ce37d1c3accb0df52fdc456b360541.zip |
httpd: don't drop/abuse QUERY_STRING when /cgi-bin/index.cgi is used
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/httpd.c')
-rw-r--r-- | networking/httpd.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index e9cd213f1..3f4e6aab7 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -1265,18 +1265,21 @@ static void setenv1(const char *name, const char *value) | |||
1265 | * | 1265 | * |
1266 | * Parameters: | 1266 | * Parameters: |
1267 | * const char *url The requested URL (with leading /). | 1267 | * const char *url The requested URL (with leading /). |
1268 | * const char *orig_uri The original URI before rewriting (if any) | ||
1268 | * int post_len Length of the POST body. | 1269 | * int post_len Length of the POST body. |
1269 | * const char *cookie For set HTTP_COOKIE. | 1270 | * const char *cookie For set HTTP_COOKIE. |
1270 | * const char *content_type For set CONTENT_TYPE. | 1271 | * const char *content_type For set CONTENT_TYPE. |
1271 | */ | 1272 | */ |
1272 | static void send_cgi_and_exit( | 1273 | static void send_cgi_and_exit( |
1273 | const char *url, | 1274 | const char *url, |
1275 | const char *orig_uri, | ||
1274 | const char *request, | 1276 | const char *request, |
1275 | int post_len, | 1277 | int post_len, |
1276 | const char *cookie, | 1278 | const char *cookie, |
1277 | const char *content_type) NORETURN; | 1279 | const char *content_type) NORETURN; |
1278 | static void send_cgi_and_exit( | 1280 | static void send_cgi_and_exit( |
1279 | const char *url, | 1281 | const char *url, |
1282 | const char *orig_uri, | ||
1280 | const char *request, | 1283 | const char *request, |
1281 | int post_len, | 1284 | int post_len, |
1282 | const char *cookie, | 1285 | const char *cookie, |
@@ -1314,9 +1317,9 @@ static void send_cgi_and_exit( | |||
1314 | setenv1("PATH_INFO", script); /* set to /PATH_INFO or "" */ | 1317 | setenv1("PATH_INFO", script); /* set to /PATH_INFO or "" */ |
1315 | setenv1("REQUEST_METHOD", request); | 1318 | setenv1("REQUEST_METHOD", request); |
1316 | if (g_query) { | 1319 | if (g_query) { |
1317 | putenv(xasprintf("%s=%s?%s", "REQUEST_URI", url, g_query)); | 1320 | putenv(xasprintf("%s=%s?%s", "REQUEST_URI", orig_uri, g_query)); |
1318 | } else { | 1321 | } else { |
1319 | setenv1("REQUEST_URI", url); | 1322 | setenv1("REQUEST_URI", orig_uri); |
1320 | } | 1323 | } |
1321 | if (script != NULL) | 1324 | if (script != NULL) |
1322 | *script = '\0'; /* cut off /PATH_INFO */ | 1325 | *script = '\0'; /* cut off /PATH_INFO */ |
@@ -2248,12 +2251,20 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2248 | /* protect listing "cgi-bin/" */ | 2251 | /* protect listing "cgi-bin/" */ |
2249 | send_headers_and_exit(HTTP_FORBIDDEN); | 2252 | send_headers_and_exit(HTTP_FORBIDDEN); |
2250 | } | 2253 | } |
2251 | send_cgi_and_exit(urlcopy, prequest, length, cookie, content_type); | 2254 | send_cgi_and_exit(urlcopy, urlcopy, prequest, length, cookie, content_type); |
2252 | } | 2255 | } |
2253 | #endif | 2256 | #endif |
2254 | 2257 | ||
2255 | if (urlp[-1] == '/') | 2258 | if (urlp[-1] == '/') { |
2259 | /* When index_page string is appended to <dir>/ URL, it overwrites | ||
2260 | * the query string. If we fall back to call /cgi-bin/index.cgi, | ||
2261 | * query string would be lost and not available to the CGI. | ||
2262 | * Work around it by making a deep copy. | ||
2263 | */ | ||
2264 | if (ENABLE_FEATURE_HTTPD_CGI) | ||
2265 | g_query = xstrdup(g_query); /* ok for NULL too */ | ||
2256 | strcpy(urlp, index_page); | 2266 | strcpy(urlp, index_page); |
2267 | } | ||
2257 | if (stat(tptr, &sb) == 0) { | 2268 | if (stat(tptr, &sb) == 0) { |
2258 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 2269 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
2259 | char *suffix = strrchr(tptr, '.'); | 2270 | char *suffix = strrchr(tptr, '.'); |
@@ -2261,7 +2272,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2261 | Htaccess *cur; | 2272 | Htaccess *cur; |
2262 | for (cur = script_i; cur; cur = cur->next) { | 2273 | for (cur = script_i; cur; cur = cur->next) { |
2263 | if (strcmp(cur->before_colon + 1, suffix) == 0) { | 2274 | if (strcmp(cur->before_colon + 1, suffix) == 0) { |
2264 | send_cgi_and_exit(urlcopy, prequest, length, cookie, content_type); | 2275 | send_cgi_and_exit(urlcopy, urlcopy, prequest, length, cookie, content_type); |
2265 | } | 2276 | } |
2266 | } | 2277 | } |
2267 | } | 2278 | } |
@@ -2274,9 +2285,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2274 | /* It's a dir URL and there is no index.html | 2285 | /* It's a dir URL and there is no index.html |
2275 | * Try cgi-bin/index.cgi */ | 2286 | * Try cgi-bin/index.cgi */ |
2276 | if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) { | 2287 | if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) { |
2277 | urlp[0] = '\0'; | 2288 | urlp[0] = '\0'; /* remove index_page */ |
2278 | g_query = urlcopy; | 2289 | send_cgi_and_exit("/cgi-bin/index.cgi", urlcopy, prequest, length, cookie, content_type); |
2279 | send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); | ||
2280 | } | 2290 | } |
2281 | } | 2291 | } |
2282 | /* else fall through to send_file, it errors out if open fails: */ | 2292 | /* else fall through to send_file, it errors out if open fails: */ |