feat: add bounded admin WebSocket backend (Phase 8D.5)
- Require current admin cookie sessions, Origin checks and single-use tickets - Reuse the shared console with session-aware authorization and slot allocation - Add HTTPD-owned I/O, bounded buffering and revocation cleanup - Prevent LRU eviction of serial clients and stale admin socket closure - Reject unsupported web-shell mutations before side effects - Add host regressions, a smoke client and resource accounting Validated by user sign-off after a 15-minute full-client soak at 230400 baud, with a few broker drops under heavy output. Browser UI remains for Phase 8D.6; numeric memory reserves remain open.
This commit is contained in:
@@ -4,10 +4,13 @@
|
||||
No target scheduler, socket library, or hardware execution is claimed.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
IDF = Path(os.environ.get("IDF_PATH", str(Path.home() / ".platformio/packages/framework-espidf")))
|
||||
parser = str(IDF / "components/console/split_argv.c")
|
||||
source = (ROOT / "src/admin_ssh_console.c").read_text()
|
||||
header = (ROOT / "src/admin_ssh_console.h").read_text()
|
||||
def strip_includes(text):
|
||||
@@ -21,18 +24,18 @@ with tempfile.TemporaryDirectory(prefix="admin-console-boundary-") as directory:
|
||||
+ (ROOT / "tests/admin_console_boundary/test.c").read_text())
|
||||
(path / "test.c").write_text(unit)
|
||||
subprocess.run(["cc", "-std=c11", "-Wall", "-Wextra", "-Werror",
|
||||
"-g", str(path / "test.c"),
|
||||
"-g", str(path / "test.c"), parser,
|
||||
"-o", str(path / "test")], check=True, timeout=30)
|
||||
subprocess.run([str(path / "test")], check=True, timeout=10)
|
||||
ssh = (ROOT / "src/ssh_transport.c").read_text()
|
||||
adapter = ssh[ssh.index("static bool admin_console_drained("):
|
||||
ssh.index("static bool consume_external_close(")]
|
||||
adapter = ssh[ssh.index("static admin_ssh_console_token_t admin_console_token("):
|
||||
ssh.index("static void *ssh_malloc(")]
|
||||
unit = ((ROOT / "tests/admin_console_boundary/fakes.h").read_text()
|
||||
+ strip_includes(header) + "\n" + strip_includes(source)
|
||||
+ (ROOT / "tests/admin_console_boundary/adapter.c").read_text()
|
||||
+ adapter + "\nint main(void) { test_adapter(); }\n")
|
||||
(path / "adapter.c").write_text(unit)
|
||||
subprocess.run(["cc", "-std=c11", "-Wall", "-Wextra", "-Werror",
|
||||
"-Wno-unused-variable", str(path / "adapter.c"),
|
||||
"-Wno-unused-variable", str(path / "adapter.c"), parser,
|
||||
"-o", str(path / "adapter")], check=True, timeout=30)
|
||||
subprocess.run([str(path / "adapter")], check=True, timeout=10)
|
||||
|
||||
Reference in New Issue
Block a user