Add SSH Console Ownership Boundary (Phase 8D.4)
Implement transport-qualified session identity and immutable owner adapters for SSH console lifecycle and output-drain operations. Add focused host tests covering admission, stale identities, deferred actions, completion races, prompts, backpressure, and slot reuse. Update Phase 8D documentation and current-state tracking.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
|
||||
#define SSH_TRANSPORT_MAX_SESSIONS 2U
|
||||
typedef struct { bool active, tx_pending; uint32_t session_id, generation; } ssh_transport_session_snapshot_t;
|
||||
static ssh_transport_session_snapshot_t s_session_snapshots[2];
|
||||
static unsigned stopped, disconnected, rotated, reset, restarted;
|
||||
static esp_err_t ssh_transport_stop(void) { ++stopped; return ESP_OK; }
|
||||
static esp_err_t ssh_transport_disconnect(uint32_t id) { disconnected=id; return ESP_OK; }
|
||||
static esp_err_t ssh_transport_replace_host_key(bool r) { if(r) ++reset; else ++rotated; return ESP_OK; }
|
||||
static void esp_restart(void) { ++restarted; }
|
||||
static bool admin_console_drained(const admin_ssh_console_token_t *);
|
||||
static esp_err_t admin_console_perform(const admin_ssh_console_token_t *, admin_ssh_deferred_action_type_t, uint32_t);
|
||||
static void test_adapter(void)
|
||||
{
|
||||
admin_ssh_console_token_t token={ .slot_index=0, .session_id=7, .slot_generation=3 };
|
||||
user_principal_t admin={ .role=USER_ROLE_ADMIN };
|
||||
assert(admin_ssh_console_init()==ESP_OK);
|
||||
assert(admin_ssh_console_start_uart_frontend()==ESP_OK);
|
||||
assert(admin_ssh_console_open(&token,&admin)==ESP_OK);
|
||||
assert(!admin_console_drained(&token));
|
||||
s_session_snapshots[0]=(ssh_transport_session_snapshot_t){ .active=true, .session_id=7, .generation=3 };
|
||||
assert(admin_console_drained(&token));
|
||||
token.transport=1; assert(!admin_console_drained(&token));
|
||||
assert(admin_ssh_console_open(&token,&admin)==ESP_ERR_INVALID_ARG);
|
||||
token.transport=0; token.slot_generation=4; assert(!admin_console_drained(&token));
|
||||
assert(admin_console_perform(&token,ADMIN_SSH_DEFER_STOP,0)==ESP_ERR_NOT_FOUND && stopped==0);
|
||||
token.slot_generation=3; s_session_snapshots[0].tx_pending=true;
|
||||
assert(!admin_console_drained(&token)); s_session_snapshots[0].tx_pending=false;
|
||||
assert(admin_console_perform(&token,ADMIN_CONSOLE_DEFER_SELF_CLOSE,99)==ESP_OK && disconnected==7);
|
||||
assert(admin_console_perform(&token,ADMIN_SSH_DEFER_DISCONNECT,99)==ESP_OK && disconnected==99);
|
||||
assert(admin_console_perform(&token,ADMIN_SSH_DEFER_STOP,0)==ESP_OK && stopped==1);
|
||||
assert(admin_console_perform(&token,ADMIN_SSH_DEFER_HOST_KEY_ROTATE,0)==ESP_OK && rotated==1);
|
||||
assert(admin_console_perform(&token,ADMIN_SSH_DEFER_HOST_KEY_RESET,0)==ESP_OK && reset==1);
|
||||
assert(admin_console_perform(&token,ADMIN_SSH_DEFER_REBOOT,0)==ESP_OK && restarted==1);
|
||||
puts("PASS: actual SSH adapter identity/drain checks, legacy admission and lifecycle action routing");
|
||||
}
|
||||
Reference in New Issue
Block a user