Enable bounded browser account administration for Phase 8D.7
Allow other-account add/password and forced delete/role commands through shared dispatcher and handler policy. Keep self-target, generated-secret, key, bootstrap, and recovery workflows blocked. Revalidate currentness after password prompts and before database API admission. Document that admitted mutations may finish after disconnect, while subsequent stale operations must reject. Add policy, transaction-failure, cleanup, and targeted-revocation regressions. Record completed review, passing host tests and firmware build, with target validation and M2 acceptance still pending.
This commit is contained in:
@@ -132,6 +132,36 @@ static void test_currentness(void)
|
||||
admin_ssh_console_close(&a);
|
||||
puts("PASS: owner stale/account current isolation, callback close/reuse, revoked submitted prompts, periodic unanswered invalidation/stale wake, UART recovery, consumed output wiping");
|
||||
}
|
||||
static void test_dispatch_currentness(void)
|
||||
{
|
||||
++a.slot_generation; live[0]=true; principal_current=true;
|
||||
assert(admin_ssh_console_open_owned(&a,&admin,&owner)==ESP_OK);
|
||||
setup_dispatch();
|
||||
assert(admin_ssh_console_dispatch_is_current());
|
||||
current_task=(void *)2;
|
||||
assert(!admin_ssh_console_dispatch_is_current());
|
||||
current_task=s_task;
|
||||
live[0]=false;
|
||||
assert(!admin_ssh_console_dispatch_is_current());
|
||||
assert(!s_sessions[0].active);
|
||||
secure_wipe(&s_sessions[0],sizeof(s_sessions[0]));
|
||||
++a.slot_generation; live[0]=true;
|
||||
assert(admin_ssh_console_open_owned(&a,&admin,&owner)==ESP_OK);
|
||||
setup_dispatch(); principal_current=false;
|
||||
assert(!admin_ssh_console_dispatch_is_current());
|
||||
assert(!s_sessions[0].active);
|
||||
secure_wipe(&s_sessions[0],sizeof(s_sessions[0])); principal_current=true;
|
||||
++a.slot_generation;
|
||||
assert(admin_ssh_console_open_owned(&a,&admin,&owner)==ESP_OK);
|
||||
setup_dispatch(); s_dispatch_token.slot_generation--;
|
||||
assert(!admin_ssh_console_dispatch_is_current());
|
||||
assert(s_sessions[0].active); /* Stale dispatch cannot close replacement. */
|
||||
secure_wipe(&s_sessions[0],sizeof(s_sessions[0]));
|
||||
s_dispatch_remote=false;
|
||||
assert(admin_ssh_console_dispatch_is_current()); /* Trusted UART0. */
|
||||
puts("PASS: handler currentness API rejects wrong task, stale owner/account/token; preserves replacement and UART0");
|
||||
}
|
||||
|
||||
static void test_shared_admission(void)
|
||||
{
|
||||
admin_ssh_console_token_t web={.slot_index=255, .session_id=7,
|
||||
@@ -220,7 +250,12 @@ int main(void)
|
||||
++a.slot_generation; assert(admin_ssh_console_open_owned(&a,&admin,&owner)==ESP_OK);
|
||||
setup_dispatch(); clear_output(&a); prompt_hook=hidden_reply;
|
||||
uint8_t secret[32]; size_t n;
|
||||
uint8_t history_before[sizeof(s_sessions[0].history)];
|
||||
memcpy(history_before,s_sessions[0].history,sizeof(history_before));
|
||||
assert(admin_ssh_console_dispatch_is_current());
|
||||
assert(admin_ssh_console_dispatch_read_input("Password: ",secret,sizeof(secret),true,&n)==ESP_OK);
|
||||
assert(!memcmp(history_before,s_sessions[0].history,sizeof(history_before)));
|
||||
for (size_t i=0;i<sizeof(s_sessions[0].prompt_input);++i) assert(!s_sessions[0].prompt_input[i]);
|
||||
assert(n==6 && !memcmp(secret,"secret",6));
|
||||
assert(s_sessions[0].output_length==strlen("Password: \r\n"));
|
||||
clear_output(&a);
|
||||
@@ -277,5 +312,6 @@ int main(void)
|
||||
assert(ssh_output_write(&a,"x",1)==-1 && errno==EPIPE);
|
||||
assert(!lock_depth);
|
||||
test_currentness();
|
||||
test_dispatch_currentness();
|
||||
puts("PASS: admission/identity, two owners, completion contention/reopen, history, queued stale/revoked work, UART dispatch, hidden/disconnected prompts, exit-to-SELF_CLOSE, deferred rejection/drain/close, 5s output backpressure");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user