uhttpd: finish basic auth support, read realms from /etc/httpd.conf
authorJo-Philipp Wich <jow@openwrt.org>
Sun, 21 Mar 2010 01:15:36 +0000 (01:15 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Sun, 21 Mar 2010 01:15:36 +0000 (01:15 +0000)
contrib/package/uhttpd/src/uhttpd-utils.c
contrib/package/uhttpd/src/uhttpd-utils.h
contrib/package/uhttpd/src/uhttpd.c
contrib/package/uhttpd/src/uhttpd.h

index 19918da16620c975e397fbfa0b7521c23f19c62c..914c6061166b31445d177da28d812a8e2fb9cc83 100644 (file)
@@ -482,9 +482,8 @@ struct path_info * uh_path_lookup(struct client *cl, const char *url)
 static char uh_realms[UH_LIMIT_AUTHREALMS * sizeof(struct auth_realm)] = { 0 };
 static int uh_realm_count = 0;
 
-struct auth_realm * uh_auth_add(
-       char *path, char *realm, char *user, char *pass
-) {
+struct auth_realm * uh_auth_add(char *path, char *user, char *pass)
+{
        struct auth_realm *new = NULL;
        struct passwd *pwd;
        struct spwd *spwd;
@@ -496,9 +495,6 @@ struct auth_realm * uh_auth_add(
 
                memset(new, 0, sizeof(struct auth_realm));
 
-               memcpy(new->realm, realm,
-                       min(strlen(realm), sizeof(new->realm) - 1));
-
                memcpy(new->path, path,
                        min(strlen(path), sizeof(new->path) - 1));
 
@@ -633,7 +629,7 @@ int uh_auth_check(
                        "Content-Type: text/plain\r\n"
                        "Content-Length: 23\r\n\r\n"
                        "Authorization Required\n",
-                               req->version, realm ? realm->realm : ""
+                               req->version, cl->server->conf->realm
                );
 
                return 0;
index 62731dcc114d290870c37f31699250a8b3f880d2..da82ab0285d0da917fac83421c17f2d2185c1185 100644 (file)
@@ -79,9 +79,7 @@ int uh_urlencode(char *buf, int blen, const char *src, int slen);
 int uh_b64decode(char *buf, int blen, const unsigned char *src, int slen);
 
 
-struct auth_realm * uh_auth_add(
-       char *path, char *realm, char *user, char *pass
-);
+struct auth_realm * uh_auth_add(char *path, char *user, char *pass);
 
 int uh_auth_check(
        struct client *cl, struct http_request *req, struct path_info *pi
index 7a5f42ad61d6dc97c935db91b4896eccfc063346..788606068d24afea78bcf163f7695af4b23a41af 100644 (file)
@@ -16,6 +16,8 @@
  *  limitations under the License.
  */
 
+#define _XOPEN_SOURCE 500      /* crypt() */
+
 #include "uhttpd.h"
 #include "uhttpd-utils.h"
 #include "uhttpd-file.h"
@@ -40,6 +42,43 @@ static void uh_sigterm(int sig)
        run = 0;
 }
 
+static void uh_config_parse(const char *path)
+{
+       FILE *c;
+       char line[512];
+       char *user = NULL;
+       char *pass = NULL;
+       char *eol  = NULL;
+
+       if( (c = fopen(path ? path : "/etc/httpd.conf", "r")) != NULL )
+       {
+               memset(line, 0, sizeof(line));
+
+               while( fgets(line, sizeof(line) - 1, c) )
+               {
+                       if( (line[0] == '/') && (strchr(line, ':') != NULL) )
+                       {
+                               if( !(user = strchr(line, ':')) || (*user++ = 0) ||
+                                   !(pass = strchr(user, ':')) || (*pass++ = 0) ||
+                                       !(eol = strchr(pass, '\n')) || (*eol++  = 0) )
+                                               continue;
+
+                               if( !uh_auth_add(line, user, pass) )
+                               {
+                                       fprintf(stderr,
+                                               "Can not manage more than %i basic auth realms, "
+                                               "will skip the rest\n", UH_LIMIT_AUTHREALMS
+                                       );
+
+                                       break;
+                               } 
+                       }
+               }
+
+               fclose(c);
+       }
+}
+
 static int uh_socket_bind(
        fd_set *serv_fds, int *max_fd, const char *host, const char *port,
        struct addrinfo *hints, int do_tls, struct config *conf
@@ -398,7 +437,7 @@ int main (int argc, char **argv)
        }
 #endif
 
-       while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:")) > 0 )
+       while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:")) > 0 )
        {
                switch(opt)
                {
@@ -467,7 +506,7 @@ int main (int argc, char **argv)
 
 #ifdef HAVE_CGI
                        /* cgi prefix */
-                       case 'c':
+                       case 'x':
                                conf.cgi_prefix = optarg;
                                break;
 #endif
@@ -501,25 +540,44 @@ int main (int argc, char **argv)
                                }
                                break;
 
+                       /* basic auth realm */
+                       case 'r':
+                               conf.realm = optarg;
+                               break;
+
+                       /* md5 crypt */
+                       case 'm':
+                               printf("%s\n", crypt(optarg, "$1$"));
+                               exit(0);
+                               break;
+
+                       /* config file */
+                       case 'c':
+                               conf.file = optarg;
+                               break;
+
                        default:
                                fprintf(stderr,
                                        "Usage: %s -p [addr:]port [-h docroot]\n"
-                                       "       -p      Bind to specified address and port, multiple allowed\n"
+                                       "       -f              Do not fork to background\n"
+                                       "       -c file         Configuration file, default is '/etc/httpd.conf'\n"
+                                       "       -p [addr:]port  Bind to specified address and port, multiple allowed\n"
 #ifdef HAVE_TLS
-                                       "       -s      Like -p but provide HTTPS on this port\n"
-                                       "       -C      ASN.1 server certificate file\n"
-                                       "       -K      ASN.1 server private key file\n"
+                                       "       -s [addr:]port  Like -p but provide HTTPS on this port\n"
+                                       "       -C file         ASN.1 server certificate file\n"
+                                       "       -K file         ASN.1 server private key file\n"
 #endif
-                                       "       -h      Specify the document root, default is '.'\n"
-                                       "       -f      Do not fork to background\n"
+                                       "       -h directory    Specify the document root, default is '.'\n"
 #ifdef HAVE_LUA
-                                       "       -l      URL prefix for Lua handler, default is '/lua'\n"
-                                       "       -L      Lua handler script, omit to disable Lua\n"
+                                       "       -l string       URL prefix for Lua handler, default is '/lua'\n"
+                                       "       -L file         Lua handler script, omit to disable Lua\n"
 #endif
 #ifdef HAVE_CGI
-                                       "       -c      URL prefix for CGI handler, default is '/cgi-bin'\n"
+                                       "       -x string       URL prefix for CGI handler, default is '/cgi-bin'\n"
 #endif
-                                       "       -d      URL decode given string\n"
+                                       "       -d string       URL decode given string\n"
+                                       "       -r string       Specify basic auth realm\n"
+                                       "       -m string       MD5 crypt given string\n"
                                        "\n", argv[0]
                                );
 
@@ -549,6 +607,13 @@ int main (int argc, char **argv)
                exit(1);
        }
 
+       /* default realm */
+       if( ! conf.realm )
+               conf.realm = "Protected Area";
+
+       /* config file */
+       uh_config_parse(conf.file);
+
 #ifdef HAVE_CGI
        /* default cgi prefix */
        if( ! conf.cgi_prefix )
index c6212109b48e36f80c9750a183b569e4c355eac3..eca3580b86343effc434f3e54a381bf5baf60d4f 100644 (file)
@@ -51,6 +51,8 @@
 
 struct config {
        char docroot[PATH_MAX];
+       char *realm;
+       char *file;
 #ifdef HAVE_CGI
        char *cgi_prefix;
 #endif
@@ -88,7 +90,6 @@ struct client {
 
 struct auth_realm {
        char path[PATH_MAX];
-       char realm[128];
        char user[32];
        char pass[128];
 };