add config parser
authorFelix Fietkau <nbd@openwrt.org>
Sun, 30 Dec 2012 20:56:11 +0000 (21:56 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 30 Dec 2012 20:56:23 +0000 (21:56 +0100)
CMakeLists.txt
auth.c [new file with mode: 0644]
main.c
uhttpd.h

index 34894142eb4d90614460b92fa400beb2dc15ac46..2740fed9608835e58b5e35e6f23b413c2197cbf2 100644 (file)
@@ -8,5 +8,5 @@ IF(APPLE)
   LINK_DIRECTORIES(/opt/local/lib)
 ENDIF()
 
-ADD_EXECUTABLE(uhttpd main.c listen.c client.c utils.c file.c)
+ADD_EXECUTABLE(uhttpd main.c listen.c client.c utils.c file.c auth.c)
 TARGET_LINK_LIBRARIES(uhttpd ubox ubus)
diff --git a/auth.c b/auth.c
new file mode 100644 (file)
index 0000000..da7263f
--- /dev/null
+++ b/auth.c
@@ -0,0 +1,63 @@
+/*
+ * uhttpd - Tiny single-threaded httpd
+ *
+ *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
+ *   Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "uhttpd.h"
+
+static LIST_HEAD(auth_realms);
+
+void uh_auth_add(const char *path, const char *user, const char *pass)
+{
+       struct auth_realm *new = NULL;
+       struct passwd *pwd;
+       const char *new_pass = NULL;
+
+#ifdef HAVE_SHADOW
+       struct spwd *spwd;
+#endif
+
+       /* given password refers to a passwd entry */
+       if ((strlen(pass) > 3) && !strncmp(pass, "$p$", 3)) {
+#ifdef HAVE_SHADOW
+               /* try to resolve shadow entry */
+               spwd = getspnam(&pass[3]);
+               if (spwd)
+                       new_pass = spwd->sp_pwdp;
+#endif
+               if (!new_pass) {
+                       pwd = getpwnam(&pass[3]);
+                       if (pwd && pwd->pw_passwd && pwd->pw_passwd[0] &&
+                           pwd->pw_passwd[0] != '!')
+                               new_pass = pwd->pw_passwd;
+               }
+       } else {
+               new_pass = pass;
+       }
+
+       if (!new_pass || !new_pass[0])
+               return;
+
+       new = calloc(1, sizeof(*new));
+       if (!new)
+               return;
+
+       snprintf(new->path, sizeof(new->path), "%s", path);
+       snprintf(new->user, sizeof(new->user), "%s", user);
+       snprintf(new->pass, sizeof(new->user), "%s", new_pass);
+       list_add(&new->list, &auth_realms);
+}
diff --git a/main.c b/main.c
index 945be1604615a76a75356bc58fb3444fe97181ea..76096b283cd433f6dfae68e402abcd2c3c4ffcde 100644 (file)
--- a/main.c
+++ b/main.c
@@ -40,6 +40,64 @@ static int run_server(void)
        return 0;
 }
 
+static void uh_config_parse(void)
+{
+       const char *path = conf.file;
+       FILE *c;
+       char line[512];
+       char *col1;
+       char *col2;
+       char *eol;
+
+       if (!path)
+               path = "/etc/httpd.conf";
+
+       c = fopen(path, "r");
+       if (!c)
+               return;
+
+       memset(line, 0, sizeof(line));
+
+       while (fgets(line, sizeof(line) - 1, c)) {
+               if ((line[0] == '/') && (strchr(line, ':') != NULL)) {
+                       if (!(col1 = strchr(line, ':')) || (*col1++ = 0) ||
+                               !(col2 = strchr(col1, ':')) || (*col2++ = 0) ||
+                               !(eol = strchr(col2, '\n')) || (*eol++  = 0))
+                               continue;
+
+                       uh_auth_add(line, col1, col2);
+               } else if (!strncmp(line, "I:", 2)) {
+                       if (!(col1 = strchr(line, ':')) || (*col1++ = 0) ||
+                               !(eol = strchr(col1, '\n')) || (*eol++  = 0))
+                               continue;
+
+                       uh_index_add(strdup(col1));
+               } else if (!strncmp(line, "E404:", 5)) {
+                       if (!(col1 = strchr(line, ':')) || (*col1++ = 0) ||
+                               !(eol = strchr(col1, '\n')) || (*eol++  = 0))
+                               continue;
+
+                       conf.error_handler = strdup(col1);
+               }
+#ifdef HAVE_CGI
+               else if ((line[0] == '*') && (strchr(line, ':') != NULL)) {
+                       if (!(col1 = strchr(line, '*')) || (*col1++ = 0) ||
+                               !(col2 = strchr(col1, ':')) || (*col2++ = 0) ||
+                               !(eol = strchr(col2, '\n')) || (*eol++  = 0))
+                               continue;
+
+                       if (!uh_interpreter_add(col1, col2))
+                               fprintf(stderr,
+                                               "Unable to add interpreter %s for extension %s: "
+                                               "Out of memory\n", col2, col1
+                               );
+               }
+#endif
+       }
+
+       fclose(c);
+}
+
 static void add_listener_arg(char *arg, bool tls)
 {
        char *host = NULL;
@@ -102,5 +160,7 @@ int main(int argc, char **argv)
                }
        }
 
+       uh_config_parse();
+
        return run_server();
 }
index 0cb8eb8ad9c9d0764327dedbe482b5bf9d409966..0c1cd8b6165d46850bcb35287b00819e7512cb0d 100644 (file)
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -49,6 +49,13 @@ struct config {
        int http_keepalive;
 };
 
+struct auth_realm {
+       struct list_head list;
+       char path[PATH_MAX];
+       char user[32];
+       char pass[128];
+};
+
 enum http_method {
        UH_HTTP_MSG_GET,
        UH_HTTP_MSG_POST,
@@ -146,4 +153,6 @@ uh_client_error(struct client *cl, int code, const char *summary, const char *fm
 
 void uh_handle_file_request(struct client *cl);
 
+void uh_auth_add(const char *path, const char *user, const char *pass);
+
 #endif