feat(agent): v2 secure-session-core Task 6 - full key fidelity
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m1s
Build and Test / Build Server (Linux) (push) Successful in 11m32s
Build and Test / Security Audit (push) Successful in 4m31s
Build and Test / Build Summary (push) Successful in 11s

SPEC-002 Phase 1 Task 6, code-reviewed APPROVED (2 rounds), locally verified
(cargo fmt + clippy -D warnings exit 0 + cargo test --workspace 70 pass + build).

- Viewer WH_KEYBOARD_LL hook diverts system combos (Win/Win+R, Alt+Tab, Alt+Esc,
  Ctrl+Esc) to the remote as a full KeyEvent (vk + scan + is_extended + modifiers)
  and suppresses local handling - GATED on the viewer window having focus AND a
  "send system keys" toggle (default on; Pause/Break host-key), so it never bricks
  the technician's local keyboard when unfocused.
- Agent injection via SendInput KEYEVENTF_SCANCODE + correct KEYEVENTF_EXTENDEDKEY
  (right Ctrl/Alt, arrows, nav, Win, NumLock, numpad Divide) - layout-independent,
  extended-key-correct.
- Ctrl+Alt+Del completes through the SAS helper (SYSTEM SendSAS); installer sets
  the SoftwareSASGeneration policy; 3-tier fail-loud (no false success). SAS named
  pipe DACL tightened from NULL/Everyone to Authenticated Users.
- Modifier hygiene: viewer emits key-ups for held Ctrl/Alt/Shift/Win on focus loss
  / close so modifiers never stick on the remote.
- proto: KeyEvent.is_extended = 7 (additive; older agents derive the flag).

Closes Win+R / Ctrl+C-V / Ctrl+Alt+Del / arrows-vs-numpad fidelity. Live on-device
testing is plan Task 8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 09:16:26 -07:00
parent d0de888dd1
commit bb73ba667f
8 changed files with 848 additions and 133 deletions

View File

@@ -616,7 +616,15 @@ impl SessionManager {
Some(message::Payload::KeyEvent(key)) => {
if let Some(input) = self.input.as_mut() {
input.key_event(key.vk_code as u16, key.down)?;
// Full-fidelity scan-code injection: pass the viewer-captured
// scan code and extended-key flag through. A scan_code of 0 (older
// viewers / synthesized events) makes the agent derive it from the VK.
input.key_event_full(
key.vk_code as u16,
key.scan_code as u16,
key.is_extended,
key.down,
)?;
}
}