Phase 8D.1 implemented and validated.
This commit is contained in:
@@ -102,6 +102,8 @@ HTTP Basic authentication uses `user_database`. Before administrator bootstrap,
|
||||
|
||||
The boot-local Basic-authentication cache has four RAM entries and a five-minute sliding lifetime. It stores a keyed digest of the complete `Authorization` header rather than the raw header, and every hit revalidates principal currentness. Its current lack of locking relies on the single-HTTPD-owner execution model.
|
||||
|
||||
Phase 8D.1 adds **dormant** `web_session_store` primitives alongside Basic auth: four static records with token/origin digests, copied principal, separate CSRF state, one-hour absolute expiry and non-reused 64-bit session IDs. No HTTP handler uses these sessions yet. A portMUX protects short state copies/mutations; database/RNG/SHA calls occur outside it. Resolution rechecks ID/expiry after database validation; issuance also checks an invalidation epoch. Stop wipes records without resetting IDs/epochs. Only admitted HTTPS starts initialize the store; failed starts and accepted stops disable it before cleanup. Store-init failure cannot fail existing Basic HTTPS. Session/user invalidation APIs do not yet close transports or receive account-mutation notifications (8D.2); HTTP Origin/CSRF enforcement is not implemented by these storage primitives. Sensitive views must be wiped by callers; snapshots contain only counts and storage sizes. Focused host checks live in `tests/web_session_store/`.
|
||||
|
||||
A WebSocket connection requires a one-time, principal-bound ticket with a maximum 30-second lifetime. Only four tickets can be outstanding; minting another evicts the live entry with the earliest expiry. Ticket issuance and upgrade also validate a supplied `Origin` against `https://<Host>`; absence of `Origin` is accepted for non-browser clients. Tickets are stored as digests, consumed before currentness validation, and are never persisted. An admitted session starts the serial service if necessary, creates a broker client, and opportunistically requests writer ownership. The web transport has two fixed session slots. Binary frames carry serial data; small text messages request or release writer ownership. HTTPD owns socket send/close operations, while the web transport task mediates broker work through bounded scheduling. The browser's combined Connect/Disconnect control closes the WebSocket and pauses automatic reconnect; after a user-paused disconnect it changes to Connect, which resumes connection attempts.
|
||||
|
||||
Web serial initialization is failure-isolated from the base HTTPS service: if the transport cannot initialize, `web_server_init()` can still succeed and serve authenticated non-WebSocket routes.
|
||||
|
||||
@@ -61,7 +61,7 @@ This is a semantic map, not a complete file inventory. Start here, then read the
|
||||
**Responsibility:** serve authenticated HTTPS UI/API, issue WebSocket tickets, and adapt browser serial sessions to broker clients.
|
||||
|
||||
- Files: `src/web_server.{h,c}`, `src/web_serial_transport.{h,c}`, `src/web_ui.{h,c}`, `src/web_console.{h,c}`
|
||||
- Security files: `src/web_security.{h,c}`
|
||||
- Security files: `src/web_security.{h,c}`; `src/web_session_store.{h,c}` contains dormant Phase 8D.1 cookie-session primitives, not active HTTP authentication.
|
||||
- Asset files: authored/generated boundary in `src/web_assets_data.{h,c}`, `web_assets/SOURCES.md`, `web_assets/generate_embedded_assets.py`
|
||||
- Interfaces: web init/start/stop/snapshots; HTTP handlers; ticket mint/consume; attach/detach; targeted session revocation
|
||||
- Called by: startup, ESP-IDF HTTPS server, user administration revocation, console/local UI
|
||||
@@ -69,6 +69,7 @@ This is a semantic map, not a complete file inventory. Start here, then read the
|
||||
- Flow: `browser -> HTTPS Basic auth -> ticket -> WebSocket -> web transport -> broker`
|
||||
- Ownership: HTTPD owns socket send/close work; transport task owns broker mediation; two fixed WebSocket slots and four outstanding tickets.
|
||||
- Security constraints: Basic-auth cache hits still revalidate principal currentness; the browser's combined Connect/Disconnect control closes the WebSocket and pauses automatic reconnect until Connect is selected. Changes to the authored inline loader must update its hard-coded CSP hash in the same change.
|
||||
- Session-store boundary: admitted HTTPS start initializes four static records; failed start/accepted stop disables and wipes them. No route/ticket/account-revocation binding yet. RNG/SHA/database calls run outside its short portMUX; ID/expiry/epoch checks reject stale work. Run focused host checks with `python3 tests/web_session_store/run.py`.
|
||||
- Asset constraint: `web_assets_data.c` is checked-in generated input to the build; do not hand-edit or regenerate casually.
|
||||
|
||||
## SSH
|
||||
|
||||
@@ -4,6 +4,8 @@ This file is working memory. Update it during active work and before handoff; do
|
||||
|
||||
## Development state
|
||||
|
||||
- **8D.1 target validation in progress (2026-09-05):** User supplied fresh-boot (UART stopped) and full-client-mix (115200 baud, SSH writer, admin SSH, USB and two web observers) samples, recorded separately in `docs/phase8d_baseline.md`. Loaded internal/DMA/PSRAM free bytes **41,420 / 33,664 / 8,162,824**, minima **19,384 / 11,628 / 8,115,028**; SSH stack minimum-free **16,288 B**. No reported SSH I/O or web failures; one cumulative SSH broker revocation retained without diagnosis. These supersede older statements below that no target samples exist, but are not full 8D.1 sign-off. Exact changed-firmware hash, lifecycle/HTTPS restart and soak/cleanup coverage remain pending. No continuation to 8D.2 requested.
|
||||
|
||||
- **8D.0 sign-off (2026-09-05):** User marked the baseline validated and identified tested source as latest checked-in revision `d8999cd4a96e477fabd392ced02d810c3cd22d0f`. Current samples and authoritative sign-off are in `docs/phase8d_baseline.md`; they supersede older baseline measurements/provenance notes below. User attributes SSH I/O errors to out-of-spec **460400-baud** testing, distinct from transcript UART configuration **460800**. Numeric reserve approval and 8D.1 post-change target validation remain pending; do not reopen 8D.0 solely for unrecorded checklist details or claim those checks were executed.
|
||||
|
||||
Based on checked-in source plus `README.md` and `docs/roadmap.md`:
|
||||
|
||||
Reference in New Issue
Block a user