Add Bounded Web Admission Diagnostics

This commit is contained in:
2026-09-08 18:04:46 +02:00
parent 42f6423d4e
commit f6263042ff
17 changed files with 682 additions and 13 deletions
+12 -9
View File
@@ -79,6 +79,7 @@ typedef struct {
const uint8_t *servercert, *prvtkey_pem;
size_t servercert_len, prvtkey_len;
unsigned port_secure, tls_handshake_timeout_ms;
void (*user_cb)(void *);
} httpd_ssl_config_t;
/* Nonproduction defaults deliberately make explicit overrides observable. */
#define HTTPD_SSL_CONFIG_DEFAULT() ((httpd_ssl_config_t){.httpd = {.max_open_sockets = 1, .lru_purge_enable = true}})
@@ -104,9 +105,10 @@ static void xSemaphoreTake(SemaphoreHandle_t m, int wait) { (void)wait; assert(m
static void xSemaphoreGive(SemaphoreHandle_t m) { assert(m && locked); locked = 0; }
static void secure_wipe(void *p, size_t n) { assert(!locked); memset(p, 0, n); }
#define HANDLER(name) static esp_err_t name(httpd_req_t *r) { (void)r; assert(!"HTTP handler must not run in lifecycle harness"); return ESP_FAIL; }
HANDLER(root_handler) HANDLER(status_handler) HANDLER(ticket_handler)
HANDLER(websocket_handler) HANDLER(asset_handler) HANDLER(web_cookie_auth_handler)
HANDLER(web_admin_transport_ticket_handler) HANDLER(web_admin_transport_upgrade_handler)
HANDLER(root_handler) HANDLER(status_handler) HANDLER(traced_ticket_handler)
HANDLER(traced_websocket_handler) HANDLER(asset_handler) HANDLER(web_cookie_auth_handler)
HANDLER(traced_admin_ticket_handler) HANDLER(traced_admin_upgrade_handler)
static void web_diagnostics_tls(void *arg) { (void)arg; assert(false); }
HANDLER(serial_settings_handler)
HANDLER(web_serial_settings_handler) HANDLER(web_account_settings_handler)
HANDLER(web_account_generate_password_handler) HANDLER(web_account_keys_handler)
@@ -129,6 +131,7 @@ static esp_err_t httpd_ssl_start(httpd_handle_t *server, const httpd_ssl_config_
assert(config->httpd.max_uri_handlers == 24 && config->port_secure == 443);
assert(config->httpd.recv_wait_timeout == 1 && config->httpd.send_wait_timeout == 1);
assert(config->tls_handshake_timeout_ms == 5000);
assert(config->user_cb == web_diagnostics_tls);
assert(config->servercert_len == 1 && config->servercert[0] == 1);
assert(config->prvtkey_len == 1 && config->prvtkey_pem[0] == 2);
if (ssl_start_error != ESP_OK) return ssl_start_error;
@@ -297,8 +300,8 @@ int main(void) {
assert(route("/api/settings/serial")->handler == serial_settings_handler);
assert(keys_calls == 1 && route("/api/settings/accounts/keys")->handler == web_account_keys_handler);
const httpd_uri_t *ticket = route("/api/admin/ws-ticket"), *ws = route("/ws/admin");
assert(ticket->method == HTTP_POST && ticket->handler == web_admin_transport_ticket_handler && !ticket->is_websocket);
assert(ws->method == HTTP_GET && ws->handler == web_admin_transport_upgrade_handler && !ws->is_websocket);
assert(ticket->method == HTTP_POST && ticket->handler == traced_admin_ticket_handler && !ticket->is_websocket);
assert(ws->method == HTTP_GET && ws->handler == traced_admin_upgrade_handler && !ws->is_websocket);
assert(route("/ws/serial")->method == HTTP_GET && !route("/ws/serial")->is_websocket);
assert(route("/api/login")->method == HTTP_POST && route("/api/session")->method == HTTP_GET);
assert(web_server_start() == ESP_ERR_INVALID_STATE && auth_starts == 1 && ssl_starts == 1);
@@ -349,7 +352,7 @@ int main(void) {
assert(registered_count == 22 && unregister_calls == failure - 17);
for (unsigned i = 0; i < registered_count; ++i)
assert(strcmp(registered[i]->uri, "/api/admin/ws-ticket") && strcmp(registered[i]->uri, "/ws/admin"));
assert(route("/ws/serial")->handler == websocket_handler);
assert(route("/ws/serial")->handler == traced_websocket_handler);
assert(route("/api/session")->handler == web_cookie_auth_handler);
assert(web_server_start() == ESP_ERR_INVALID_STATE && ssl_starts == 1);
clear_events(); assert(web_server_stop() == ESP_OK && !strcmp(events, "ASH"));
@@ -366,7 +369,7 @@ int main(void) {
assert(!admin_inits && !admin_attaches && !admin_owned && !s_admin_transport_owned);
ticket = route("/api/admin/ws-ticket");
assert(ticket->method == HTTP_POST && !ticket->is_websocket &&
ticket->handler == web_admin_transport_ticket_handler);
ticket->handler == traced_admin_ticket_handler);
for (unsigned i = 0; i < registered_count; ++i) assert(strcmp(registered[i]->uri, "/ws/admin"));
/* Handler identity is checked, not its authentication implementation (doubled). */
assert(!auth_stops && !ssl_stops && !s_transitioning && s_last_error == ESP_OK);
@@ -451,8 +454,8 @@ int main(void) {
assert(route("/api/settings/accounts")->handler == web_account_settings_handler);
assert(route("/api/settings/accounts/generate-password")->handler == web_account_generate_password_handler);
assert(route("/api/session")->handler == web_cookie_auth_handler);
assert(route("/ws/serial")->handler == websocket_handler);
assert(route("/ws/admin")->handler == web_admin_transport_upgrade_handler);
assert(route("/ws/serial")->handler == traced_websocket_handler);
assert(route("/ws/admin")->handler == traced_admin_upgrade_handler);
account_mutations = 0;
for (unsigned i = 0; i < registered_count; ++i) {
assert(strcmp(registered[i]->uri, "/api/settings/accounts/keys"));