From 204034d859c37b42a18ec8792a8df89d9c2a3bb0 Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 17 Nov 2019 10:00:17 -0500 Subject: [PATCH] Add basic auth. Fixes #4 --- CMakeLists.txt | 1 + src/cli.c | 6 +++++ src/cli.h | 2 ++ src/ctx.h | 1 + src/main.c | 4 ++- src/sist.h | 2 ++ src/web/auth_basic.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ src/web/auth_basic.h | 4 +++ src/web/serve.c | 7 +++++- 9 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/web/auth_basic.c create mode 100644 src/web/auth_basic.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cd70f5f..25f0fb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ if (WITH_SIST2) src/parsing/text.h src/parsing/text.c src/index/web.c src/index/web.h src/web/serve.c src/web/serve.h + src/web/auth_basic.h src/web/auth_basic.c src/index/elastic.c src/index/elastic.h src/util.c src/util.h src/ctx.h src/types.h src/parsing/font.c src/parsing/font.h diff --git a/src/cli.c b/src/cli.c index 9ed2918..3444f79 100644 --- a/src/cli.c +++ b/src/cli.c @@ -157,6 +157,12 @@ int web_args_validate(web_args_t *args, int argc, const char **argv) { args->port = DEFAULT_PORT; } + if (args->credentials != NULL) { + args->b64credentials = onion_base64_encode(args->credentials, (int)strlen(args->credentials)); + //Remove trailing newline + *(args->b64credentials + strlen(args->b64credentials) - 1) = '\0'; + } + args->index_count = argc - 1; args->indices = argv + 1; diff --git a/src/cli.h b/src/cli.h index f151c9d..7734f2e 100644 --- a/src/cli.h +++ b/src/cli.h @@ -32,6 +32,8 @@ typedef struct web_args { char *es_url; char *bind; char *port; + char *credentials; + char *b64credentials; int index_count; const char **indices; } web_args_t; diff --git a/src/ctx.h b/src/ctx.h index a2831b8..207f72b 100644 --- a/src/ctx.h +++ b/src/ctx.h @@ -34,6 +34,7 @@ struct { struct { char *es_url; int index_count; + char* b64credentials; struct index_t indices[16]; } WebCtx; #endif diff --git a/src/main.c b/src/main.c index bef221f..bd8d4a0 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,7 @@ #define EPILOG "Made by simon987 . Released under GPL-3.0" -static const char *const Version = "1.1.5"; +static const char *const Version = "1.1.6"; static const char *const usage[] = { "sist2 scan [OPTION]... PATH", "sist2 index [OPTION]... INDEX", @@ -175,6 +175,7 @@ void sist2_web(web_args_t *args) { WebCtx.es_url = args->es_url; WebCtx.index_count = args->index_count; + WebCtx.b64credentials = args->b64credentials; for (int i = 0; i < args->index_count; i++) { char *abs_path = abspath(args->indices[i]); @@ -243,6 +244,7 @@ int main(int argc, const char *argv[]) { OPT_STRING(0, "es-url", &common_es_url, "Elasticsearch url. DEFAULT=http://localhost:9200"), OPT_STRING(0, "bind", &web_args->bind, "Listen on this address. DEFAULT=localhost"), OPT_STRING(0, "port", &web_args->port, "Listen on this port. DEFAULT=4090"), + OPT_STRING(0, "auth", &web_args->credentials, "Basic auth in user:password format"), #endif OPT_END(), diff --git a/src/sist.h b/src/sist.h index ab14d0a..ef91196 100644 --- a/src/sist.h +++ b/src/sist.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #endif @@ -56,6 +57,7 @@ #include "src/index/elastic.h" #include "index/web.h" #include "web/serve.h" +#include "web/auth_basic.h" #endif ; diff --git a/src/web/auth_basic.c b/src/web/auth_basic.c new file mode 100644 index 0000000..34fb2c5 --- /dev/null +++ b/src/web/auth_basic.c @@ -0,0 +1,59 @@ +#import "auth_basic.h" + +#define UNAUTHORIZED_TEXT "Unauthorized" + +typedef struct auth_basic_data { + onion_handler *inside; + const char *b64credentials; +} auth_basic_data_t; + + +int authenticate(const char *expected, const char *credentials) { + + if (expected == NULL) { + return TRUE; + } + + if (credentials && strncmp(credentials, "Basic ", 6) == 0) { + if (strcmp((credentials + 6), expected) == 0) { + return TRUE; + } + } + + return FALSE; +} + +int auth_basic_handler(auth_basic_data_t *d, + onion_request *req, + onion_response *res) { + + const char *credentials = onion_request_get_header(req, "Authorization"); + + if (authenticate(d->b64credentials, credentials)) { + return onion_handler_handle(d->inside, req, res); + } + + onion_response_set_header(res, "WWW-Authenticate", "Basic realm=\"sist2\""); + onion_response_set_code(res, HTTP_UNAUTHORIZED); + onion_response_write(res, UNAUTHORIZED_TEXT, sizeof(UNAUTHORIZED_TEXT)); + onion_response_set_length(res, sizeof(UNAUTHORIZED_TEXT)); + + return OCS_PROCESSED; +} + +void auth_basic_free(auth_basic_data_t *data) { + onion_handler_free(data->inside); + free(data); +} + +onion_handler *auth_basic(const char *b64credentials, onion_handler *inside_level) { + + auth_basic_data_t *privdata = malloc(sizeof(auth_basic_data_t)); + + privdata->b64credentials = b64credentials; + privdata->inside = inside_level; + + return onion_handler_new((onion_handler_handler) auth_basic_handler, privdata, + (onion_handler_private_data_free) auth_basic_free); +} + diff --git a/src/web/auth_basic.h b/src/web/auth_basic.h new file mode 100644 index 0000000..df0e3a6 --- /dev/null +++ b/src/web/auth_basic.h @@ -0,0 +1,4 @@ +#include "src/sist.h" + + +onion_handler *auth_basic(const char *b64credentials, onion_handler *inside_level); diff --git a/src/web/serve.c b/src/web/serve.c index 6e6db66..1ce6f60 100644 --- a/src/web/serve.c +++ b/src/web/serve.c @@ -245,6 +245,8 @@ int search(void *p, onion_request *req, onion_response *res) { if (r->status_code == 200) { onion_response_write(res, r->body, r->size); + } else { + onion_response_set_code(res, HTTP_INTERNAL_ERROR); } free_response(r); @@ -391,9 +393,11 @@ void serve(const char *hostname, const char *port) { onion_set_hostname(o, hostname); onion_set_port(o, port); - onion_url *urls = onion_root_url(o); + onion_url *urls = onion_url_new(); // Static paths + onion_set_root_handler(o, auth_basic(WebCtx.b64credentials, onion_url_to_handler(urls))); + onion_url_add(urls, "", search_index); onion_url_add(urls, "css", style); onion_url_add(urls, "js", javascript); @@ -410,6 +414,7 @@ void serve(const char *hostname, const char *port) { onion_url_add(urls, "^f/([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$", file); onion_url_add(urls, "i", index_info); + printf("Starting web server @ http://%s:%s\n", hostname, port); onion_listen(o);