From 5ddf71b3638788f8d1dd1d312ec79acfac7f3e74 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 30 Dec 2012 21:56:11 +0100 Subject: [PATCH] add config parser --- CMakeLists.txt | 2 +- auth.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ uhttpd.h | 9 +++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 auth.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3489414..2740fed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..da7263f --- /dev/null +++ b/auth.c @@ -0,0 +1,63 @@ +/* + * uhttpd - Tiny single-threaded httpd + * + * Copyright (C) 2010-2012 Jo-Philipp Wich + * Copyright (C) 2012 Felix Fietkau + * + * 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 945be16..76096b2 100644 --- 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(); } diff --git a/uhttpd.h b/uhttpd.h index 0cb8eb8..0c1cd8b 100644 --- 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 -- 2.11.0