Merge pull request #1662 from pi-hole/tweak/searchAPIauth

Add new config option webserver.api.searchAPIauth
This commit is contained in:
DL6ER 2023-10-14 16:21:47 +02:00 committed by GitHub
commit 1cfe77f703
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 46 additions and 6 deletions

View File

@ -17,6 +17,8 @@
#include "shmem.h"
// exit_code
#include "signals.h"
// struct config
#include "config/config.h"
static int api_endpoints(struct ftl_conn *api);
@ -109,7 +111,8 @@ int api_handler(struct mg_connection *conn, void *ignored)
{ false, false, 0 }
};
log_debug(DEBUG_API, "Requested API URI: %s %s ? %s (Content-Type %s)",
log_debug(DEBUG_API, "Requested API URI: %s -> %s %s ? %s (Content-Type %s)",
api.request->remote_addr,
api.request->request_method,
api.request->local_uri_raw,
api.request->query_string,
@ -158,7 +161,22 @@ int api_handler(struct mg_connection *conn, void *ignored)
}
// Verify requesting client is allowed to see this resource
if(api_request[i].require_auth && check_client_auth(&api, true) == API_AUTH_UNAUTHORIZED)
if(api_request[i].func == api_search)
{
// Handle /api/search special as it may be allowed for local users due to webserver.api.searchAPIauth
if(!config.webserver.api.searchAPIauth.v.b && is_local_api_user(api.request->remote_addr))
{
// Local users does not need to authenticate when searchAPIauth is false
;
}
else if(api_request[i].require_auth && check_client_auth(&api, true) == API_AUTH_UNAUTHORIZED)
{
// Users need to authenticate but authentication failed
unauthorized = true;
break;
}
}
else if(api_request[i].require_auth && check_client_auth(&api, true) == API_AUTH_UNAUTHORIZED)
{
unauthorized = true;
break;

View File

@ -16,7 +16,7 @@
#include "webserver/cJSON/cJSON.h"
#include "webserver/http-common.h"
// Commo definitions
// Common definitions
#define LOCALHOSTv4 "127.0.0.1"
#define LOCALHOSTv6 "::1"
@ -87,6 +87,7 @@ int api_auth(struct ftl_conn *api);
void delete_all_sessions(void);
int api_auth_sessions(struct ftl_conn *api);
int api_auth_session_delete(struct ftl_conn *api);
bool is_local_api_user(const char *remote_addr) __attribute__((pure));
// 2FA methods
bool verifyTOTP(const uint32_t code);

View File

@ -83,6 +83,13 @@ static void add_request_info(struct ftl_conn *api, const char *csrf)
memset((int*)&api->request->is_authenticated, 1, sizeof(api->request->is_authenticated));
}
// Is this client connecting from localhost?
bool __attribute__((pure)) is_local_api_user(const char *remote_addr)
{
return strcmp(remote_addr, LOCALHOSTv4) == 0 ||
strcmp(remote_addr, LOCALHOSTv6) == 0;
}
// Can we validate this client?
// Returns -1 if not authenticated or expired
// Returns >= 0 for any valid authentication
@ -90,8 +97,7 @@ int check_client_auth(struct ftl_conn *api, const bool is_api)
{
// Is the user requesting from localhost?
// This may be allowed without authentication depending on the configuration
if(!config.webserver.api.localAPIauth.v.b && (strcmp(api->request->remote_addr, LOCALHOSTv4) == 0 ||
strcmp(api->request->remote_addr, LOCALHOSTv6) == 0))
if(!config.webserver.api.localAPIauth.v.b && is_local_api_user(api->request->remote_addr))
{
add_request_info(api, NULL);
return API_AUTH_LOCALHOST;

View File

@ -379,6 +379,8 @@ components:
properties:
localAPIauth:
type: boolean
searchAPIauth:
type: boolean
prettyJSON:
type: boolean
password:
@ -652,6 +654,7 @@ components:
theme: "default-darker"
api:
localAPIauth: false
searchAPIauth: false
prettyJSON: false
password: "********"
pwhash: ''

View File

@ -17,6 +17,7 @@ components:
Search for domains in Pi-hole's list. The optional parameters `N` and `partial` limit the maximum number of returned records and whether partial matches should be returned, respectively.
There is a hard upper limit of `N` defined in FTL (currently set to 10,000) to ensure that the response is not too large.
ABP matches are not returned when partial matching is requested.
Depending on the value of the config option webserver.api.searchAPIauth, local clients may not need to authenticate for this endpoint.
responses:
'200':
description: OK

View File

@ -886,8 +886,13 @@ void initConfig(struct config *conf)
conf->webserver.interface.theme.d.web_theme = THEME_DEFAULT_AUTO;
// sub-struct api
conf->webserver.api.searchAPIauth.k = "webserver.api.searchAPIauth";
conf->webserver.api.searchAPIauth.h = "Do local clients need to authenticate to access the search API? This settings allows local clients to use pihole -q ... without authentication. Note that \"local\" in the sense of the option means only 127.0.0.1 and [::1]";
conf->webserver.api.searchAPIauth.t = CONF_BOOL;
conf->webserver.api.searchAPIauth.d.b = false;
conf->webserver.api.localAPIauth.k = "webserver.api.localAPIauth";
conf->webserver.api.localAPIauth.h = "Do local clients need to authenticate to access the API?";
conf->webserver.api.localAPIauth.h = "Do local clients need to authenticate to access the API? This settings allows local clients to use the API without authentication.";
conf->webserver.api.localAPIauth.t = CONF_BOOL;
conf->webserver.api.localAPIauth.d.b = true;

View File

@ -220,6 +220,7 @@ struct config {
} interface;
struct {
struct conf_item localAPIauth;
struct conf_item searchAPIauth;
struct conf_item prettyJSON;
struct conf_item pwhash;
struct conf_item password; // This is a pseudo-item

View File

@ -594,6 +594,11 @@
# Does local clients need to authenticate to access the API?
localAPIauth = true
# Do local clients need to authenticate to access the search API? This settings allows
# local clients to use pihole -q ... without authentication. Note that "local" in the
# sense of the option means only 127.0.0.1 and [::1]
searchAPIauth = false
# Should FTL prettify the API output (add extra spaces, newlines and indentation)?
prettyJSON = false