Skip to content

Commit 37f9a96

Browse files
authored
Merge pull request #2296 from pi-hole/development
Pi-hole FTL v6.0.3
2 parents ac500d5 + f0a4ac1 commit 37f9a96

39 files changed

+541
-235
lines changed

patch/civetweb.sh

+3
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ patch -p1 < patch/civetweb/0001-Register-CSRF-token-in-conn-request_info.patch
2020
echo "Applying patch 0001-Log-debug-messages-to-webserver.log-when-debug.webse.patch"
2121
patch -p1 < patch/civetweb/0001-Log-debug-messages-to-webserver.log-when-debug.webse.patch
2222

23+
echo "Applying patch 0001-Expose-bound-to-addresses-from-CivetWeb-to-the-front.patch"
24+
patch -p1 < patch/civetweb/0001-Expose-bound-to-addresses-from-CivetWeb-to-the-front.patch
25+
2326
echo "ALL PATCHES APPLIED OKAY"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
From 0bee9e9f7942c5b73a715eaeadf5ab2d09a8c74d Mon Sep 17 00:00:00 2001
2+
From: DL6ER <[email protected]>
3+
Date: Sat, 22 Feb 2025 18:33:25 +0100
4+
Subject: [PATCH] Expose bound-to addresses from CivetWeb to the frontend
5+
6+
Signed-off-by: DL6ER <[email protected]>
7+
---
8+
src/webserver/civetweb/civetweb.c | 1 +
9+
src/webserver/civetweb/civetweb.h | 6 ++++++
10+
2 files changed, 7 insertions(+)
11+
12+
diff --git a/src/webserver/civetweb/civetweb.c b/src/webserver/civetweb/civetweb.c
13+
index fa908e54..66fcab01 100644
14+
--- a/src/webserver/civetweb/civetweb.c
15+
+++ b/src/webserver/civetweb/civetweb.c
16+
@@ -3339,6 +3339,7 @@ mg_get_server_ports(const struct mg_context *ctx,
17+
ports[cnt].is_ssl = ctx->listening_sockets[i].is_ssl;
18+
ports[cnt].is_redirect = ctx->listening_sockets[i].ssl_redir;
19+
ports[cnt].is_optional = ctx->listening_sockets[i].is_optional;
20+
+ memcpy(&ports[cnt].addr, &ctx->listening_sockets[i].lsa, sizeof(ports[cnt].addr));
21+
22+
if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET) {
23+
/* IPv4 */
24+
diff --git a/src/webserver/civetweb/civetweb.h b/src/webserver/civetweb/civetweb.h
25+
index eee958b4..6dcfa457 100644
26+
--- a/src/webserver/civetweb/civetweb.h
27+
+++ b/src/webserver/civetweb/civetweb.h
28+
@@ -23,6 +23,8 @@
29+
#ifndef CIVETWEB_HEADER_INCLUDED
30+
#define CIVETWEB_HEADER_INCLUDED
31+
32+
+#include <netinet/in.h> /* Pi-hole extension */
33+
+
34+
#define CIVETWEB_VERSION "1.17"
35+
#define CIVETWEB_VERSION_MAJOR (1)
36+
#define CIVETWEB_VERSION_MINOR (17)
37+
@@ -721,6 +723,10 @@ struct mg_server_port {
38+
int _reserved2;
39+
int _reserved3;
40+
int _reserved4;
41+
+ union {
42+
+ struct sockaddr_in sa4; /* Pi-hole extension */
43+
+ struct sockaddr_in6 sa6; /* Pi-hole extension */
44+
+ } addr;
45+
};
46+
47+
/* Legacy name */
48+
--
49+
2.43.0
50+

src/FTL.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@
5959
#define MAXITER 1000
6060

6161
// How many hours do we want to store in FTL's memory? [hours]
62-
#define MAXLOGAGE 24
62+
#define MAXLOGAGE 24u
6363

6464
// Interval for overTime data [seconds]
6565
// Default: 600 (10 minutes)
66-
#define OVERTIME_INTERVAL 600
66+
#define OVERTIME_INTERVAL 600u
6767

6868
// How many overTime slots do we need?
6969
// This is the maximum log age divided by the overtime interval

src/api/2fa.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
#include "webserver/json_macros.h"
1414
#include "log.h"
1515
#include "config/config.h"
16-
// getrandom()
17-
#include "daemon.h"
1816
// generate_password()
1917
#include "config/password.h"
2018

@@ -269,10 +267,8 @@ int generateTOTP(struct ftl_conn *api)
269267
{
270268
// Generate random secret using the system's random number generator
271269
uint8_t random_secret[RFC6238_SECRET_LEN];
272-
if(getrandom(random_secret, sizeof(random_secret), 0) < (ssize_t)sizeof(random_secret))
273-
{
270+
if(!get_secure_randomness(random_secret, sizeof(random_secret)))
274271
return send_json_error(api, 500, "internal_error", "Failed to generate random secret", strerror(errno));
275-
}
276272

277273
// Encode base32 secret
278274
const size_t base32_len = sizeof(random_secret)*8/5+1;

src/api/auth.c

+3-5
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ static int send_api_auth_status(struct ftl_conn *api, const int user_id, const t
401401
const int code = delete_session(user_id) ? 204 : 404;
402402

403403
// Send empty reply with appropriate HTTP status code
404-
send_http_code(api, "application/json; charset=utf-8", code, "");
404+
send_http_code(api, NULL, code, "");
405405
return code;
406406
}
407407
else
@@ -435,11 +435,9 @@ static int send_api_auth_status(struct ftl_conn *api, const int user_id, const t
435435
static void generateSID(char *sid)
436436
{
437437
uint8_t raw_sid[SID_SIZE];
438-
if(getrandom(raw_sid, sizeof(raw_sid), 0) < 0)
439-
{
440-
log_err("getrandom() failed in generateSID()");
438+
if(!get_secure_randomness(raw_sid, sizeof(raw_sid)))
441439
return;
442-
}
440+
443441
base64_encode_raw(NETTLE_SIGN sid, SID_BITSIZE/8, raw_sid);
444442
sid[SID_SIZE-1] = '\0';
445443
}

src/api/config.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,7 @@ static int api_config_put_delete(struct ftl_conn *api)
10081008
if(!new_item->c(&new_item->v, new_item->k, errbuf))
10091009
{
10101010
free_config(&newconf);
1011+
free_config_path(requested_path);
10111012
return send_json_error(api, 400,
10121013
"bad_request",
10131014
"Invalid value",
@@ -1032,13 +1033,15 @@ static int api_config_put_delete(struct ftl_conn *api)
10321033
// Error 404 if config element not found
10331034
if(!found)
10341035
{
1036+
free_config(&newconf);
10351037
cJSON *json = JSON_NEW_OBJECT();
10361038
JSON_SEND_OBJECT_CODE(json, 404);
10371039
}
10381040

10391041
// Error 400 if unique item already present
10401042
if(message != NULL)
10411043
{
1044+
free_config(&newconf);
10421045
return send_json_error(api, 400,
10431046
"bad_request",
10441047
message,
@@ -1081,8 +1084,17 @@ static int api_config_put_delete(struct ftl_conn *api)
10811084

10821085
// Send empty reply with matching HTTP status code
10831086
// 201 - Created or 204 - No content
1084-
cJSON *json = JSON_NEW_OBJECT();
1085-
JSON_SEND_OBJECT_CODE(json, api->method == HTTP_PUT ? 201 : 204);
1087+
if(api->method == HTTP_PUT)
1088+
{
1089+
cJSON *json = JSON_NEW_OBJECT();
1090+
JSON_SEND_OBJECT_CODE(json, 201);
1091+
}
1092+
else
1093+
{
1094+
// 204 - No content
1095+
send_http_code(api, NULL, 204, "");
1096+
return 204;
1097+
}
10861098
}
10871099

10881100
// Endpoint /api/config router

src/api/docs/content/specs/clients.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ components:
5555
- $ref: 'clients.yaml#/components/schemas/clients/put'
5656
- $ref: 'common.yaml#/components/schemas/took'
5757
responses:
58-
'201':
59-
description: Created item
58+
'200':
59+
description: Created or Updated Item
6060
content:
6161
application/json:
6262
schema:

src/api/docs/content/specs/config.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ components:
409409
type: string
410410
threads:
411411
type: integer
412+
headers:
413+
type: array
414+
items:
415+
type: string
412416
session:
413417
type: object
414418
properties:
@@ -744,6 +748,12 @@ components:
744748
acl: "+0.0.0.0/0,::/0"
745749
port: 80,[::]:80
746750
threads: 0
751+
headers:
752+
- "Content-Security-Policy: default-src 'self' 'unsafe-inline';"
753+
- "X-Frame-Options: DENY"
754+
- "X-XSS-Protection: 0"
755+
- "X-Content-Type-Options: nosniff"
756+
- "Referrer-Policy: strict-origin-when-cross-origin"
747757
session:
748758
timeout: 300
749759
restore: true

src/api/docs/content/specs/domains.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ components:
7979
- $ref: 'domains.yaml#/components/schemas/domains/put'
8080
- $ref: 'common.yaml#/components/schemas/took'
8181
responses:
82-
'201':
83-
description: Created domain
82+
'200':
83+
description: Created or Updated domain
8484
content:
8585
application/json:
8686
schema:

src/api/docs/content/specs/groups.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ components:
5454
schema:
5555
$ref: 'groups.yaml#/components/schemas/groups/put'
5656
responses:
57-
'201':
58-
description: Created item
57+
'200':
58+
description: Created or Updated Item
5959
content:
6060
application/json:
6161
schema:

src/api/docs/content/specs/history.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ components:
88
- Metrics
99
operationId: "get_activity_metrics"
1010
description: |
11-
Request data needed to generate the \"Query over last 24 hours\" graph. The sum of the values in the individual data arrays may be smaller than the total number of queries for the corresponding timestamp. The remaining queries are queries that do not fit into the shown categories (e.g. database busy, unknown status queries, etc.).
11+
Request data needed to generate the total queries over time graph. The sum of the values in the individual data arrays may be smaller than the total number of queries for the corresponding timestamp. The remaining queries are queries that do not fit into the shown categories (e.g. database busy, unknown status queries, etc.).
1212
responses:
1313
'200':
1414
description: OK

src/api/docs/content/specs/lists.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ components:
5454
schema:
5555
$ref: 'lists.yaml#/components/schemas/lists/put'
5656
responses:
57-
'201':
58-
description: Created item
57+
'200':
58+
description: Created or Updated Item
5959
content:
6060
application/json:
6161
schema:

src/api/history.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@
1818
#include "overTime.h"
1919
// config struct
2020
#include "config/config.h"
21+
// get_max_overtime_slot()
22+
#include "gc.h"
2123

2224
int api_history(struct ftl_conn *api)
2325
{
2426
lock_shm();
2527

26-
// Loop over all overTime slots and add them to the array
2728
cJSON *history = JSON_NEW_ARRAY();
28-
for(unsigned int slot = 0; slot < OVERTIME_SLOTS; slot++)
29+
const unsigned int max_slot = get_max_overtime_slot();
30+
// Loop over all overTime slots and add them to the array
31+
for(unsigned int slot = 0; slot <= max_slot; slot++)
2932
{
3033
cJSON *item = JSON_NEW_OBJECT();
3134
JSON_ADD_NUMBER_TO_OBJECT(item, "timestamp", overTime[slot].timestamp);
@@ -148,7 +151,8 @@ int api_history_clients(struct ftl_conn *api)
148151
int others_total = 0;
149152

150153
cJSON *history = JSON_NEW_ARRAY();
151-
for(unsigned int slot = 0; slot < OVERTIME_SLOTS; slot++)
154+
const unsigned int max_slot = get_max_overtime_slot();
155+
for(unsigned int slot = 0; slot <= max_slot; slot++)
152156
{
153157
cJSON *item = JSON_NEW_OBJECT();
154158
JSON_ADD_NUMBER_TO_OBJECT(item, "timestamp", overTime[slot].timestamp);

src/api/info.c

+3-10
Original file line numberDiff line numberDiff line change
@@ -974,16 +974,9 @@ static int api_info_messages_DELETE(struct ftl_conn *api)
974974
char *endptr = NULL;
975975
long int idval = strtol(token, &endptr, 10);
976976
if(errno != 0 || endptr == token || *endptr != '\0' || idval < 0)
977-
{
978-
// Send error reply
979-
free(id);
980-
return send_json_error(api, 400, // 400 Bad Request
981-
"uri_error",
982-
"Invalid ID in path",
983-
api->action_path);
984-
}
985-
986-
cJSON_AddNumberToObject(ids, "id", idval);
977+
log_warn("API: URI error - skipping invalid ID in path (%s): %s", api->action_path, token);
978+
else
979+
cJSON_AddNumberToArray(ids, idval);
987980

988981
// Get next token
989982
token = strtok_r(NULL, ",", &saveptr);

0 commit comments

Comments
 (0)