[BusyBox] httpd setgid support and CGI SERVER_ADDR var

John McCarthy jgmcc at magma.ca
Fri Oct 17 21:33:28 UTC 2003


Hi,

I'm trying to replace my current embedded Boa web server with the
BusyBox 1.00-pre3 (well, httpd.c is from CVS) and have run into 3
problems.  Initial patches for two of them are attached.

httpd supports setting the uid but not the gid after performing
privileged operations.  I've added a -g switch to do this as it is
needed by my CGI application.  It is also missing usage text for the -h
option which I've added as part of the same patch.

httpd does not set the SERVER_ADDR or SERVER_NAME env vars for CGI
programs.  This breaks a CGI engine I'm using that requires this to
generate HTTP redirect requests.  With BOA I'm getting both sent as the
IP addr of the server, but the name is specified in a config. file so
this should probably be a command line arg. in httpd.  For now I just
set both to the string representation of the server IP addr from the
server socket. Oops, that reminds me, I need to do the same in the
inetd_server_only side as well--that will be in the next patch.

My third problem is that I've discovered that httpd does not deal with
HTTP redirects returned by the CGI program.  I'll be looking at adding
that next (unless someone else has already done it, hint hint ;-)

I've attached an initial patch to usage.h and httpd.c to fix the first
two problems.  How does it look?



Cheers,
John McCarthy.
jmccarthy at symbium.com
-------------- next part --------------
--- busybox-1.00-cvs/busybox/networking/httpd.c	2003-10-06 13:36:22.000000000 -0400
+++ busybox-1.00-pre3-s1/networking/httpd.c	2003-10-17 16:10:33.000000000 -0400
@@ -182,7 +182,7 @@
 void bb_show_usage(void)
 {
   fprintf(stderr, "Usage: %s [-p <port>] [-c configFile] [-d/-e <string>] "
-		  "[-r realm] [-u user] [-h homedir]\n", bb_applet_name);
+		  "[-r realm] [-u user] [-g group] [-h homedir]\n", bb_applet_name);
   exit(1);
 }
 #endif
@@ -231,6 +231,11 @@
   unsigned port;           /* server initial port and for
 			      set env REMOTE_PORT */
 
+#if defined(CONFIG_FEATURE_HTTPD_CGI) || defined(DEBUG)
+  unsigned int loc_ip;
+  char loc_ip_str[16];     /* for set env SERVER_ADDR */
+#endif
+
   const char *found_mime_type;
   off_t ContentLength;          /* -1 - unknown */
   time_t last_mod;
@@ -1131,6 +1136,8 @@
       /* set SCRIPT_NAME as full path: /cgi-bin/dirs/script.cgi */
       addEnv("SCRIPT_NAME",    "",         purl);
       addEnv("QUERY_STRING",   "",         urlArgs);
+      addEnv("SERVER",         "ADDR",     config->loc_ip_str);
+      addEnv("SERVER",         "NAME",     config->loc_ip_str);
       addEnv("SERVER",         "SOFTWARE", httpdVersion);
       addEnv("SERVER",         "PROTOCOL", "HTTP/1.0");
       addEnv("GATEWAY_INTERFACE", "",      "CGI/1.1");
@@ -1747,14 +1754,20 @@
       if (FD_ISSET(server, &readfd)) {
 	int on;
 	struct sockaddr_in fromAddr;
+        struct sockaddr_in myAddr;
 
 	socklen_t fromAddrLen = sizeof(fromAddr);
+        socklen_t myAddrLen = sizeof(myAddr);
 	int s = accept(server,
 		       (struct sockaddr *)&fromAddr, &fromAddrLen);
 
 	if (s < 0) {
 	    continue;
 	}
+
+        memset(&myAddr, 0, myAddrLen);
+        getsockname(s, (struct sockaddr *)&myAddr, &myAddrLen);
+
 	config->accepted_socket = s;
 	config->rmt_ip = ntohl(fromAddr.sin_addr.s_addr);
 #if defined(CONFIG_FEATURE_HTTPD_CGI) || defined(DEBUG)
@@ -1764,6 +1777,13 @@
 		(unsigned char)(config->rmt_ip >> 8),
 				config->rmt_ip & 0xff);
 	config->port = ntohs(fromAddr.sin_port);
+
+	config->loc_ip = ntohl(myAddr.sin_addr.s_addr);
+	sprintf(config->loc_ip_str, "%u.%u.%u.%u",
+		(unsigned char)(config->loc_ip >> 24),
+		(unsigned char)(config->loc_ip >> 16),
+		(unsigned char)(config->loc_ip >> 8),
+				config->loc_ip & 0xff);
 #ifdef DEBUG
 	if (config->debugHttpd) {
 	    bb_error_msg("connection from IP=%s, port %u\n",
@@ -1853,7 +1873,7 @@
 #ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
 				"p:v"
 #ifdef CONFIG_FEATURE_HTTPD_SETUID
-				"u:"
+				"u:g:"
 #endif
 #endif /* CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY */
 					;
@@ -1867,6 +1887,7 @@
 #define OPT_PORT        (1<<(3+OPT_INC_1+OPT_INC_2))
 #define OPT_DEBUG       (1<<(4+OPT_INC_1+OPT_INC_2))
 #define OPT_SETUID      (1<<(5+OPT_INC_1+OPT_INC_2))
+#define OPT_SETGID      (1<<(5+OPT_INC_1+OPT_INC_2))
 
 
 #ifdef HTTPD_STANDALONE
@@ -1891,7 +1912,9 @@
 
 #ifdef CONFIG_FEATURE_HTTPD_SETUID
   const char *s_uid;
+  const char *s_gid;
   long uid = -1;
+  long gid = -1;
 #endif
 
 #ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
@@ -1924,6 +1947,7 @@
 			, &s_port
 #ifdef CONFIG_FEATURE_HTTPD_SETUID
 			, &s_uid
+			, &s_gid
 #endif
 #endif
     );
@@ -1958,6 +1982,14 @@
 		uid = my_getpwnam(s_uid);
 	}
       }
+    if(opt & OPT_SETGID) {
+	char *e;
+	gid = strtol(s_gid, &e, 0);
+	if(*e != '\0') {
+		/* not integer */
+		gid = my_getpwnamegid(s_gid);
+	}
+      }
 #endif
 #endif
 
@@ -1968,6 +2000,8 @@
   server = openServer();
 # ifdef CONFIG_FEATURE_HTTPD_SETUID
   /* drop privilegies */
+  if(gid > 0)
+	setgid(gid);
   if(uid > 0)
 	setuid(uid);
 # endif
-------------- next part --------------
--- busybox-1.00-pre3/include/usage.h	2003-08-29 10:18:26.000000000 -0400
+++ busybox-1.00-pre3-s1/include/usage.h	2003-10-17 14:48:52.000000000 -0400
@@ -959,25 +959,30 @@
   #define USAGE_HTTPD_STANDALONE(a) a
   #ifdef CONFIG_FEATURE_HTTPD_SETUID
     #define USAGE_HTTPD_SETUID(a) a
+    #define USAGE_HTTPD_SETGID(a) a
   #else
     #define USAGE_HTTPD_SETUID(a)
+    #define USAGE_HTTPD_SETGID(a)
   #endif
 #endif
 #define httpd_trivial_usage \
 	"[-c <conf file>]" \
 	USAGE_HTTPD_STANDALONE(" [-p <port>]") \
 	USAGE_HTTPD_SETUID(" [-u user]") \
+	USAGE_HTTPD_SETGID(" [-g group]") \
 	USAGE_HTTPD_BASIC_AUTH(" [-r <realm>]") \
 	USAGE_HTTPD_AUTH_MD5(" [-m pass]") \
-	" [-d/-e <string>]"
+	" [-h dir] [-d/-e <string>]"
 #define httpd_full_usage \
        "Listens for incoming http server requests.\n"\
        "Options:\n" \
        "\t-c FILE\tSpecifies configuration file. (default httpd.conf)\n" \
        USAGE_HTTPD_STANDALONE("\t-p PORT\tServer port (default 80)\n") \
        USAGE_HTTPD_SETUID("\t-u USER\tSet uid to USER after listening privilegies port\n") \
+       USAGE_HTTPD_SETGID("\t-g GROUP\tSet gid to GROUP after listening privilegies port\n") \
        USAGE_HTTPD_BASIC_AUTH("\t-r REALM\tAuthentication Realm for Basic Authentication\n") \
        USAGE_HTTPD_AUTH_MD5("\t-m PASS\tCrypt PASS with md5 algorithm\n") \
+       "\t-h DIR\tSet document root for web content to DIR\n" \
        "\t-e STRING\tHtml encode STRING\n" \
        "\t-d STRING\tURL decode STRING"
 


More information about the busybox mailing list