From 97cfa69557c103f581f8d96c96337f297ee3e87c Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 14:27:55 +0200 Subject: [PATCH 01/13] Remove unnecessary redirection from **/$ -> **$ Signed-off-by: DL6ER --- src/api/docs/docs.c | 1 + src/webserver/webserver.c | 43 ++------------------------------------- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/src/api/docs/docs.c b/src/api/docs/docs.c index 7a6c1ee3..460cadf7 100644 --- a/src/api/docs/docs.c +++ b/src/api/docs/docs.c @@ -15,6 +15,7 @@ int api_docs(struct ftl_conn *api) // Handle resource request by redirecting to "/" if(strcmp(api->request->request_uri, "/api/docs") == 0) { + log_debug(DEBUG_API, "Redirecting /api/docs --301--> /api/docs/"); mg_send_http_redirect(api->conn, "/api/docs/", 301); } diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c index 26cf4f9e..409f2b21 100644 --- a/src/webserver/webserver.c +++ b/src/webserver/webserver.c @@ -86,6 +86,8 @@ static int redirect_root_handler(struct mg_connection *conn, void *input) // 308 Permanent Redirect from http://pi.hole -> http://pi.hole/admin if(strcmp(uri, "/") == 0) { + log_debug(DEBUG_API, "Redirecting / --308--> %s", + config.webserver.paths.webhome.v.s); mg_send_http_redirect(conn, config.webserver.paths.webhome.v.s, 308); return 1; } @@ -125,44 +127,6 @@ static int redirect_lp_handler(struct mg_connection *conn, void *input) return 1; } -static int redirect_slash_handler(struct mg_connection *conn, void *input) -{ - // Get requested URI - const struct mg_request_info *request = mg_get_request_info(conn); - const char *uri = request->local_uri_raw; - const char *query_string = request->query_string; - const size_t query_len = query_string != NULL ? strlen(query_string) : 0; - - // Do not redirect if the new URI is the webhome - if(strcmp(uri, config.webserver.paths.webhome.v.s) == 0) - { - log_debug(DEBUG_API, "Not redirecting %s?%s", - uri, query_string); - - // Handle as a normal request - return request_handler(conn, input); - } - - // Remove the trailing slash from the URI - char *new_uri = strdup(uri); - new_uri[strlen(new_uri) - 1] = '\0'; - - // Append query string to the new URI if present - if(query_len > 0) - { - strcat(new_uri, "?"); - strcat(new_uri, query_string); - } - - // Send a 301 redirect to the new URI - log_debug(DEBUG_API, "Redirecting %s?%s ==301==> %s", - uri, query_string, new_uri); - mg_send_http_redirect(conn, new_uri, 301); - free(new_uri); - - return 1; -} - static int log_http_message(const struct mg_connection *conn, const char *message) { log_web("%s", message); @@ -330,9 +294,6 @@ void http_init(void) // Register **.lp -> ** redirect handler mg_set_request_handler(ctx, "**.lp$", redirect_lp_handler, NULL); - // Register **/ -> ** redirect handler - mg_set_request_handler(ctx, "**/$", redirect_slash_handler, NULL); - // Register handler for the rest mg_set_request_handler(ctx, "**", request_handler, NULL); From e41d902b5b01896360e1235aebabd3eb352158aa Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 14:31:20 +0200 Subject: [PATCH 02/13] Do not try to guess server hostname in Civetweb when redirecting directory URIs to end with a slash Signed-off-by: DL6ER --- src/webserver/civetweb/civetweb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/webserver/civetweb/civetweb.c b/src/webserver/civetweb/civetweb.c index f44b17ba..3df8eab9 100644 --- a/src/webserver/civetweb/civetweb.c +++ b/src/webserver/civetweb/civetweb.c @@ -15306,7 +15306,9 @@ handle_request(struct mg_connection *conn) if (!new_path) { mg_send_http_error(conn, 500, "out or memory"); } else { - mg_get_request_link(conn, new_path, buflen - 1); + /* Pi-hole modification */ + //mg_get_request_link(conn, new_path, buflen - 1); + strcpy(new_path, ri->local_uri_raw); strcat(new_path, "/"); if (ri->query_string) { /* Append ? and query string */ From 3427c043966dffbdc7ab6c7b336e3d072b0c8165 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 14:32:20 +0200 Subject: [PATCH 03/13] Add new Civetweb patch Signed-off-by: DL6ER --- patch/civetweb.sh | 1 + ...ess-server-hostname-in-Civetweb-when.patch | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 patch/civetweb/0001-Do-not-try-to-guess-server-hostname-in-Civetweb-when.patch diff --git a/patch/civetweb.sh b/patch/civetweb.sh index d1905a29..b2c0fa6e 100644 --- a/patch/civetweb.sh +++ b/patch/civetweb.sh @@ -7,5 +7,6 @@ patch -p1 < patch/civetweb/0001-Always-Kepler-syntax-for-Lua-server-pages.patch patch -p1 < patch/civetweb/0001-Add-FTL-URI-rewriting-changes-to-CivetWeb.patch patch -p1 < patch/civetweb/0001-Add-mbedTLS-debug-logging-hook.patch patch -p1 < patch/civetweb/0001-Register-CSRF-token-in-conn-request_info.patch +patch -p1 < patch/civetweb/0001-Do-not-try-to-guess-server-hostname-in-Civetweb-when.patch echo "ALL PATCHES APPLIED OKAY" diff --git a/patch/civetweb/0001-Do-not-try-to-guess-server-hostname-in-Civetweb-when.patch b/patch/civetweb/0001-Do-not-try-to-guess-server-hostname-in-Civetweb-when.patch new file mode 100644 index 00000000..862cc421 --- /dev/null +++ b/patch/civetweb/0001-Do-not-try-to-guess-server-hostname-in-Civetweb-when.patch @@ -0,0 +1,29 @@ +From e41d902b5b01896360e1235aebabd3eb352158aa Mon Sep 17 00:00:00 2001 +From: DL6ER +Date: Sun, 8 Oct 2023 14:31:20 +0200 +Subject: [PATCH] Do not try to guess server hostname in Civetweb when + redirecting directory URIs to end with a slash + +Signed-off-by: DL6ER +--- + src/webserver/civetweb/civetweb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/webserver/civetweb/civetweb.c b/src/webserver/civetweb/civetweb.c +index f44b17ba..3df8eab9 100644 +--- a/src/webserver/civetweb/civetweb.c ++++ b/src/webserver/civetweb/civetweb.c +@@ -15306,7 +15306,9 @@ handle_request(struct mg_connection *conn) + if (!new_path) { + mg_send_http_error(conn, 500, "out or memory"); + } else { +- mg_get_request_link(conn, new_path, buflen - 1); ++ /* Pi-hole modification */ ++ //mg_get_request_link(conn, new_path, buflen - 1); ++ strcpy(new_path, ri->local_uri_raw); + strcat(new_path, "/"); + if (ri->query_string) { + /* Append ? and query string */ +-- +2.34.1 + From c4237f1846bbc34bb2e78e7afe3f62fdb768bc15 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 18:32:59 +0200 Subject: [PATCH 04/13] Include HTTPS port (if any) in /api/auth response Signed-off-by: DL6ER --- src/api/auth.c | 5 +++ src/api/docs/content/specs/auth.yaml | 3 ++ src/webserver/webserver.c | 49 ++++++++++++++++++++++++++++ src/webserver/webserver.h | 2 ++ 4 files changed, 59 insertions(+) diff --git a/src/api/auth.c b/src/api/auth.c index aa8fb9af..3b531476 100644 --- a/src/api/auth.c +++ b/src/api/auth.c @@ -22,6 +22,8 @@ #include "daemon.h" // sha256_raw_to_hex() #include "config/password.h" +// get_https_port() +#include "webserver/webserver.h" // crypto library #include @@ -312,6 +314,7 @@ static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_ JSON_ADD_NULL_TO_OBJECT(session, "sid"); JSON_ADD_NUMBER_TO_OBJECT(session, "validity", -1); JSON_ADD_ITEM_TO_OBJECT(json, "session", session); + JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); return 0; } @@ -325,6 +328,7 @@ static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_ JSON_REF_STR_IN_OBJECT(session, "csrf", auth_data[user_id].csrf); JSON_ADD_NUMBER_TO_OBJECT(session, "validity", auth_data[user_id].valid_until - now); JSON_ADD_ITEM_TO_OBJECT(json, "session", session); + JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); return 0; } @@ -335,6 +339,7 @@ static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_ JSON_ADD_NULL_TO_OBJECT(session, "sid"); JSON_ADD_NUMBER_TO_OBJECT(session, "validity", -1); JSON_ADD_ITEM_TO_OBJECT(json, "session", session); + JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); return 0; } diff --git a/src/api/docs/content/specs/auth.yaml b/src/api/docs/content/specs/auth.yaml index 2c314181..2f24ade8 100644 --- a/src/api/docs/content/specs/auth.yaml +++ b/src/api/docs/content/specs/auth.yaml @@ -245,6 +245,9 @@ components: validity: type: integer description: Remaining lifetime of this session unless refreshed (seconds) + https_port: + type: integer + description: HTTPS port of the Pi-hole webserver (0 if disabled) dns: type: boolean description: Whether the DNS server is up and running. False only in failed state diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c index 26cf4f9e..962a31f3 100644 --- a/src/webserver/webserver.c +++ b/src/webserver/webserver.c @@ -204,6 +204,52 @@ void FTL_mbed_debug(void *user_param, int level, const char *file, int line, con log_web("mbedTLS(%s:%d, %d): %.*s", file, line, level, (int)len, message); } +#define MAXPORTS 8 +static struct serverports +{ + bool is_secure; + unsigned char protocol; // 1 = IPv4, 2 = IPv4+IPv6, 3 = IPv6 + in_port_t port; +} server_ports[MAXPORTS] = { 0 }; +static in_port_t https_port = 0; +static void get_server_ports(void) +{ + if(ctx == NULL) + return; + + // Loop over all listening ports + struct mg_server_port mgports[MAXPORTS] = { 0 }; + if(mg_get_server_ports(ctx, MAXPORTS, mgports) > 0) + { + // Loop over all ports + for(unsigned int i = 0; i < MAXPORTS; i++) + { + // Stop if no more ports are configured + if(mgports[i].protocol == 0) + break; + + // Store port information + server_ports[i].port = mgports[i].port; + server_ports[i].is_secure = mgports[i].is_ssl; + server_ports[i].protocol = mgports[i].protocol; + + // Store HTTPS port if not already set + if(mgports[i].is_ssl && https_port == 0) + https_port = mgports[i].port; + + // Print port information + log_debug(DEBUG_API, "Listening on port %d (HTTP%s, IPv%s)", + mgports[i].port, mgports[i].is_ssl ? "S" : "", + mgports[i].protocol == 1 ? "4" : (mgports[i].protocol == 3 ? "6" : "4+6")); + } + } +} + +in_port_t __attribute__((pure)) get_https_port(void) +{ + return https_port; +} + void http_init(void) { log_web("Initializing HTTP server on port %s", config.webserver.port.v.s); @@ -338,6 +384,9 @@ void http_init(void) // Prepare prerequisites for Lua allocate_lua(); + + // Get server ports + get_server_ports(); } static char *append_to_path(char *path, const char *append) diff --git a/src/webserver/webserver.h b/src/webserver/webserver.h index e551498d..d90b4494 100644 --- a/src/webserver/webserver.h +++ b/src/webserver/webserver.h @@ -13,4 +13,6 @@ void http_init(void); void http_terminate(void); +in_port_t get_https_port(void) __attribute__((pure)); + #endif // WEBSERVER_H \ No newline at end of file From b46d0019bfecd722f51fb201a95eb12c923d63b4 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 14:39:41 +0200 Subject: [PATCH 05/13] Add allocation memory explanation as code comments Signed-off-by: DL6ER --- src/webserver/webserver.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c index 409f2b21..901e873b 100644 --- a/src/webserver/webserver.c +++ b/src/webserver/webserver.c @@ -102,14 +102,23 @@ static int redirect_lp_handler(struct mg_connection *conn, void *input) // Get requested URI const struct mg_request_info *request = mg_get_request_info(conn); const char *uri = request->local_uri_raw; + const size_t uri_len = strlen(uri); const char *query_string = request->query_string; const size_t query_len = query_string != NULL ? strlen(query_string) : 0; - // Remove the ".lp" from the URI - char *pos = strstr(uri, ".lp"); - char *new_uri = calloc(strlen(uri) + query_len, sizeof(char)); - // Copy everything from before the ".lp" to the new URI - strncpy(new_uri, uri, pos - uri); + // We allocate uri_len + query_len - 1 bytes, which is enough for the + // new URI. The calculation is as follows: + // 1. We are saving three bytes by skipping ".lp" at the end of the URI + // 2. We are adding one byte for the trailing '\0' + // 3. We are adding query_len bytes for the query string (if present) + // 4. We are adding one byte for the '?' between URI and query string + // (if present) + // Total bytes required: uri_len - 3 + query_len + 1 + 1 + char *new_uri = calloc(uri_len + query_len - 1, sizeof(char)); + + // Copy everything from before the ".lp" to the new URI to effectively + // remove it + strncpy(new_uri, uri, uri_len - 3); // Append query string to the new URI if present if(query_len > 0) From 970695b65fa6a088da638da622fad87a0156408d Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 19:57:35 +0200 Subject: [PATCH 06/13] Adjust tests to include the new https_port property Signed-off-by: DL6ER --- src/api/docs/content/specs/auth.yaml | 5 +++++ test/test_suite.bats | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/api/docs/content/specs/auth.yaml b/src/api/docs/content/specs/auth.yaml index 2f24ade8..48a24cbd 100644 --- a/src/api/docs/content/specs/auth.yaml +++ b/src/api/docs/content/specs/auth.yaml @@ -374,6 +374,7 @@ components: sid: null csrf: null validity: 300 + https_port: 443 dns: true no_login_required: summary: No login required for this client @@ -384,6 +385,7 @@ components: sid: null csrf: null validity: -1 + https_port: 443 dns: true login_required: summary: Login required @@ -394,6 +396,7 @@ components: sid: null csrf: null validity: -1 + https_port: 443 dns: true login_failed: summary: Login failed @@ -404,6 +407,7 @@ components: sid: null csrf: null validity: -1 + https_port: 443 dns: true dns_failure: summary: DNS server failure @@ -414,6 +418,7 @@ components: sid: null csrf: null validity: -1 + https_port: 443 dns: false errors: no_payload: diff --git a/test/test_suite.bats b/test/test_suite.bats index 9f7852f6..480c3c3d 100644 --- a/test/test_suite.bats +++ b/test/test_suite.bats @@ -1266,7 +1266,7 @@ @test "API authorization (without password): No login required" { run bash -c 'curl -s 127.0.0.1/api/auth' printf "%s\n" "${lines[@]}" - [[ ${lines[0]} == '{"session":{"valid":true,"totp":false,"sid":null,"validity":-1},"dns":true,"took":'*'}' ]] + [[ ${lines[0]} == '{"session":{"valid":true,"totp":false,"sid":null,"validity":-1},"https_port":443,"dns":true,"took":'*'}' ]] } @test "API authorization: Setting password" { From b60e8bdc2f729cc49b64f34847347a454fb76ed9 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 8 Oct 2023 22:55:24 +0200 Subject: [PATCH 07/13] Add /api/info/login and remove some parts from /api/auth Signed-off-by: DL6ER --- src/api/api.c | 1 + src/api/api.h | 1 + src/api/auth.c | 9 --------- src/api/docs/content/specs/auth.yaml | 27 --------------------------- src/api/docs/content/specs/info.yaml | 26 ++++++++++++++++++++++++++ src/api/docs/content/specs/main.yaml | 3 +++ src/api/info.c | 15 +++++++++++++++ test/test_suite.bats | 2 +- 8 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/api/api.c b/src/api/api.c index 2c132fc5..61a98455 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -44,6 +44,7 @@ static struct { { "/api/groups", "/{name}", api_list, { false, true, 0 }, true, HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_DELETE }, { "/api/lists", "/{list}", api_list, { false, true, 0 }, true, HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_DELETE }, { "/api/info/client", "", api_info_client, { false, true, 0 }, false, HTTP_GET }, + { "/api/info/login", "", api_info_login, { false, true, 0 }, false, HTTP_GET }, { "/api/info/system", "", api_info_system, { false, true, 0 }, true, HTTP_GET }, { "/api/info/database", "", api_info_database, { false, true, 0 }, true, HTTP_GET }, { "/api/info/sensors", "", api_info_sensors, { false, true, 0 }, true, HTTP_GET }, diff --git a/src/api/api.h b/src/api/api.h index f05045f3..1603ecee 100644 --- a/src/api/api.h +++ b/src/api/api.h @@ -60,6 +60,7 @@ int api_info_version(struct ftl_conn *api); int api_info_messages_count(struct ftl_conn *api); int api_info_messages(struct ftl_conn *api); int api_info_metrics(struct ftl_conn *api); +int api_info_login(struct ftl_conn *api); // Config methods int api_config(struct ftl_conn *api); diff --git a/src/api/auth.c b/src/api/auth.c index 3b531476..501f6f94 100644 --- a/src/api/auth.c +++ b/src/api/auth.c @@ -22,8 +22,6 @@ #include "daemon.h" // sha256_raw_to_hex() #include "config/password.h" -// get_https_port() -#include "webserver/webserver.h" // crypto library #include @@ -304,7 +302,6 @@ static int get_all_sessions(struct ftl_conn *api, cJSON *json) static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_id, const time_t now) { cJSON *session = JSON_NEW_OBJECT(); - const bool dns = get_blockingstatus() != DNS_FAILED; // Authentication not needed if(user_id == API_AUTH_LOCALHOST || user_id == API_AUTH_EMPTYPASS) @@ -314,8 +311,6 @@ static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_ JSON_ADD_NULL_TO_OBJECT(session, "sid"); JSON_ADD_NUMBER_TO_OBJECT(session, "validity", -1); JSON_ADD_ITEM_TO_OBJECT(json, "session", session); - JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); - JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); return 0; } @@ -328,8 +323,6 @@ static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_ JSON_REF_STR_IN_OBJECT(session, "csrf", auth_data[user_id].csrf); JSON_ADD_NUMBER_TO_OBJECT(session, "validity", auth_data[user_id].valid_until - now); JSON_ADD_ITEM_TO_OBJECT(json, "session", session); - JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); - JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); return 0; } @@ -339,8 +332,6 @@ static int get_session_object(struct ftl_conn *api, cJSON *json, const int user_ JSON_ADD_NULL_TO_OBJECT(session, "sid"); JSON_ADD_NUMBER_TO_OBJECT(session, "validity", -1); JSON_ADD_ITEM_TO_OBJECT(json, "session", session); - JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); - JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); return 0; } diff --git a/src/api/docs/content/specs/auth.yaml b/src/api/docs/content/specs/auth.yaml index 48a24cbd..2a8df9ce 100644 --- a/src/api/docs/content/specs/auth.yaml +++ b/src/api/docs/content/specs/auth.yaml @@ -26,8 +26,6 @@ components: $ref: 'auth.yaml#/components/examples/no_login_required' login_required: $ref: 'auth.yaml#/components/examples/login_required' - dns_failure: - $ref: 'auth.yaml#/components/examples/dns_failure' post: summary: Submit password for login tags: @@ -245,12 +243,6 @@ components: validity: type: integer description: Remaining lifetime of this session unless refreshed (seconds) - https_port: - type: integer - description: HTTPS port of the Pi-hole webserver (0 if disabled) - dns: - type: boolean - description: Whether the DNS server is up and running. False only in failed state password: type: object @@ -374,8 +366,6 @@ components: sid: null csrf: null validity: 300 - https_port: 443 - dns: true no_login_required: summary: No login required for this client value: @@ -385,8 +375,6 @@ components: sid: null csrf: null validity: -1 - https_port: 443 - dns: true login_required: summary: Login required value: @@ -396,8 +384,6 @@ components: sid: null csrf: null validity: -1 - https_port: 443 - dns: true login_failed: summary: Login failed value: @@ -407,19 +393,6 @@ components: sid: null csrf: null validity: -1 - https_port: 443 - dns: true - dns_failure: - summary: DNS server failure - value: - session: - valid: false - totp: false - sid: null - csrf: null - validity: -1 - https_port: 443 - dns: false errors: no_payload: summary: Bad request (no valid JSON payload) diff --git a/src/api/docs/content/specs/info.yaml b/src/api/docs/content/specs/info.yaml index 08fc9f63..b6d53978 100644 --- a/src/api/docs/content/specs/info.yaml +++ b/src/api/docs/content/specs/info.yaml @@ -278,6 +278,23 @@ components: allOf: - $ref: 'common.yaml#/components/errors/unauthorized' - $ref: 'common.yaml#/components/schemas/took' + login: + get: + summary: Login page related information + tags: + - "FTL information" + operationId: "get_logininfo" + description: | + This API hook returns information used on the login page to possibly display messages/warnings. + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: 'info.yaml#/components/schemas/login' + - $ref: 'common.yaml#/components/schemas/took' schemas: client: @@ -1068,6 +1085,15 @@ components: type: integer description: Number of items example: 42 + login: + type: object + properties: + https_port: + type: integer + description: HTTPS port of the Pi-hole webserver (0 if disabled) + dns: + type: boolean + description: Whether the DNS server is up and running. False only in failed state examples: errors: messages: diff --git a/src/api/docs/content/specs/main.yaml b/src/api/docs/content/specs/main.yaml index 817c0606..9b9121e2 100644 --- a/src/api/docs/content/specs/main.yaml +++ b/src/api/docs/content/specs/main.yaml @@ -190,6 +190,9 @@ paths: /info/metrics: $ref: 'info.yaml#/components/paths/metrics' + /info/login: + $ref: 'info.yaml#/components/paths/login' + /logs/dnsmasq: $ref: 'logs.yaml#/components/paths/logs/dnsmasq' diff --git a/src/api/info.c b/src/api/info.c index 6d9a2b42..312f52d9 100644 --- a/src/api/info.c +++ b/src/api/info.c @@ -49,6 +49,9 @@ #include #include "metrics.h" +// get_https_port() +#include "webserver/webserver.h" + // DIR #include @@ -1032,3 +1035,15 @@ int api_info_metrics(struct ftl_conn *api) JSON_ADD_ITEM_TO_OBJECT(json2, "metrics", json); JSON_SEND_OBJECT(json2); } + +int api_info_login(struct ftl_conn *api) +{ + cJSON *json = JSON_NEW_OBJECT(); + + const bool dns = get_blockingstatus() != DNS_FAILED; + JSON_ADD_BOOL_TO_OBJECT(json, "dns", dns); + + JSON_ADD_NUMBER_TO_OBJECT(json, "https_port", get_https_port()); + + JSON_SEND_OBJECT(json); +} diff --git a/test/test_suite.bats b/test/test_suite.bats index 480c3c3d..7f43d27d 100644 --- a/test/test_suite.bats +++ b/test/test_suite.bats @@ -1266,7 +1266,7 @@ @test "API authorization (without password): No login required" { run bash -c 'curl -s 127.0.0.1/api/auth' printf "%s\n" "${lines[@]}" - [[ ${lines[0]} == '{"session":{"valid":true,"totp":false,"sid":null,"validity":-1},"https_port":443,"dns":true,"took":'*'}' ]] + [[ ${lines[0]} == '{"session":{"valid":true,"totp":false,"sid":null,"validity":-1},"took":'*'}' ]] } @test "API authorization: Setting password" { From 687e489e2a8aa7010dba76c92d2f47765eb6a57f Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 9 Oct 2023 16:55:12 +0200 Subject: [PATCH 08/13] Allow generating X.509 TLS certificates for arbitrary domain names. When auto-generated, FTL uses the config value webserver.domain defaulting to "pi.hole". The generated certificate may be checked using, e.g. openssl x509 -in /etc/pihole/tls.pem -text -noout Signed-off-by: DL6ER --- src/args.c | 14 ++++++++------ src/webserver/webserver.c | 5 ++++- src/webserver/x509.c | 12 ++++++++++-- src/webserver/x509.h | 2 +- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/args.c b/src/args.c index 877b0bc9..0d923ed9 100644 --- a/src/args.c +++ b/src/args.c @@ -311,18 +311,20 @@ void parse_args(int argc, char* argv[]) if(argc > 1 && strcmp(argv[1], "--gen-x509") == 0) { - if(argc != 3 && argc != 4) + if(argc < 3 || argc > 5) { - printf("Usage: %s --gen-x509 [rsa]\n", argv[0]); - printf("Example: %s --gen-x509 /etc/pihole/tls.pem\n", argv[0]); - printf(" or: %s --gen-x509 /etc/pihole/tls.pem rsa\n", argv[0]); + printf("Usage: %s --gen-x509 [] [rsa]\n", argv[0]); + printf("Example: %s --gen-x509 /etc/pihole/tls.pem\n", argv[0]); + printf(" with domain: %s --gen-x509 /etc/pihole/tls.pem pi.hole\n", argv[0]); + printf(" RSA with domain: %s --gen-x509 /etc/pihole/tls.pem nanopi.lan rsa\n", argv[0]); exit(EXIT_FAILURE); } // Enable stdout printing cli_mode = true; log_ctrl(false, true); - const bool rsa = argc == 4 && strcasecmp(argv[3], "rsa") == 0; - exit(generate_certificate(argv[2], rsa) ? EXIT_SUCCESS : EXIT_FAILURE); + const char *domain = argc > 3 ? argv[3] : "pi.hole"; + const bool rsa = argc > 4 && strcasecmp(argv[4], "rsa") == 0; + exit(generate_certificate(argv[2], rsa, domain) ? EXIT_SUCCESS : EXIT_FAILURE); } // If the first argument is "gravity" (e.g., /usr/bin/pihole-FTL gravity), diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c index 26cf4f9e..d600fb56 100644 --- a/src/webserver/webserver.c +++ b/src/webserver/webserver.c @@ -278,7 +278,7 @@ void http_init(void) { // Try to generate certificate if not present if(!file_readable(config.webserver.tls.cert.v.s) && - !generate_certificate(config.webserver.tls.cert.v.s, false)) + !generate_certificate(config.webserver.tls.cert.v.s, false, config.webserver.domain.v.s)) { log_err("Generation of SSL/TLS certificate %s failed!", config.webserver.tls.cert.v.s); @@ -288,6 +288,9 @@ void http_init(void) { options[++next_option] = "ssl_certificate"; options[++next_option] = config.webserver.tls.cert.v.s; + + log_info("Created SSL/TLS certificate for %s at %s", + config.webserver.domain.v.s, config.webserver.tls.cert.v.s); } else { diff --git a/src/webserver/x509.c b/src/webserver/x509.c index 4eef2ccb..50b1af02 100644 --- a/src/webserver/x509.c +++ b/src/webserver/x509.c @@ -78,7 +78,7 @@ static int generate_private_key_ec(mbedtls_pk_context *key, return 0; } -bool generate_certificate(const char* certfile, bool rsa) +bool generate_certificate(const char* certfile, bool rsa, const char *domain) { int ret; mbedtls_x509write_cert crt; @@ -153,13 +153,21 @@ bool generate_certificate(const char* certfile, bool rsa) mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256); mbedtls_x509write_crt_set_subject_key(&crt, &key); mbedtls_x509write_crt_set_issuer_key(&crt, &key); - mbedtls_x509write_crt_set_subject_name(&crt, "CN=pi.hole"); mbedtls_x509write_crt_set_issuer_name(&crt, "CN=pi.hole"); mbedtls_x509write_crt_set_validity(&crt, "20010101000000", "20301231235959"); mbedtls_x509write_crt_set_basic_constraints(&crt, 0, -1); mbedtls_x509write_crt_set_subject_key_identifier(&crt); mbedtls_x509write_crt_set_authority_key_identifier(&crt); + // Set subject name depending on the (optionally) specified domain + { + char *subject_name = calloc(strlen(domain) + 4, sizeof(char)); + strcpy(subject_name, "CN="); + strcat(subject_name, domain); + mbedtls_x509write_crt_set_subject_name(&crt, subject_name); + free(subject_name); + } + // Export certificate in PEM format if((ret = mbedtls_x509write_crt_pem(&crt, cert_buffer, sizeof(cert_buffer), mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) diff --git a/src/webserver/x509.h b/src/webserver/x509.h index 3a783748..ad97537a 100644 --- a/src/webserver/x509.h +++ b/src/webserver/x509.h @@ -13,6 +13,6 @@ #include #include -bool generate_certificate(const char* certfile, bool rsa); +bool generate_certificate(const char* certfile, bool rsa, const char *domain); #endif // X509_H From 231f8f876edef99325fcfc223c0a65ffbd48dc03 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 10 Oct 2023 19:45:37 +0200 Subject: [PATCH 09/13] Fix endpoint security requirements for /info/login, /auth/totp, /info/client Signed-off-by: DL6ER --- src/api/docs/content/specs/auth.yaml | 1 + src/api/docs/content/specs/info.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/api/docs/content/specs/auth.yaml b/src/api/docs/content/specs/auth.yaml index 2a8df9ce..b8c819f2 100644 --- a/src/api/docs/content/specs/auth.yaml +++ b/src/api/docs/content/specs/auth.yaml @@ -155,6 +155,7 @@ components: tags: - Authentication operationId: "get_auth_totp" + security: [] description: Suggest new TOTP credentials for two-factor authentication (2FA) responses: '200': diff --git a/src/api/docs/content/specs/info.yaml b/src/api/docs/content/specs/info.yaml index b6d53978..34a50199 100644 --- a/src/api/docs/content/specs/info.yaml +++ b/src/api/docs/content/specs/info.yaml @@ -6,6 +6,7 @@ components: summary: Get information about requesting client tags: - "FTL information" + security: [] operationId: "get_client" description: | The property `timer` may contain additional details concerning a temporary en-/disabling. @@ -284,6 +285,7 @@ components: tags: - "FTL information" operationId: "get_logininfo" + security: [] description: | This API hook returns information used on the login page to possibly display messages/warnings. responses: From 05a4f728289742cdb90ddd38fecf6f400b6b5259 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 11 Oct 2023 20:20:54 +0200 Subject: [PATCH 10/13] Update SQLite3 to 3.43.2 Signed-off-by: DL6ER --- src/database/shell.c | 2 +- src/database/sqlite3.c | 45 ++++++++++++++++++++++++------------------ src/database/sqlite3.h | 6 +++--- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/database/shell.c b/src/database/shell.c index 6d63bfa1..ad855321 100644 --- a/src/database/shell.c +++ b/src/database/shell.c @@ -1262,7 +1262,7 @@ static void shellDtostr( char z[400]; if( n<1 ) n = 1; if( n>350 ) n = 350; - sprintf(z, "%#+.*e", n, r); + snprintf(z, sizeof(z)-1, "%#+.*e", n, r); sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); } diff --git a/src/database/sqlite3.c b/src/database/sqlite3.c index 72c40ffa..2a48e0c7 100644 --- a/src/database/sqlite3.c +++ b/src/database/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.43.1. By combining all the individual C code files into this +** version 3.43.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** d3a40c05c49e1a49264912b1a05bc2143ac. +** 310099cce5a487035fa535dd3002c59ac7f. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.43.1" -#define SQLITE_VERSION_NUMBER 3043001 -#define SQLITE_SOURCE_ID "2023-09-11 12:01:27 2d3a40c05c49e1a49264912b1a05bc2143ac0e7c3df588276ce80a4cbc9bd1b0" +#define SQLITE_VERSION "3.43.2" +#define SQLITE_VERSION_NUMBER 3043002 +#define SQLITE_SOURCE_ID "2023-10-10 12:14:04 4310099cce5a487035fa535dd3002c59ac7f1d1bec68d7cf317fd3e769484790" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -35185,29 +35185,29 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou double rr[2]; rr[0] = r; rr[1] = 0.0; - if( rr[0]>1.84e+19 ){ - while( rr[0]>1.84e+119 ){ + if( rr[0]>9.223372036854774784e+18 ){ + while( rr[0]>9.223372036854774784e+118 ){ exp += 100; dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); } - while( rr[0]>1.84e+29 ){ + while( rr[0]>9.223372036854774784e+28 ){ exp += 10; dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); } - while( rr[0]>1.84e+19 ){ + while( rr[0]>9.223372036854774784e+18 ){ exp += 1; dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } }else{ - while( rr[0]<1.84e-82 ){ + while( rr[0]<9.223372036854774784e-83 ){ exp -= 100; dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); } - while( rr[0]<1.84e+08 ){ + while( rr[0]<9.223372036854774784e+07 ){ exp -= 10; dekkerMul2(rr, 1.0e+10, 0.0); } - while( rr[0]<1.84e+18 ){ + while( rr[0]<9.22337203685477478e+17 ){ exp -= 1; dekkerMul2(rr, 1.0e+01, 0.0); } @@ -77024,6 +77024,7 @@ static int rebuildPage( int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ + assert( nCell>0 ); assert( i(u32)usableSize) ){ j = 0; } @@ -77330,6 +77331,7 @@ static int editPage( return SQLITE_OK; editpage_fail: /* Unable to edit this page. Rebuild it from scratch instead. */ + if( nNew<1 ) return SQLITE_CORRUPT_BKPT; populateCellCache(pCArray, iNew, nNew); return rebuildPage(pCArray, iNew, nNew, pPg); } @@ -100833,8 +100835,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ /* Set the value of register r[1] in the SQL statement to integer iRow. ** This is done directly as a performance optimization */ - v->aMem[1].flags = MEM_Int; - v->aMem[1].u.i = iRow; + sqlite3VdbeMemSetInt64(&v->aMem[1], iRow); /* If the statement has been run before (and is paused at the OP_ResultRow) ** then back it up to the point where it does the OP_NotExists. This could @@ -204134,6 +204135,7 @@ static void jsonReplaceFunc( } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; + pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); pParse->useMod = 1; @@ -204146,6 +204148,7 @@ static void jsonReplaceFunc( jsonReturnJson(pParse, pParse->aNode, ctx, 1); replace_err: jsonDebugPrintParse(pParse); + jsonParseFree(pParse); } @@ -204180,6 +204183,7 @@ static void jsonSetFunc( } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; + pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); bApnd = 0; @@ -204196,9 +204200,8 @@ static void jsonSetFunc( } jsonDebugPrintParse(pParse); jsonReturnJson(pParse, pParse->aNode, ctx, 1); - jsonSetDone: - /* no cleanup required */; + jsonParseFree(pParse); } /* @@ -239687,7 +239690,6 @@ static void fts5DoSecureDelete( int iIdx = 0; int iStart = 0; int iKeyOff = 0; - int iPrevKeyOff = 0; int iDelKeyOff = 0; /* Offset of deleted key, if any */ nIdx = nPg-iPgIdx; @@ -244249,6 +244251,9 @@ static int fts5FilterMethod( pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64); } + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + if( rc!=SQLITE_OK ) goto filter_out; + if( pTab->pSortCsr ){ /* If pSortCsr is non-NULL, then this call is being made as part of ** processing for a "... MATCH ORDER BY rank" query (ePlan is @@ -244271,7 +244276,9 @@ static int fts5FilterMethod( pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); }else if( pCsr->pExpr ){ - rc = fts5CursorParseRank(pConfig, pCsr, pRank); + if( rc==SQLITE_OK ){ + rc = fts5CursorParseRank(pConfig, pCsr, pRank); + } if( rc==SQLITE_OK ){ if( bOrderByRank ){ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; @@ -245752,7 +245759,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-09-11 12:01:27 2d3a40c05c49e1a49264912b1a05bc2143ac0e7c3df588276ce80a4cbc9bd1b0", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2023-10-10 12:14:04 4310099cce5a487035fa535dd3002c59ac7f1d1bec68d7cf317fd3e769484790", -1, SQLITE_TRANSIENT); } /* diff --git a/src/database/sqlite3.h b/src/database/sqlite3.h index b9d06929..03761134 100644 --- a/src/database/sqlite3.h +++ b/src/database/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.43.1" -#define SQLITE_VERSION_NUMBER 3043001 -#define SQLITE_SOURCE_ID "2023-09-11 12:01:27 2d3a40c05c49e1a49264912b1a05bc2143ac0e7c3df588276ce80a4cbc9bd1b0" +#define SQLITE_VERSION "3.43.2" +#define SQLITE_VERSION_NUMBER 3043002 +#define SQLITE_SOURCE_ID "2023-10-10 12:14:04 4310099cce5a487035fa535dd3002c59ac7f1d1bec68d7cf317fd3e769484790" /* ** CAPI3REF: Run-Time Library Version Numbers From 3630bb1adb6c3b235179546b986b9cf244e6031f Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 11 Oct 2023 22:08:31 +0200 Subject: [PATCH 11/13] Add new option dns.listeningMode = NONE Signed-off-by: DL6ER --- src/config/config.c | 3 ++- src/config/dnsmasq_config.c | 3 +++ src/datastructure.c | 4 ++++ src/enums.h | 3 ++- test/pihole.toml | 5 +++++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/config/config.c b/src/config/config.c index f15dd34b..8a90e87d 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -509,7 +509,8 @@ void initConfig(struct config *conf) { "LOCAL", "Allow only local requests. This setting accepts DNS queries only from hosts whose address is on a local subnet, i.e., a subnet for which an interface exists on the server. It is intended to be set as a default on installation, to allow unconfigured installations to be useful but also safe from being used for DNS amplification attacks if (accidentally) running public." }, { "SINGLE", "Permit all origins, accept only on the specified interface. Respond only to queries arriving on the specified interface. The loopback (lo) interface is automatically added to the list of interfaces to use when this option is used. Make sure your Pi-hole is properly firewalled!" }, { "BIND", "By default, FTL binds the wildcard address. If this is not what you want, you can use this option as it forces FTL to really bind only the interfaces it is listening on. Note that this may result in issues when the interface may go down (cable unplugged, etc.). About the only time when this is useful is when running another nameserver on the same port on the same machine. This may also happen if you run a virtualization API such as libvirt. When this option is used, IP alias interface labels (e.g. enp2s0:0) are checked rather than interface names." }, - { "ALL", "Permit all origins, accept on all interfaces. Make sure your Pi-hole is properly firewalled! This truly allows any traffic to be replied to and is a dangerous thing to do as your Pi-hole could become an open resolver. You should always ask yourself if the first option doesn't work for you as well." } + { "ALL", "Permit all origins, accept on all interfaces. Make sure your Pi-hole is properly firewalled! This truly allows any traffic to be replied to and is a dangerous thing to do as your Pi-hole could become an open resolver. You should always ask yourself if the first option doesn't work for you as well." }, + { "NONE", "Do not add any configuration concerning the listening mode to the dnsmasq configuration file. This is useful if you want to manually configure the listening mode in auxiliary configuration files. This option is really meant for advanced users only, support for this option may be limited." } }; CONFIG_ADD_ENUM_OPTIONS(conf->dns.listeningMode.a, listeningMode); } diff --git a/src/config/dnsmasq_config.c b/src/config/dnsmasq_config.c index f07ebe48..2b1f2e42 100644 --- a/src/config/dnsmasq_config.c +++ b/src/config/dnsmasq_config.c @@ -360,6 +360,9 @@ bool __attribute__((const)) write_dnsmasq_config(struct config *conf, bool test_ fprintf(pihole_conf, "interface=%s\n", interface); fputs("bind-interfaces\n", pihole_conf); break; + case LISTEN_NONE: + fputs("# No interface configuration applied, make sure to cover this yourself\n", pihole_conf); + break; } fputs("\n", pihole_conf); diff --git a/src/datastructure.c b/src/datastructure.c index 45d91716..7998d99b 100644 --- a/src/datastructure.c +++ b/src/datastructure.c @@ -1051,6 +1051,8 @@ const char * __attribute__ ((const)) get_listeningMode_str(const enum listening_ return "SINGLE"; case LISTEN_BIND: return "BIND"; + case LISTEN_NONE: + return "NONE"; } return NULL; } @@ -1065,6 +1067,8 @@ int __attribute__ ((pure)) get_listeningMode_val(const char *listeningMode) return LISTEN_SINGLE; else if(strcasecmp(listeningMode, "BIND") == 0) return LISTEN_BIND; + else if(strcasecmp(listeningMode, "NONE") == 0) + return LISTEN_NONE; // Invalid value return -1; diff --git a/src/enums.h b/src/enums.h index 49e660f3..4848c2ed 100644 --- a/src/enums.h +++ b/src/enums.h @@ -288,7 +288,8 @@ enum listening_mode { LISTEN_LOCAL, LISTEN_ALL, LISTEN_SINGLE, - LISTEN_BIND + LISTEN_BIND, + LISTEN_NONE } __attribute__ ((packed)); enum fifo_logs { diff --git a/test/pihole.toml b/test/pihole.toml index 878750f0..2bac9a11 100644 --- a/test/pihole.toml +++ b/test/pihole.toml @@ -159,6 +159,11 @@ # properly firewalled! This truly allows any traffic to be replied to and is a # dangerous thing to do as your Pi-hole could become an open resolver. You # should always ask yourself if the first option doesn't work for you as well. + # - "NONE" + # Do not add any configuration concerning the listening mode to the dnsmasq + # configuration file. This is useful if you want to manually configure the + # listening mode in auxiliary configuration files. This option is really meant + # for advanced users only, support for this option may be limited. listeningMode = "LOCAL" # Log DNS queries and replies to pihole.log From 39a6324426cf6643f17171414a4b4fc382267bae Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 11 Oct 2023 22:17:46 +0200 Subject: [PATCH 12/13] Fix wording of info message concerning self-generated TLS certificate. Before this commit, we incorrectly logged that we created a TLS certificate not only when we really did this but also after each restart when simply using it. Signed-off-by: DL6ER --- src/webserver/webserver.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c index 78de3c4e..67488233 100644 --- a/src/webserver/webserver.c +++ b/src/webserver/webserver.c @@ -296,11 +296,18 @@ void http_init(void) strlen(config.webserver.tls.cert.v.s) > 0) { // Try to generate certificate if not present - if(!file_readable(config.webserver.tls.cert.v.s) && - !generate_certificate(config.webserver.tls.cert.v.s, false, config.webserver.domain.v.s)) + if(!file_readable(config.webserver.tls.cert.v.s)) { - log_err("Generation of SSL/TLS certificate %s failed!", - config.webserver.tls.cert.v.s); + if(generate_certificate(config.webserver.tls.cert.v.s, false, config.webserver.domain.v.s)) + { + log_info("Created SSL/TLS certificate for %s at %s", + config.webserver.domain.v.s, config.webserver.tls.cert.v.s); + } + else + { + log_err("Generation of SSL/TLS certificate %s failed!", + config.webserver.tls.cert.v.s); + } } if(file_readable(config.webserver.tls.cert.v.s)) @@ -308,8 +315,8 @@ void http_init(void) options[++next_option] = "ssl_certificate"; options[++next_option] = config.webserver.tls.cert.v.s; - log_info("Created SSL/TLS certificate for %s at %s", - config.webserver.domain.v.s, config.webserver.tls.cert.v.s); + log_info("Using SSL/TLS certificate file %s", + config.webserver.tls.cert.v.s); } else { From 71f384f999ca53c6f1c0478d2e6274d0d413aff7 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 12 Oct 2023 18:12:27 +0200 Subject: [PATCH 13/13] Fix domain type and kind not being added for certain /api/domains calls This is a regression of https://github.com/pi-hole/FTL/pull/1649 Signed-off-by: DL6ER --- src/database/gravity-db.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/database/gravity-db.c b/src/database/gravity-db.c index 86488a0f..b978b12e 100644 --- a/src/database/gravity-db.c +++ b/src/database/gravity-db.c @@ -2207,9 +2207,14 @@ bool gravityDB_readTableGetRow(const enum gravity_list_type listtype, tablerow * // Convert to string if(listtype == GRAVITY_DOMAINLIST_ALLOW_EXACT || - listtype == GRAVITY_DOMAINLIST_DENY_EXACT || listtype == GRAVITY_DOMAINLIST_ALLOW_REGEX || - listtype == GRAVITY_DOMAINLIST_DENY_REGEX) + listtype == GRAVITY_DOMAINLIST_ALLOW_ALL || + listtype == GRAVITY_DOMAINLIST_DENY_EXACT || + listtype == GRAVITY_DOMAINLIST_DENY_REGEX || + listtype == GRAVITY_DOMAINLIST_DENY_ALL || + listtype == GRAVITY_DOMAINLIST_ALL_EXACT || + listtype == GRAVITY_DOMAINLIST_ALL_REGEX || + listtype == GRAVITY_DOMAINLIST_ALL_ALL) { switch(row->type_int) {