Documentation
¶
Overview ¶
Package ssh provides the core SSH2 protocol implementation for Microsoft Dev Tunnels.
This package implements the SSH2 protocol over any bidirectional stream (not just TCP), supporting session management, channel multiplexing, key exchange, authentication, and session reconnection.
Architecture ¶
The central type is Session, which manages the connection lifecycle and message dispatch. Sessions are created via ClientSession (for initiating connections) or ServerSession (for accepting connections). Both embed Session and add role-specific behavior.
Sessions operate over any io.ReadWriteCloser, enabling SSH over TCP, named pipes, WebSockets, or in-memory pipes for testing.
Key Exchange and Encryption ¶
Algorithm negotiation follows RFC 4253. Supported algorithms are configured via SessionConfig and negotiated during the initial key exchange. The library supports ECDH (P-256, P-384, P-521), DH (group14, group16), AES-GCM, AES-CTR, AES-CBC, and HMAC-SHA2 variants.
A nil entry in an algorithm list means "none" (no security), useful for testing or trusted network scenarios.
Channel Multiplexing ¶
Multiple logical channels can be multiplexed over a single session. Channels support bidirectional data transfer with flow control (window management). Use Session.OpenChannel to create channels and Session.AcceptChannel to accept incoming channel requests.
Authentication ¶
Authentication is event-driven via the [Session.OnAuthenticating] callback. Supported methods include password, public key, and keyboard-interactive.
Reconnection ¶
Sessions support transparent reconnection over a new stream without losing channel state. This is negotiated via protocol extensions and enabled automatically when both sides support it.
Services ¶
Services extend session functionality. They are activated on-demand when a matching service request, channel type, or session request is received. The Service interface defines the contract for pluggable services.
Index ¶
- Constants
- Variables
- func PipeSession(ctx context.Context, sessionA, sessionB *Session) error
- func WaitUntilReconnectEnabled(ctx context.Context, sessions ...*Session) error
- type AuthenticatingEventArgs
- type AuthenticationType
- type Channel
- func (c *Channel) AdjustWindow(messageLength uint32)
- func (c *Channel) Close() error
- func (c *Channel) CloseWithContext(ctx context.Context) error
- func (c *Channel) CloseWithSignal(ctx context.Context, signal string, errorMessage string) error
- func (c *Channel) CloseWithStatus(ctx context.Context, exitStatus uint32) error
- func (c *Channel) IsClosed() bool
- func (c *Channel) Metrics() *ChannelMetrics
- func (c *Channel) OpenConfirmationMessage() *messages.ChannelOpenConfirmationMessage
- func (c *Channel) OpenMessage() *messages.ChannelOpenMessage
- func (c *Channel) Pipe(ctx context.Context, target *Channel) error
- func (c *Channel) Request(ctx context.Context, msg *messages.ChannelRequestMessage) (bool, error)
- func (c *Channel) Send(ctx context.Context, data []byte) error
- func (c *Channel) SendExtendedData(ctx context.Context, dataType SSHExtendedDataType, data []byte) error
- func (c *Channel) SendSignal(ctx context.Context, signalName string) error
- func (c *Channel) SetClosedHandler(handler func(*ChannelClosedEventArgs))
- func (c *Channel) SetDataReceivedHandler(handler func([]byte))
- func (c *Channel) SetEofHandler(handler func())
- func (c *Channel) SetExtendedDataReceivedHandler(handler func(SSHExtendedDataType, []byte))
- func (c *Channel) SetRequestHandler(handler func(*RequestEventArgs))
- type ChannelClosedEventArgs
- type ChannelError
- type ChannelMetrics
- type ChannelOpeningEventArgs
- type ClientCredentials
- type ClientSession
- func (cs *ClientSession) Authenticate(ctx context.Context, creds *ClientCredentials) (bool, error)
- func (cs *ClientSession) AuthenticatePublicKeyQuery(ctx context.Context, username string, key KeyPair) (bool, error)
- func (cs *ClientSession) Reconnect(ctx context.Context, newStream io.ReadWriteCloser) error
- type ConnectionError
- type ContourUpdate
- type EcdsaKeyPair
- func (k *EcdsaKeyPair) Comment() string
- func (k *EcdsaKeyPair) GetPublicKeyBytes() ([]byte, error)
- func (k *EcdsaKeyPair) HasPrivateKey() bool
- func (k *EcdsaKeyPair) KeyAlgorithmName() string
- func (k *EcdsaKeyPair) PrivateKey() *ecdsa.PrivateKey
- func (k *EcdsaKeyPair) PublicKey() *ecdsa.PublicKey
- func (k *EcdsaKeyPair) SetComment(comment string)
- func (k *EcdsaKeyPair) SetPublicKeyBytes(data []byte) error
- func (k *EcdsaKeyPair) Sign(data []byte) ([]byte, error)
- func (k *EcdsaKeyPair) Verify(data, signature []byte) (bool, error)
- type KeyPair
- type MessageHandler
- type MultiChannelStream
- func (mcs *MultiChannelStream) AcceptChannel(ctx context.Context, channelType string) (*Channel, error)
- func (mcs *MultiChannelStream) AcceptStream(ctx context.Context, channelType string) (*Stream, error)
- func (mcs *MultiChannelStream) Close() error
- func (mcs *MultiChannelStream) Connect(ctx context.Context) error
- func (mcs *MultiChannelStream) ConnectAndRunUntilClosed(ctx context.Context) error
- func (mcs *MultiChannelStream) IsClosed() bool
- func (mcs *MultiChannelStream) OpenChannel(ctx context.Context, channelType string) (*Channel, error)
- func (mcs *MultiChannelStream) OpenStream(ctx context.Context, channelType string) (*Stream, error)
- func (mcs *MultiChannelStream) Session() *Session
- type PasswordProvider
- type PrivateKeyProvider
- type Progress
- type ReconnectError
- type ReconnectableSessions
- type RequestEventArgs
- type RsaKeyPair
- func (k *RsaKeyPair) Comment() string
- func (k *RsaKeyPair) GetPublicKeyBytes() ([]byte, error)
- func (k *RsaKeyPair) HasPrivateKey() bool
- func (k *RsaKeyPair) KeyAlgorithmName() string
- func (k *RsaKeyPair) PrivateKey() *rsa.PrivateKey
- func (k *RsaKeyPair) PublicKey() *rsa.PublicKey
- func (k *RsaKeyPair) SetComment(comment string)
- func (k *RsaKeyPair) SetPublicKeyBytes(data []byte) error
- func (k *RsaKeyPair) Sign(data []byte) ([]byte, error)
- func (k *RsaKeyPair) Verify(data, signature []byte) (bool, error)
- type SSHExtendedDataType
- type SSHProtocol
- type SecureStream
- func (ss *SecureStream) Close() error
- func (ss *SecureStream) Connect(ctx context.Context) error
- func (ss *SecureStream) IsClosed() bool
- func (ss *SecureStream) Read(p []byte) (int, error)
- func (ss *SecureStream) Reconnect(ctx context.Context, newTransportStream io.ReadWriteCloser) error
- func (ss *SecureStream) Session() *Session
- func (ss *SecureStream) Write(p []byte) (int, error)
- type SequencedMessage
- type ServerCredentials
- type ServerSession
- type Service
- type ServiceActivation
- type ServiceFactory
- type ServiceRegistration
- type Session
- func (s *Session) AcceptChannel(ctx context.Context) (*Channel, error)
- func (s *Session) AcceptChannelWithType(ctx context.Context, channelType string) (*Channel, error)
- func (s *Session) ActivateService(name string) Service
- func (s *Session) Channels() map[uint32]*Channel
- func (s *Session) Close() error
- func (s *Session) CloseWithError(reason messages.SSHDisconnectReason, msg string, err error) error
- func (s *Session) CloseWithReason(ctx context.Context, reason messages.SSHDisconnectReason, msg string) error
- func (s *Session) Connect(ctx context.Context, stream io.ReadWriteCloser) error
- func (s *Session) CreateReconnectToken(previousSessionID, newSessionID []byte) ([]byte, error)
- func (s *Session) Done() <-chan struct{}
- func (s *Session) GetService(name string) Service
- func (s *Session) IsClosed() bool
- func (s *Session) IsConnected() bool
- func (s *Session) Metrics() *SessionMetrics
- func (s *Session) OpenChannel(ctx context.Context) (*Channel, error)
- func (s *Session) OpenChannelWithMessage(ctx context.Context, channelType string, ...) (*Channel, error)
- func (s *Session) OpenChannelWithRequest(ctx context.Context, openMsg *messages.ChannelOpenMessage, ...) (*Channel, error)
- func (s *Session) OpenChannelWithType(ctx context.Context, channelType string) (*Channel, error)
- func (s *Session) Protocol() *SSHProtocol
- func (s *Session) Request(ctx context.Context, msg *messages.SessionRequestMessage) (bool, error)
- func (s *Session) RequestService(serviceName string) error
- func (s *Session) RequestServiceContext(ctx context.Context, serviceName string) error
- func (s *Session) RequestWithPayload(ctx context.Context, msg messages.Message, wantReply bool) (bool, []byte, error)
- func (s *Session) SendMessage(msg messages.Message) error
- func (s *Session) SendRawMessage(payload []byte) error
- func (s *Session) Services() []Service
- func (s *Session) SetAuthenticatingHandler(handler func(*AuthenticatingEventArgs))
- func (s *Session) SetChannelOpeningHandler(handler func(*ChannelOpeningEventArgs))
- func (s *Session) SetClosedHandler(handler func(*SessionClosedEventArgs))
- func (s *Session) SetReportProgressHandler(handler func(Progress))
- func (s *Session) SetRequestHandler(handler func(*RequestEventArgs))
- func (s *Session) SetTraceHandler(handler TraceFunc)
- func (s *Session) VerifyReconnectToken(previousSessionID, newSessionID, token []byte) (bool, error)
- type SessionClosedEventArgs
- type SessionConfig
- type SessionContour
- func (c *SessionContour) AddUpdate(u ContourUpdate)
- func (c *SessionContour) BytesReceivedAt(i int) int64
- func (c *SessionContour) BytesReceivedSlice() []int64
- func (c *SessionContour) BytesSentAt(i int) int64
- func (c *SessionContour) BytesSentSlice() []int64
- func (c *SessionContour) CollectMetrics(metrics *SessionMetrics)
- func (c *SessionContour) Export() string
- func (c *SessionContour) IntervalCount() int
- func (c *SessionContour) IntervalMs() int64
- func (c *SessionContour) LatencyAverageMsAt(i int) float32
- func (c *SessionContour) LatencyAverageMsSlice() []float32
- func (c *SessionContour) LatencyMaxMsAt(i int) float32
- func (c *SessionContour) LatencyMaxMsSlice() []float32
- func (c *SessionContour) LatencyMinMsAt(i int) float32
- func (c *SessionContour) LatencyMinMsSlice() []float32
- func (c *SessionContour) MaxIntervals() int
- func (c *SessionContour) Stop()
- type SessionMetrics
- func (m *SessionMetrics) BytesReceived() int64
- func (m *SessionMetrics) BytesSent() int64
- func (m *SessionMetrics) LatencyAverageMs() float32
- func (m *SessionMetrics) LatencyCurrentMs() float32
- func (m *SessionMetrics) LatencyMaxMs() float32
- func (m *SessionMetrics) LatencyMinMs() float32
- func (m *SessionMetrics) MessagesReceived() int64
- func (m *SessionMetrics) MessagesSent() int64
- func (m *SessionMetrics) Reconnections() int64
- func (m *SessionMetrics) TimeMicroseconds() int64
- type Stream
- type TraceFunc
- type TraceLevel
- type VersionInfo
Constants ¶
const ( // DefaultMaxPacketSize is the default maximum packet size for channel data (32 KB). DefaultMaxPacketSize uint32 = 32 * 1024 // DefaultMaxWindowSize is the default maximum window size for channel flow control (1 MB). DefaultMaxWindowSize uint32 = DefaultMaxPacketSize * 32 )
const ( ExtensionServerSignatureAlgorithms = "server-sig-algs" ExtensionOpenChannelRequest = "open-channel-request@microsoft.com" ExtensionSessionReconnect = "session-reconnect@microsoft.com" ExtensionSessionLatency = "session-latency@microsoft.com" )
Protocol extension name constants.
The @microsoft.com domain is used for all Dev Tunnels SSH custom extensions. This matches the C# and TypeScript implementations exactly, and is the domain expected by the Dev Tunnels relay service. Extensions are negotiated via RFC 8308 ext-info messages during key exchange.
const ( ExtensionRequestInitialChannelRequest = "initial-channel-request@microsoft.com" ExtensionRequestKeepAlive = "keepalive@openssh.com" ExtensionRequestEnableSessionReconnect = "enable-session-reconnect@microsoft.com" )
Extension request type constants.
Uses the same @microsoft.com domain as the extension names above. The keepalive extension uses @openssh.com for OpenSSH compatibility.
const ( AlgoKexEcdhNistp521 = "ecdh-sha2-nistp521" AlgoKexEcdhNistp384 = "ecdh-sha2-nistp384" AlgoKexEcdhNistp256 = "ecdh-sha2-nistp256" AlgoKexDHGroup16 = "diffie-hellman-group16-sha512" AlgoKexDHGroup14 = "diffie-hellman-group14-sha256" AlgoKexNone = "none" AlgoPKRsaSha512 = "rsa-sha2-512" AlgoPKRsaSha256 = "rsa-sha2-256" AlgoPKEcdsaSha2P384 = "ecdsa-sha2-nistp384" AlgoPKEcdsaSha2P256 = "ecdsa-sha2-nistp256" AlgoPKEcdsaSha2P521 = "ecdsa-sha2-nistp521" AlgoPKNone = "none" AlgoEncAes256Gcm = "aes256-gcm@openssh.com" AlgoEncAes256Cbc = "aes256-cbc" AlgoEncAes256Ctr = "aes256-ctr" AlgoEncNone = "none" AlgoHmacSha512Etm = "hmac-sha2-512-etm@openssh.com" AlgoHmacSha256Etm = "hmac-sha2-256-etm@openssh.com" AlgoHmacSha512 = "hmac-sha2-512" AlgoHmacSha256 = "hmac-sha2-256" AlgoHmacNone = "none" AlgoCompNone = "none" )
Well-known algorithm names used in configuration.
const ( AuthMethodNone = "none" AuthMethodPassword = "password" AuthMethodPublicKey = "publickey" AuthMethodKeyboardInteractive = "keyboard-interactive" AuthMethodHostBased = "hostbased" )
Well-known authentication method names.
const ( // TraceEventUnknownError is reported for unexpected errors. TraceEventUnknownError = baseEventID + 0 // TraceEventStreamReadError is reported when reading from the stream fails. TraceEventStreamReadError = baseEventID + 1 // TraceEventStreamWriteError is reported when writing to the stream fails. TraceEventStreamWriteError = baseEventID + 2 // TraceEventStreamCloseError is reported when closing the stream fails. TraceEventStreamCloseError = baseEventID + 3 // TraceEventSendMessageFailed is reported when sending a message fails. TraceEventSendMessageFailed = baseEventID + 4 // TraceEventReceiveMessageFailed is reported when receiving a message fails. TraceEventReceiveMessageFailed = baseEventID + 5 // TraceEventHandleMessageFailed is reported when handling a message fails. TraceEventHandleMessageFailed = baseEventID + 6 // TraceEventServerAuthenticationFailed is reported when server authentication fails. TraceEventServerAuthenticationFailed = baseEventID + 7 // TraceEventClientAuthenticationFailed is reported when client authentication fails. TraceEventClientAuthenticationFailed = baseEventID + 8 // TraceEventAuthenticationError is reported for authentication errors. TraceEventAuthenticationError = baseEventID + 9 // TraceEventChannelWindowAdjustFailed is reported when a channel window adjust fails. TraceEventChannelWindowAdjustFailed = baseEventID + 10 // TraceEventSessionReconnectInitFailed is reported when reconnect initialization fails. TraceEventSessionReconnectInitFailed = baseEventID + 20 // TraceEventServerSessionReconnectFailed is reported when server reconnect fails. TraceEventServerSessionReconnectFailed = baseEventID + 21 // TraceEventClientSessionReconnectFailed is reported when client reconnect fails. TraceEventClientSessionReconnectFailed = baseEventID + 22 // TraceEventSessionRequestFailed is reported when a session request fails. TraceEventSessionRequestFailed = baseEventID + 23 // TraceEventChannelRequestFailed is reported when a channel request fails. TraceEventChannelRequestFailed = baseEventID + 24 // TraceEventChannelCloseFailed is reported when closing a channel fails. TraceEventChannelCloseFailed = baseEventID + 25 // TraceEventKeepAliveFailed is reported when a keep-alive fails. TraceEventKeepAliveFailed = baseEventID + 62 // TraceEventKeepAliveResponseNotReceived is reported when keep-alive response times out. TraceEventKeepAliveResponseNotReceived = baseEventID + 64 // TraceEventProtocolVersion is reported after version exchange. TraceEventProtocolVersion = baseEventID + 100 // TraceEventSendingMessage is reported when sending a non-channel-data message. TraceEventSendingMessage = baseEventID + 101 // TraceEventReceivingMessage is reported when receiving a non-channel-data message. TraceEventReceivingMessage = baseEventID + 102 // TraceEventSendingChannelData is reported when sending channel data (TraceChannelData only). TraceEventSendingChannelData = baseEventID + 103 // TraceEventReceivingChannelData is reported when receiving channel data (TraceChannelData only). TraceEventReceivingChannelData = baseEventID + 104 // TraceEventSessionEncrypted is reported after key exchange completes and encryption is active. TraceEventSessionEncrypted = baseEventID + 110 // TraceEventSessionAuthenticating is reported when authentication starts. TraceEventSessionAuthenticating = baseEventID + 111 // TraceEventSessionAuthenticated is reported when authentication succeeds. TraceEventSessionAuthenticated = baseEventID + 112 // TraceEventSessionClosing is reported when the session is closing. TraceEventSessionClosing = baseEventID + 113 // TraceEventSessionConnecting is reported when the session is connecting. TraceEventSessionConnecting = baseEventID + 114 // TraceEventChannelOpened is reported when a channel is successfully opened. TraceEventChannelOpened = baseEventID + 120 // TraceEventChannelOpenFailed is reported when a channel open fails. TraceEventChannelOpenFailed = baseEventID + 121 // TraceEventChannelClosed is reported when a channel is closed. TraceEventChannelClosed = baseEventID + 123 // TraceEventSessionDisconnected is reported when the session is disconnected. TraceEventSessionDisconnected = baseEventID + 160 // TraceEventClientSessionReconnecting is reported when a client is reconnecting. TraceEventClientSessionReconnecting = baseEventID + 161 // TraceEventServerSessionReconnecting is reported when a server is reconnecting. TraceEventServerSessionReconnecting = baseEventID + 162 // TraceEventAlgorithmNegotiation is reported during algorithm negotiation. TraceEventAlgorithmNegotiation = baseEventID + 170 )
SSHTraceEventID constants match the C#/TypeScript implementations. Event IDs use a base of 9000.
const (
// AlgoKeyRsa is the SSH key algorithm name for RSA keys.
AlgoKeyRsa = "ssh-rsa"
)
KeyAlgorithmName constants for SSH key types.
const AuthServiceName = "ssh-userauth"
AuthServiceName is the SSH service name for user authentication.
const ConnectionServiceName = "ssh-connection"
ConnectionServiceName is the service name requested during auth.
Variables ¶
var ( ErrSessionClosed = errors.New("session is closed") ErrClosed = errors.New("resource is closed") ErrNotConnected = errors.New("session is not connected") ErrNotAuthenticated = errors.New("session is not authenticated") )
Sentinel errors for common SSH session states.
Functions ¶
func PipeSession ¶
PipeSession pipes two sessions together bidirectionally. When a session request arrives on one session, it is forwarded to the other. When a channel is opened remotely on one session, a corresponding channel is opened on the other session with the same type, and the two channels are piped together (including data, extended data, EOF, and close events). When one session closes, the other is closed too.
PipeSession blocks until one session closes or the context is cancelled.
func WaitUntilReconnectEnabled ¶
WaitUntilReconnectEnabled polls until both sides of a session pair have reconnect extensions negotiated and enabled, AND both protocols have IncomingMessagesHaveReconnectInfo set (meaning each side has received the other's enable-reconnect message and message caching is active). Used in tests for initial setup with kex:none (where enableReconnect is called manually rather than via extension info exchange).
Types ¶
type AuthenticatingEventArgs ¶
type AuthenticatingEventArgs struct {
AuthenticationType AuthenticationType
Username string
Password string
PublicKey KeyPair
ClientHostname string
ClientUsername string
InfoRequest *messages.AuthenticationInfoRequestMessage
InfoResponse *messages.AuthenticationInfoResponseMessage
Ctx context.Context
// AuthenticationResult should be set by the event handler.
// A non-nil value indicates successful authentication.
AuthenticationResult interface{}
}
AuthenticatingEventArgs contains arguments for session authentication events.
type AuthenticationType ¶
type AuthenticationType int
AuthenticationType indicates the type of authentication being requested by an SSH client or server.
const ( // AuthClientNone indicates the client is authenticating without credentials, // with only a username, or is checking what methods the server supports. AuthClientNone AuthenticationType = 0 // AuthClientHostBased indicates the client is authenticating with a host public key. AuthClientHostBased AuthenticationType = 1 // AuthClientPassword indicates the client is authenticating with username and password. AuthClientPassword AuthenticationType = 2 // AuthClientPublicKeyQuery indicates the client is querying whether a public key // would be accepted, without proving possession of the private key. AuthClientPublicKeyQuery AuthenticationType = 3 // AuthClientPublicKey indicates the client is authenticating with a public key, // including a signature proving possession of the private key. AuthClientPublicKey AuthenticationType = 4 // AuthClientInteractive indicates the client is authenticating via // keyboard-interactive prompts. AuthClientInteractive AuthenticationType = 5 // AuthServerPublicKey indicates the server is authenticating with its host key. AuthServerPublicKey AuthenticationType = 10 )
type Channel ¶
type Channel struct {
// ChannelType is the type string for this channel (e.g., "session").
ChannelType string
// ChannelID is the local channel ID.
ChannelID uint32
// RemoteChannelID is the remote side's channel ID.
RemoteChannelID uint32
// MaxWindowSize is the local maximum receive window size.
MaxWindowSize uint32
// MaxPacketSize is the local maximum packet size.
MaxPacketSize uint32
// OnDataReceived is called when data is received on this channel.
// The handler must call AdjustWindow(len(data)) when done processing.
OnDataReceived func(data []byte)
// OnExtendedDataReceived is called when extended data (e.g. stderr) is received.
// If nil, extended data falls through to OnDataReceived for backward compatibility.
// The handler must call AdjustWindow(len(data)) when done processing.
OnExtendedDataReceived func(dataType SSHExtendedDataType, data []byte)
// OnClosed is called when the channel is closed.
OnClosed func(*ChannelClosedEventArgs)
// OnEof is called when an EOF message is received from the remote side.
OnEof func()
// OnRequest is called when a channel request is received.
OnRequest func(*RequestEventArgs)
// contains filtered or unexported fields
}
Channel represents a single SSH channel within a session. Channels are multiplexed over a single SSH connection and support bidirectional data transfer with flow control.
func (*Channel) AdjustWindow ¶
AdjustWindow is called by the data receiver after processing received data. It sends a WindowAdjust message to the remote side when more than 50% of the window has been consumed.
func (*Channel) Close ¶
Close closes the channel by sending EOF (if not already sent) and Close messages. It waits for the remote side to acknowledge the close.
func (*Channel) CloseWithContext ¶
CloseWithContext closes the channel with context support.
func (*Channel) CloseWithSignal ¶
CloseWithSignal closes the channel with a signal name and error message. The signal info is propagated to the remote side via OnClosed callback.
func (*Channel) CloseWithStatus ¶
CloseWithStatus closes the channel with an exit status code. The exit status is propagated to the remote side via OnClosed callback.
func (*Channel) Metrics ¶
func (c *Channel) Metrics() *ChannelMetrics
Metrics returns a pointer to the channel's metrics counters.
func (*Channel) OpenConfirmationMessage ¶
func (c *Channel) OpenConfirmationMessage() *messages.ChannelOpenConfirmationMessage
OpenConfirmationMessage returns the message that confirmed opening the channel. It is non-nil after the channel open is confirmed.
func (*Channel) OpenMessage ¶
func (c *Channel) OpenMessage() *messages.ChannelOpenMessage
OpenMessage returns the message that requested opening the channel. It is non-nil after the channel is opened.
func (*Channel) Pipe ¶
Pipe relays data bidirectionally between this channel and the target channel. When one channel closes, the other is also closed. Pipe blocks until one of the channels is closed.
All handlers are installed synchronously in the calling goroutine before any events can be missed. Close handlers are installed atomically (read old + write new under a single lock) to prevent a race where the channel closes between snapshotting the old handler and installing the new one.
func (*Channel) Request ¶
Request sends a channel request and waits for a success/failure response. Returns true if the request was accepted, false otherwise.
func (*Channel) Send ¶
Send sends data on the channel. It blocks if the remote window is exhausted and resumes when a WindowAdjust message is received. Sending empty/nil data sends an EOF message. Send is safe for concurrent use; multiple sends are serialized to prevent data interleaving across multi-packet messages.
func (*Channel) SendExtendedData ¶
func (c *Channel) SendExtendedData(ctx context.Context, dataType SSHExtendedDataType, data []byte) error
SendExtendedData sends extended data (e.g. stderr) on the channel. It respects flow control the same way as Send.
func (*Channel) SendSignal ¶
SendSignal sends a standalone signal channel request to the remote side. The signalName should be a signal name like "TERM", "HUP", "INT", etc.
func (*Channel) SetClosedHandler ¶
func (c *Channel) SetClosedHandler(handler func(*ChannelClosedEventArgs))
SetClosedHandler sets the OnClosed callback in a thread-safe manner.
func (*Channel) SetDataReceivedHandler ¶
SetDataReceivedHandler sets the OnDataReceived callback and flushes any data that was buffered while no handler was attached.
func (*Channel) SetEofHandler ¶
func (c *Channel) SetEofHandler(handler func())
SetEofHandler sets the OnEof callback in a thread-safe manner.
func (*Channel) SetExtendedDataReceivedHandler ¶
func (c *Channel) SetExtendedDataReceivedHandler(handler func(SSHExtendedDataType, []byte))
SetExtendedDataReceivedHandler sets the OnExtendedDataReceived callback and flushes any extended data that was buffered while no handler was attached.
func (*Channel) SetRequestHandler ¶
func (c *Channel) SetRequestHandler(handler func(*RequestEventArgs))
SetRequestHandler sets the OnRequest callback in a thread-safe manner. Use this method instead of direct field assignment when the channel is already active, to avoid data races with the request handler goroutine.
type ChannelClosedEventArgs ¶
type ChannelClosedEventArgs struct {
ExitStatus *uint32
ExitSignal string
ErrorMessage string
Err error
}
ChannelClosedEventArgs contains arguments for channel closed events.
type ChannelError ¶
type ChannelError struct {
Reason messages.SSHChannelOpenFailureReason
Msg string
Err error
}
ChannelError represents an SSH channel error with a failure reason.
func (*ChannelError) Error ¶
func (e *ChannelError) Error() string
func (*ChannelError) Unwrap ¶
func (e *ChannelError) Unwrap() error
type ChannelMetrics ¶
type ChannelMetrics struct {
// contains filtered or unexported fields
}
ChannelMetrics tracks byte counters for a single SSH channel.
func (*ChannelMetrics) BytesReceived ¶
func (m *ChannelMetrics) BytesReceived() int64
BytesReceived returns the total number of data bytes received on this channel.
func (*ChannelMetrics) BytesSent ¶
func (m *ChannelMetrics) BytesSent() int64
BytesSent returns the total number of data bytes sent on this channel.
func (*ChannelMetrics) DroppedRequests ¶
func (m *ChannelMetrics) DroppedRequests() int64
DroppedRequests returns the number of channel requests dropped due to a full queue.
type ChannelOpeningEventArgs ¶
type ChannelOpeningEventArgs struct {
Request *messages.ChannelOpenMessage
Channel *Channel
IsRemoteRequest bool
FailureReason messages.SSHChannelOpenFailureReason
FailureDescription string
Ctx context.Context
// Payload contains the raw message payload bytes.
// Services can use this to parse extended fields beyond the base ChannelOpenMessage.
Payload []byte
}
ChannelOpeningEventArgs contains arguments for channel opening events.
type ClientCredentials ¶
type ClientCredentials struct {
Username string
Password string
PublicKeys []KeyPair
// PasswordProvider is an optional callback that lazily provides a username and
// password during authentication. When set, it is called instead of using the
// static Username/Password fields for password authentication. This enables
// interactive prompting or deferred credential loading, matching C#/TS
// PasswordCredentialProvider behavior.
PasswordProvider PasswordProvider
// PrivateKeyProvider is an optional callback that provides a full key pair
// (with private key material) given a public-key-only key pair. It is called
// during authentication when a key in PublicKeys does not have HasPrivateKey() == true.
// This enables deferred loading of private keys from secure storage.
PrivateKeyProvider PrivateKeyProvider
}
ClientCredentials defines credentials for authenticating an SSH client session.
type ClientSession ¶
type ClientSession struct {
Session
}
ClientSession is an SSH client session that connects to a server.
func NewClientSession ¶
func NewClientSession(config *SessionConfig) *ClientSession
NewClientSession creates a new SSH client session with the given configuration. If config is nil, a no-security configuration is used.
func (*ClientSession) Authenticate ¶
func (cs *ClientSession) Authenticate(ctx context.Context, creds *ClientCredentials) (bool, error)
Authenticate authenticates the client session with the given credentials. It first verifies the server's host key (if any), then sends authentication credentials to the server. Returns true if authentication succeeds.
func (*ClientSession) AuthenticatePublicKeyQuery ¶
func (cs *ClientSession) AuthenticatePublicKeyQuery(ctx context.Context, username string, key KeyPair) (bool, error)
AuthenticatePublicKeyQuery sends a public key query to check if the server would accept the given key, without proving possession of the private key.
func (*ClientSession) Reconnect ¶
func (cs *ClientSession) Reconnect(ctx context.Context, newStream io.ReadWriteCloser) error
Reconnect reconnects a disconnected client session over a new stream. The new stream must connect to the same server (same host key). After reconnection, channels continue operating normally.
type ConnectionError ¶
type ConnectionError struct {
Reason messages.SSHDisconnectReason
Msg string
Err error
}
ConnectionError represents an SSH connection error with a disconnect reason.
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
func (*ConnectionError) Unwrap ¶
func (e *ConnectionError) Unwrap() error
type ContourUpdate ¶
ContourUpdate contains a single metrics update to be applied to the contour.
type EcdsaKeyPair ¶
type EcdsaKeyPair struct {
// contains filtered or unexported fields
}
EcdsaKeyPair implements KeyPair for ECDSA keys.
func NewEcdsaKeyPair ¶
func NewEcdsaKeyPair(privateKey *ecdsa.PrivateKey) (*EcdsaKeyPair, error)
NewEcdsaKeyPair creates a new EcdsaKeyPair from an existing crypto/ecdsa private key.
func NewEcdsaKeyPairFromPublicKey ¶
func NewEcdsaKeyPairFromPublicKey(pubKey *ecdsa.PublicKey) (*EcdsaKeyPair, error)
NewEcdsaKeyPairFromPublicKey creates a public-key-only EcdsaKeyPair from a crypto/ecdsa public key.
func (*EcdsaKeyPair) Comment ¶
func (k *EcdsaKeyPair) Comment() string
Comment returns the key comment.
func (*EcdsaKeyPair) GetPublicKeyBytes ¶
func (k *EcdsaKeyPair) GetPublicKeyBytes() ([]byte, error)
GetPublicKeyBytes returns the ECDSA public key in SSH wire format. Format: [string algorithm][string curve-name][binary 0x04||X||Y]
func (*EcdsaKeyPair) HasPrivateKey ¶
func (k *EcdsaKeyPair) HasPrivateKey() bool
HasPrivateKey returns true if this key pair includes a private key.
func (*EcdsaKeyPair) KeyAlgorithmName ¶
func (k *EcdsaKeyPair) KeyAlgorithmName() string
KeyAlgorithmName returns the SSH algorithm name (e.g., "ecdsa-sha2-nistp256").
func (*EcdsaKeyPair) PrivateKey ¶
func (k *EcdsaKeyPair) PrivateKey() *ecdsa.PrivateKey
PrivateKey returns the underlying crypto/ecdsa private key, or nil.
func (*EcdsaKeyPair) PublicKey ¶
func (k *EcdsaKeyPair) PublicKey() *ecdsa.PublicKey
PublicKey returns the underlying crypto/ecdsa public key.
func (*EcdsaKeyPair) SetComment ¶
func (k *EcdsaKeyPair) SetComment(comment string)
SetComment sets the key comment.
func (*EcdsaKeyPair) SetPublicKeyBytes ¶
func (k *EcdsaKeyPair) SetPublicKeyBytes(data []byte) error
SetPublicKeyBytes imports an ECDSA public key from SSH wire format bytes.
type KeyPair ¶
type KeyPair interface {
// KeyAlgorithmName returns the SSH key algorithm name
// (e.g., "ssh-rsa", "ecdsa-sha2-nistp256").
KeyAlgorithmName() string
// HasPrivateKey returns true if the key pair includes a private key for signing.
HasPrivateKey() bool
// GetPublicKeyBytes returns the public key in SSH wire format.
// The format is: [string algorithm-name][key-type-specific data].
GetPublicKeyBytes() ([]byte, error)
// SetPublicKeyBytes imports a public key from SSH wire format bytes.
// After calling this, HasPrivateKey returns false.
SetPublicKeyBytes(data []byte) error
// Comment returns the key comment string.
Comment() string
// SetComment sets the key comment string.
SetComment(comment string)
}
KeyPair represents an SSH key pair with optional private key for signing.
func GenerateKeyPair ¶
GenerateKeyPair generates a new key pair for the specified algorithm using a default key size. Supported algorithm names:
- "rsa-sha2-256": RSA 2048-bit with SHA-256 signing
- "rsa-sha2-512": RSA 4096-bit with SHA-512 signing
- "ecdsa-sha2-nistp256": ECDSA with P-256 curve
- "ecdsa-sha2-nistp384": ECDSA with P-384 curve
- "ecdsa-sha2-nistp521": ECDSA with P-521 curve
func GenerateKeyPairWithSize ¶
GenerateKeyPairWithSize generates a new key pair for the specified algorithm with an explicit key size in bits. For RSA algorithms, keySizeInBits controls the RSA key length (e.g., 2048, 4096). For ECDSA algorithms, keySizeInBits is ignored (the curve determines the key size).
func KeyPairFromPublicKeyBytes ¶
KeyPairFromPublicKeyBytes creates a KeyPair from SSH wire-format public key bytes. The algorithm name is read from the beginning of the data.
type MessageHandler ¶
MessageHandler is a callback that handles a custom SSH message type. The payload parameter contains the full raw message including the type byte.
type MultiChannelStream ¶
type MultiChannelStream struct {
// OnChannelOpening is called when a channel open request is received.
OnChannelOpening func(*ChannelOpeningEventArgs)
// OnClosed is called when the stream is closed.
OnClosed func(*SessionClosedEventArgs)
// ChannelMaxWindowSize is the maximum window size for channels.
// Zero uses the default (1 MB).
ChannelMaxWindowSize uint32
// contains filtered or unexported fields
}
MultiChannelStream provides lightweight channel multiplexing over a single transport stream without encryption. It is suitable for scenarios where the transport is already secure (e.g., TLS).
MultiChannelStream uses an underlying SSH session configured with "none" algorithms (no encryption, no HMAC, no key exchange) to provide channel multiplexing, flow control, and message framing without cryptographic overhead.
func NewMultiChannelStream ¶
func NewMultiChannelStream(transportStream io.ReadWriteCloser, isClient bool) *MultiChannelStream
NewMultiChannelStream creates a new MultiChannelStream wrapping the given transport stream. The isClient parameter indicates whether this end acts as the SSH client (true) or server (false).
func (*MultiChannelStream) AcceptChannel ¶
func (mcs *MultiChannelStream) AcceptChannel(ctx context.Context, channelType string) (*Channel, error)
AcceptChannel waits for and accepts an incoming channel with the given type. If channelType is empty, any channel type is accepted.
func (*MultiChannelStream) AcceptStream ¶
func (mcs *MultiChannelStream) AcceptStream(ctx context.Context, channelType string) (*Stream, error)
AcceptStream waits for an incoming channel and wraps it as an io.ReadWriteCloser.
func (*MultiChannelStream) Close ¶
func (mcs *MultiChannelStream) Close() error
Close closes the underlying session and transport stream.
func (*MultiChannelStream) Connect ¶
func (mcs *MultiChannelStream) Connect(ctx context.Context) error
Connect establishes the multiplexed connection by performing SSH version exchange and key exchange (with "none" algorithms). This method is idempotent — calling it multiple times returns immediately after the first successful connection.
func (*MultiChannelStream) ConnectAndRunUntilClosed ¶
func (mcs *MultiChannelStream) ConnectAndRunUntilClosed(ctx context.Context) error
ConnectAndRunUntilClosed connects and then blocks until the session is closed or the context is cancelled. This is useful for server-side code that needs to process channels until the connection ends.
func (*MultiChannelStream) IsClosed ¶
func (mcs *MultiChannelStream) IsClosed() bool
IsClosed returns true if the stream has been closed.
func (*MultiChannelStream) OpenChannel ¶
func (mcs *MultiChannelStream) OpenChannel(ctx context.Context, channelType string) (*Channel, error)
OpenChannel opens a new channel with the given channel type. If channelType is empty, "session" is used as the default.
func (*MultiChannelStream) OpenStream ¶
OpenStream opens a new channel and wraps it as an io.ReadWriteCloser.
func (*MultiChannelStream) Session ¶
func (mcs *MultiChannelStream) Session() *Session
Session returns the underlying SSH session.
type PasswordProvider ¶
PasswordProvider is an optional callback that lazily provides a username and password during authentication. This enables interactive prompting or deferred credential loading. If the provider returns an error, the session is closed with DisconnectAuthCancelledByUser. If the provider returns empty username and password, password auth is skipped.
type PrivateKeyProvider ¶
PrivateKeyProvider is a callback that provides a full key pair (with private key) given a public-key-only key pair. It is called during authentication or key exchange when a key in the credentials list does not have private key material loaded. This enables deferred/lazy loading of private keys from secure storage (e.g., HSMs, key vaults, or encrypted files) rather than requiring all private keys in memory upfront.
type Progress ¶
type Progress int
Progress represents connection progress events reported during session lifecycle. These match the C#/TS Progress enum values.
const ( // ProgressOpeningSSHSessionConnection is reported when starting a new SSH session connection. ProgressOpeningSSHSessionConnection Progress = iota // ProgressOpenedSSHSessionConnection is reported after the SSH session connection is fully established. ProgressOpenedSSHSessionConnection // ProgressStartingProtocolVersionExchange is reported when starting the protocol version exchange. ProgressStartingProtocolVersionExchange // ProgressCompletedProtocolVersionExchange is reported after the protocol version exchange completes. ProgressCompletedProtocolVersionExchange // ProgressStartingKeyExchange is reported when starting the key exchange. ProgressStartingKeyExchange // ProgressCompletedKeyExchange is reported after the key exchange completes. ProgressCompletedKeyExchange // ProgressStartingSessionAuthentication is reported when starting session authentication. ProgressStartingSessionAuthentication // ProgressCompletedSessionAuthentication is reported after session authentication completes. ProgressCompletedSessionAuthentication )
type ReconnectError ¶
type ReconnectError struct {
Reason messages.SSHReconnectFailureReason
Msg string
Err error
}
ReconnectError represents an SSH reconnection error with a failure reason.
func (*ReconnectError) Error ¶
func (e *ReconnectError) Error() string
func (*ReconnectError) Unwrap ¶
func (e *ReconnectError) Unwrap() error
type ReconnectableSessions ¶
type ReconnectableSessions struct {
// contains filtered or unexported fields
}
ReconnectableSessions is a thread-safe collection of disconnected server sessions awaiting reconnection. It must be shared across all ServerSession instances that should be able to reconnect to each other.
func NewReconnectableSessions ¶
func NewReconnectableSessions() *ReconnectableSessions
NewReconnectableSessions creates a new empty collection.
func (*ReconnectableSessions) Add ¶
func (r *ReconnectableSessions) Add(s *ServerSession)
Add adds a session to the collection if it isn't already present. Call this after a session is connected and reconnect is enabled to make it available for reconnection after disconnect.
type RequestEventArgs ¶
type RequestEventArgs struct {
RequestType string
Request messages.Message
IsAuthorized bool
Ctx context.Context
// Principal holds the authenticated identity from the session.
// This is populated from Session.Principal when the request is dispatched.
Principal interface{}
// Payload contains the raw message payload bytes.
// Services can use this to parse extended fields beyond the base message.
Payload []byte
// ResponseMessage, if set, will be sent instead of the plain success message
// when IsAuthorized is true. This allows services to send custom response data
// (e.g., allocated port in port forwarding).
ResponseMessage messages.Message
// ResponseHandled indicates the service has already sent the response.
// When true, the session will not send any automatic response.
ResponseHandled bool
}
RequestEventArgs contains arguments for session or channel request events.
type RsaKeyPair ¶
type RsaKeyPair struct {
// contains filtered or unexported fields
}
RsaKeyPair implements KeyPair for RSA keys. It supports signing with SHA-256 (rsa-sha2-256) or SHA-512 (rsa-sha2-512).
func NewRsaKeyPair ¶
func NewRsaKeyPair(privateKey *rsa.PrivateKey, algorithmName string) (*RsaKeyPair, error)
NewRsaKeyPair creates a new RsaKeyPair from an existing crypto/rsa private key. algorithmName should be "rsa-sha2-256" or "rsa-sha2-512" to determine the hash.
func NewRsaKeyPairFromPublicKey ¶
func NewRsaKeyPairFromPublicKey(pubKey *rsa.PublicKey) *RsaKeyPair
NewRsaKeyPairFromPublicKey creates a public-key-only RsaKeyPair from a crypto/rsa public key.
func (*RsaKeyPair) GetPublicKeyBytes ¶
func (k *RsaKeyPair) GetPublicKeyBytes() ([]byte, error)
GetPublicKeyBytes returns the RSA public key in SSH wire format. Format: [string "ssh-rsa"][mpint e][mpint n]
func (*RsaKeyPair) HasPrivateKey ¶
func (k *RsaKeyPair) HasPrivateKey() bool
HasPrivateKey returns true if this key pair includes a private key.
func (*RsaKeyPair) KeyAlgorithmName ¶
func (k *RsaKeyPair) KeyAlgorithmName() string
KeyAlgorithmName returns "ssh-rsa", the SSH key algorithm identifier for RSA.
func (*RsaKeyPair) PrivateKey ¶
func (k *RsaKeyPair) PrivateKey() *rsa.PrivateKey
PrivateKey returns the underlying crypto/rsa private key, or nil.
func (*RsaKeyPair) PublicKey ¶
func (k *RsaKeyPair) PublicKey() *rsa.PublicKey
PublicKey returns the underlying crypto/rsa public key.
func (*RsaKeyPair) SetComment ¶
func (k *RsaKeyPair) SetComment(comment string)
SetComment sets the key comment.
func (*RsaKeyPair) SetPublicKeyBytes ¶
func (k *RsaKeyPair) SetPublicKeyBytes(data []byte) error
SetPublicKeyBytes imports an RSA public key from SSH wire format bytes. Accepts algorithm names: "ssh-rsa", "rsa-sha2-256", "rsa-sha2-512".
type SSHExtendedDataType ¶
type SSHExtendedDataType uint32
SSHExtendedDataType represents the type code for SSH extended data.
const ( // ExtendedDataStderr is the standard type code for stderr data. ExtendedDataStderr SSHExtendedDataType = 1 )
type SSHProtocol ¶
type SSHProtocol struct {
// SendSequence tracks the number of messages sent (64-bit for reconnect tracking).
// The lower 32 bits are used for HMAC computation per SSH spec.
SendSequence uint64
// ReceiveSequence tracks the number of messages received (64-bit for reconnect tracking).
// Atomic because it is written by the dispatch loop and read by sendMessage via LastIncomingSequence.
ReceiveSequence uint64 // atomic
// Reconnect info flags. When enabled, extra bytes are appended to/stripped from
// each packet for sequence acknowledgment and optional latency measurement.
// These are atomic int32 (0/1) to allow concurrent access from send and dispatch goroutines.
OutgoingMessagesHaveReconnectInfo int32 // atomic; 0 = false, 1 = true
IncomingMessagesHaveReconnectInfo int32 // atomic; 0 = false, 1 = true
OutgoingMessagesHaveLatencyInfo int32 // atomic; 0 = false, 1 = true
IncomingMessagesHaveLatencyInfo int32 // atomic; 0 = false, 1 = true
// BytesSent and BytesReceived track cumulative wire bytes for key rotation threshold.
// These are atomic to allow concurrent send/receive access.
// Reset to 0 after successful key exchange in activateNewKeys.
BytesSent uint64 // atomic
BytesReceived uint64 // atomic
// contains filtered or unexported fields
}
SSHProtocol handles binary SSH packet framing on a stream.
Wire packet format (RFC 4253):
[uint32 packet_length] [byte padding_length] [payload] [random padding] [MAC]
Where packet_length = padding_length_size(1) + payload_length + padding_length.
Three encryption modes are supported:
- Standard: HMAC on plaintext, then encrypt full packet (including length)
- EtM (encrypt-then-MAC): encrypt without length, then HMAC on ciphertext
- GCM (AEAD): encrypt without length, authentication tag from cipher
func (*SSHProtocol) GetSentMessages ¶
func (p *SSHProtocol) GetSentMessages(startingSequenceNumber uint64) [][]byte
GetSentMessages retrieves cached sent messages starting from the given sequence number. Returns:
- empty slice if the remote side is already up-to-date
- nil if the cache doesn't go back far enough (messages were purged)
- slice of payload bytes otherwise
Key exchange and disconnect messages are excluded since they cannot be retransmitted; a reconnected session will do key exchange separately.
func (*SSHProtocol) LastIncomingSequence ¶
func (p *SSHProtocol) LastIncomingSequence() uint64
LastIncomingSequence returns the sequence number of the last received message. Returns 0 if no messages have been received yet (avoids uint64 underflow).
func (*SSHProtocol) SetEncryption ¶
func (p *SSHProtocol) SetEncryption( encryptCipher, decryptCipher algorithms.Cipher, signer algorithms.MessageSigner, verifier algorithms.MessageVerifier, )
SetEncryption activates encryption and HMAC on this protocol instance. Called after key exchange completes. Pass nil to disable encryption. Acquires sendMu to prevent races with sendMessage reading send-side fields.
type SecureStream ¶
type SecureStream struct {
// OnAuthenticating is called when authentication credentials need to be
// verified. For a client, it is called to verify the server host key. For
// a server, it is called to verify the client's credentials.
//
// The handler must set AuthenticationResult to a non-nil value to accept.
OnAuthenticating func(*AuthenticatingEventArgs)
// OnDisconnected is called when the session disconnects while reconnection
// is enabled. After this fires, the client application should call
// Reconnect() with a new transport stream. The server handles reconnections
// automatically during the session handshake.
OnDisconnected func()
// OnClosed is called when the underlying SSH session is closed.
OnClosed func(*SessionClosedEventArgs)
// contains filtered or unexported fields
}
SecureStream establishes an end-to-end encrypted, two-way authenticated data stream over an underlying transport stream, using the SSH protocol but providing a simplified interface that is limited to a single duplex stream (channel).
This type is a complement to MultiChannelStream, which provides only the channel-multiplexing functions of SSH without encryption.
To establish a secure connection, the two sides first establish an insecure transport stream over a pipe, socket, or anything else. Then they encrypt and authenticate the connection before beginning to send and receive data.
func NewSecureStreamClient ¶
func NewSecureStreamClient( transportStream io.ReadWriteCloser, clientCredentials *ClientCredentials, enableReconnect bool, ) *SecureStream
NewSecureStreamClient creates a SecureStream over an underlying transport stream using client credentials. Set enableReconnect to true to enable SSH session reconnection.
func NewSecureStreamServer ¶
func NewSecureStreamServer( transportStream io.ReadWriteCloser, serverCredentials *ServerCredentials, reconnectableSessions *ReconnectableSessions, ) *SecureStream
NewSecureStreamServer creates a SecureStream over an underlying transport stream using server credentials. Pass a non-nil reconnectableSessions collection to enable reconnection support.
func (*SecureStream) Close ¶
func (ss *SecureStream) Close() error
Close closes the underlying SSH session and transport stream. Close implements io.Closer.
func (*SecureStream) Connect ¶
func (ss *SecureStream) Connect(ctx context.Context) error
Connect initiates the SSH session over the transport stream. It performs version exchange, key exchange, authentication, and opens a channel. On success, Read and Write can be used to exchange data.
func (*SecureStream) IsClosed ¶
func (ss *SecureStream) IsClosed() bool
IsClosed returns true if the secure stream has been closed.
func (*SecureStream) Read ¶
func (ss *SecureStream) Read(p []byte) (int, error)
Read reads data from the secure stream. It blocks until data is available, the stream is closed, or an error occurs. Read implements io.Reader.
func (*SecureStream) Reconnect ¶
func (ss *SecureStream) Reconnect(ctx context.Context, newTransportStream io.ReadWriteCloser) error
Reconnect reconnects a disconnected client session over a new transport stream. The new stream must connect to the same server (same host key). This method applies only to client-side secure streams.
func (*SecureStream) Session ¶
func (ss *SecureStream) Session() *Session
Session returns the underlying SSH session.
type SequencedMessage ¶
type SequencedMessage struct {
Sequence uint64
Payload []byte // original payload (before reconnect info appended)
SentTime int64 // timestamp in microseconds
}
SequencedMessage stores a sent message payload with its sequence number and timestamp for reconnection retransmission.
type ServerCredentials ¶
type ServerCredentials struct {
PublicKeys []KeyPair
// PrivateKeyProvider is an optional callback that provides a full key pair
// (with private key material) given a public-key-only key pair. It is called
// during key exchange when the host key does not have HasPrivateKey() == true.
// This enables deferred loading of private keys from secure storage.
PrivateKeyProvider PrivateKeyProvider
}
ServerCredentials defines credentials for authenticating an SSH server session.
type ServerSession ¶
type ServerSession struct {
Session
Credentials *ServerCredentials
// OnClientAuthenticated is called when a client successfully authenticates.
OnClientAuthenticated func()
// OnReconnected is called after a client successfully reconnects to this session.
OnReconnected func()
// ReconnectableSessions is a shared collection of disconnected sessions
// awaiting reconnection. Must be set before connecting if reconnection
// support is desired. Multiple ServerSession instances can share the same
// collection to enable reconnection across sessions.
ReconnectableSessions *ReconnectableSessions
}
ServerSession is an SSH server session that accepts client connections.
func NewServerSession ¶
func NewServerSession(config *SessionConfig) *ServerSession
NewServerSession creates a new SSH server session with the given configuration. If config is nil, a no-security configuration is used.
func (*ServerSession) SetClientAuthenticatedHandler ¶
func (ss *ServerSession) SetClientAuthenticatedHandler(handler func())
SetClientAuthenticatedHandler sets the OnClientAuthenticated callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
func (*ServerSession) SetReconnectedHandler ¶
func (ss *ServerSession) SetReconnectedHandler(handler func())
SetReconnectedHandler sets the OnReconnected callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
type Service ¶
type Service interface {
// OnSessionRequest is called when a session request is received that
// matches this service's activation rule.
OnSessionRequest(args *RequestEventArgs)
// OnChannelOpening is called when a channel open request is received
// that matches this service's channel type activation rule.
OnChannelOpening(args *ChannelOpeningEventArgs)
// OnChannelRequest is called when a channel request is received that
// matches this service's channel request activation rule.
OnChannelRequest(channel *Channel, args *RequestEventArgs)
// Close is called when the session is closing to clean up resources.
// Implements io.Closer.
Close() error
}
Service is the interface that SSH services must implement. Services handle incoming requests and are activated on-demand based on activation rules (service request name, session request type, channel type, channel request type).
type ServiceActivation ¶
type ServiceActivation struct {
// ServiceRequest activates the service when a service request (MSG 5) is
// received with the specified name. Only server-side.
ServiceRequest string
// SessionRequest activates the service when a session request (MSG 80) is
// received with the specified request type.
SessionRequest string
// SessionRequests activates the service when a session request (MSG 80)
// matches any of the specified request types.
SessionRequests []string
// ChannelType activates the service when a channel open request is received
// for the specified channel type.
ChannelType string
// ChannelTypes activates the service when a channel open request matches
// any of the specified channel types.
ChannelTypes []string
// ChannelRequest activates the service when a channel request is received
// for the specified request type. If ChannelType is also set, both must match.
ChannelRequest string
}
ServiceActivation defines activation rules for a service. Each field specifies a condition under which the service is activated. For services that respond to multiple triggers (e.g., port forwarding), use the plural fields (SessionRequests, ChannelTypes) which accept slices.
type ServiceFactory ¶
ServiceFactory creates a new instance of a service for the given session. The config parameter is the value from SessionConfig.Services map (may be nil).
type ServiceRegistration ¶
type ServiceRegistration struct {
Activation ServiceActivation
Factory ServiceFactory
Config interface{}
}
ServiceRegistration combines activation rules with a factory function.
type Session ¶
type Session struct {
Config *SessionConfig
// OnAuthenticating is called when authentication credentials need to be verified.
OnAuthenticating func(*AuthenticatingEventArgs)
// OnChannelOpening is called when a channel open request is received.
OnChannelOpening func(*ChannelOpeningEventArgs)
// OnClosed is called when the session is closed.
OnClosed func(*SessionClosedEventArgs)
// OnRequest is called when a session request is received.
OnRequest func(*RequestEventArgs)
// OnServiceActivated is called when a service is activated for the first time.
OnServiceActivated func(Service)
// OnKeepAliveSucceeded is called when a keep-alive response is received.
// The argument is the consecutive success count.
OnKeepAliveSucceeded func(int)
// OnKeepAliveFailed is called when no keep-alive response is received within the timeout.
// The argument is the consecutive failure count.
OnKeepAliveFailed func(int)
// OnDisconnected is called when the session transitions to a disconnected
// (but not closed) state while reconnection is enabled. Applications can
// call Reconnect() with a new stream to resume the session.
OnDisconnected func()
// OnReportProgress is called to report connection progress at key handshake stages.
OnReportProgress func(Progress)
// Principal holds the authenticated identity after successful authentication.
// On the server side, this is populated from AuthenticatingEventArgs.AuthenticationResult.
// It is nil before authentication completes.
Principal interface{}
// Trace is called for structured trace events during session operation.
// Set this before calling Connect to receive all trace events.
// The function is nil-safe — no overhead when not set.
Trace TraceFunc
// RemoteVersion contains parsed version info from the remote side
// after the version exchange completes.
RemoteVersion *VersionInfo
// ProtocolExtensions from remote side (from ExtensionInfoMessage).
ProtocolExtensions map[string]string
// SessionID is the exchange hash from the first key exchange.
// It is set once and never changes, even on re-exchange.
SessionID []byte
// contains filtered or unexported fields
}
Session is the base type for SSH client and server sessions. It manages the connection lifecycle, message dispatch, and channel multiplexing.
func (*Session) AcceptChannel ¶
AcceptChannel waits for and accepts an incoming channel of any type.
func (*Session) AcceptChannelWithType ¶
AcceptChannelWithType waits for and accepts an incoming channel of the specified type. If channelType is empty, any channel type is accepted.
Uses a broadcast notification pattern so that multiple goroutines waiting for different channel types are all woken when a new channel arrives. Each waiter checks the queue for its specific type, avoiding the livelock that would occur with a single-consumer notification channel.
func (*Session) ActivateService ¶
ActivateService activates a service by name. If the service is already activated, returns the existing instance. Returns nil if the service name is not registered.
func (*Session) Channels ¶
Channels returns a snapshot (copy) of the active channels map. The returned map is safe to iterate without holding any lock.
func (*Session) Close ¶
Close closes the session gracefully with DisconnectByApplication reason. Implements io.Closer. Returns nil; close errors are reported via OnClosed.
func (*Session) CloseWithError ¶
CloseWithError closes the session with a specific disconnect reason and a custom error that is propagated to channel OnClosed callbacks.
func (*Session) CloseWithReason ¶
func (s *Session) CloseWithReason(ctx context.Context, reason messages.SSHDisconnectReason, msg string) error
CloseWithReason closes the session with a specific disconnect reason and message.
func (*Session) Connect ¶
Connect connects the session over the given stream. Both sides exchange SSH-2.0 version strings and key exchange init messages.
func (*Session) CreateReconnectToken ¶
CreateReconnectToken generates an HMAC-based reconnect token from previous and new session IDs. The token proves knowledge of the old session ID without disclosing it, and prevents replay attacks by including the new session ID. Uses the dedicated reconnect HMAC signer (not the GCM cipher, which would race with the dispatch loop's packet encryption).
func (*Session) Done ¶
func (s *Session) Done() <-chan struct{}
Done returns a channel that is closed when the session's dispatch loop exits. This can be used to derive contexts that are scoped to the session's lifetime.
func (*Session) GetService ¶
GetService returns the active service with the given name, or nil if not activated.
func (*Session) IsConnected ¶
IsConnected returns true if the session is currently connected.
func (*Session) Metrics ¶
func (s *Session) Metrics() *SessionMetrics
Metrics returns a pointer to the session's metrics counters.
func (*Session) OpenChannel ¶
OpenChannel opens a new channel with the default "session" type.
func (*Session) OpenChannelWithMessage ¶
func (s *Session) OpenChannelWithMessage( ctx context.Context, channelType string, buildMsg func(senderChannel, maxWindowSize, maxPacketSize uint32) messages.Message, ) (*Channel, error)
OpenChannelWithMessage opens a new channel by sending a custom channel open message. The buildMsg callback receives the allocated local channel ID, window size, and packet size, and returns the message to send. The message must serialize as a valid SSH_MSG_CHANNEL_OPEN (type 90) with matching SenderChannel, MaxWindowSize, and MaxPacketSize. This is used by services like port forwarding that need extended channel open data.
func (*Session) OpenChannelWithRequest ¶
func (s *Session) OpenChannelWithRequest( ctx context.Context, openMsg *messages.ChannelOpenMessage, initialRequest *messages.ChannelRequestMessage, ) (*Channel, error)
OpenChannelWithRequest opens a channel and sends an initial channel request. If the open-channel-request protocol extension is negotiated, the request is bundled with the channel open to avoid an extra round-trip. Otherwise, the request is sent as a standard channel request after the channel is opened. Returns the opened channel. Returns an error if the channel open or the initial request fails.
func (*Session) OpenChannelWithType ¶
OpenChannelWithType opens a new channel with the given channel type.
func (*Session) Protocol ¶
func (s *Session) Protocol() *SSHProtocol
Protocol returns the session's protocol layer. Used by reconnection logic to access sequence tracking and message cache.
func (*Session) Request ¶
Request sends a session request and waits for the response. Returns true if the request was accepted, false otherwise.
func (*Session) RequestService ¶
RequestService sends a service request (SSH_MSG_SERVICE_REQUEST) to the remote side and waits for the service accept response. This is used by clients to request server-side service activation.
This is a convenience wrapper around RequestServiceContext with context.Background().
func (*Session) RequestServiceContext ¶
RequestServiceContext sends a service request (SSH_MSG_SERVICE_REQUEST) to the remote side and waits for the service accept response, respecting the provided context for cancellation and timeouts. This is used by clients to request server-side service activation.
func (*Session) RequestWithPayload ¶
func (s *Session) RequestWithPayload(ctx context.Context, msg messages.Message, wantReply bool) (bool, []byte, error)
RequestWithPayload sends a session request and returns both success and the raw response payload. This is useful for requests like tcpip-forward where the success response contains additional data (e.g., allocated port).
func (*Session) SendMessage ¶
SendMessage sends a message through the protocol layer.
func (*Session) SendRawMessage ¶
SendRawMessage sends a raw byte payload through the protocol layer. This is primarily used for testing (e.g., sending unknown message types).
func (*Session) SetAuthenticatingHandler ¶
func (s *Session) SetAuthenticatingHandler(handler func(*AuthenticatingEventArgs))
SetAuthenticatingHandler sets the OnAuthenticating callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
func (*Session) SetChannelOpeningHandler ¶
func (s *Session) SetChannelOpeningHandler(handler func(*ChannelOpeningEventArgs))
SetChannelOpeningHandler sets the OnChannelOpening callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
func (*Session) SetClosedHandler ¶
func (s *Session) SetClosedHandler(handler func(*SessionClosedEventArgs))
SetClosedHandler sets the OnClosed callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
func (*Session) SetReportProgressHandler ¶
SetReportProgressHandler sets the OnReportProgress callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
func (*Session) SetRequestHandler ¶
func (s *Session) SetRequestHandler(handler func(*RequestEventArgs))
SetRequestHandler sets the OnRequest callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
func (*Session) SetTraceHandler ¶
SetTraceHandler sets the Trace callback in a thread-safe manner. Use this method instead of direct field assignment when the session is already connected, to avoid data races with the dispatch goroutine.
type SessionClosedEventArgs ¶
type SessionClosedEventArgs struct {
Reason messages.SSHDisconnectReason
Message string
Err error
}
SessionClosedEventArgs contains arguments for session closed events.
type SessionConfig ¶
type SessionConfig struct {
// ProtocolExtensions lists protocol extensions enabled for the session.
ProtocolExtensions []string
// AuthenticationMethods lists enabled authentication methods.
AuthenticationMethods []string
// KeyExchangeAlgorithms lists enabled KEX algorithms in preference order.
// A "none" entry means no key exchange (no security).
KeyExchangeAlgorithms []string
// PublicKeyAlgorithms lists enabled public key algorithms in preference order.
PublicKeyAlgorithms []string
// EncryptionAlgorithms lists enabled encryption algorithms in preference order.
EncryptionAlgorithms []string
// HmacAlgorithms lists enabled HMAC algorithms in preference order.
HmacAlgorithms []string
// CompressionAlgorithms lists enabled compression algorithms in preference order.
CompressionAlgorithms []string
// TraceChannelData enables tracing of all channel data messages.
TraceChannelData bool
// MaxClientAuthenticationAttempts is the max number of client auth attempts
// allowed by the server. Default is 5.
MaxClientAuthenticationAttempts int
// EnableKeyExchangeGuess controls whether the client sends a KEX guess
// before receiving server preferences. Disabled by default.
EnableKeyExchangeGuess bool
// KeepAliveIntervalSeconds is the keep-alive interval in seconds (0 = disabled).
KeepAliveIntervalSeconds int
// KeyRotationThreshold is the number of bytes after which key rotation is triggered.
// Default is 512MB. This should only be changed for testing.
KeyRotationThreshold int
// MaxReconnectMessageCacheSize is the maximum number of sent messages to cache
// for reconnection retransmission. When the cache exceeds this limit, the oldest
// messages are evicted. Default is 1024.
MaxReconnectMessageCacheSize int
// MaxChannelWindowSize overrides the default channel window size.
// Zero means use DefaultMaxWindowSize (1 MB).
MaxChannelWindowSize uint32
// MessageHandlers maps SSH message type numbers to custom handler functions.
// When a message is received with a type that has a registered handler,
// the handler is called instead of sending an UnimplementedMessage response.
// This allows extending the SSH protocol without modifying the library.
MessageHandlers map[byte]MessageHandler
// ServiceRegistrations maps service names to their activation rules and factories.
// Use AddService() to register services.
ServiceRegistrations map[string]*ServiceRegistration
}
SessionConfig specifies the sets of algorithms and other configuration for an SSH session. Each collection of algorithms is in order of preference. Server and client negotiate the most-preferred algorithm supported by both.
func NewDefaultConfig ¶
func NewDefaultConfig() *SessionConfig
NewDefaultConfig creates a new SessionConfig with default secure algorithms. The algorithm preference order matches the C# and TypeScript implementations.
func NewDefaultConfigWithReconnect ¶
func NewDefaultConfigWithReconnect() *SessionConfig
NewDefaultConfigWithReconnect creates a new SessionConfig with default secure algorithms and reconnection extensions enabled.
func NewNoSecurityConfig ¶
func NewNoSecurityConfig() *SessionConfig
NewNoSecurityConfig creates a new SessionConfig with no-security algorithms. All algorithm lists contain only "none", meaning no encryption, no HMAC, no key exchange.
func (*SessionConfig) AddService ¶
func (c *SessionConfig) AddService(name string, activation ServiceActivation, factory ServiceFactory, config interface{})
AddService registers a service with activation rules in the session configuration.
func (*SessionConfig) Validate ¶
func (c *SessionConfig) Validate() error
Validate checks the session configuration for internal consistency. It returns an error if algorithm combinations are invalid, such as encryption algorithms specified without any key exchange algorithm.
type SessionContour ¶
type SessionContour struct {
// contains filtered or unexported fields
}
SessionContour collects session metrics over time, producing an outline of the timing, speed, and quantity of bytes sent/received during the session.
Metrics are recorded across a number of equal time intervals. As the session time increases, intervals are expanded to keep the number of intervals under the configured maximum. Each expansion doubles the length of all intervals, while combining the metrics within each pair of combined intervals.
func ImportContour ¶
func ImportContour(contourBase64 string) (*SessionContour, error)
ImportContour deserializes a session contour that was previously exported.
func NewSessionContour ¶
func NewSessionContour(maxIntervals int) *SessionContour
NewSessionContour creates a new SessionContour with the given maximum intervals. maxIntervals must be a power of two and at least 2.
func (*SessionContour) AddUpdate ¶
func (c *SessionContour) AddUpdate(u ContourUpdate)
AddUpdate directly adds a contour update. Useful for testing.
func (*SessionContour) BytesReceivedAt ¶
func (c *SessionContour) BytesReceivedAt(i int) int64
BytesReceivedAt returns the bytes received for the interval at index i.
func (*SessionContour) BytesReceivedSlice ¶
func (c *SessionContour) BytesReceivedSlice() []int64
BytesReceivedSlice returns a copy of the bytes received values for all recorded intervals.
func (*SessionContour) BytesSentAt ¶
func (c *SessionContour) BytesSentAt(i int) int64
BytesSentAt returns the bytes sent for the interval at index i.
func (*SessionContour) BytesSentSlice ¶
func (c *SessionContour) BytesSentSlice() []int64
BytesSentSlice returns a copy of the bytes sent values for all recorded intervals.
func (*SessionContour) CollectMetrics ¶
func (c *SessionContour) CollectMetrics(metrics *SessionMetrics)
CollectMetrics starts collecting session metrics and processes them until Stop is called or the session is closed.
func (*SessionContour) Export ¶
func (c *SessionContour) Export() string
Export serializes the session contour into a compact base64-encoded form.
func (*SessionContour) IntervalCount ¶
func (c *SessionContour) IntervalCount() int
IntervalCount returns the current number of intervals with recorded metrics.
func (*SessionContour) IntervalMs ¶
func (c *SessionContour) IntervalMs() int64
IntervalMs returns the current interval duration in milliseconds.
func (*SessionContour) LatencyAverageMsAt ¶
func (c *SessionContour) LatencyAverageMsAt(i int) float32
LatencyAverageMsAt returns the average latency in ms for the interval at index i.
func (*SessionContour) LatencyAverageMsSlice ¶
func (c *SessionContour) LatencyAverageMsSlice() []float32
LatencyAverageMsSlice returns a copy of the average latency values for all recorded intervals.
func (*SessionContour) LatencyMaxMsAt ¶
func (c *SessionContour) LatencyMaxMsAt(i int) float32
LatencyMaxMsAt returns the maximum latency in ms for the interval at index i.
func (*SessionContour) LatencyMaxMsSlice ¶
func (c *SessionContour) LatencyMaxMsSlice() []float32
LatencyMaxMsSlice returns a copy of the max latency values for all recorded intervals.
func (*SessionContour) LatencyMinMsAt ¶
func (c *SessionContour) LatencyMinMsAt(i int) float32
LatencyMinMsAt returns the minimum latency in ms for the interval at index i.
func (*SessionContour) LatencyMinMsSlice ¶
func (c *SessionContour) LatencyMinMsSlice() []float32
LatencyMinMsSlice returns a copy of the min latency values for all recorded intervals.
func (*SessionContour) MaxIntervals ¶
func (c *SessionContour) MaxIntervals() int
MaxIntervals returns the maximum number of intervals this contour can record.
func (*SessionContour) Stop ¶
func (c *SessionContour) Stop()
Stop signals the contour to stop collecting and waits for it to finish.
type SessionMetrics ¶
type SessionMetrics struct {
// OnMessageSent is called when a message is sent.
// Args: (sessionTimeMs int64, sizeBytes int).
OnMessageSent func(int64, int)
// OnMessageReceived is called when a message is received.
// Args: (sessionTimeMs int64, sizeBytes int).
OnMessageReceived func(int64, int)
// OnLatencyUpdated is called when latency is measured.
// Args: (sessionTimeMs int64, latencyMs float32).
OnLatencyUpdated func(int64, float32)
// OnSessionClosed is called when the session is closed.
OnSessionClosed func()
// contains filtered or unexported fields
}
SessionMetrics tracks byte, message, and latency counters for an SSH session. Latency is measured in microseconds internally but reported in milliseconds.
func (*SessionMetrics) BytesReceived ¶
func (m *SessionMetrics) BytesReceived() int64
BytesReceived returns the total number of wire bytes received on this session.
func (*SessionMetrics) BytesSent ¶
func (m *SessionMetrics) BytesSent() int64
BytesSent returns the total number of wire bytes sent on this session.
func (*SessionMetrics) LatencyAverageMs ¶
func (m *SessionMetrics) LatencyAverageMs() float32
LatencyAverageMs returns the average measured round-trip latency in milliseconds.
func (*SessionMetrics) LatencyCurrentMs ¶
func (m *SessionMetrics) LatencyCurrentMs() float32
LatencyCurrentMs returns the most recent round-trip latency in milliseconds. Returns 0 if latency has not been measured or the session is disconnected.
func (*SessionMetrics) LatencyMaxMs ¶
func (m *SessionMetrics) LatencyMaxMs() float32
LatencyMaxMs returns the maximum measured round-trip latency in milliseconds.
func (*SessionMetrics) LatencyMinMs ¶
func (m *SessionMetrics) LatencyMinMs() float32
LatencyMinMs returns the minimum measured round-trip latency in milliseconds.
func (*SessionMetrics) MessagesReceived ¶
func (m *SessionMetrics) MessagesReceived() int64
MessagesReceived returns the total number of messages received on this session.
func (*SessionMetrics) MessagesSent ¶
func (m *SessionMetrics) MessagesSent() int64
MessagesSent returns the total number of messages sent on this session.
func (*SessionMetrics) Reconnections ¶
func (m *SessionMetrics) Reconnections() int64
Reconnections returns the number of times this session has been reconnected.
func (*SessionMetrics) TimeMicroseconds ¶
func (m *SessionMetrics) TimeMicroseconds() int64
TimeMicroseconds returns the current time in microseconds since Unix epoch. Used for latency tracking in reconnection support.
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream wraps an SSH Channel as an io.ReadWriteCloser. This allows using SSH channels with any Go library that expects a stream.
Stream does not support more than one concurrent reader or more than one concurrent writer.
func NewStream ¶
NewStream creates a new Stream wrapping the given channel. The stream implements io.ReadWriteCloser.
func (*Stream) Read ¶
Read reads data from the channel into p. It blocks until data is available, the channel is closed, or an error occurs. Read implements io.Reader.
type TraceFunc ¶
type TraceFunc func(level TraceLevel, eventID int, message string)
TraceFunc is the function signature for handling SSH trace events. level is the severity level of the event. eventID is an integer that identifies the type of event (one of the SSHTraceEventID constants). message is a human-readable description of the event.
type TraceLevel ¶
type TraceLevel int
TraceLevel represents the severity level of a trace event.
const ( // TraceLevelError indicates an error event. TraceLevelError TraceLevel = iota // TraceLevelWarning indicates a warning event. TraceLevelWarning // TraceLevelInfo indicates an informational event. TraceLevelInfo // TraceLevelVerbose indicates a verbose/debug event. TraceLevelVerbose )
func (TraceLevel) String ¶
func (l TraceLevel) String() string
String returns the string representation of a TraceLevel.
type VersionInfo ¶
type VersionInfo struct {
ProtocolVersion string
Name string
Version string
// contains filtered or unexported fields
}
VersionInfo contains parsed SSH version information from the version string exchanged during the initial SSH handshake.
func GetLocalVersion ¶
func GetLocalVersion() *VersionInfo
GetLocalVersion returns the version info for this SSH library.
func ParseVersionInfo ¶
func ParseVersionInfo(versionString string) *VersionInfo
Parse attempts to parse an SSH version string (e.g., "SSH-2.0-OpenSSH_7.9") into a VersionInfo. Returns nil if the string cannot be parsed.
func (*VersionInfo) IsDevTunnelsSSH ¶
func (v *VersionInfo) IsDevTunnelsSSH() bool
IsDevTunnelsSSH returns true if this version info represents some version of the Dev Tunnels SSH library (C#, TypeScript, or Go).
func (*VersionInfo) String ¶
func (v *VersionInfo) String() string
String returns the original SSH version string.
Source Files
¶
- auth_service.go
- auth_type.go
- channel.go
- client_session.go
- config.go
- contour.go
- credentials.go
- doc.go
- ecdsa_key_pair.go
- errors.go
- events.go
- key_exchange_service.go
- key_pair.go
- metrics.go
- multi_channel_stream.go
- pipe.go
- pipe_session.go
- protocol.go
- reconnect.go
- rsa_key_pair.go
- secure_stream.go
- server_session.go
- service.go
- session.go
- session_channels.go
- session_dispatch.go
- session_encryption.go
- session_keepalive.go
- ssh.go
- stream.go
- trace.go
- version.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package algorithms provides cryptographic algorithm implementations for SSH key exchange, encryption, and message authentication.
|
Package algorithms provides cryptographic algorithm implementations for SSH key exchange, encryption, and message authentication. |
|
Package sshio provides binary data readers and writers for the SSH wire protocol.
|
Package sshio provides binary data readers and writers for the SSH wire protocol. |
|
Package messages defines SSH protocol message types and their serialization.
|
Package messages defines SSH protocol message types and their serialization. |