#!/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 #include #include #include #include #include #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)