test: preserve auth failure cleanup coverage
CI / format (pull_request) Successful in 1m26s
CI / lint (pull_request) Successful in 1m35s
CI / install (pull_request) Successful in 5m17s
CI / typetest (pull_request) Successful in 1m37s
CI / typecheck (pull_request) Successful in 1m58s
CI / node-tests (pull_request) Successful in 2m4s
CI / browser-tests (pull_request) Successful in 3m9s

Co-Authored-By: gpt-5.6-sol <noreply@openai.com>
This commit is contained in:
2026-07-26 13:32:31 +00:00
co-authored by Codex
parent 8ae0d4b974
commit a2d09ecbfb
2 changed files with 40 additions and 2 deletions
+28 -2
View File
@@ -1,10 +1,16 @@
import { suite, test } from "node:test"
import assert from "node:assert/strict"
import { loopbackListener } from "@webnet/transport/loopback"
import { loopbackListener, loopbackTransportPair } from "@webnet/transport/loopback"
import type { RawDialer, RawListener } from "@webnet/transport"
import { MemoryVFS } from "@webnet/vfs/memory"
import type { AsyncVFS } from "@webnet/vfs"
import { Channel, SSHClientConnection, SSHAuthError, type HostKeyVerifier } from "@webnet/ssh"
import {
Channel,
generateHostKey,
SSHClientConnection,
SSHAuthError,
type HostKeyVerifier,
} from "@webnet/ssh"
import { Reader, Writer } from "../sftp/cursor.js"
import {
FXP,
@@ -17,6 +23,7 @@ import {
} from "../sftp/packets.js"
import { SSH_FX } from "../sftp/status.js"
import { SFTPServer } from "./server.js"
import { Session } from "./session.js"
import type { SFTPServerOptions } from "./types.js"
type Response = { type: number; r: Reader }
@@ -504,4 +511,23 @@ suite("SFTPServer", () => {
}
assert.equal(seen[0], seen[1])
})
test("an authentication failure closes the connection instead of leaking it", async () => {
const [clientTransport, serverTransport] = loopbackTransportPair()
const running = new Session(serverTransport, {
vfs: new MemoryVFS(),
hostKey: await generateHostKey(),
authenticate: async () => null,
}).run()
await assert.rejects(
() =>
SSHClientConnection.connect(clientTransport, {
user: "alice",
password: "wrong",
}),
(error) => error instanceof SSHAuthError,
)
await assert.rejects(running)
assert.equal(serverTransport.closed, true)
})
})
+12
View File
@@ -164,4 +164,16 @@ suite("ssh auth", () => {
await ct.close().catch(() => {})
await st.close().catch(() => {})
})
test("a malformed auth request rejects authentication", async () => {
const [ct, st] = await connect()
const server = authenticateServer(st, { authenticate: async () => ({}) })
await ct.send(new Writer().u8(SSH_MSG.SERVICE_REQUEST).string("ssh-userauth").finish())
const accept = await ct.readMessage()
assert.equal(accept[0], SSH_MSG.SERVICE_ACCEPT)
await ct.send(new Writer().u8(SSH_MSG.USERAUTH_REQUEST).finish())
await assert.rejects(server)
await ct.close().catch(() => {})
await st.close().catch(() => {})
})
})