feat: authenticate Windows command launcher and signal helper
This commit is contained in:
@@ -1937,12 +1937,14 @@ import Windows APIs. Keep launch phases identical across platforms:
|
||||
|
||||
The first native adapter is now required to expose this contract through
|
||||
`internal/client/supervisor.Supervisor`: the non-Windows adapter is test-only,
|
||||
while the Windows implementation must perform token selection and Job setup
|
||||
inside the same `Start` call. It may return only after the child has been
|
||||
assigned to its kill-on-close Job and released; all token/session attempts must
|
||||
be represented in the returned immutable identity. A failed start clears the
|
||||
pre-launch barrier and produces one rejected lifecycle event; an uncertain
|
||||
authorized row is never retried as a fresh process.
|
||||
while the Windows implementation must perform token selection, launcher
|
||||
authentication, and Job setup inside the same `Start` call. It may return only
|
||||
after the launcher and shell are prepared, suspended, and assigned to the
|
||||
kill-on-close Job; `Process.Release` crosses the later durable authorization
|
||||
barrier. All token/session attempts must be represented in the returned
|
||||
immutable identity. A failed start clears the pre-launch barrier and produces
|
||||
one rejected lifecycle event; an uncertain authorized row is never retried as a
|
||||
fresh process.
|
||||
|
||||
Implement one exhaustive token selector; do not scatter token fallback across
|
||||
launch code:
|
||||
@@ -2045,6 +2047,27 @@ effective token SID the required access.
|
||||
Service exit therefore kills launcher, shell, and descendants in every crash
|
||||
window. Recovery never signals or kills by PID alone.
|
||||
|
||||
The Windows implementation uses the same signed `rvbox.exe` for the private
|
||||
`--launcher` and `--signal-helper` modes. The service creates one random
|
||||
per-command generation and four byte-mode named pipes (`control`, `stdin`,
|
||||
`stdout`, `stderr`) with a protected DACL containing only SYSTEM and the
|
||||
effective token SID plus `PIPE_REJECT_REMOTE_CLIENTS`. The launcher receives
|
||||
only the opaque channel name on its command line. Every control frame has a
|
||||
fixed magic/version/type/generation/length/checksum header and a bounded JSON
|
||||
payload; the service rejects a peer before reading launch material unless the
|
||||
pipe client PID, process-creation `FILETIME`, token SID, session ID, and frame
|
||||
generation all match the suspended process it created. The shell inherits only
|
||||
the three explicitly listed stdio pipe handles. `Process.Release` writes the
|
||||
authorized frame and waits for the launcher's release acknowledgement.
|
||||
|
||||
TERM starts a separate helper with a fresh one-pipe generation under the same
|
||||
verified effective token/session. The helper authenticates identically, then
|
||||
receives the target PID and creation time over the pipe, reopens the target,
|
||||
checks creation time/SID/session, attaches to its private console, and emits a
|
||||
bounded result. It receives no Job or stdio handle. A helper creation or attach
|
||||
failure is recorded and may use the verified direct attach fallback before the
|
||||
configured grace-period Job escalation.
|
||||
|
||||
Do not combine `CREATE_NEW_PROCESS_GROUP` with `CREATE_NEW_CONSOLE`: Windows
|
||||
ignores the former, and it is unnecessary because every command owns a distinct
|
||||
hidden console. For TERM, start a short-lived private signal-helper mode of the
|
||||
|
||||
+10
-3
@@ -61,9 +61,16 @@ that command text is accepted once, output is journaled, lifecycle/terminal
|
||||
events are durable, and a script cannot launch before its contiguous upload is
|
||||
committed. The Windows build uses the same executor contract with the
|
||||
platform-native adapter: a verified token is selected, the child is created
|
||||
suspended, assigned to a kill-on-close Job, and only then released. The
|
||||
durable `launch_phase` barrier is recovered as `interrupted` after a daemon
|
||||
restart, so an uncertain release is never redispatched.
|
||||
suspended, assigned to a kill-on-close Job, and held behind an authenticated
|
||||
per-command launcher pipe. The daemon records `launch_prepared`, then the
|
||||
durable `launch_authorized` transition sends the launcher's release frame; the
|
||||
launcher resumes the shell only after that acknowledgement. The durable
|
||||
`launch_phase` barrier is recovered as `interrupted` after a daemon restart, so
|
||||
an uncertain release is never redispatched.
|
||||
|
||||
The Windows artifact is linked with the GUI subsystem (`-H=windowsgui`) so
|
||||
service, launcher, and tray startup do not flash a console. Human-facing modes
|
||||
still attach to a parent console explicitly when one exists.
|
||||
|
||||
Suite output is capped at 1 MiB and stored as `artifacts/suite.log`. A failed
|
||||
run remains inspectable and can be moved back to `ready` with `recover`, then
|
||||
|
||||
Reference in New Issue
Block a user