From 2a07c992ab66cbd49efe5f4f2d31446367f84784 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 23 Nov 2019 19:15:23 +0100 Subject: [PATCH] Add option for whether authentication is needed for localhost requests. Defaults to false. (API_AUTH_FOR_LOCALHOST) Signed-off-by: DL6ER --- src/api/auth.c | 29 +++++++++++++++++++++++++---- src/api/http-common.c | 11 ++++++++++- src/config.c | 14 ++++++++++++++ src/config.h | 1 + 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/api/auth.c b/src/api/auth.c index 95eec7b3..e66ee80f 100644 --- a/src/api/auth.c +++ b/src/api/auth.c @@ -39,10 +39,18 @@ static void generateRandomString(char *str, size_t size) // Can we validate this client? // Returns -1 if not authenticated or expired // Returns >= 0 for any valid authentication +#define LOCALHOSTv4 "127.0.0.1" +#define LOCALHOSTv6 "::1" int check_client_auth(struct mg_connection *conn) { int user_id = -1; const struct mg_request_info *request = mg_get_request_info(conn); + + // Is the user requesting from localhost? + if(!httpsettings.api_auth_for_localhost && (strcmp(request->remote_addr, LOCALHOSTv4) == 0 || + strcmp(request->remote_addr, LOCALHOSTv6) == 0)) + return API_MAX_CLIENTS; + // Does the client provide a user_id cookie? int num; if(http_get_cookie_int(conn, "user_id", &num) && num > -1 && num < API_MAX_CLIENTS) @@ -136,10 +144,10 @@ int api_auth(struct mg_connection *conn) logg("Registered new user: user_id %i valid_until: %s remote_addr %s", user_id, timestr, auth_data[user_id].remote_addr); } - else - { - logg("No free user slots available, not authenticating user"); - } + } + if(user_id == -1) + { + logg("WARNING: No free slots available, not authenticating user"); } } else if(config.debug & DEBUG_API) @@ -155,6 +163,19 @@ int api_auth(struct mg_connection *conn) user_id = check_client_auth(conn); int method = http_method(conn); + if(user_id == API_MAX_CLIENTS) + { + if(config.debug & DEBUG_API) + logg("Authentification: OK, localhost does not need auth."); + // We still have to send a cookie for the web interface to be happy + char *additional_headers = NULL; + if(asprintf(&additional_headers, + "Set-Cookie: user_id=%u; Path=/; Max-Age=%u\r\n", + API_MAX_CLIENTS, API_SESSION_EXPIRE) < 0) + { + return send_json_error(conn, 500, "internal_error", "Internal server error", NULL, NULL); + } + } if(user_id > -1 && method == HTTP_GET) { if(config.debug & DEBUG_API) diff --git a/src/api/http-common.c b/src/api/http-common.c index 290835f1..94334578 100644 --- a/src/api/http-common.c +++ b/src/api/http-common.c @@ -83,7 +83,16 @@ int send_json_success(struct mg_connection *conn, { cJSON *json = JSON_NEW_OBJ(); JSON_OBJ_REF_STR(json, "status", "success"); - JSON_SEND_OBJECT_AND_HEADERS(json, additional_headers); + + // Send additional headers if supplied + if(additional_headers == NULL) + { + JSON_SEND_OBJECT(json); + } + else + { + JSON_SEND_OBJECT_AND_HEADERS(json, additional_headers); + } } int send_http_internal_error(struct mg_connection *conn) diff --git a/src/config.c b/src/config.c index 40f20b05..c8014685 100644 --- a/src/config.c +++ b/src/config.c @@ -408,6 +408,20 @@ void read_FTLconf(void) logg(" WEBACL: Allowing all access."); } + // API_AUTH_FOR_LOALHOST + // defaults to: false + httpsettings.api_auth_for_localhost = false; + buffer = parse_FTLconf(fp, "API_AUTH_FOR_LOALHOST"); + + if(buffer != NULL && (strcasecmp(buffer, "yes") == 0 || + strcasecmp(buffer, "true") == 0)) + httpsettings.api_auth_for_localhost = true; + + if(httpsettings.api_auth_for_localhost) + logg(" API_AUTH_FOR_LOCALHOST: Active"); + else + logg(" API_AUTH_FOR_LOCALHOST: Inactive"); + // Read DEBUG_... setting from pihole-FTL.conf // This option should be the last one as it causes // some rather verbose output into the log when diff --git a/src/config.h b/src/config.h index 27225b05..45a8b1b4 100644 --- a/src/config.h +++ b/src/config.h @@ -57,6 +57,7 @@ typedef struct httpsettings { char *webroot; char *webhome; const char *acl; + bool api_auth_for_localhost; char port[20]; // enough space for 2*(maximum length of number in a uint16_t = 5 characters) + ",[::]:" + NULL } httpsettingsStruct;