3.5 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | ||
|---|---|---|---|---|---|---|---|---|---|
| core/ssh-interface-extraction | Extract SshInterface from ServerHandler — refactor SSH into Layer 2 | completed |
|
broad | high | project | implementation |
Description
This is the most invasive change in Phase 1. Extract SSH session handling from ServerHandler into SshInterface, making it implement the Interface trait defined in the previous task. Per interface.md and ADR-026, SshInterface becomes one implementation of the Interface trait alongside RawFramingInterface.
Current state: ServerHandler is a russh::server::Handler that owns auth, channel management, and proxy logic — all tangled together.
Target state:
SshInterfaceimplementsInterfaceand wraps the SSH handshake and session management- Auth delegation goes through
IdentityProvider(already wired from task 1.5) - Channel open requests (including forwarding policy checks) are Layer 3 concerns routed through the Interface session
- Port forwarding proxy logic is per-connection state managed by the session
Key changes:
SshInterfacewrapsrusshserver config and session handlingSshInterface::accept()takes aTransportStreamandSshInterfaceConfig, performs SSH handshake, returns a session- The session produces call protocol events (for
alknet-control:0channels) and handles channel routing - Forwarding policy check is invoked from Layer 3 (call protocol handler), not embedded in the interface
RawFramingInterfacestub: just the type definition, no implementation (Phase 4+ for DNS and WebTransport)- The server accept loop uses
(Transport, Interface)pairs instead of directly spawning SSH handlers
This is explicitly flagged as high-risk in the integration plan. The refactoring must preserve all existing behavior. Strategy: implement SshInterface as a wrapper around the existing ServerHandler logic initially, then progressively move concerns to the right layer.
Acceptance Criteria
SshInterfacestruct implementsInterfacetrait withaccept()methodSshInterface::accept()performs SSH handshake overTransportStream- Auth is delegated through
IdentityProvider(not embedded in SshInterface) - Channel open requests route through the session to Layer 3 (forwarding policy, call protocol)
alknet-control:0channels produce call protocol events via the session- Port forwarding proxy logic is per-connection state, not embedded in the interface
RawFramingInterfacetype exists but is stub-only (no implementation beyond type definition)- Server accept loop uses
(Transport, Interface)pairs to spawn sessions - All existing server/auth/transport tests pass unchanged
- New tests:
SshInterfacesession over TCP and TLS transports - New tests: forwarding policy applied when channels are opened (Layer 3, not Layer 2)
References
- docs/architecture/interface.md — SshInterface, what stays in Layer 2 vs Layer 3, OQ-IF-02
- docs/architecture/decisions/026-transport-interface-separation.md — ADR-026
- crates/alknet-core/src/server/handler.rs — current ServerHandler to be extracted
Notes
This is the highest-risk task in Phase 1. Consider implementing incrementally: first wrap existing ServerHandler in SshInterface, then progressively move auth to IdentityProvider, channel routing to call protocol, etc. Each step should have passing tests before proceeding.
Summary
To be filled on completion