Replace Web Basic Auth With Cookie Sessions
Add bounded login challenges, CSRF/origin enforcement, logout, and session-bound WebSocket admission. Isolate private HTTPD access behind a version-guarded adapter and add focused host coverage. Also let empty admin SSH input reach the normal console handler.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Focused policy test: actual project helper plus installed IDF argv parser.
|
||||
|
||||
Requires Python 3, cc and IDF_PATH (defaults to PlatformIO's installed SDK).
|
||||
Does not run FreeRTOS dispatch, SSH I/O or target hardware.
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
IDF = Path(os.environ.get("IDF_PATH", str(Path.home() / ".platformio/packages/framework-espidf")))
|
||||
source = (ROOT / "src/admin_ssh_console.c").read_text()
|
||||
start = source.index("static bool remote_command_allowed(")
|
||||
helper = source[start:source.index("\n}", start) + 2]
|
||||
prelude = r'''
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#define ADMIN_SSH_CONSOLE_COMMAND_LINE_CAPACITY 256U
|
||||
#define ADMIN_SSH_CONSOLE_MAX_ARGUMENTS 10U
|
||||
typedef struct { char line[ADMIN_SSH_CONSOLE_COMMAND_LINE_CAPACITY + 1U]; } admin_request_t;
|
||||
size_t esp_console_split_argv(char *, char **, size_t);
|
||||
static void secure_wipe(void *p, size_t n) {
|
||||
volatile unsigned char *bytes = p;
|
||||
while (n--) *bytes++ = 0;
|
||||
}
|
||||
'''
|
||||
cases = r'''
|
||||
int main(void) {
|
||||
const struct { const char *line; bool allowed; } cases[] = {
|
||||
{"", true}, {" ", true}, {" ", true},
|
||||
{"memory", true}, {"user", true}, {"user list", true},
|
||||
{"user show bootstrap", true}, {"exit", true},
|
||||
{"user bootstrap", false}, {"user bootstrap extra", false},
|
||||
{"user recover", false}, {"user recover --force", false},
|
||||
{" user recover --force ", false},
|
||||
{"\"user\" \"bootstrap\"", false},
|
||||
{"\"user\" \"recover\" --force", false},
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(cases)/sizeof(cases[0]); ++i) {
|
||||
admin_request_t request = {0};
|
||||
strcpy(request.line, cases[i].line);
|
||||
assert(remote_command_allowed(&request) == cases[i].allowed);
|
||||
assert(!strcmp(request.line, cases[i].line));
|
||||
}
|
||||
puts("PASS: empty input/ordinary commands allowed; physical-only commands (including quoted forms) remain denied");
|
||||
}
|
||||
'''
|
||||
with tempfile.TemporaryDirectory(prefix="admin-ssh-policy-") as directory:
|
||||
path = Path(directory)
|
||||
(path / "test.c").write_text(prelude + helper + cases)
|
||||
subprocess.run(["cc", "-std=c11", "-Wall", "-Wextra", "-Werror",
|
||||
str(path / "test.c"), str(IDF / "components/console/split_argv.c"),
|
||||
"-o", str(path / "test")], check=True, timeout=30)
|
||||
subprocess.run([str(path / "test")], check=True, timeout=10)
|
||||
Reference in New Issue
Block a user