aboutsummaryrefslogtreecommitdiff
path: root/networking/httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/httpd.c')
-rw-r--r--networking/httpd.c131
1 files changed, 51 insertions, 80 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 737b030a7..e125095f1 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -160,15 +160,8 @@ typedef struct {
160 Htaccess *mime_a; /* config mime types */ 160 Htaccess *mime_a; /* config mime types */
161#endif 161#endif
162 162
163#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
164 int server_socket; 163 int server_socket;
165 int accepted_socket; 164 int accepted_socket;
166# define a_c_r config->accepted_socket
167# define a_c_w config->accepted_socket
168#else
169# define a_c_r 0
170# define a_c_w 1
171#endif
172 volatile int alarm_signaled; 165 volatile int alarm_signaled;
173 166
174#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR 167#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
@@ -791,7 +784,6 @@ static void decodeBase64(char *Data)
791#endif 784#endif
792 785
793 786
794#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
795/**************************************************************************** 787/****************************************************************************
796 * 788 *
797 > $Function: openServer() 789 > $Function: openServer()
@@ -828,7 +820,6 @@ static int openServer(void)
828 signal(SIGCHLD, SIG_IGN); /* prevent zombie (defunct) processes */ 820 signal(SIGCHLD, SIG_IGN); /* prevent zombie (defunct) processes */
829 return fd; 821 return fd;
830} 822}
831#endif /* CONFIG_FEATURE_HTTPD_WITHOUT_INETD */
832 823
833/**************************************************************************** 824/****************************************************************************
834 * 825 *
@@ -905,7 +896,7 @@ static int sendHeaders(HttpResponseNum responseNum)
905#if DEBUG 896#if DEBUG
906 fprintf(stderr, "Headers: '%s'", buf); 897 fprintf(stderr, "Headers: '%s'", buf);
907#endif 898#endif
908 return full_write(a_c_w, buf, len); 899 return full_write(config->accepted_socket, buf, len);
909} 900}
910 901
911/**************************************************************************** 902/****************************************************************************
@@ -924,7 +915,7 @@ static int getLine(void)
924 int count = 0; 915 int count = 0;
925 char *buf = config->buf; 916 char *buf = config->buf;
926 917
927 while (read(a_c_r, buf + count, 1) == 1) { 918 while (read(config->accepted_socket, buf + count, 1) == 1) {
928 if (buf[count] == '\r') continue; 919 if (buf[count] == '\r') continue;
929 if (buf[count] == '\n') { 920 if (buf[count] == '\n') {
930 buf[count] = 0; 921 buf[count] = 0;
@@ -1106,9 +1097,8 @@ static int sendCgi(const char *url,
1106 } 1097 }
1107 } 1098 }
1108 } 1099 }
1109#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD 1100 /* send to stdout (even if we are not from inetd) */
1110 config->accepted_socket = 1; /* send to stdout */ 1101 config->accepted_socket = 1;
1111#endif
1112 sendHeaders(HTTP_NOT_FOUND); 1102 sendHeaders(HTTP_NOT_FOUND);
1113 _exit(242); 1103 _exit(242);
1114 } /* end child */ 1104 } /* end child */
@@ -1140,9 +1130,9 @@ static int sendCgi(const char *url,
1140 FD_SET(outFd, &writeSet); 1130 FD_SET(outFd, &writeSet);
1141 nfound = outFd > inFd ? outFd : inFd; 1131 nfound = outFd > inFd ? outFd : inFd;
1142 if (post_readed_size == 0) { 1132 if (post_readed_size == 0) {
1143 FD_SET(a_c_r, &readSet); 1133 FD_SET(config->accepted_socket, &readSet);
1144 if (nfound < a_c_r) 1134 if (nfound < config->accepted_socket)
1145 nfound = a_c_r; 1135 nfound = config->accepted_socket;
1146 } 1136 }
1147 /* Now wait on the set of sockets! */ 1137 /* Now wait on the set of sockets! */
1148 nfound = select(nfound + 1, &readSet, &writeSet, 0, NULL); 1138 nfound = select(nfound + 1, &readSet, &writeSet, 0, NULL);
@@ -1175,9 +1165,9 @@ static int sendCgi(const char *url,
1175 } else { 1165 } else {
1176 post_readed_size = post_readed_idx = bodyLen = 0; /* broken pipe to CGI */ 1166 post_readed_size = post_readed_idx = bodyLen = 0; /* broken pipe to CGI */
1177 } 1167 }
1178 } else if (bodyLen > 0 && post_readed_size == 0 && FD_ISSET(a_c_r, &readSet)) { 1168 } else if (bodyLen > 0 && post_readed_size == 0 && FD_ISSET(config->accepted_socket, &readSet)) {
1179 count = bodyLen > (int)sizeof(wbuf) ? (int)sizeof(wbuf) : bodyLen; 1169 count = bodyLen > (int)sizeof(wbuf) ? (int)sizeof(wbuf) : bodyLen;
1180 count = safe_read(a_c_r, wbuf, count); 1170 count = safe_read(config->accepted_socket, wbuf, count);
1181 if (count > 0) { 1171 if (count > 0) {
1182 post_readed_size += count; 1172 post_readed_size += count;
1183 bodyLen -= count; 1173 bodyLen -= count;
@@ -1186,7 +1176,7 @@ static int sendCgi(const char *url,
1186 } 1176 }
1187 } 1177 }
1188 if (FD_ISSET(inFd, &readSet)) { 1178 if (FD_ISSET(inFd, &readSet)) {
1189 int s = a_c_w; 1179 int s = config->accepted_socket;
1190 char *rbuf = config->buf; 1180 char *rbuf = config->buf;
1191 1181
1192#ifndef PIPE_BUF 1182#ifndef PIPE_BUF
@@ -1282,7 +1272,7 @@ static int sendFile(const char *url)
1282 1272
1283 sendHeaders(HTTP_OK); 1273 sendHeaders(HTTP_OK);
1284 while ((count = full_read(f, buf, MAX_MEMORY_BUFF)) > 0) { 1274 while ((count = full_read(f, buf, MAX_MEMORY_BUFF)) > 0) {
1285 if (full_write(a_c_w, buf, count) != count) 1275 if (full_write(config->accepted_socket, buf, count) != count)
1286 break; 1276 break;
1287 } 1277 }
1288 close(f); 1278 close(f);
@@ -1670,18 +1660,13 @@ FORBIDDEN: /* protect listing /cgi-bin */
1670 config->last_mod = sb.st_mtime; 1660 config->last_mod = sb.st_mtime;
1671 } 1661 }
1672 sendFile(test); 1662 sendFile(test);
1673#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
1674 /* unset if non inetd looped */
1675 config->ContentLength = -1; 1663 config->ContentLength = -1;
1676#endif
1677#if ENABLE_FEATURE_HTTPD_CGI 1664#if ENABLE_FEATURE_HTTPD_CGI
1678 } 1665 }
1679 } 1666 }
1680#endif 1667#endif
1681 } while (0); 1668 } while (0);
1682 1669
1683#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
1684/* from inetd don't looping: freeing, closing automatic from exit always */
1685# if DEBUG 1670# if DEBUG
1686 fprintf(stderr, "closing socket\n"); 1671 fprintf(stderr, "closing socket\n");
1687# endif 1672# endif
@@ -1689,27 +1674,25 @@ FORBIDDEN: /* protect listing /cgi-bin */
1689 free(cookie); 1674 free(cookie);
1690 free(content_type); 1675 free(content_type);
1691 free(config->referer); 1676 free(config->referer);
1692#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 1677# if ENABLE_FEATURE_HTTPD_BASIC_AUTH
1693 free(config->remoteuser); 1678 free(config->remoteuser);
1694#endif 1679# endif
1695# endif 1680# endif
1696#endif /* CONFIG_FEATURE_HTTPD_WITHOUT_INETD */ 1681 shutdown(config->accepted_socket, SHUT_WR);
1697 shutdown(a_c_w, SHUT_WR);
1698 1682
1699 /* Properly wait for remote to closed */ 1683 /* Properly wait for remote to closed */
1700 FD_ZERO(&s_fd); 1684 FD_ZERO(&s_fd);
1701 FD_SET(a_c_r, &s_fd); 1685 FD_SET(config->accepted_socket, &s_fd);
1702 1686
1703 do { 1687 do {
1704 tv.tv_sec = 2; 1688 tv.tv_sec = 2;
1705 tv.tv_usec = 0; 1689 tv.tv_usec = 0;
1706 retval = select(a_c_r + 1, &s_fd, NULL, NULL, &tv); 1690 retval = select(config->accepted_socket + 1, &s_fd, NULL, NULL, &tv);
1707 } while (retval > 0 && read(a_c_r, buf, sizeof(config->buf) > 0)); 1691 } while (retval > 0 && read(config->accepted_socket, buf, sizeof(config->buf) > 0));
1708 1692
1709 shutdown(a_c_r, SHUT_RD); 1693 shutdown(config->accepted_socket, SHUT_RD);
1710#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD 1694 /* In inetd case, we close fd 1 (stdout) here. We will exit soon anyway */
1711 close(config->accepted_socket); 1695 close(config->accepted_socket);
1712#endif /* CONFIG_FEATURE_HTTPD_WITHOUT_INETD */
1713} 1696}
1714 1697
1715/**************************************************************************** 1698/****************************************************************************
@@ -1727,7 +1710,6 @@ FORBIDDEN: /* protect listing /cgi-bin */
1727 * $Return: (int) . . . . Always 0. 1710 * $Return: (int) . . . . Always 0.
1728 * 1711 *
1729 ****************************************************************************/ 1712 ****************************************************************************/
1730#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
1731static int miniHttpd(int server) 1713static int miniHttpd(int server)
1732{ 1714{
1733 fd_set readfd, portfd; 1715 fd_set readfd, portfd;
@@ -1789,10 +1771,8 @@ static int miniHttpd(int server)
1789 return 0; 1771 return 0;
1790} 1772}
1791 1773
1792#else 1774/* from inetd */
1793 /* from inetd */ 1775static int miniHttpd_inetd(void)
1794
1795static int miniHttpd(void)
1796{ 1776{
1797 struct sockaddr_in fromAddrLen; 1777 struct sockaddr_in fromAddrLen;
1798 socklen_t sinlen = sizeof(struct sockaddr_in); 1778 socklen_t sinlen = sizeof(struct sockaddr_in);
@@ -1810,7 +1790,6 @@ static int miniHttpd(void)
1810 handleIncoming(); 1790 handleIncoming();
1811 return 0; 1791 return 0;
1812} 1792}
1813#endif /* CONFIG_FEATURE_HTTPD_WITHOUT_INETD */
1814 1793
1815#if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP 1794#if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
1816static void sighup_handler(int sig) 1795static void sighup_handler(int sig)
@@ -1834,7 +1813,9 @@ enum {
1834 USE_FEATURE_HTTPD_BASIC_AUTH( r_opt_realm ,) 1813 USE_FEATURE_HTTPD_BASIC_AUTH( r_opt_realm ,)
1835 USE_FEATURE_HTTPD_AUTH_MD5( m_opt_md5 ,) 1814 USE_FEATURE_HTTPD_AUTH_MD5( m_opt_md5 ,)
1836 USE_FEATURE_HTTPD_SETUID( u_opt_setuid ,) 1815 USE_FEATURE_HTTPD_SETUID( u_opt_setuid ,)
1837 USE_FEATURE_HTTPD_WITHOUT_INETD( p_opt_port ,) 1816 p_opt_port ,
1817 p_opt_inetd ,
1818 p_opt_foreground,
1838 OPT_CONFIG_FILE = 1 << c_opt_config_file, 1819 OPT_CONFIG_FILE = 1 << c_opt_config_file,
1839 OPT_DECODE_URL = 1 << d_opt_decode_url, 1820 OPT_DECODE_URL = 1 << d_opt_decode_url,
1840 OPT_HOME_HTTPD = 1 << h_opt_home_httpd, 1821 OPT_HOME_HTTPD = 1 << h_opt_home_httpd,
@@ -1842,7 +1823,9 @@ enum {
1842 OPT_REALM = USE_FEATURE_HTTPD_BASIC_AUTH( (1 << r_opt_realm )) + 0, 1823 OPT_REALM = USE_FEATURE_HTTPD_BASIC_AUTH( (1 << r_opt_realm )) + 0,
1843 OPT_MD5 = USE_FEATURE_HTTPD_AUTH_MD5( (1 << m_opt_md5 )) + 0, 1824 OPT_MD5 = USE_FEATURE_HTTPD_AUTH_MD5( (1 << m_opt_md5 )) + 0,
1844 OPT_SETUID = USE_FEATURE_HTTPD_SETUID( (1 << u_opt_setuid )) + 0, 1825 OPT_SETUID = USE_FEATURE_HTTPD_SETUID( (1 << u_opt_setuid )) + 0,
1845 OPT_PORT = USE_FEATURE_HTTPD_WITHOUT_INETD( (1 << p_opt_port )) + 0, 1826 OPT_PORT = 1 << p_opt_port,
1827 OPT_INETD = 1 << p_opt_inetd,
1828 OPT_FOREGROUND = 1 << p_opt_foreground,
1846}; 1829};
1847 1830
1848static const char httpd_opts[] = "c:d:h:" 1831static const char httpd_opts[] = "c:d:h:"
@@ -1850,7 +1833,7 @@ static const char httpd_opts[] = "c:d:h:"
1850 USE_FEATURE_HTTPD_BASIC_AUTH("r:") 1833 USE_FEATURE_HTTPD_BASIC_AUTH("r:")
1851 USE_FEATURE_HTTPD_AUTH_MD5("m:") 1834 USE_FEATURE_HTTPD_AUTH_MD5("m:")
1852 USE_FEATURE_HTTPD_SETUID("u:") 1835 USE_FEATURE_HTTPD_SETUID("u:")
1853 USE_FEATURE_HTTPD_WITHOUT_INETD("p:"); 1836 "p:if";
1854 1837
1855 1838
1856int httpd_main(int argc, char *argv[]) 1839int httpd_main(int argc, char *argv[])
@@ -1859,22 +1842,16 @@ int httpd_main(int argc, char *argv[])
1859 const char *home_httpd = home; 1842 const char *home_httpd = home;
1860 char *url_for_decode; 1843 char *url_for_decode;
1861 USE_FEATURE_HTTPD_ENCODE_URL_STR(const char *url_for_encode;) 1844 USE_FEATURE_HTTPD_ENCODE_URL_STR(const char *url_for_encode;)
1862 USE_FEATURE_HTTPD_WITHOUT_INETD(const char *s_port;) 1845 const char *s_port;
1863
1864 USE_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;) 1846 USE_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;)
1865 USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) 1847 USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;)
1866
1867 USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;) 1848 USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;)
1868 1849
1869 config = xzalloc(sizeof(*config)); 1850 config = xzalloc(sizeof(*config));
1870#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 1851#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
1871 config->realm = "Web Server Authentication"; 1852 config->realm = "Web Server Authentication";
1872#endif 1853#endif
1873
1874#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
1875 config->port = 80; 1854 config->port = 80;
1876#endif
1877
1878 config->ContentLength = -1; 1855 config->ContentLength = -1;
1879 1856
1880 opt = getopt32(argc, argv, httpd_opts, 1857 opt = getopt32(argc, argv, httpd_opts,
@@ -1883,9 +1860,8 @@ int httpd_main(int argc, char *argv[])
1883 USE_FEATURE_HTTPD_BASIC_AUTH(, &(config->realm)) 1860 USE_FEATURE_HTTPD_BASIC_AUTH(, &(config->realm))
1884 USE_FEATURE_HTTPD_AUTH_MD5(, &pass) 1861 USE_FEATURE_HTTPD_AUTH_MD5(, &pass)
1885 USE_FEATURE_HTTPD_SETUID(, &s_ugid) 1862 USE_FEATURE_HTTPD_SETUID(, &s_ugid)
1886 USE_FEATURE_HTTPD_WITHOUT_INETD(, &s_port) 1863 , &s_port
1887 ); 1864 );
1888
1889 if (opt & OPT_DECODE_URL) { 1865 if (opt & OPT_DECODE_URL) {
1890 printf("%s", decodeString(url_for_decode, 1)); 1866 printf("%s", decodeString(url_for_decode, 1));
1891 return 0; 1867 return 0;
@@ -1902,9 +1878,9 @@ int httpd_main(int argc, char *argv[])
1902 return 0; 1878 return 0;
1903 } 1879 }
1904#endif 1880#endif
1905#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD
1906 if (opt & OPT_PORT) 1881 if (opt & OPT_PORT)
1907 config->port = xatou16(s_port); 1882 config->port = xatou16(s_port);
1883
1908#if ENABLE_FEATURE_HTTPD_SETUID 1884#if ENABLE_FEATURE_HTTPD_SETUID
1909 if (opt & OPT_SETUID) { 1885 if (opt & OPT_SETUID) {
1910 char *e; 1886 char *e;
@@ -1923,24 +1899,22 @@ int httpd_main(int argc, char *argv[])
1923 } 1899 }
1924 } 1900 }
1925#endif 1901#endif
1926#endif
1927 1902
1928 xchdir(home_httpd); 1903 xchdir(home_httpd);
1929#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD 1904 if (!(opt & OPT_INETD)) {
1930 config->server_socket = openServer(); 1905 config->server_socket = openServer();
1931# if ENABLE_FEATURE_HTTPD_SETUID 1906#if ENABLE_FEATURE_HTTPD_SETUID
1932 /* drop privileges */ 1907 /* drop privileges */
1933 if (opt & OPT_SETUID) { 1908 if (opt & OPT_SETUID) {
1934 if (ugid.gid != (gid_t)-1) { 1909 if (ugid.gid != (gid_t)-1) {
1935 // FIXME: needed? 1910 if (setgroups(1, &ugid.gid) == -1)
1936 //if (setgroups(1, &ugid.gid) == -1) 1911 bb_perror_msg_and_die("setgroups");
1937 // bb_perror_msg_and_die("setgroups"); 1912 xsetgid(ugid.gid);
1938 xsetgid(ugid.gid); 1913 }
1914 xsetuid(ugid.uid);
1939 } 1915 }
1940 xsetuid(ugid.uid);
1941 }
1942# endif
1943#endif 1916#endif
1917 }
1944 1918
1945#if ENABLE_FEATURE_HTTPD_CGI 1919#if ENABLE_FEATURE_HTTPD_CGI
1946 { 1920 {
@@ -1950,10 +1924,9 @@ int httpd_main(int argc, char *argv[])
1950 } 1924 }
1951 clearenv(); 1925 clearenv();
1952 if (p) 1926 if (p)
1953 setenv("PATH", p, 1); 1927 setenv1("PATH", p);
1954# if ENABLE_FEATURE_HTTPD_WITHOUT_INETD 1928 if (!(opt & OPT_INETD))
1955 setenv_long("SERVER_PORT", config->port); 1929 setenv_long("SERVER_PORT", config->port);
1956# endif
1957 } 1930 }
1958#endif 1931#endif
1959 1932
@@ -1963,12 +1936,10 @@ int httpd_main(int argc, char *argv[])
1963 parse_conf(default_path_httpd_conf, FIRST_PARSE); 1936 parse_conf(default_path_httpd_conf, FIRST_PARSE);
1964#endif 1937#endif
1965 1938
1966#if ENABLE_FEATURE_HTTPD_WITHOUT_INETD 1939 if (opt & OPT_INETD)
1967# if !DEBUG 1940 return miniHttpd_inetd();
1968 xdaemon(1, 0); /* don't change current directory */ 1941
1969# endif 1942 if (!(opt & OPT_FOREGROUND))
1943 xdaemon(1, 0); /* don't change current directory */
1970 return miniHttpd(config->server_socket); 1944 return miniHttpd(config->server_socket);
1971#else
1972 return miniHttpd();
1973#endif
1974} 1945}