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
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:
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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(() => {})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user