codinget
  • Joined on 2022-10-19
codinget commented on pull request webnet/webnet#65 2026-07-11 00:02:11 +02:00
feat(ssh): split SSH out of @webnet/sftp into @webnet/ssh + TCP forwarding

If the accept loop has already exited (#failSessions ran), a waiter pushed here never settles — unlike ConnectionMux.acceptOpen, there's no error-state check. The in-repo sftp caller happens to call this immediately after accept(), but any public-API user calling acceptSession() on a dead connection hangs forever. Storing the loop-exit error and rejecting here would match the mux behaviour.

codinget commented on pull request webnet/webnet#65 2026-07-11 00:02:11 +02:00
feat(ssh): split SSH out of @webnet/sftp into @webnet/ssh + TCP forwarding

Fable review pass over the whole diff. I ran the full unit suites (ssh 104/104, sftp 109/109, 0 cancelled) and also stood up a local OpenSSH sshd and ran both opt-in interop suites (SSH_TEST_* forwarding tests and SFTP_TEST_*) — all pass, so the wire-level claims in the description check out. The split itself is clean (pure renames, no @webnet/vfs dependency left in @webnet/ssh), window accounting including extended-data is correct, and global-request reply ordering matches RFC 4254 §4.

codinget commented on pull request webnet/webnet#65 2026-07-11 00:02:11 +02:00
feat(ssh): split SSH out of @webnet/sftp into @webnet/ssh + TCP forwarding

A second tcpip-forward for the same bindHost:port overwrites the map entry, orphaning the previous listener and its #forwardAccept loop (never closed, even by close()). Rejecting the duplicate (return null) or closing the old listener first would avoid the leak. Related nit: RemoteForward.close()/_shutdown drop #queue without closing the queued transports, leaving those accepted channels dangling.

codinget commented on pull request webnet/webnet#65 2026-07-11 00:02:11 +02:00
feat(ssh): split SSH out of @webnet/sftp into @webnet/ssh + TCP forwarding

The comment says "unique port match" but this returns the first forward with a matching port. With two forwards on the same port on different hosts (the exact scenario the "two forwards sharing a port" test exercises via exact-match), a server that reports the bound host differently than requested (the OpenSSH behaviour this fallback exists for) can get its connections routed to the wrong forward. Making the fallback apply only when exactly one forward has that port would fail closed (reject) instead of misrouting.

codinget commented on pull request webnet/webnet#65 2026-07-11 00:02:11 +02:00
feat(ssh): split SSH out of @webnet/sftp into @webnet/ssh + TCP forwarding

Confirmed deadlock. If the remote window is exhausted and the peer sends CHANNEL_EOF/CHANNEL_CLOSE (or just closes) instead of WINDOW_ADJUST, this waiter is never woken: _deliverClose and _deliverEof don't touch #windowWaiters, and the CHANNEL_CLOSE dispatch deletes the channel from #channels, so even a later connection-level #failAll can't fail it. send() then hangs forever — and in pipe() that wedges the whole forward, leaving the other transport open. Repro: send 1MiB to a non-reading peer, start a second send, then close the peer channel — the second send never settles.

codinget pushed to feat/ssh-package at webnet/webnet 2026-07-09 21:33:30 +02:00
722cf9886c fix(ssh): harden remote-forward routing and accept-loop teardown
codinget created pull request webnet/webnet#65 2026-07-09 21:18:50 +02:00
WIP: feat(ssh): split SSH out of @webnet/sftp into @webnet/ssh + TCP forwarding
codinget pushed to feat/ssh-package at webnet/webnet 2026-07-09 21:18:11 +02:00
fcb0a57261 docs: record @webnet/ssh split and TCP forwarding in AI_CHANGES
1231d42c0c test(ssh): add opt-in OpenSSH forwarding interop suite
655c8737e4 refactor(sftp): build on the @webnet/ssh connection API
8c5ea77375 feat(ssh): add client and server connections with TCP forwarding
83d4bb1292 feat(ssh): add a RawTransport adapter for channels
Compare 8 commits »
codinget created branch feat/ssh-package in webnet/webnet 2026-07-09 21:18:10 +02:00
codinget pushed to feat/ftp at webnet/webnet 2026-07-09 00:56:27 +02:00
b108ec5e74 feat(test-app): add ftp to test-app
codinget commented on pull request webnet/webnet#63 2026-07-07 22:31:06 +02:00
feat(transport): add explicit TLS upgrade (STARTTLS / AUTH TLS) to RawTransport

Both neutral-review findings addressed in eff16c5 — both were correct:

Pipelined ClientHello (server-side race): confirmed — after a completed read() the socket stays in flowing mode, so…

codinget pushed to feat/transport-upgrade-tls at webnet/webnet 2026-07-07 22:30:53 +02:00
eff16c528e fix(transport): address neutral-review findings on TLS upgrade
codinget pushed to feat/ftp at webnet/webnet 2026-07-07 20:23:02 +02:00
e00411ab59 fix(ftp): address review findings on error handling and interop
codinget commented on pull request webnet/webnet#64 2026-07-07 19:04:28 +02:00
feat: add @webnet/sftp package (SFTP v3 client and server)

Thanks — addressed in 2ef788e / 7df49d3.

Short-read data corruption (client read pipeline) — fixed. This was the real one. Each in-flight READ now carries its {offset, want}; on a short…

codinget pushed to feat/sftp at webnet/webnet 2026-07-07 19:03:43 +02:00
7df49d332a docs(sftp): note the short-read fix and intentional limitations
2ef788e9c5 fix(sftp): handle short reads in the client read pipeline
Compare 2 commits »
codinget commented on pull request webnet/webnet#60 2026-07-07 13:57:58 +02:00
feat(smb2): SMB2/3 client with async VFS interface

Thanks — this second pass caught real issues. All five addressed in 118a3d1:

Availability bug — failed connect cached forever (#ensure): a rejected #doConnect() no longer wedges the…

codinget pushed to smb2-package at webnet/webnet 2026-07-07 13:57:32 +02:00
118a3d1f2f fix(smb2): verify response signatures; fix connect caching and mapping
codinget commented on pull request webnet/webnet#64 2026-07-07 09:50:43 +02:00
feat: add @webnet/sftp package (SFTP v3 client and server)

Minor/robustness: writes are accepted only when offset === handle.pos, i.e. strictly sequential append from 0. This matches how the bundled client and sftp put behave, but a client that legitimately seeks (partial-file update, resumed upload at a non-zero offset via OPEN without TRUNC) gets SSH_FX_FAILURE. Worth documenting as a server limitation so it's a known constraint rather than a surprise.

codinget commented on pull request webnet/webnet#64 2026-07-07 09:50:43 +02:00
feat: add @webnet/sftp package (SFTP v3 client and server)

Autonomous review (Claude Fable 5). This is an impressive, careful package — I read the whole SSH stack. Highlights that check out: the AES-CTR non-ETM frame reconstruction (headerSize/bodySize/open byte math is exactly right, incl. the +20 = 32-byte MAC minus the 12 packet bytes already consumed with the length block), the GCM RFC 5647 invocation-nonce increment, curve25519 exchange-hash + RFC 4253 KDF, all-zero-secret rejection, the rekey send-gate (kex packets bypass the app gate via #sendPacket, app send() blocks on #kexGate — no interleave, no deadlock), and the bounds-checked cursor. The publickey server path correctly verifies the signature over session-id-bound data before accepting. No memory-safety or crypto-correctness bugs found.

codinget commented on pull request webnet/webnet#64 2026-07-07 09:50:43 +02:00
feat: add @webnet/sftp package (SFTP v3 client and server)

SETSTAT/FSETSTAT return SSH_FX_OK without doing anything. The inline rationale (make sftp put succeed) is reasonable, but silently succeeding on chmod/timestamp/truncate means a client's put -p or chmod reports success while nothing changed — surprising for a filesystem server. Since the VFS exposes setProps, honoring at least the timestamp/permission bits of the incoming ATTRs (and truncate via size) would make this a real success rather than a lie; otherwise a doc note on the server option is warranted.