aboutsummaryrefslogtreecommitdiff
path: root/networking/httpd.c
diff options
context:
space:
mode:
authorSergey Ponomarev <stokito@gmail.com>2020-08-16 14:58:31 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2020-08-16 14:58:31 +0200
commita949399d178f7b052ada2099c62621736eafce44 (patch)
treebc0fb58ad8a919de24b6633993b441cc2a14aa6b /networking/httpd.c
parent4864a685967bd098307a0d64293b5de1fc5f8210 (diff)
downloadbusybox-w32-a949399d178f7b052ada2099c62621736eafce44.tar.gz
busybox-w32-a949399d178f7b052ada2099c62621736eafce44.tar.bz2
busybox-w32-a949399d178f7b052ada2099c62621736eafce44.zip
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>
Diffstat (limited to 'networking/httpd.c')
-rw-r--r--networking/httpd.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 0297cf9ec..2946b2a54 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -245,6 +245,13 @@
245//config: help 245//config: help
246//config: RFC2616 says that server MUST add Date header to response. 246//config: RFC2616 says that server MUST add Date header to response.
247//config: But it is almost useless and can be omitted. 247//config: But it is almost useless and can be omitted.
248//config:
249//config:config FEATURE_HTTPD_ACL_IP
250//config: bool "ACL IP"
251//config: default y
252//config: depends on HTTPD
253//config: help
254//config: Support IP deny/allow rules
248 255
249//applet:IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) 256//applet:IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP))
250 257
@@ -314,6 +321,7 @@ typedef struct Htaccess {
314 char before_colon[1]; /* really bigger, must be last */ 321 char before_colon[1]; /* really bigger, must be last */
315} Htaccess; 322} Htaccess;
316 323
324#if ENABLE_FEATURE_HTTPD_ACL_IP
317/* Must have "next" as a first member */ 325/* Must have "next" as a first member */
318typedef struct Htaccess_IP { 326typedef struct Htaccess_IP {
319 struct Htaccess_IP *next; 327 struct Htaccess_IP *next;
@@ -321,6 +329,7 @@ typedef struct Htaccess_IP {
321 unsigned mask; 329 unsigned mask;
322 int allow_deny; 330 int allow_deny;
323} Htaccess_IP; 331} Htaccess_IP;
332#endif
324 333
325/* Must have "next" as a first member */ 334/* Must have "next" as a first member */
326typedef struct Htaccess_Proxy { 335typedef struct Htaccess_Proxy {
@@ -449,7 +458,9 @@ struct globals {
449 458
450 const char *found_mime_type; 459 const char *found_mime_type;
451 const char *found_moved_temporarily; 460 const char *found_moved_temporarily;
461#if ENABLE_FEATURE_HTTPD_ACL_IP
452 Htaccess_IP *ip_a_d; /* config allow/deny lines */ 462 Htaccess_IP *ip_a_d; /* config allow/deny lines */
463#endif
453 464
454 IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) 465 IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;)
455 IF_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;) 466 IF_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;)
@@ -499,7 +510,6 @@ struct globals {
499#define found_mime_type (G.found_mime_type ) 510#define found_mime_type (G.found_mime_type )
500#define found_moved_temporarily (G.found_moved_temporarily) 511#define found_moved_temporarily (G.found_moved_temporarily)
501#define last_mod (G.last_mod ) 512#define last_mod (G.last_mod )
502#define ip_a_d (G.ip_a_d )
503#define g_realm (G.g_realm ) 513#define g_realm (G.g_realm )
504#define remoteuser (G.remoteuser ) 514#define remoteuser (G.remoteuser )
505#define file_size (G.file_size ) 515#define file_size (G.file_size )
@@ -560,11 +570,14 @@ static ALWAYS_INLINE void free_Htaccess_list(Htaccess **pptr)
560 free_llist((has_next_ptr**)pptr); 570 free_llist((has_next_ptr**)pptr);
561} 571}
562 572
573#if ENABLE_FEATURE_HTTPD_ACL_IP
563static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr) 574static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr)
564{ 575{
565 free_llist((has_next_ptr**)pptr); 576 free_llist((has_next_ptr**)pptr);
566} 577}
578#endif
567 579
580#if ENABLE_FEATURE_HTTPD_ACL_IP
568/* Returns presumed mask width in bits or < 0 on error. 581/* Returns presumed mask width in bits or < 0 on error.
569 * Updates strp, stores IP at provided pointer */ 582 * Updates strp, stores IP at provided pointer */
570static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc) 583static 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)
649 *maskp = (uint32_t)(~mask); 662 *maskp = (uint32_t)(~mask);
650 return 0; 663 return 0;
651} 664}
665#endif
652 666
653/* 667/*
654 * Parse configuration file into in-memory linked list. 668 * Parse configuration file into in-memory linked list.
@@ -678,7 +692,9 @@ static void parse_conf(const char *path, int flag)
678 char buf[160]; 692 char buf[160];
679 693
680 /* discard old rules */ 694 /* discard old rules */
681 free_Htaccess_IP_list(&ip_a_d); 695#if ENABLE_FEATURE_HTTPD_ACL_IP
696 free_Htaccess_IP_list(&G.ip_a_d);
697#endif
682 flg_deny_all = 0; 698 flg_deny_all = 0;
683 /* retain previous auth and mime config only for subdir parse */ 699 /* retain previous auth and mime config only for subdir parse */
684 if (flag != SUBDIR_PARSE) { 700 if (flag != SUBDIR_PARSE) {
@@ -783,6 +799,7 @@ static void parse_conf(const char *path, int flag)
783 continue; 799 continue;
784 } 800 }
785 801
802#if ENABLE_FEATURE_HTTPD_ACL_IP
786 if (ch == 'A' || ch == 'D') { 803 if (ch == 'A' || ch == 'D') {
787 Htaccess_IP *pip; 804 Htaccess_IP *pip;
788 805
@@ -804,13 +821,13 @@ static void parse_conf(const char *path, int flag)
804 pip->allow_deny = ch; 821 pip->allow_deny = ch;
805 if (ch == 'D') { 822 if (ch == 'D') {
806 /* Deny:from_IP - prepend */ 823 /* Deny:from_IP - prepend */
807 pip->next = ip_a_d; 824 pip->next = G.ip_a_d;
808 ip_a_d = pip; 825 G.ip_a_d = pip;
809 } else { 826 } else {
810 /* A:from_IP - append (thus all D's precedes A's) */ 827 /* A:from_IP - append (thus all D's precedes A's) */
811 Htaccess_IP *prev_IP = ip_a_d; 828 Htaccess_IP *prev_IP = G.ip_a_d;
812 if (prev_IP == NULL) { 829 if (prev_IP == NULL) {
813 ip_a_d = pip; 830 G.ip_a_d = pip;
814 } else { 831 } else {
815 while (prev_IP->next) 832 while (prev_IP->next)
816 prev_IP = prev_IP->next; 833 prev_IP = prev_IP->next;
@@ -819,6 +836,7 @@ static void parse_conf(const char *path, int flag)
819 } 836 }
820 continue; 837 continue;
821 } 838 }
839#endif
822 840
823#if ENABLE_FEATURE_HTTPD_ERROR_PAGES 841#if ENABLE_FEATURE_HTTPD_ERROR_PAGES
824 if (flag == FIRST_PARSE && ch == 'E') { 842 if (flag == FIRST_PARSE && ch == 'E') {
@@ -1920,11 +1938,12 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1920 log_and_exit(); 1938 log_and_exit();
1921} 1939}
1922 1940
1941#if ENABLE_FEATURE_HTTPD_ACL_IP
1923static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip) 1942static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip)
1924{ 1943{
1925 Htaccess_IP *cur; 1944 Htaccess_IP *cur;
1926 1945
1927 for (cur = ip_a_d; cur; cur = cur->next) { 1946 for (cur = G.ip_a_d; cur; cur = cur->next) {
1928#if DEBUG 1947#if DEBUG
1929 fprintf(stderr, 1948 fprintf(stderr,
1930 "checkPermIP: '%s' ? '%u.%u.%u.%u/%u.%u.%u.%u'\n", 1949 "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)
1949 if (flg_deny_all) /* depends on whether we saw "D:*" */ 1968 if (flg_deny_all) /* depends on whether we saw "D:*" */
1950 send_headers_and_exit(HTTP_FORBIDDEN); 1969 send_headers_and_exit(HTTP_FORBIDDEN);
1951} 1970}
1971#else
1972# define if_ip_denied_send_HTTP_FORBIDDEN_and_exit(arg) ((void)0)
1973#endif
1952 1974
1953#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 1975#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
1954 1976
@@ -2184,7 +2206,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2184 char *urlcopy; 2206 char *urlcopy;
2185 char *urlp; 2207 char *urlp;
2186 char *tptr; 2208 char *tptr;
2209#if ENABLE_FEATURE_HTTPD_ACL_IP
2187 unsigned remote_ip; 2210 unsigned remote_ip;
2211#endif
2188#if ENABLE_FEATURE_HTTPD_CGI 2212#if ENABLE_FEATURE_HTTPD_CGI
2189 unsigned total_headers_len; 2213 unsigned total_headers_len;
2190#endif 2214#endif
@@ -2206,17 +2230,6 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2206 * (IOW, server process doesn't need to waste 8k) */ 2230 * (IOW, server process doesn't need to waste 8k) */
2207 iobuf = xmalloc(IOBUF_SIZE); 2231 iobuf = xmalloc(IOBUF_SIZE);
2208 2232
2209 remote_ip = 0;
2210 if (fromAddr->u.sa.sa_family == AF_INET) {
2211 remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr);
2212 }
2213#if ENABLE_FEATURE_IPV6
2214 if (fromAddr->u.sa.sa_family == AF_INET6
2215 && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0
2216 && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0
2217 && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff)
2218 remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]);
2219#endif
2220 if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) { 2233 if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) {
2221 /* NB: can be NULL (user runs httpd -i by hand?) */ 2234 /* NB: can be NULL (user runs httpd -i by hand?) */
2222 rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr->u.sa); 2235 rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr->u.sa);
@@ -2228,7 +2241,20 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2228 if (verbose > 2) 2241 if (verbose > 2)
2229 bb_simple_error_msg("connected"); 2242 bb_simple_error_msg("connected");
2230 } 2243 }
2244#if ENABLE_FEATURE_HTTPD_ACL_IP
2245 remote_ip = 0;
2246 if (fromAddr->u.sa.sa_family == AF_INET) {
2247 remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr);
2248 }
2249# if ENABLE_FEATURE_IPV6
2250 if (fromAddr->u.sa.sa_family == AF_INET6
2251 && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0
2252 && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0
2253 && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff)
2254 remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]);
2255# endif
2231 if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip); 2256 if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip);
2257#endif
2232 2258
2233 /* Install timeout handler. get_line() needs it. */ 2259 /* Install timeout handler. get_line() needs it. */
2234 signal(SIGALRM, send_REQUEST_TIMEOUT_and_exit); 2260 signal(SIGALRM, send_REQUEST_TIMEOUT_and_exit);