feat(ssh): add bounded Windows relay staging control

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo-H
2026-07-16 15:50:36 -04:00
co-authored by Orca
parent d24f877d96
commit 68737239b9
6 changed files with 581 additions and 6 deletions
@@ -289,6 +289,7 @@ jobs:
src/main/ssh/ssh-relay-runtime-posix-control-command.test.ts \
src/main/ssh/ssh-relay-runtime-posix-file-destination.test.ts \
src/main/ssh/ssh-relay-runtime-windows-file-destination.test.ts \
src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts \
src/main/ssh/ssh-relay-runtime-posix-tree-transfer.test.ts \
src/main/ssh/ssh-relay-runtime-system-ssh-file-channel.test.ts \
src/main/ssh/ssh-relay-runtime-sftp-file-destination.test.ts \
@@ -1029,6 +1030,7 @@ jobs:
src/main/ssh/ssh-relay-runtime-posix-control-command.test.ts `
src/main/ssh/ssh-relay-runtime-posix-file-destination.test.ts `
src/main/ssh/ssh-relay-runtime-windows-file-destination.test.ts `
src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts `
src/main/ssh/ssh-relay-runtime-posix-tree-transfer.test.ts `
src/main/ssh/ssh-relay-runtime-system-ssh-file-channel.test.ts `
src/main/ssh/ssh-relay-runtime-sftp-file-destination.test.ts `
@@ -203,6 +203,7 @@ describe('SSH relay runtime artifact workflow', () => {
'ssh-relay-runtime-posix-control-command.test.ts',
'ssh-relay-runtime-posix-file-destination.test.ts',
'ssh-relay-runtime-windows-file-destination.test.ts',
'ssh-relay-runtime-windows-staging-control.test.ts',
'ssh-relay-runtime-posix-tree-transfer.test.ts',
'ssh-relay-runtime-system-ssh-file-channel.test.ts',
'ssh-relay-runtime-sftp-file-destination.test.ts',
@@ -10,12 +10,19 @@ A checked box means the work has evidence in the detailed ledger. Design approva
complete a box.
Active checkpoint: **Milestone 6 / Work Package 5 bounded runtime transfer — disconnected Windows
system-SSH staging-control contract audit, 2026-07-15, Codex implementation owner.**
system-SSH staging control is locally green; native Windows CI is next, 2026-07-15, Codex
implementation owner.**
The next slice is limited to fixed-command, bounded binary PowerShell 5.1 requests for exclusive
staging-root creation, declared-directory creation, and owned-root cleanup. It must preserve a
pre-existing root, bound and strictly decode paths, join cancellation/settlement, and remain
disconnected. File/tree composition, live OpenSSH, product callers, legacy upload/fallback/default
behavior, tuple enablement, publication, and SignPath remain out of scope.
`E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-RED-001` proves the native workflow oracle passes 9/9 and
the purpose suite fails solely because the audited production staging-control module is absent.
`E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001` records 16/17 purpose cases locally with the real
PowerShell case honestly skipped, 207 focused cases, 686 broad relay cases, 282/282 release
contracts, typecheck, full lint, formatting, diff, protected-resolver, and no-product-consumer
gates. Native Windows x64/arm64 `powershell.exe` proof remains required.
`E-M6-WINDOWS-SYSTEM-SSH-FILE-LOCAL-RED-001` proves the workflow oracle passes 9/9 and the new
purpose suite fails solely because the audited production destination is absent.
`E-M6-WINDOWS-SYSTEM-SSH-FILE-LOCAL-001` records 14/15 Windows purpose cases locally with the real
@@ -8,8 +8,8 @@ work; keep exact commands, runner identities, hashes, metrics, and residual gaps
Date created: 2026-07-14<br>
Last updated: 2026-07-15<br>
Current phase: Milestone 6 / Work Package 5 bounded runtime transfer — **In progress — 2026-07-15, Codex implementation owner: disconnected Windows system-SSH staging-control contract audit**. Keep every capability disconnected from every production/default SSH path. Real Apple/SignPath rehearsals remain an explicit late gate and are not on this package's critical path.<br>
Session checkpoint: **WINDOWS PER-FILE NATIVE PROOF CLOSED / STAGING CONTROL AUDIT ACTIVE — 2026-07-15, Codex implementation owner** — `E-M6-WINDOWS-SYSTEM-SSH-FILE-CI-001` proves the real PowerShell receiver on native Windows x64/arm64 and closes the adjacent watcher flake with a same-SHA rerun; only the declared hosted Windows arm64 build-26200 versus required-26100 floor rejection remains. Audit the next disconnected fixed-command staging-root/directory/cleanup contract before writing RED tests. Do not compose file streaming into a tree, connect a product caller, change legacy upload/fallback/default behavior, enable a tuple, publish an artifact, or perform SignPath work in this package. Merging to `main` remains prohibited, SignPath is deferred, and legacy remains the production default.<br>
Current phase: Milestone 6 / Work Package 5 bounded runtime transfer — **In progress — 2026-07-15, Codex implementation owner: disconnected Windows system-SSH staging-control native proof**. Keep every capability disconnected from every production/default SSH path. Real Apple/SignPath rehearsals remain an explicit late gate and are not on this package's critical path.<br>
Session checkpoint: **WINDOWS STAGING CONTROL LOCALLY GREEN / NATIVE WINDOWS CI NEXT — 2026-07-15, Codex implementation owner** — `E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001` proves the fixed-command bounded request, strict rooted-path/descendant validation, exclusive root/directory creation, parent-first enforcement, owned-root removal primitive, 30-second ceiling, joined command-channel lifecycle, prior transfer regressions, and production isolation locally. The real PowerShell 5.1 case is skipped on macOS and earns no native claim; commit and push the exact package, then require native Windows x64/arm64 proof. Do not compose file streaming into a tree, connect a product caller, change legacy upload/fallback/default behavior, enable a tuple, publish an artifact, or perform SignPath work in this package. Merging to `main` remains prohibited, SignPath is deferred, and legacy remains the production default.<br>
Primary design: [SSH relay GitHub Release plan](./2026-07-14-ssh-relay-github-release-plan.html)<br>
Motivating issues: [#8450](https://github.com/stablyai/orca/issues/8450), [#1693](https://github.com/stablyai/orca/issues/1693)
@@ -18286,6 +18286,73 @@ src/main/ssh/ssh-remote-node-resolution.ts src/main/ssh/ssh-remote-node-resoluti
settings/fallback/tuple/publication/default behavior, or SignPath is included. Legacy remains the
sole production/default path and every tuple stays disabled.
### E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-RED-001 — audited staging control is absent
- Date/owner/base/runner: 2026-07-15, Codex implementation owner; purpose test, native-workflow
wiring, and checklist-only diff atop exact base
`d24f877d96f07d691508cc686c0791a86d3dd308` on Apple arm64, macOS 26.2 build 25C56, Node
26.0.0, pnpm 10.24.0.
- Command: `pnpm exec vitest run --config config/vitest.config.ts --maxWorkers=1
src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts
config/scripts/ssh-relay-runtime-workflow.test.mjs`.
- Result: expected failure in 1.39 seconds. The workflow oracle passes 9/9 and proves the new purpose
suite occurs exactly once in both native artifact command families. The purpose suite fails before
collection solely because `./ssh-relay-runtime-windows-staging-control` does not exist; zero
production modules are added or changed at this boundary.
- Residual boundary: no PowerShell staging behavior or Windows runner claim follows from a missing
module. Purpose, native Windows, prior Windows/POSIX regression, broad relay/release, static,
isolation, and no-product-consumer gates remain required.
### E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001 — bounded staging control is locally green
- Date/owner/base/runner: 2026-07-15, Codex implementation owner; uncommitted implementation,
purpose-test, native-workflow, and checklist package atop exact base
`d24f877d96f07d691508cc686c0791a86d3dd308` on Apple arm64, macOS 26.2 build 25C56, Node
26.0.0, pnpm 10.24.0. The local Node version is newer than the repository's Node 24 contract and
the real Windows PowerShell case is skipped off Windows, so exact-head native proof remains
mandatory.
- Implementation: add one disconnected fixed encoded PowerShell receiver with an at-most
65,556-byte request, two independently bounded 32-KiB strict-UTF-8 path fields, operation byte and
zeroed reserved bytes. Client validation rejects non-rooted, reserved, traversal, non-descendant,
and oversized paths before channel open. The receiver rejects malformed framing/extra bytes,
requires each direct parent to exist, uses fail-on-existing `New-Item` for root/directories, and
removes only a root whose ownership is tracked by a later tree caller. Each operation has a
30-second ceiling and reuses the proven 250 ms graceful/2-second forced channel settlement.
- Focused command: `/usr/bin/time -l pnpm exec vitest run --config config/vitest.config.ts
--maxWorkers=1` with the staging-control, Windows/POSIX file/control/tree, system-channel,
source-tree/scan/stream, system-fallback, connection, and workflow-oracle suites. Result: 11 files,
207 passed and three declared platform skips out of 210; 8.85 seconds real, 184,500,224-byte
maximum RSS, 96,818,624-byte peak footprint, zero swaps and block I/O. The staging-control suite
contributes 16 passed plus one macOS-skipped real-PowerShell case; the workflow oracle passes 9/9.
- Broad relay command: `/usr/bin/time -l pnpm exec vitest run --config config/vitest.config.ts
--maxWorkers=1 src/main/ssh/ssh-relay-*.test.ts`. Result: 52 files passed, five files skipped; 686
passed and nine declared skips out of 695; 113.77 seconds real, 257,605,632-byte maximum RSS,
97,572,312-byte peak footprint, zero swaps and block I/O. This and the release/lint commands ran
concurrently, so their wall times are recorded but are not standalone performance baselines.
- Release-contract command: `/usr/bin/time -l pnpm exec vitest run --config
config/vitest.config.ts --maxWorkers=1 config/scripts/ssh-relay-runtime-*.test.mjs`. Result: 50 files
and 282/282 cases pass; 81.81 seconds real, 189,317,120-byte maximum RSS, 96,146,808-byte peak
footprint, zero swaps and block I/O. Two prior quoted-wildcard invocations found no literal file;
they were command errors and were immediately replaced by these exact checklist commands.
- Static evidence: `pnpm typecheck` passes. `/usr/bin/time -l pnpm lint` passes in 78.78 seconds real
with 2,106,277,888-byte maximum RSS and 96,081,152-byte peak footprint; its 26 warnings are
pre-existing outside this diff. Full lint proves switch exhaustiveness, 41 reliability gates, the
355-entry max-lines ratchet with no new bypass, bundled guides, and localization checks. Targeted
`oxlint` and `oxfmt --check` pass.
- Isolation evidence: `git diff --check` passes; `git diff --exit-code
d24f877d96f07d691508cc686c0791a86d3dd308 -- src/main/ssh/ssh-remote-node-resolution.ts
src/main/ssh/ssh-remote-node-resolution.test.ts` is empty. A non-test reference search finds the
staging-control export only in its owning production module. The intended diff is limited to the
disconnected staging-control module/purpose test, native workflow/oracle wiring, and both
checklist documents. No existing file receiver, POSIX/SFTP transfer, legacy uploader, product
importer, settings, Beta, fallback, tuple, publication, default-path, or signing behavior changes.
- Residual boundary: local execution does not prove Windows PowerShell 5.1 parsing, exclusive
directory semantics, or cleanup on native Windows. Exact-head native Windows x64/arm64 purpose
proof and all-six adjacent native regression cells remain required. File/tree composition, live
Windows OpenSSH, full-size runtime transfer, long paths, endpoint-protection faults, capability
classification/cache, bundled-Node verification/install/publish/launch, product/Beta/fallback/
default behavior, tuple enablement, publication, Apple signing, and SignPath remain absent.
## Accepted Gaps
No product gap is accepted merely because it appears in this list. Each entry requires explicit
@@ -18344,9 +18411,9 @@ The project is not complete until every applicable item below is checked with ev
## Next Required Action
Write and run the purpose-named RED suite and native-workflow oracle for
`E-M6-WINDOWS-SYSTEM-SSH-CONTROL-AUDIT-001`, proving failure solely because the audited production
module is absent. Do not check the broad Milestone 6 Windows system-SSH item yet. Do not compose file
Commit and push the exact `E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001` package, then require the real
PowerShell 5.1 process oracle on native Windows x64/arm64 plus all-six native and adjacent repository
regression cells. Do not check the broad Milestone 6 Windows system-SSH item yet. Do not compose file
streaming into a remote-tree owner or add an Electron/startup/product importer, per-target mode
wiring, fallback, tuple enablement, release publication, or default behavior.
Keep Node upstream `.tar.xz` inputs, Windows ZIP, `ORCA_RELAY_PATH`, existing desktop required-assets
@@ -0,0 +1,285 @@
import { spawn } from 'node:child_process'
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import path from 'node:path'
import { afterEach, describe, expect, it, vi } from 'vitest'
import type { SshRelayRuntimeCommandFileChannel } from './ssh-relay-runtime-command-file-destination'
import {
runSshRelayRuntimeWindowsStagingControl,
SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS
} from './ssh-relay-runtime-windows-staging-control'
type Callback = (error?: Error) => void
function createChannel() {
let resolveSettled: () => void = () => {}
let rejectSettled: (error: Error) => void = () => {}
const settled = new Promise<void>((resolve, reject) => {
resolveSettled = resolve
rejectSettled = reject
})
const channel = {
write: vi.fn((_chunk: Buffer, callback: Callback) => callback()),
end: vi.fn(),
settled,
requestClose: vi.fn(),
forceClose: vi.fn()
}
return { channel, resolve: resolveSettled, reject: rejectSettled }
}
function decodeRequest(frame: Buffer) {
const rootLength = frame.readUInt32LE(12)
const pathLength = frame.readUInt32LE(16)
const rootStart = 20
const pathStart = rootStart + rootLength
return {
magic: frame.subarray(0, 8).toString('ascii'),
operation: frame.readUInt8(8),
reserved: frame.subarray(9, 12),
remoteRoot: frame.subarray(rootStart, pathStart).toString('utf8'),
remotePath: frame.subarray(pathStart, pathStart + pathLength).toString('utf8')
}
}
function decodePowerShellCommand(command: string): string {
const encoded = command.match(/-EncodedCommand\s+([A-Za-z0-9+/=]+)$/u)?.[1]
if (!encoded) {
throw new Error('PowerShell staging control command is not encoded')
}
return Buffer.from(encoded, 'base64').toString('utf16le')
}
function runControl(
channel: SshRelayRuntimeCommandFileChannel,
overrides: Partial<Parameters<typeof runSshRelayRuntimeWindowsStagingControl>[0]> = {}
) {
return runSshRelayRuntimeWindowsStagingControl({
operation: 'create-directory',
remoteRoot: 'C:/Users/测试/.orca-remote/stage',
remotePath: 'C:/Users/测试/.orca-remote/stage/bin/native',
signal: new AbortController().signal,
openChannel: vi.fn(async () => channel),
...overrides
})
}
afterEach(() => {
vi.useRealTimers()
vi.restoreAllMocks()
})
describe('SSH relay runtime Windows system-SSH staging control', () => {
it.each([
['create-root', 1, ''],
['create-directory', 2, 'C:/Users/测试/.orca-remote/stage/bin/native'],
['remove-root', 3, '']
] as const)(
'sends one fixed bounded binary %s request',
async (operation, opcode, remotePath) => {
const fixture = createChannel()
const openChannel = vi.fn(async (_command: string, _signal: AbortSignal) => fixture.channel)
const running = runControl(fixture.channel, {
operation,
remotePath: remotePath || undefined,
openChannel
})
await vi.waitFor(() => expect(fixture.channel.end).toHaveBeenCalledOnce())
expect(openChannel).toHaveBeenCalledOnce()
const command = openChannel.mock.calls[0]?.[0] ?? ''
expect(command).toMatch(/^powershell\.exe .* -EncodedCommand [A-Za-z0-9+/=]+$/u)
expect(command).not.toContain('测试')
const script = decodePowerShellCommand(command)
expect(script).toContain('[Console]::OpenStandardInput()')
expect(script).toContain('New-Item -ItemType Directory -Path')
expect(script).toContain('[IO.Path]::GetDirectoryName')
expect(script).toContain('[IO.Directory]::Delete')
expect(script).toContain('$inputStream.ReadByte() -ne -1')
for (const forbidden of ['ReadToEnd', 'FromBase64String', 'ConvertFrom-Json']) {
expect(script).not.toContain(forbidden)
}
const frame = fixture.channel.write.mock.calls[0]?.[0]
expect(Buffer.isBuffer(frame)).toBe(true)
expect(frame.length).toBeLessThanOrEqual(
SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS.maximumRequestBytes
)
expect(decodeRequest(frame)).toEqual({
magic: 'ORCACTL1',
operation: opcode,
reserved: Buffer.alloc(3),
remoteRoot: 'C:/Users/测试/.orca-remote/stage',
remotePath
})
fixture.resolve()
await expect(running).resolves.toBeUndefined()
}
)
it.each([
['create-root', 'relative/stage', undefined],
['create-root', 'C:/', undefined],
['create-root', 'C:/owned/../stage', undefined],
['create-root', 'C:/owned/NUL', undefined],
[
'create-root',
`C:/${'a'.repeat(SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS.maximumPathBytes)}`,
undefined
],
['create-root', 'C:/owned/stage', 'C:/owned/stage/extra'],
['create-directory', 'C:/owned/stage', undefined],
['create-directory', 'C:/owned/stage', 'C:/outside'],
['create-directory', 'C:/owned/stage', 'C:/owned/stage'],
['create-directory', 'C:/owned/stage', 'C:/owned/stage/report.txt:stream']
] as const)(
'rejects hostile %s root %j path %j before channel open',
async (operation, remoteRoot, remotePath) => {
const fixture = createChannel()
const openChannel = vi.fn(async () => fixture.channel)
await expect(
runControl(fixture.channel, { operation, remoteRoot, remotePath, openChannel })
).rejects.toThrow(/invalid/i)
expect(openChannel).not.toHaveBeenCalled()
}
)
it('settles retained-request cancellation before rejecting', async () => {
const fixture = createChannel()
const controller = new AbortController()
const reason = new Error('cancelled retained Windows control request')
fixture.channel.write.mockImplementationOnce(() => {})
fixture.channel.requestClose.mockImplementation(() => fixture.resolve())
const running = runControl(fixture.channel, { signal: controller.signal })
await vi.waitFor(() => expect(fixture.channel.write).toHaveBeenCalledOnce())
controller.abort(reason)
await expect(running).rejects.toBe(reason)
expect(fixture.channel.requestClose).toHaveBeenCalledOnce()
expect(fixture.channel.forceClose).not.toHaveBeenCalled()
})
it('propagates remote failure only after request EOF and settlement', async () => {
const fixture = createChannel()
const running = runControl(fixture.channel)
await vi.waitFor(() => expect(fixture.channel.end).toHaveBeenCalledOnce())
const error = new Error('PowerShell staging control failed')
fixture.reject(error)
await expect(running).rejects.toBe(error)
})
it('turns the command ceiling into bounded cancellation and settlement', async () => {
vi.useFakeTimers()
const fixture = createChannel()
fixture.channel.requestClose.mockImplementation(() => fixture.resolve())
const running = runControl(fixture.channel)
const rejection = expect(running).rejects.toThrow(/timed out/i)
await vi.advanceTimersByTimeAsync(
SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS.commandTimeoutMs
)
await rejection
expect(fixture.channel.requestClose).toHaveBeenCalledOnce()
expect(fixture.channel.forceClose).not.toHaveBeenCalled()
})
it.skipIf(process.platform !== 'win32')(
'proves exclusive root ownership, Unicode directories, and owned cleanup in PowerShell 5.1',
async () => {
const parent = await mkdtemp(path.join(tmpdir(), 'orca-relay-win-control-'))
const remoteRoot = path.join(parent, '测试 stage')
const remoteParent = path.join(remoteRoot, 'bin')
const remotePath = path.join(remoteParent, 'native')
try {
await runSshRelayRuntimeWindowsStagingControl({
operation: 'create-root',
remoteRoot,
signal: new AbortController().signal,
openChannel: openPowerShellChannel
})
const marker = path.join(remoteRoot, 'original.txt')
await writeFile(marker, 'preserve')
await expect(
runSshRelayRuntimeWindowsStagingControl({
operation: 'create-root',
remoteRoot,
signal: new AbortController().signal,
openChannel: openPowerShellChannel
})
).rejects.toThrow(/PowerShell staging control failed/i)
expect(await readFile(marker, 'utf8')).toBe('preserve')
await expect(
runSshRelayRuntimeWindowsStagingControl({
operation: 'create-directory',
remoteRoot,
remotePath,
signal: new AbortController().signal,
openChannel: openPowerShellChannel
})
).rejects.toThrow(/PowerShell staging control failed/i)
await runSshRelayRuntimeWindowsStagingControl({
operation: 'create-directory',
remoteRoot,
remotePath: remoteParent,
signal: new AbortController().signal,
openChannel: openPowerShellChannel
})
await runSshRelayRuntimeWindowsStagingControl({
operation: 'create-directory',
remoteRoot,
remotePath,
signal: new AbortController().signal,
openChannel: openPowerShellChannel
})
await runSshRelayRuntimeWindowsStagingControl({
operation: 'remove-root',
remoteRoot,
signal: new AbortController().signal,
openChannel: openPowerShellChannel
})
await expect(readFile(marker)).rejects.toMatchObject({ code: 'ENOENT' })
} finally {
await rm(parent, { recursive: true, force: true })
}
},
30_000
)
})
async function openPowerShellChannel(command: string): Promise<SshRelayRuntimeCommandFileChannel> {
const encoded = command.match(/-EncodedCommand\s+([A-Za-z0-9+/=]+)$/u)?.[1]
if (!encoded) {
throw new Error('PowerShell staging control command is not encoded')
}
const child = spawn(
'powershell.exe',
['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', encoded],
{ stdio: ['pipe', 'ignore', 'pipe'], windowsHide: true }
)
let diagnostic = ''
child.stderr.setEncoding('utf8')
child.stderr.on('data', (chunk: string) => {
diagnostic = `${diagnostic}${chunk}`.slice(-4_096)
})
const settled = new Promise<void>((resolve, reject) => {
child.once('error', reject)
child.once('close', (code, signal) => {
if (code === 0) {
resolve()
} else {
reject(new Error(`PowerShell staging control failed (${code ?? signal}): ${diagnostic}`))
}
})
})
return {
write: (chunk: Buffer, callback: Callback) => {
child.stdin.write(chunk, (error) => callback(error ?? undefined))
},
end: () => child.stdin.end(),
settled,
requestClose: () => child.kill(),
forceClose: () => child.kill('SIGKILL')
}
}
@@ -0,0 +1,213 @@
import { assertSafeRemotePathSegment, normalizeWindowsRemotePath } from './ssh-remote-platform'
import { powerShellCommand } from './ssh-remote-powershell'
import {
openSshRelayRuntimeCommandFileDestination,
type SshRelayRuntimeCommandFileChannel
} from './ssh-relay-runtime-command-file-destination'
export type SshRelayRuntimeWindowsStagingOperation =
| 'create-root'
| 'create-directory'
| 'remove-root'
export type RunSshRelayRuntimeWindowsStagingControlOptions = Readonly<{
operation: SshRelayRuntimeWindowsStagingOperation
remoteRoot: string
remotePath?: string
signal: AbortSignal
openChannel: (command: string, signal: AbortSignal) => Promise<SshRelayRuntimeCommandFileChannel>
}>
const REQUEST_MAGIC = Buffer.from('ORCACTL1', 'ascii')
const FIXED_REQUEST_BYTES = 20
const MAXIMUM_PATH_BYTES = 32 * 1024
const COMMAND_TIMEOUT_MS = 30_000
const OPERATION_CODES: Record<SshRelayRuntimeWindowsStagingOperation, number> = {
'create-root': 1,
'create-directory': 2,
'remove-root': 3
}
export const SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS = Object.freeze({
commandTimeoutMs: COMMAND_TIMEOUT_MS,
maximumPathBytes: MAXIMUM_PATH_BYTES,
maximumRequestBytes: FIXED_REQUEST_BYTES + MAXIMUM_PATH_BYTES * 2
})
const RECEIVER_SCRIPT = `
$ErrorActionPreference = 'Stop'
function Read-Exact([System.IO.Stream]$Stream, [byte[]]$Buffer, [int]$Count) {
$offset = 0
while ($offset -lt $Count) {
$read = $Stream.Read($Buffer, $offset, $Count - $offset)
if ($read -eq 0) { throw 'SSH relay runtime Windows staging control early EOF' }
$offset += $read
}
}
$inputStream = [Console]::OpenStandardInput()
try {
[byte[]]$header = New-Object byte[] ${FIXED_REQUEST_BYTES}
Read-Exact $inputStream $header ${FIXED_REQUEST_BYTES}
if ([Text.Encoding]::ASCII.GetString($header, 0, 8) -ne 'ORCACTL1') { throw 'bad header' }
[byte]$operation = $header[8]
if ($header[9] -ne 0 -or $header[10] -ne 0 -or $header[11] -ne 0) { throw 'bad reserved bytes' }
[uint32]$rootLength = [BitConverter]::ToUInt32($header, 12)
[uint32]$pathLength = [BitConverter]::ToUInt32($header, 16)
if ($rootLength -eq 0 -or $rootLength -gt ${MAXIMUM_PATH_BYTES}) { throw 'bad root length' }
if ($pathLength -gt ${MAXIMUM_PATH_BYTES}) { throw 'bad path length' }
if (($operation -eq 2 -and $pathLength -eq 0) -or ($operation -ne 2 -and $pathLength -ne 0)) { throw 'bad operation path' }
if ($operation -lt 1 -or $operation -gt 3) { throw 'bad operation' }
[byte[]]$rootBytes = New-Object byte[] ([int]$rootLength)
[byte[]]$pathBytes = New-Object byte[] ([int]$pathLength)
Read-Exact $inputStream $rootBytes ([int]$rootLength)
Read-Exact $inputStream $pathBytes ([int]$pathLength)
if ($inputStream.ReadByte() -ne -1) { throw 'extra byte' }
$utf8 = New-Object Text.UTF8Encoding($false, $true)
$root = $utf8.GetString($rootBytes)
$path = if ($pathLength -eq 0) { '' } else { $utf8.GetString($pathBytes) }
if (-not [IO.Path]::IsPathRooted($root) -or $root.IndexOf([char]0) -ge 0) { throw 'bad root' }
if ($operation -eq 2) {
if (-not [IO.Path]::IsPathRooted($path) -or $path.IndexOf([char]0) -ge 0 -or -not $path.StartsWith($root + '/', [StringComparison]::Ordinal)) { throw 'bad child path' }
}
switch ($operation) {
1 {
$parent = [IO.Path]::GetDirectoryName($root)
if ([string]::IsNullOrEmpty($parent) -or -not [IO.Directory]::Exists($parent)) { throw 'missing root parent' }
New-Item -ItemType Directory -Path $root -ErrorAction Stop | Out-Null
}
2 {
$parent = [IO.Path]::GetDirectoryName($path)
if ([string]::IsNullOrEmpty($parent) -or -not [IO.Directory]::Exists($parent)) { throw 'missing directory parent' }
New-Item -ItemType Directory -Path $path -ErrorAction Stop | Out-Null
}
3 {
if ([IO.File]::Exists($root)) { throw 'staging root became a file' }
if ([IO.Directory]::Exists($root)) { [IO.Directory]::Delete($root, $true) }
}
}
} catch {
throw 'SSH relay runtime Windows staging control failed'
}
`.trim()
const RECEIVER_COMMAND = powerShellCommand(RECEIVER_SCRIPT)
function normalizeAbsolutePath(value: string): string {
if (
typeof value !== 'string' ||
value === '' ||
value.includes('\0') ||
value.includes('\r') ||
value.includes('\n')
) {
throw new Error('SSH relay runtime Windows staging control path is invalid')
}
const normalized = normalizeWindowsRemotePath(value)
const driveRooted = /^[A-Za-z]:\//u.test(normalized)
const uncRooted = /^\/\/[^/]+\/[^/]+\//u.test(normalized)
if ((!driveRooted && !uncRooted) || normalized.endsWith('/')) {
throw new Error('SSH relay runtime Windows staging control path is invalid')
}
const segments = driveRooted ? normalized.slice(3).split('/') : normalized.slice(2).split('/')
try {
for (const segment of segments) {
assertSafeRemotePathSegment(segment, 'windows')
}
} catch {
throw new Error('SSH relay runtime Windows staging control path is invalid')
}
if (Buffer.byteLength(normalized, 'utf8') > MAXIMUM_PATH_BYTES) {
throw new Error('SSH relay runtime Windows staging control path is invalid')
}
return normalized
}
function validateOptions(options: RunSshRelayRuntimeWindowsStagingControlOptions): {
operation: SshRelayRuntimeWindowsStagingOperation
remoteRoot: string
remotePath: string
} {
if (
!options ||
typeof options.operation !== 'string' ||
!Object.hasOwn(OPERATION_CODES, options.operation) ||
!options.signal ||
typeof options.openChannel !== 'function'
) {
throw new Error('SSH relay runtime Windows staging control input is invalid')
}
const remoteRoot = normalizeAbsolutePath(options.remoteRoot)
if (options.operation !== 'create-directory') {
if (options.remotePath !== undefined) {
throw new Error('SSH relay runtime Windows staging control input is invalid')
}
return { operation: options.operation, remoteRoot, remotePath: '' }
}
const remotePath = normalizeAbsolutePath(options.remotePath as string)
// Why: control requests may create only a strict descendant of the root owned by the tree caller.
if (!remotePath.startsWith(`${remoteRoot}/`)) {
throw new Error('SSH relay runtime Windows staging control path is invalid')
}
return { operation: options.operation, remoteRoot, remotePath }
}
function buildRequest(
operation: SshRelayRuntimeWindowsStagingOperation,
remoteRoot: string,
remotePath: string
): Buffer {
const rootBytes = Buffer.from(remoteRoot, 'utf8')
const pathBytes = Buffer.from(remotePath, 'utf8')
const request = Buffer.alloc(FIXED_REQUEST_BYTES + rootBytes.length + pathBytes.length)
REQUEST_MAGIC.copy(request, 0)
request.writeUInt8(OPERATION_CODES[operation], 8)
request.writeUInt32LE(rootBytes.length, 12)
request.writeUInt32LE(pathBytes.length, 16)
rootBytes.copy(request, FIXED_REQUEST_BYTES)
pathBytes.copy(request, FIXED_REQUEST_BYTES + rootBytes.length)
return request
}
export async function runSshRelayRuntimeWindowsStagingControl(
options: RunSshRelayRuntimeWindowsStagingControlOptions
): Promise<void> {
const { operation, remoteRoot, remotePath } = validateOptions(options)
const request = buildRequest(operation, remoteRoot, remotePath)
const commandController = new AbortController()
const onCallerAbort = (): void => commandController.abort(options.signal.reason)
options.signal.addEventListener('abort', onCallerAbort, { once: true })
if (options.signal.aborted) {
onCallerAbort()
}
const timeout = setTimeout(
() => commandController.abort(new Error('SSH relay runtime Windows staging control timed out')),
COMMAND_TIMEOUT_MS
)
try {
const destination = await openSshRelayRuntimeCommandFileDestination({
command: RECEIVER_COMMAND,
fileKind: 'Windows',
signal: commandController.signal,
openChannel: options.openChannel
})
try {
await destination.write(request)
await destination.close()
} catch (error) {
try {
// Why: a retained request buffer must settle before this bounded control operation returns.
await destination.abort(error)
} catch (cleanupError) {
throw new AggregateError(
[error, cleanupError],
'SSH relay runtime Windows staging control cleanup failed'
)
}
throw error
}
} finally {
clearTimeout(timeout)
options.signal.removeEventListener('abort', onCallerAbort)
}
}