last_patch84 by Vodz.
This commit is contained in:
parent
49e74effbc
commit
c9163fee91
@ -42,7 +42,7 @@
|
|||||||
* The server can also be invoked as a url arg decoder and html text encoder
|
* The server can also be invoked as a url arg decoder and html text encoder
|
||||||
* as follows:
|
* as follows:
|
||||||
* foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World"
|
* 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:
|
* httpd.conf has the following format:
|
||||||
|
|
||||||
@ -56,51 +56,17 @@ D:* # Deny from other IP connections
|
|||||||
/adm:toor:PaSsWd # or user toor, pwd PaSsWd on urls starting with /adm/
|
/adm:toor:PaSsWd # or user toor, pwd PaSsWd on urls starting with /adm/
|
||||||
.au:audio/basic # additional mime type for audio.au files
|
.au:audio/basic # additional mime type for audio.au files
|
||||||
|
|
||||||
A shortes path and D:from[^*] automaticaly sorting to top.
|
|
||||||
All longest path can`t reset user:password if shorted protect setted.
|
|
||||||
|
|
||||||
A/D may be as a/d or allow/deny - first char case unsensitive parsed only.
|
A/D may be as a/d or allow/deny - first char case unsensitive parsed only.
|
||||||
|
|
||||||
Each subdir can have config file.
|
Each subdir can have config file.
|
||||||
|
You can set less IP allow from subdir config.
|
||||||
|
Password protection from subdir config can rewriten previous sets for
|
||||||
|
current or/and next subpathes.
|
||||||
For protect as user:pass current subdir and subpathes set from subdir config:
|
For protect as user:pass current subdir and subpathes set from subdir config:
|
||||||
/:user:pass
|
/:user:pass
|
||||||
if not, other subpathes for give effect must have path from httpd root
|
/subpath:user2:pass2
|
||||||
/current_subdir_path_from_httpd_root/subpath:user:pass
|
|
||||||
|
|
||||||
The Deny/Allow IP logic:
|
|
||||||
|
|
||||||
1. Allow all:
|
|
||||||
The config don`t set D: lines
|
|
||||||
|
|
||||||
2. Allow from setted only:
|
|
||||||
see the begin format example
|
|
||||||
|
|
||||||
3. Set deny, allow from other:
|
|
||||||
D:1.2.3. # deny from 1.2.3.0 - 1.2.3.255
|
|
||||||
D:2.3.4. # deny from 2.3.4.0 - 2.3.4.255
|
|
||||||
A:* # allow from other, this line not strongly require
|
|
||||||
|
|
||||||
A global and subdirs config merging logic:
|
|
||||||
allow rules reducing, deny lines strongled.
|
|
||||||
The algorithm combinations:
|
|
||||||
|
|
||||||
4. If current config have
|
|
||||||
A:from
|
|
||||||
D:*
|
|
||||||
subdir config A: lines skiping, D:from - moving top
|
|
||||||
|
|
||||||
5. If current config have
|
|
||||||
D:from
|
|
||||||
A:*
|
|
||||||
result config:
|
|
||||||
D:from current
|
|
||||||
D:from subdir
|
|
||||||
A:from subdir
|
|
||||||
and seting D:* if subdir config have this
|
|
||||||
|
|
||||||
If -c don`t setted, used httpd root config, else httpd root config skiped.
|
If -c don`t setted, used httpd root config, else httpd root config skiped.
|
||||||
Exited with fault if can`t open start config.
|
|
||||||
For set wide open server, use -c /dev/null ;=)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -120,30 +86,29 @@ A:from subdir
|
|||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
|
|
||||||
static const char httpdVersion[] = "busybox httpd/1.20 31-Jan-2003";
|
static const char httpdVersion[] = "busybox httpd/1.25 10-May-2003";
|
||||||
static const char default_patch_httpd_conf[] = "/etc";
|
static const char default_path_httpd_conf[] = "/etc";
|
||||||
static const char httpd_conf[] = "httpd.conf";
|
static const char httpd_conf[] = "httpd.conf";
|
||||||
static const char home[] = "/www";
|
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.
|
// if something bad happens due to a malformed user request.
|
||||||
// As a result, all memory allocation after daemonize
|
// As a result, all memory allocation after daemonize
|
||||||
// is checked rigorously
|
// is checked rigorously
|
||||||
|
|
||||||
//#define DEBUG 1
|
//#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_SET_CGI_VARS_TO_ENV
|
||||||
//#define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
//#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_SET_REMOTE_PORT_TO_ENV
|
||||||
//#define CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
//#define CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
||||||
//#define CONFIG_FEATURE_HTTPD_SETUID
|
//#define CONFIG_FEATURE_HTTPD_SETUID
|
||||||
//#define CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
|
//#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
|
//#define CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
||||||
|
|
||||||
/* You can use this server as standalone, require libbb.a for linking */
|
/* You can use this server as standalone, require libbb.a for linking */
|
||||||
@ -160,7 +125,6 @@ static const char home[] = "/www";
|
|||||||
#undef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
#undef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
#undef CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
|
#undef CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
|
||||||
#undef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
#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_SET_REMOTE_PORT_TO_ENV
|
||||||
#undef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
#undef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
||||||
#undef CONFIG_FEATURE_HTTPD_CGI
|
#undef CONFIG_FEATURE_HTTPD_CGI
|
||||||
@ -170,7 +134,6 @@ static const char home[] = "/www";
|
|||||||
#define CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
#define CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
#define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
|
#define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
|
||||||
#define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
#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_SET_REMOTE_PORT_TO_ENV
|
||||||
#define CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
#define CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
||||||
#define CONFIG_FEATURE_HTTPD_CGI
|
#define CONFIG_FEATURE_HTTPD_CGI
|
||||||
@ -183,7 +146,7 @@ const char *bb_applet_name = "httpd";
|
|||||||
void bb_show_usage(void)
|
void bb_show_usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-p <port>] [-c configFile] [-d/-e <string>] "
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -232,6 +195,15 @@ typedef struct
|
|||||||
const char *found_mime_type;
|
const char *found_mime_type;
|
||||||
off_t ContentLength; /* -1 - unknown */
|
off_t ContentLength; /* -1 - unknown */
|
||||||
time_t last_mod;
|
time_t last_mod;
|
||||||
|
|
||||||
|
Htaccess *ip_a_d; /* config allow/deny lines */
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
|
Htaccess *auth; /* config user:password lines */
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
||||||
|
Htaccess *mime_a; /* config mime types */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
||||||
int accepted_socket;
|
int accepted_socket;
|
||||||
#define a_c_r config->accepted_socket
|
#define a_c_r config->accepted_socket
|
||||||
@ -241,7 +213,6 @@ typedef struct
|
|||||||
#define a_c_r 0
|
#define a_c_r 0
|
||||||
#define a_c_w 1
|
#define a_c_w 1
|
||||||
#endif
|
#endif
|
||||||
Htaccess *Httpd_conf_parsed;
|
|
||||||
} HttpdConfig;
|
} HttpdConfig;
|
||||||
|
|
||||||
static HttpdConfig *config;
|
static HttpdConfig *config;
|
||||||
@ -308,15 +279,16 @@ static const HttpEnumString httpResponseNames[] = {
|
|||||||
{ HTTP_OK, "OK" },
|
{ HTTP_OK, "OK" },
|
||||||
{ HTTP_NOT_IMPLEMENTED, "Not Implemented",
|
{ HTTP_NOT_IMPLEMENTED, "Not Implemented",
|
||||||
"The requested method is not recognized by this server." },
|
"The requested method is not recognized by this server." },
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
{ HTTP_UNAUTHORIZED, "Unauthorized", "" },
|
{ HTTP_UNAUTHORIZED, "Unauthorized", "" },
|
||||||
|
#endif
|
||||||
{ HTTP_NOT_FOUND, "Not Found",
|
{ HTTP_NOT_FOUND, "Not Found",
|
||||||
"The requested URL was not found on this server." },
|
"The requested URL was not found on this server." },
|
||||||
{ HTTP_BAD_REQUEST, "Bad Request" ,
|
{ HTTP_BAD_REQUEST, "Bad Request", "Unsupported method." },
|
||||||
"Unsupported method." },
|
|
||||||
{ HTTP_FORBIDDEN, "Forbidden", "" },
|
{ HTTP_FORBIDDEN, "Forbidden", "" },
|
||||||
{ HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"
|
{ HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error",
|
||||||
"Internal Server Error" },
|
"Internal Server Error" },
|
||||||
#if 0
|
#if 0 /* not implemented */
|
||||||
{ HTTP_CREATED, "Created" },
|
{ HTTP_CREATED, "Created" },
|
||||||
{ HTTP_ACCEPTED, "Accepted" },
|
{ HTTP_ACCEPTED, "Accepted" },
|
||||||
{ HTTP_NO_CONTENT, "No Content" },
|
{ HTTP_NO_CONTENT, "No Content" },
|
||||||
@ -334,157 +306,106 @@ static const char RFC1123FMT[] = "%a, %d %b %Y %H:%M:%S GMT";
|
|||||||
static const char Content_length[] = "Content-length:";
|
static const char Content_length[] = "Content-length:";
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sotring to:
|
static void free_config_lines(Htaccess **pprev)
|
||||||
* .ext:mime/type
|
|
||||||
* /path:user:pass
|
|
||||||
* /path/subdir:user:pass
|
|
||||||
* D:from
|
|
||||||
* A:from
|
|
||||||
* D:*
|
|
||||||
*/
|
|
||||||
static int conf_sort(const void *p1, const void *p2)
|
|
||||||
{
|
{
|
||||||
const Htaccess *cl1 = *(const Htaccess **)p1;
|
Htaccess *prev = *pprev;
|
||||||
const Htaccess *cl2 = *(const Htaccess **)p2;
|
|
||||||
char c1 = cl1->before_colon[0];
|
|
||||||
char c2 = cl2->before_colon[0];
|
|
||||||
int test;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
while( prev ) {
|
||||||
/* .ext line up before other lines for simlify algorithm */
|
Htaccess *cur = prev;
|
||||||
test = c2 == '.';
|
|
||||||
if(c1 == '.')
|
|
||||||
return -(!test);
|
|
||||||
if(test)
|
|
||||||
return test;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
prev = cur->next;
|
||||||
test = c1 == '/';
|
free(cur);
|
||||||
/* /path line up before A/D lines for simlify algorithm */
|
|
||||||
if(test) {
|
|
||||||
if(c2 != '/')
|
|
||||||
return -test;
|
|
||||||
/* a shortes path with user:pass must be first */
|
|
||||||
return strlen(cl1->before_colon) - strlen(cl2->before_colon);
|
|
||||||
} else if(c2 == '/')
|
|
||||||
return !test;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* D:from must move top */
|
|
||||||
test = c2 == 'D' && cl2->after_colon[0] != 0;
|
|
||||||
if(c1 == 'D' && cl1->after_colon[0] != 0) {
|
|
||||||
return -(!test);
|
|
||||||
}
|
}
|
||||||
if(test)
|
*pprev = NULL;
|
||||||
return test;
|
|
||||||
|
|
||||||
/* next lines - A:from */
|
|
||||||
test = c2 == 'A' && cl2->after_colon[0] != 0;
|
|
||||||
if(c1 == 'A' && cl1->after_colon[0] != 0) {
|
|
||||||
return -(!test);
|
|
||||||
}
|
|
||||||
if(test)
|
|
||||||
return test;
|
|
||||||
|
|
||||||
/* end lines - D:* */
|
|
||||||
test = c2 == 'D' && cl2->after_colon[0] == 0;
|
|
||||||
if(c1 == 'D' && cl1->after_colon[0] == 0) {
|
|
||||||
return -(!test);
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
if(!test)
|
|
||||||
bb_error_msg_and_die("sort: can`t found compares!");
|
|
||||||
#endif
|
|
||||||
return test;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_config_line(Htaccess **pprev, Htaccess *cur)
|
||||||
|
{
|
||||||
|
if(*pprev == NULL) {
|
||||||
|
*pprev = cur;
|
||||||
|
} else {
|
||||||
|
Htaccess *prev;
|
||||||
|
|
||||||
|
for(prev = *pprev; prev->next; prev = prev->next)
|
||||||
|
;
|
||||||
|
prev->next = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* flag */
|
/* flag */
|
||||||
#define FIRST_PARSE 0
|
#define FIRST_PARSE 0
|
||||||
#define SUBDIR_PARSE 1
|
#define SUBDIR_PARSE 1
|
||||||
#define SIGNALED_PARSE 2
|
#define SIGNALED_PARSE 2
|
||||||
|
#define FIND_FROM_HTTPD_ROOT 3
|
||||||
|
|
||||||
static void parse_conf(const char *path, int flag)
|
static void parse_conf(const char *path, int flag)
|
||||||
{
|
{
|
||||||
#define bc cur->before_colon[0]
|
|
||||||
#define ac cur->after_colon[0]
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
Htaccess *prev;
|
|
||||||
Htaccess *cur;
|
Htaccess *cur;
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
|
Htaccess *prev;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *cf = config->configFile;
|
const char *cf = config->configFile;
|
||||||
char buf[80];
|
char buf[80];
|
||||||
char *p0 = NULL;
|
char *p0 = NULL;
|
||||||
int deny_all = 0; /* default A:* */
|
char *c, *p;
|
||||||
int n = 0; /* count config lines */
|
|
||||||
|
/* free previous setuped */
|
||||||
|
free_config_lines(&config->ip_a_d);
|
||||||
|
if(flag != SUBDIR_PARSE) {
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
|
free_config_lines(&config->auth)
|
||||||
|
#endif
|
||||||
|
; /* syntax confuse */
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
||||||
|
free_config_lines(&config->mime_a);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if(flag == SUBDIR_PARSE || cf == NULL) {
|
if(flag == SUBDIR_PARSE || cf == NULL) {
|
||||||
cf = p0 = alloca(strlen(path) + sizeof(httpd_conf) + 2);
|
cf = alloca(strlen(path) + sizeof(httpd_conf) + 2);
|
||||||
if(p0 == NULL) {
|
if(cf == NULL) {
|
||||||
if(flag == FIRST_PARSE)
|
if(flag == FIRST_PARSE)
|
||||||
bb_error_msg_and_die(bb_msg_memory_exhausted);
|
bb_error_msg_and_die(bb_msg_memory_exhausted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sprintf(p0, "%s/%s", path, httpd_conf);
|
sprintf((char *)cf, "%s/%s", path, httpd_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
while((f = fopen(cf, "r")) == NULL) {
|
while((f = fopen(cf, "r")) == NULL) {
|
||||||
if(flag != FIRST_PARSE)
|
if(flag != FIRST_PARSE) {
|
||||||
return; /* subdir config not found */
|
/* config file not found */
|
||||||
if(p0 == NULL) /* if -c option gived */
|
return;
|
||||||
|
}
|
||||||
|
if(config->configFile) /* if -c option given */
|
||||||
bb_perror_msg_and_die("%s", cf);
|
bb_perror_msg_and_die("%s", cf);
|
||||||
p0 = NULL;
|
flag = FIND_FROM_HTTPD_ROOT;
|
||||||
cf = httpd_conf; /* set -c ./httpd_conf */
|
cf = httpd_conf;
|
||||||
}
|
|
||||||
|
|
||||||
prev = config->Httpd_conf_parsed;
|
|
||||||
if(flag != SUBDIR_PARSE) {
|
|
||||||
/* free previous setuped */
|
|
||||||
while( prev ) {
|
|
||||||
cur = prev;
|
|
||||||
prev = cur->next;
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
config->Httpd_conf_parsed = prev; /* eq NULL */
|
|
||||||
} else {
|
|
||||||
/* parse previous IP logic for merge */
|
|
||||||
for(cur = prev; cur; cur = cur->next) {
|
|
||||||
if(bc == 'D' && ac == 0)
|
|
||||||
deny_all++;
|
|
||||||
n++;
|
|
||||||
/* find last for set prev->next of merging */
|
|
||||||
if(cur != prev)
|
|
||||||
prev = prev->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
|
prev = config->auth;
|
||||||
|
#endif
|
||||||
/* This could stand some work */
|
/* This could stand some work */
|
||||||
while ( (p0 = fgets(buf, 80, f)) != NULL) {
|
while ( (p0 = fgets(buf, 80, f)) != NULL) {
|
||||||
char *p;
|
c = NULL;
|
||||||
char *colon;
|
for(p = p0; *p0 != 0 && *p0 != '#'; p0++) {
|
||||||
|
if(!isspace(*p0)) {
|
||||||
for(p = colon = p0; *p; p++) {
|
*p++ = *p0;
|
||||||
if(*p == '#') {
|
if(*p0 == ':' && c == NULL)
|
||||||
|
c = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(isspace(*p)) {
|
|
||||||
if(p != p0) {
|
|
||||||
*p = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p0++;
|
|
||||||
}
|
|
||||||
else if(*p == ':' && colon <= p0)
|
|
||||||
colon = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test for empty or strange line */
|
/* test for empty or strange line */
|
||||||
if (colon <= p0 || colon[1] == 0)
|
if (c == NULL || *c == 0)
|
||||||
continue;
|
continue;
|
||||||
if(colon[1] == '*')
|
if(*c == '*')
|
||||||
colon[1] = 0; /* Allow all */
|
*c = 0; /* Allow all */
|
||||||
|
p0 = buf;
|
||||||
if(*p0 == 'a')
|
if(*p0 == 'a')
|
||||||
*p0 = 'A';
|
*p0 = 'A';
|
||||||
if(*p0 == 'd')
|
if(*p0 == 'd')
|
||||||
@ -498,70 +419,109 @@ static void parse_conf(const char *path, int flag)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(*p0 == 'A' && *c == 0) {
|
||||||
|
/* skip default A:* */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p0 = buf;
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
if(*p0 == '/' && colon[1] == 0) {
|
if(*p0 == '/') {
|
||||||
|
if(*c == 0) {
|
||||||
/* skip /path:* */
|
/* skip /path:* */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* make full path from httpd root / curent_path / config_line_path */
|
||||||
|
cf = flag == SUBDIR_PARSE ? path : "";
|
||||||
|
p0 = malloc(strlen(cf) + (c - buf) + 2 + strlen(c));
|
||||||
|
if(p0 == NULL)
|
||||||
|
continue;
|
||||||
|
c[-1] = 0;
|
||||||
|
sprintf(p0, "/%s%s", cf, buf);
|
||||||
|
|
||||||
|
/* another call bb_simplify_path */
|
||||||
|
cf = p = p0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (*p == '/') {
|
||||||
|
if (*cf == '/') { /* skip duplicate (or initial) slash */
|
||||||
|
continue;
|
||||||
|
} else if (*cf == '.') {
|
||||||
|
if (cf[1] == '/' || cf[1] == 0) { /* remove extra '.' */
|
||||||
|
continue;
|
||||||
|
} else if ((cf[1] == '.') && (cf[2] == '/' || cf[2] == 0)) {
|
||||||
|
++cf;
|
||||||
|
if (p > p0) {
|
||||||
|
while (*--p != '/'); /* omit previous dir */
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*++p = *cf;
|
||||||
|
} while (*++cf);
|
||||||
|
|
||||||
|
if ((p == p0) || (*p != '/')) { /* not a trailing slash */
|
||||||
|
++p; /* so keep last character */
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
sprintf(p0, "%s:%s", p0, c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* storing current config line */
|
||||||
|
|
||||||
|
cur = calloc(1, sizeof(Htaccess) + strlen(p0));
|
||||||
|
if(cur) {
|
||||||
|
cf = strcpy(cur->before_colon, p0);
|
||||||
|
c = strchr(cf, ':');
|
||||||
|
*c++ = 0;
|
||||||
|
cur->after_colon = c;
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
|
if(*cf == '/')
|
||||||
|
free(p0);
|
||||||
|
#endif
|
||||||
|
if(*cf == 'A' || *cf == 'D')
|
||||||
|
add_config_line(&config->ip_a_d, cur);
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
||||||
|
else if(*cf == '.')
|
||||||
|
add_config_line(&config->mime_a, cur);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(*p0 == 'A' || *p0 == 'D') {
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
if(colon[1] == 0) {
|
else if(prev == NULL) {
|
||||||
if(*p0 == 'A' || deny_all != 0)
|
|
||||||
continue; /* skip default A:* or double D:* */
|
|
||||||
}
|
|
||||||
if(deny_all != 0 && *p0 == 'A')
|
|
||||||
continue; // if previous setted rule D:* skip all subdir A:
|
|
||||||
}
|
|
||||||
|
|
||||||
/* storing current config line */
|
|
||||||
cur = calloc(1, sizeof(Htaccess) + (p-p0));
|
|
||||||
if(cur) {
|
|
||||||
if(*(colon-1) == '/' && (colon-1) != p0)
|
|
||||||
colon[-1] = 0; // remove last / from /path/
|
|
||||||
cur->after_colon = strcpy(cur->before_colon, p0);
|
|
||||||
cur->after_colon += (colon-p0);
|
|
||||||
*cur->after_colon++ = 0;
|
|
||||||
|
|
||||||
if(prev == NULL) {
|
|
||||||
/* first line */
|
/* first line */
|
||||||
config->Httpd_conf_parsed = prev = cur;
|
config->auth = prev = cur;
|
||||||
} else {
|
} else {
|
||||||
|
/* sort path, if current lenght eq or bigger then move up */
|
||||||
|
Htaccess *prev_hti = config->auth;
|
||||||
|
int l = strlen(cf);
|
||||||
|
Htaccess *hti;
|
||||||
|
|
||||||
|
for(hti = prev_hti; hti; hti = hti->next) {
|
||||||
|
if(l >= strlen(hti->before_colon)) {
|
||||||
|
/* insert before hti */
|
||||||
|
cur->next = hti;
|
||||||
|
if(prev_hti != hti) {
|
||||||
|
prev_hti->next = cur;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* insert as top */
|
||||||
|
config->auth = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(prev_hti != hti)
|
||||||
|
prev_hti = prev_hti->next;
|
||||||
|
}
|
||||||
|
if(!hti) { /* not inserted, add to bottom */
|
||||||
prev->next = cur;
|
prev->next = cur;
|
||||||
prev = cur;
|
prev = cur;
|
||||||
}
|
}
|
||||||
n++;
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if(n > 1) {
|
|
||||||
/* sorting conf lines */
|
|
||||||
Htaccess ** pcur; /* array for qsort */
|
|
||||||
|
|
||||||
prev = config->Httpd_conf_parsed;
|
|
||||||
pcur = alloca((n + 1) * sizeof(Htaccess *));
|
|
||||||
if(pcur == NULL) {
|
|
||||||
if(flag == FIRST_PARSE)
|
|
||||||
bb_error_msg_and_die(bb_msg_memory_exhausted);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
n = 0;
|
|
||||||
for(cur = prev; cur; cur = cur->next)
|
|
||||||
pcur[n++] = cur;
|
|
||||||
pcur[n] = NULL;
|
|
||||||
|
|
||||||
qsort(pcur, n, sizeof(Htaccess *), conf_sort);
|
|
||||||
|
|
||||||
/* storing sorted config */
|
|
||||||
config->Httpd_conf_parsed = *pcur;
|
|
||||||
for(cur = *pcur; cur; cur = cur->next) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
bb_error_msg("%s: %s:%s", cf, cur->before_colon, cur->after_colon);
|
|
||||||
#endif
|
|
||||||
cur->next = *++pcur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
||||||
@ -602,7 +562,6 @@ static char *encodeString(const char *string)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_FEATURE_HTTPD_ENCODE_URL_STR */
|
#endif /* CONFIG_FEATURE_HTTPD_ENCODE_URL_STR */
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
> $Function: decodeString()
|
> $Function: decodeString()
|
||||||
@ -615,20 +574,21 @@ 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 require decode '+' as ' ' for CGI
|
||||||
*
|
*
|
||||||
* $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 *string)
|
static char *decodeString(char *string, int flag_plus_to_space)
|
||||||
{
|
{
|
||||||
/* note that decoded string is always shorter than original */
|
/* note that decoded string is always shorter than original */
|
||||||
char *orig = string;
|
char *orig = string;
|
||||||
char *ptr = string;
|
char *ptr = string;
|
||||||
while (*ptr)
|
while (*ptr)
|
||||||
{
|
{
|
||||||
if (*ptr == '+') { *string++ = ' '; ptr++; }
|
if (*ptr == '+' && flag_plus_to_space) { *string++ = ' '; ptr++; }
|
||||||
else if (*ptr != '%') *string++ = *ptr++;
|
else if (*ptr != '%') *string++ = *ptr++;
|
||||||
else {
|
else {
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
@ -640,7 +600,6 @@ static char *decodeString(char *string)
|
|||||||
*string = '\0';
|
*string = '\0';
|
||||||
return orig;
|
return orig;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FEATURE_HTTPD_DECODE_URL_STR */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_CGI
|
#ifdef CONFIG_FEATURE_HTTPD_CGI
|
||||||
@ -730,7 +689,7 @@ static void addEnvCgi(const char *pargs)
|
|||||||
args = strchr(value, '&');
|
args = strchr(value, '&');
|
||||||
if (args)
|
if (args)
|
||||||
*args++ = 0;
|
*args++ = 0;
|
||||||
addEnv("CGI", name, decodeString(value));
|
addEnv("CGI", name, decodeString(value, 1));
|
||||||
}
|
}
|
||||||
free(memargs);
|
free(memargs);
|
||||||
}
|
}
|
||||||
@ -758,27 +717,38 @@ static void addEnvCgi(const char *pargs)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void decodeBase64(char *Data)
|
static void decodeBase64(char *Data)
|
||||||
{
|
{
|
||||||
int i = 0;
|
|
||||||
static const char base64ToBin[] =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
|
|
||||||
const unsigned char *in = Data;
|
const unsigned char *in = Data;
|
||||||
// The decoded size will be at most 3/4 the size of the encoded
|
// The decoded size will be at most 3/4 the size of the encoded
|
||||||
unsigned long ch = 0;
|
unsigned long ch = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (*in) {
|
while (*in) {
|
||||||
unsigned char conv = 0;
|
int t = *in++;
|
||||||
|
|
||||||
while (*in) {
|
switch(t) {
|
||||||
const char *p64;
|
case '+':
|
||||||
|
t = 62;
|
||||||
p64 = strchr(base64ToBin, *in++);
|
|
||||||
if(p64 == NULL)
|
|
||||||
continue;
|
|
||||||
conv = (p64 - base64ToBin);
|
|
||||||
break;
|
break;
|
||||||
|
case '/':
|
||||||
|
t = 63;
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
t = 0;
|
||||||
|
break;
|
||||||
|
case 'A' ... 'Z':
|
||||||
|
t = t - 'A';
|
||||||
|
break;
|
||||||
|
case 'a' ... 'z':
|
||||||
|
t = t - 'a' + 26;
|
||||||
|
break;
|
||||||
|
case '0' ... '9':
|
||||||
|
t = t - '0' + 52;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ch = (ch << 6) | conv;
|
ch = (ch << 6) | t;
|
||||||
i++;
|
i++;
|
||||||
if (i == 4) {
|
if (i == 4) {
|
||||||
*Data++ = (char) (ch >> 16);
|
*Data++ = (char) (ch >> 16);
|
||||||
@ -1203,7 +1173,7 @@ static int sendFile(const char *url, char *buf)
|
|||||||
if (suffix) {
|
if (suffix) {
|
||||||
Htaccess * cur;
|
Htaccess * cur;
|
||||||
|
|
||||||
for (cur = config->Httpd_conf_parsed; cur; cur = cur->next) {
|
for (cur = config->mime_a; cur; cur = cur->next) {
|
||||||
if(strcmp(cur->before_colon, suffix) == 0) {
|
if(strcmp(cur->before_colon, suffix) == 0) {
|
||||||
config->found_mime_type = cur->after_colon;
|
config->found_mime_type = cur->after_colon;
|
||||||
break;
|
break;
|
||||||
@ -1255,53 +1225,32 @@ static int sendFile(const char *url, char *buf)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
static int checkPerm(const char *path, const char *request)
|
static int checkPerm(const char *path, const char *request)
|
||||||
{
|
{
|
||||||
Htaccess * cur;
|
Htaccess * cur;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
const char *p0;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
|
||||||
int ipaddr = path == NULL;
|
int ipaddr = path == NULL;
|
||||||
const char *prev = NULL;
|
const char *prev = NULL;
|
||||||
#else
|
|
||||||
# define ipaddr 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This could stand some work */
|
/* This could stand some work */
|
||||||
for (cur = config->Httpd_conf_parsed; cur; cur = cur->next) {
|
for (cur = ipaddr ? config->ip_a_d : config->auth; cur; cur = cur->next) {
|
||||||
const char *p0 = cur->before_colon;
|
p0 = cur->before_colon;
|
||||||
|
|
||||||
if(*p0 == 'A' || *p0 == 'D') {
|
|
||||||
if(!ipaddr)
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if(ipaddr)
|
|
||||||
continue;
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
|
|
||||||
if(*p0 == '.')
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
|
||||||
if(prev != NULL && strcmp(prev, p0) != 0)
|
if(prev != NULL && strcmp(prev, p0) != 0)
|
||||||
continue; /* find next identical */
|
continue; /* find next identical */
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
p = cur->after_colon;
|
p = cur->after_colon;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (config->debugHttpd)
|
if (config->debugHttpd)
|
||||||
fprintf(stderr,"checkPerm: '%s' ? '%s'\n",
|
fprintf(stderr,"checkPerm: '%s' ? '%s'\n",
|
||||||
(ipaddr ? p : p0), request);
|
(ipaddr ? (*p ? p : "*") : p0), request);
|
||||||
#endif
|
#endif
|
||||||
if(ipaddr) {
|
if(ipaddr) {
|
||||||
if(strncmp(p, request, strlen(p)) != 0)
|
if(strncmp(p, request, strlen(p)) != 0)
|
||||||
continue;
|
continue;
|
||||||
return *p0 == 'A'; /* Allow/Deny */
|
return *p0 == 'A'; /* Allow/Deny */
|
||||||
|
} else {
|
||||||
}
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
|
||||||
else {
|
|
||||||
int l = strlen(p0);
|
int l = strlen(p0);
|
||||||
|
|
||||||
if(strncmp(p0, path, l) == 0 &&
|
if(strncmp(p0, path, l) == 0 &&
|
||||||
@ -1313,16 +1262,34 @@ static int checkPerm(const char *path, const char *request)
|
|||||||
prev = p0;
|
prev = p0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} /* for */
|
} /* for */
|
||||||
|
|
||||||
#ifndef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
return prev == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ifndef CONFIG_FEATURE_HTTPD_BASIC_AUTH */
|
||||||
|
static int checkPermIP(const char *request)
|
||||||
|
{
|
||||||
|
Htaccess * cur;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
/* This could stand some work */
|
||||||
|
for (cur = config->ip_a_d; cur; cur = cur->next) {
|
||||||
|
p = cur->after_colon;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (config->debugHttpd)
|
||||||
|
fprintf(stderr, "checkPerm: '%s' ? '%s'\n",
|
||||||
|
(*p ? p : "*"), request);
|
||||||
|
#endif
|
||||||
|
if(strncmp(p, request, strlen(p)) == 0)
|
||||||
|
return *cur->before_colon == 'A'; /* Allow/Deny */
|
||||||
|
}
|
||||||
|
|
||||||
/* if uncofigured, return 1 - access from all */
|
/* if uncofigured, return 1 - access from all */
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
|
||||||
return prev == NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#define checkPerm(null, request) checkPermIP(request)
|
||||||
|
#endif /* CONFIG_FEATURE_HTTPD_BASIC_AUTH */
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1347,6 +1314,7 @@ static void handleIncoming(void)
|
|||||||
#endif
|
#endif
|
||||||
char *test;
|
char *test;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
int ip_allowed;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
int credentials = -1; /* if not requred this is Ok */
|
int credentials = -1; /* if not requred this is Ok */
|
||||||
@ -1382,6 +1350,7 @@ BAD_REQUEST:
|
|||||||
*purl = ' ';
|
*purl = ' ';
|
||||||
count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank);
|
count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank);
|
||||||
|
|
||||||
|
decodeString(buf, 0);
|
||||||
if (count < 1 || buf[0] != '/') {
|
if (count < 1 || buf[0] != '/') {
|
||||||
/* Garbled request/URL */
|
/* Garbled request/URL */
|
||||||
goto BAD_REQUEST;
|
goto BAD_REQUEST;
|
||||||
@ -1394,13 +1363,11 @@ BAD_REQUEST:
|
|||||||
strcpy(url, buf);
|
strcpy(url, buf);
|
||||||
/* extract url args if present */
|
/* extract url args if present */
|
||||||
urlArgs = strchr(url, '?');
|
urlArgs = strchr(url, '?');
|
||||||
if (urlArgs) {
|
if (urlArgs)
|
||||||
*urlArgs++ = 0; /* next code can set '/' to this pointer,
|
*urlArgs++ = 0;
|
||||||
but CGI script can`t be a directory */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* algorithm stolen from libbb bb_simplify_path(),
|
/* algorithm stolen from libbb bb_simplify_path(),
|
||||||
but don`t strdup and reducing trailing slash */
|
but don`t strdup and reducing trailing slash and protect out root */
|
||||||
purl = test = url;
|
purl = test = url;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -1441,12 +1408,14 @@ BAD_REQUEST:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
test = url;
|
test = url;
|
||||||
while((test = strchr( test + 1, '/' )) != NULL) {
|
ip_allowed = checkPerm(NULL, config->rmt_ip);
|
||||||
|
while(ip_allowed && (test = strchr( test + 1, '/' )) != NULL) {
|
||||||
/* have path1/path2 */
|
/* have path1/path2 */
|
||||||
*test = '\0';
|
*test = '\0';
|
||||||
if( is_directory(url + 1, 1, &sb) ) {
|
if( is_directory(url + 1, 1, &sb) ) {
|
||||||
/* may be having subdir config */
|
/* may be having subdir config */
|
||||||
parse_conf(url + 1, SUBDIR_PARSE);
|
parse_conf(url + 1, SUBDIR_PARSE);
|
||||||
|
ip_allowed = checkPerm(NULL, config->rmt_ip);
|
||||||
}
|
}
|
||||||
*test = '/';
|
*test = '/';
|
||||||
}
|
}
|
||||||
@ -1490,8 +1459,7 @@ BAD_REQUEST:
|
|||||||
} /* while extra header reading */
|
} /* while extra header reading */
|
||||||
|
|
||||||
|
|
||||||
if (strcmp(strrchr(url, '/') + 1, httpd_conf) == 0 ||
|
if (strcmp(strrchr(url, '/') + 1, httpd_conf) == 0 || ip_allowed == 0) {
|
||||||
checkPerm(NULL, config->rmt_ip) == 0) {
|
|
||||||
/* protect listing [/path]/httpd_conf or IP deny */
|
/* protect listing [/path]/httpd_conf or IP deny */
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_CGI
|
#ifdef CONFIG_FEATURE_HTTPD_CGI
|
||||||
FORBIDDEN: /* protect listing /cgi-bin */
|
FORBIDDEN: /* protect listing /cgi-bin */
|
||||||
@ -1525,8 +1493,8 @@ FORBIDDEN: /* protect listing /cgi-bin */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(test, "cgi-bin", 7) == 0) {
|
if (strncmp(test, "cgi-bin", 7) == 0) {
|
||||||
if(test[7] == 0 || (test[7] == '/' && test[8] == 0))
|
if(test[7] == '/' && test[8] == 0)
|
||||||
goto FORBIDDEN; // protect listing cgi-bin
|
goto FORBIDDEN; // protect listing cgi-bin/
|
||||||
sendCgi(url, prequest, urlArgs, body, length, cookie);
|
sendCgi(url, prequest, urlArgs, body, length, cookie);
|
||||||
} else {
|
} else {
|
||||||
if (prequest != request_GET)
|
if (prequest != request_GET)
|
||||||
@ -1587,7 +1555,6 @@ FORBIDDEN: /* protect listing /cgi-bin */
|
|||||||
static int miniHttpd(int server)
|
static int miniHttpd(int server)
|
||||||
{
|
{
|
||||||
fd_set readfd, portfd;
|
fd_set readfd, portfd;
|
||||||
int nfound;
|
|
||||||
|
|
||||||
FD_ZERO(&portfd);
|
FD_ZERO(&portfd);
|
||||||
FD_SET(server, &portfd);
|
FD_SET(server, &portfd);
|
||||||
@ -1597,16 +1564,7 @@ static int miniHttpd(int server)
|
|||||||
readfd = portfd;
|
readfd = portfd;
|
||||||
|
|
||||||
/* Now wait INDEFINATELY on the set of sockets! */
|
/* Now wait INDEFINATELY on the set of sockets! */
|
||||||
nfound = select(server + 1, &readfd, 0, 0, 0);
|
if (select(server + 1, &readfd, 0, 0, 0) > 0) {
|
||||||
|
|
||||||
switch (nfound) {
|
|
||||||
case 0:
|
|
||||||
/* select timeout error! */
|
|
||||||
break ;
|
|
||||||
case -1:
|
|
||||||
/* select error */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (FD_ISSET(server, &readfd)) {
|
if (FD_ISSET(server, &readfd)) {
|
||||||
int on;
|
int on;
|
||||||
struct sockaddr_in fromAddr;
|
struct sockaddr_in fromAddr;
|
||||||
@ -1639,6 +1597,10 @@ static int miniHttpd(int server)
|
|||||||
|
|
||||||
if (config->debugHttpd || fork() == 0) {
|
if (config->debugHttpd || fork() == 0) {
|
||||||
/* This is the spawned thread */
|
/* This is the spawned thread */
|
||||||
|
#ifdef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
|
||||||
|
/* protect reload config, may be confuse checking */
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
#endif
|
||||||
handleIncoming();
|
handleIncoming();
|
||||||
if(!config->debugHttpd)
|
if(!config->debugHttpd)
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -1682,7 +1644,7 @@ static void sighup_handler(int sig)
|
|||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_RESTART;
|
sa.sa_flags = SA_RESTART;
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
sigaction(SIGHUP, &sa, NULL);
|
||||||
parse_conf(default_patch_httpd_conf,
|
parse_conf(default_path_httpd_conf,
|
||||||
sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE);
|
sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1716,16 +1678,13 @@ int httpd_main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* check if user supplied a port number */
|
/* check if user supplied a port number */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = getopt( argc, argv, "c:h:"
|
int c = getopt( argc, argv, "c:d:h:"
|
||||||
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
||||||
"p:v"
|
"p:v"
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
||||||
"e:"
|
"e:"
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
|
|
||||||
"d:"
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
|
||||||
"r:"
|
"r:"
|
||||||
#endif
|
#endif
|
||||||
@ -1751,11 +1710,9 @@ int httpd_main(int argc, char *argv[])
|
|||||||
bb_error_msg_and_die("invalid %s for -p", optarg);
|
bb_error_msg_and_die("invalid %s for -p", optarg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_DECODE_URL_STR
|
|
||||||
case 'd':
|
case 'd':
|
||||||
printf("%s", decodeString(optarg));
|
printf("%s", decodeString(optarg, 1));
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
|
||||||
case 'e':
|
case 'e':
|
||||||
printf("%s", encodeString(optarg));
|
printf("%s", encodeString(optarg));
|
||||||
@ -1803,7 +1760,7 @@ int httpd_main(int argc, char *argv[])
|
|||||||
#ifdef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
|
#ifdef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
|
||||||
sighup_handler(0);
|
sighup_handler(0);
|
||||||
#else
|
#else
|
||||||
parse_conf(default_patch_httpd_conf, FIRST_PARSE);
|
parse_conf(default_path_httpd_conf, FIRST_PARSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
|
||||||
|
Loading…
Reference in New Issue
Block a user