Files
ESP32_Serial_Swiss_Army_Knife/tests/ssh_auth_policy/README.md
T

2.6 KiB

SSH authentication admission policy host tests

Run from the repository root:

CCACHE_DISABLE=1 python3 tests/ssh_auth_policy/run.py
CCACHE_DISABLE=1 CFLAGS='-O1 -g -fsanitize=undefined -fno-sanitize-recover=all' python3 tests/ssh_auth_policy/run.py

Requires Python 3 and a host C11 compiler (cc, or CC). CFLAGS may override optimization/add sanitizers. The runner disables ccache, compiles the actual src/ssh_auth_policy.c with strict warnings, and runs in a temporary directory. No ESP-IDF, mocks, third-party dependencies, sleeps or real clock are involved.

Contract

ssh_auth_policy_t is zero-initialized, allocation-free, single-owner state (72 bytes on the tested host, compile-time limit of 72 bytes). Three independent buckets lazily start at capacity:

Kind Capacity Refill
SSH_AUTH_POLICY_HANDSHAKE 6 1 token / 10 seconds
SSH_AUTH_POLICY_VERIFICATION 6 1 token / 10 seconds
SSH_AUTH_POLICY_PROBE 12 1 token / 5 seconds

The header exposes each capacity and refill interval in microseconds. ssh_auth_policy_admit(policy, kind, now_us) consumes one token on success, with no refund for subsequent failure. Below capacity, fractional elapsed credit is retained. Reaching capacity discards all surplus, including fractional credit. Empty-bucket denials do not shift the refill deadline or incur debt.

Time must be nonnegative and nondecreasing across the shared policy, including across classes and ordinary rate-limit denials. Equal timestamps are valid. Negative/regressing time, invalid enum values and NULL fail closed without mutation. Refill arithmetic remains bounded through INT64_MAX.

The integrating SSH owner must retain ONE static policy across callers/sessions, SSH stop/start, and counter clears; only reboot zeroes it. There are no locks, timers, clock reads, sleeps, reset or refund APIs. These tests do not integrate ssh_transport or CMake, and do not validate lifecycle wiring.

Coverage

All three classes: initial burst at zero and INT64_MAX; refill boundaries at minus/exact/plus one microsecond; partial and multi-token credit; 998 consecutive exact-rate refill cycles with intervening denials; idle saturation with no fractional surplus; huge forward jumps including zero to INT64_MAX; negative and regressing time with byte-for-byte unchanged state; regression after an initial zero timestamp and after denial. Also checks invalid enum/NULL handling, independent class budgets, cross-class monotonic validation, and two logical callers sharing one exhausted budget.

Hardware validation is deferred to the combined Phase 9 validation.