httpd: Make Deny/Allow by IP config support optional
When disabled: function old new delta if_ip_denied_send_HTTP_FORBIDDEN_and_exit 52 - -52 handle_incoming_and_exit 2201 2097 -104 scan_ip 170 - -170 parse_conf 1365 1065 -300 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 0/2 up/down: 0/-626) Total: -626 bytes Signed-off-by: Sergey Ponomarev <stokito@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
				
					committed by
					
						
						Denys Vlasenko
					
				
			
			
				
	
			
			
			
						parent
						
							4864a68596
						
					
				
				
					commit
					a949399d17
				
			@@ -245,6 +245,13 @@
 | 
			
		||||
//config:	help
 | 
			
		||||
//config:	RFC2616 says that server MUST add Date header to response.
 | 
			
		||||
//config:	But it is almost useless and can be omitted.
 | 
			
		||||
//config:
 | 
			
		||||
//config:config FEATURE_HTTPD_ACL_IP
 | 
			
		||||
//config:	bool "ACL IP"
 | 
			
		||||
//config:	default y
 | 
			
		||||
//config:	depends on HTTPD
 | 
			
		||||
//config:	help
 | 
			
		||||
//config:	Support IP deny/allow rules
 | 
			
		||||
 | 
			
		||||
//applet:IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP))
 | 
			
		||||
 | 
			
		||||
@@ -314,6 +321,7 @@ typedef struct Htaccess {
 | 
			
		||||
	char before_colon[1];  /* really bigger, must be last */
 | 
			
		||||
} Htaccess;
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
/* Must have "next" as a first member */
 | 
			
		||||
typedef struct Htaccess_IP {
 | 
			
		||||
	struct Htaccess_IP *next;
 | 
			
		||||
@@ -321,6 +329,7 @@ typedef struct Htaccess_IP {
 | 
			
		||||
	unsigned mask;
 | 
			
		||||
	int allow_deny;
 | 
			
		||||
} Htaccess_IP;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Must have "next" as a first member */
 | 
			
		||||
typedef struct Htaccess_Proxy {
 | 
			
		||||
@@ -449,7 +458,9 @@ struct globals {
 | 
			
		||||
 | 
			
		||||
	const char *found_mime_type;
 | 
			
		||||
	const char *found_moved_temporarily;
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
	Htaccess_IP *ip_a_d;    /* config allow/deny lines */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;)
 | 
			
		||||
	IF_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;)
 | 
			
		||||
@@ -499,7 +510,6 @@ struct globals {
 | 
			
		||||
#define found_mime_type   (G.found_mime_type  )
 | 
			
		||||
#define found_moved_temporarily (G.found_moved_temporarily)
 | 
			
		||||
#define last_mod          (G.last_mod         )
 | 
			
		||||
#define ip_a_d            (G.ip_a_d           )
 | 
			
		||||
#define g_realm           (G.g_realm          )
 | 
			
		||||
#define remoteuser        (G.remoteuser       )
 | 
			
		||||
#define file_size         (G.file_size        )
 | 
			
		||||
@@ -560,11 +570,14 @@ static ALWAYS_INLINE void free_Htaccess_list(Htaccess **pptr)
 | 
			
		||||
	free_llist((has_next_ptr**)pptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr)
 | 
			
		||||
{
 | 
			
		||||
	free_llist((has_next_ptr**)pptr);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
/* Returns presumed mask width in bits or < 0 on error.
 | 
			
		||||
 * Updates strp, stores IP at provided pointer */
 | 
			
		||||
static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc)
 | 
			
		||||
@@ -649,6 +662,7 @@ static int scan_ip_mask(const char *str, unsigned *ipp, unsigned *maskp)
 | 
			
		||||
	*maskp = (uint32_t)(~mask);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Parse configuration file into in-memory linked list.
 | 
			
		||||
@@ -678,7 +692,9 @@ static void parse_conf(const char *path, int flag)
 | 
			
		||||
	char buf[160];
 | 
			
		||||
 | 
			
		||||
	/* discard old rules */
 | 
			
		||||
	free_Htaccess_IP_list(&ip_a_d);
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
	free_Htaccess_IP_list(&G.ip_a_d);
 | 
			
		||||
#endif
 | 
			
		||||
	flg_deny_all = 0;
 | 
			
		||||
	/* retain previous auth and mime config only for subdir parse */
 | 
			
		||||
	if (flag != SUBDIR_PARSE) {
 | 
			
		||||
@@ -783,6 +799,7 @@ static void parse_conf(const char *path, int flag)
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
		if (ch == 'A' || ch == 'D') {
 | 
			
		||||
			Htaccess_IP *pip;
 | 
			
		||||
 | 
			
		||||
@@ -804,13 +821,13 @@ static void parse_conf(const char *path, int flag)
 | 
			
		||||
			pip->allow_deny = ch;
 | 
			
		||||
			if (ch == 'D') {
 | 
			
		||||
				/* Deny:from_IP - prepend */
 | 
			
		||||
				pip->next = ip_a_d;
 | 
			
		||||
				ip_a_d = pip;
 | 
			
		||||
				pip->next = G.ip_a_d;
 | 
			
		||||
				G.ip_a_d = pip;
 | 
			
		||||
			} else {
 | 
			
		||||
				/* A:from_IP - append (thus all D's precedes A's) */
 | 
			
		||||
				Htaccess_IP *prev_IP = ip_a_d;
 | 
			
		||||
				Htaccess_IP *prev_IP = G.ip_a_d;
 | 
			
		||||
				if (prev_IP == NULL) {
 | 
			
		||||
					ip_a_d = pip;
 | 
			
		||||
					G.ip_a_d = pip;
 | 
			
		||||
				} else {
 | 
			
		||||
					while (prev_IP->next)
 | 
			
		||||
						prev_IP = prev_IP->next;
 | 
			
		||||
@@ -819,6 +836,7 @@ static void parse_conf(const char *path, int flag)
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ERROR_PAGES
 | 
			
		||||
		if (flag == FIRST_PARSE && ch == 'E') {
 | 
			
		||||
@@ -1920,11 +1938,12 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
 | 
			
		||||
	log_and_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip)
 | 
			
		||||
{
 | 
			
		||||
	Htaccess_IP *cur;
 | 
			
		||||
 | 
			
		||||
	for (cur = ip_a_d; cur; cur = cur->next) {
 | 
			
		||||
	for (cur = G.ip_a_d; cur; cur = cur->next) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
		fprintf(stderr,
 | 
			
		||||
			"checkPermIP: '%s' ? '%u.%u.%u.%u/%u.%u.%u.%u'\n",
 | 
			
		||||
@@ -1949,6 +1968,9 @@ static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip)
 | 
			
		||||
	if (flg_deny_all) /* depends on whether we saw "D:*" */
 | 
			
		||||
		send_headers_and_exit(HTTP_FORBIDDEN);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
# define if_ip_denied_send_HTTP_FORBIDDEN_and_exit(arg) ((void)0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
 | 
			
		||||
 | 
			
		||||
@@ -2184,7 +2206,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
 | 
			
		||||
	char *urlcopy;
 | 
			
		||||
	char *urlp;
 | 
			
		||||
	char *tptr;
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
	unsigned remote_ip;
 | 
			
		||||
#endif
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_CGI
 | 
			
		||||
	unsigned total_headers_len;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2206,17 +2230,6 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
 | 
			
		||||
	 * (IOW, server process doesn't need to waste 8k) */
 | 
			
		||||
	iobuf = xmalloc(IOBUF_SIZE);
 | 
			
		||||
 | 
			
		||||
	remote_ip = 0;
 | 
			
		||||
	if (fromAddr->u.sa.sa_family == AF_INET) {
 | 
			
		||||
		remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr);
 | 
			
		||||
	}
 | 
			
		||||
#if ENABLE_FEATURE_IPV6
 | 
			
		||||
	if (fromAddr->u.sa.sa_family == AF_INET6
 | 
			
		||||
	 && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0
 | 
			
		||||
	 && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0
 | 
			
		||||
	 && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff)
 | 
			
		||||
		remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]);
 | 
			
		||||
#endif
 | 
			
		||||
	if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) {
 | 
			
		||||
		/* NB: can be NULL (user runs httpd -i by hand?) */
 | 
			
		||||
		rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr->u.sa);
 | 
			
		||||
@@ -2228,7 +2241,20 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
 | 
			
		||||
		if (verbose > 2)
 | 
			
		||||
			bb_simple_error_msg("connected");
 | 
			
		||||
	}
 | 
			
		||||
#if ENABLE_FEATURE_HTTPD_ACL_IP
 | 
			
		||||
	remote_ip = 0;
 | 
			
		||||
	if (fromAddr->u.sa.sa_family == AF_INET) {
 | 
			
		||||
		remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr);
 | 
			
		||||
	}
 | 
			
		||||
# if ENABLE_FEATURE_IPV6
 | 
			
		||||
	if (fromAddr->u.sa.sa_family == AF_INET6
 | 
			
		||||
	 && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0
 | 
			
		||||
	 && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0
 | 
			
		||||
	 && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff)
 | 
			
		||||
		remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]);
 | 
			
		||||
# endif
 | 
			
		||||
	if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Install timeout handler. get_line() needs it. */
 | 
			
		||||
	signal(SIGALRM, send_REQUEST_TIMEOUT_and_exit);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user