Open
Conversation
Add foundational telnet types to support telnet protocol alongside SSH: - TELNET_DEFAULTS constants (port, timeout, term, auth patterns) - TelnetAuthConfig and TelnetConfig interfaces in config types - ProtocolType, ProtocolConnection, TelnetConnectionConfig interfaces - ProtocolService interface (connect, shell, resize, disconnect) - telnet?: ProtocolService on Services interface - telnet?: TelnetConfig on Config interface - Type-level tests verifying constants and interface shapes
Add telnet configuration defaults to DEFAULT_CONFIG_BASE using TELNET_DEFAULTS constants, with deep clone support via cloneTelnetConfig(). Wire up WEBSSH2_TELNET_* environment variable mappings in env-mapper.ts and add TelnetSchema to the Zod validation schema. Includes unit tests for default values, auth patterns, and deep cloning behavior.
Implement TelnetNegotiator class that handles telnet IAC option negotiation, stripping protocol sequences from terminal data and generating correct responses for DO/WILL/DONT/WONT commands, NAWS window size, and terminal-type subnegotiations.
Implement TelnetAuthenticator state machine that automates login/password entry by matching incoming data against configurable prompt patterns. Falls through to pass-through mode when no auth is configured or on timeout.
Simple connection pool mirroring the SSH ConnectionPool pattern. Stores TelnetConnection objects (ProtocolConnection + Socket) by ConnectionId with a secondary session index for efficient lookup by SessionId. Includes add, get, getBySession, remove, clear, and size operations.
… pool Implements the full ProtocolService for telnet, wiring together TelnetNegotiator (IAC handling), TelnetAuthenticator (expect-style login), and TelnetConnectionPool into connect/shell/resize/disconnect. Key design decisions: - ShellDuplex (Duplex subclass) for bidirectional shell stream - Socket paused in connect(), resumed in shell() to prevent data loss - Connection metadata map stores original config for deferred auth setup - createSocketDataHandler extracted as module-level pure function 16 tests covering connect, shell, resize, disconnect, status, and end-to-end authentication integration.
…tern - Add protocol parameter to ConnectionOptions in connectionHandler.ts to support telnet socket path and config injection - Update html-transformer to accept basePath parameter for telnet asset paths (/telnet/assets/ instead of /ssh/assets/) - Create telnet-routes.ts with GET /, GET /host/:host, POST /, POST /host/:host, and GET /config endpoints - Mount telnet routes conditionally in app.ts when telnet is enabled - Add unit tests for route factory, config endpoint, and route structure
…ters Integrate telnet support into the Socket.IO and service adapter layers: - Add TelnetService token to DI container (container.ts, setup.ts) - Create TelnetServiceImpl in factory.ts when telnet is enabled - Add configureTelnetNamespace() in io.ts for separate /telnet/socket.io path - Make ServiceSocketAdapter protocol-aware with optional 4th parameter - Add protocol field to AdapterContext (service-socket-shared.ts) - Branch auth flow: connectTelnet() uses services.telnet for telnet protocol - Skip SSH-only features for telnet: host key verification, SFTP, exec, keyboard-interactive auth, auth method policy enforcement - Update terminal handler: use telnet service for shell/resize when protocol is telnet - Update disconnect handler: route to telnet or SSH service based on protocol - Accept protocol parameter in socket-v2.ts init() - Bootstrap telnet namespace in app.ts alongside SSH namespace - Update test contexts to include required protocol field
- Remove duplicate imports in telnet-connection-pool test - Use Array<T> syntax for complex types in telnet-types test - Fix negated condition in default-config telnet clone
…ABLES.md Document the new telnet configuration section covering all options: enabled, defaultPort, timeout, term, auth prompt patterns, expect timeout, and allowedSubnets. Includes security warnings about plaintext transmission, use case examples, and environment variable reference table.
- Enforce allowedSubnets in TelnetServiceImpl.connect() using validateConnectionWithDns (was configured but never checked) - Add WEBSSH2_TELNET_ALLOWED_SUBNETS env var mapping - Validate regex patterns in buildOptionalRegex with try/catch - Add 64KB max buffer limit to TelnetAuthenticator (prevents OOM) - Replace instant waiting-result heuristic with 500ms settle delay to allow failure messages to arrive before declaring success - Add backpressure to ShellDuplex (pause/resume socket on push) - Destroy authenticator timers in connection pool clear() - Remove unused TelnetAuthResult export
5 tasks
Sends WILL TERMINAL-TYPE and WILL NAWS upfront so servers like busybox telnetd know the client supports terminal-type negotiation. Fixes TERM showing as 'dumb' on the remote side. Also fixes a TypeScript strict-mode error in processSubnegotiation() where array indexing returned number | undefined despite a length guard.
- S7763: use export...from for re-exports in errors.ts, middleware/index.ts, exec-handler.ts (9 instances) - S4325: remove unnecessary type assertion in service-socket-adapter test - S4623: remove redundant undefined args in validation-ssh test
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
…encies This macOS-only native binary was accidentally added as a direct dependency, causing npm ci to fail on Linux CI runners with EBADPLATFORM. Rollup already manages it as an optional dependency.
Add telnet routes section to ROUTES.md covering all endpoints (GET/POST /telnet, /telnet/host/:host, /telnet/config). Update README.md with telnet feature description, enable instructions, and security warnings. Fix docker-publish workflow to apply branch-name tags on workflow_dispatch events.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Adds telnet protocol support to WebSSH2, implementing issue #180:
ProtocolServiceinterface enabling both SSH and Telnet through the same adapter layer/telnet/routes mirroring the existing SSH route pattern (GET/POST with host parameter support)/telnet/socket.ionamespace with protocol-aware adapterstelnet.enabled: false), subnet restrictions enforced, regex pattern validation, 64KB auth buffer limitArchitecture
New Files
app/services/telnet/telnet-negotiation.tsapp/services/telnet/telnet-auth.tsapp/services/telnet/telnet-connection-pool.tsapp/services/telnet/telnet-service.tsapp/routes/telnet-routes.ts/telnet/Configuration
Telnet is configured via
config.jsonunder thetelnetkey or viaWEBSSH2_TELNET_*environment variables:{ "telnet": { "enabled": true, "defaultPort": 23, "timeout": 30000, "term": "vt100", "auth": { "loginPrompt": "login:\\s*$", "passwordPrompt": "[Pp]assword:\\s*$", "failurePattern": "Login incorrect|Access denied|Login failed", "expectTimeout": 10000 }, "allowedSubnets": [] } }Test Plan
/telnet/host/<host>Closes #180