srv

package
v4.3.6+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2020 License: Apache-2.0 Imports: 36 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConfigureCommand

func ConfigureCommand(ctx *ServerContext) (*exec.Cmd, error)

ConfigureCommand creates a command fully configured to execute. This function is used by Teleport to re-execute itself and pass whatever data is need to the child to actually execute the shell.

func RunAndExit

func RunAndExit(commandType string)

RunAndExit will run the requested command and then exit. This wrapper allows Run{Command,Forward} to use defers and makes sure error messages are consistent across both.

func RunCommand

func RunCommand() (io.Writer, int, error)

RunCommand reads in the command to run from the parent process (over a pipe) then constructs and runs the command.

func RunForward

func RunForward() (io.Writer, int, error)

RunForward reads in the command to run from the parent process (over a pipe) then port forwards.

func StartKeepAliveLoop

func StartKeepAliveLoop(p KeepAliveParams)

StartKeepAliveLoop starts the keep-alive loop.

Types

type ActivityTracker

type ActivityTracker interface {
	// GetClientLastActive returns the time of the last recorded activity
	GetClientLastActive() time.Time
	// UpdateClient updates client activity
	UpdateClientActivity()
}

ActivityTracker is a connection activity tracker, it allows to update the activity on the connection and retrieve the time when the connection was last active

type AuthHandlers

type AuthHandlers struct {
	*log.Entry

	// Server is the services.Server in the backend.
	Server Server

	// Component is the type of SSH server (node, proxy, or recording proxy).
	Component string

	// AuditLog is the service used to access Audit Log.
	AuditLog events.IAuditLog

	// AccessPoint is used to access the Auth Server.
	AccessPoint auth.AccessPoint

	// FIPS mode means Teleport started in a FedRAMP/FIPS 140-2 compliant
	// configuration.
	FIPS bool
}

AuthHandlers are common authorization and authentication related handlers used by the regular and forwarding server.

func (*AuthHandlers) CheckAgentForward

func (h *AuthHandlers) CheckAgentForward(ctx *ServerContext) error

CheckAgentForward checks if agent forwarding is allowed for the users RoleSet.

func (*AuthHandlers) CheckPortForward

func (h *AuthHandlers) CheckPortForward(addr string, ctx *ServerContext) error

CheckPortForward checks if port forwarding is allowed for the users RoleSet.

func (*AuthHandlers) CreateIdentityContext

func (h *AuthHandlers) CreateIdentityContext(sconn *ssh.ServerConn) (IdentityContext, error)

CreateIdentityContext returns an IdentityContext populated with information about the logged in user on the connection.

func (*AuthHandlers) HostKeyAuth

func (h *AuthHandlers) HostKeyAuth(addr string, remote net.Addr, key ssh.PublicKey) error

HostKeyAuth implements host key verification and is called by the client to validate the certificate presented by the target server. If the target server presents a SSH certificate, we validate that it was Teleport that generated the certificate. If the target server presents a public key, if we are strictly checking keys, we reject the target server. If we are not we take whatever.

func (*AuthHandlers) IsHostAuthority

func (h *AuthHandlers) IsHostAuthority(cert ssh.PublicKey, address string) bool

IsHostAuthority is called when checking the host certificate a server presents. It make sure that the key used to sign the host certificate was a Teleport CA.

func (*AuthHandlers) IsUserAuthority

func (h *AuthHandlers) IsUserAuthority(cert ssh.PublicKey) bool

IsUserAuthority is called during checking the client key, to see if the key used to sign the certificate was a Teleport CA.

func (*AuthHandlers) UserKeyAuth

func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error)

UserKeyAuth implements SSH client authentication using public keys and is called by the server every time the client connects.

type Exec

type Exec interface {
	// GetCommand returns the command to be executed.
	GetCommand() string

	// SetCommand sets the command to be executed.
	SetCommand(string)

	// Start will start the execution of the command.
	Start(channel ssh.Channel) (*ExecResult, error)

	// Wait will block while the command executes.
	Wait() *ExecResult

	// Continue will resume execution of the process after it completes its
	// pre-processing routine (placed in a cgroup).
	Continue()

	// PID returns the PID of the Teleport process that was re-execed.
	PID() int
}

Exec executes an "exec" request.

func NewExecRequest

func NewExecRequest(ctx *ServerContext, command string) (Exec, error)

NewExecRequest creates a new local or remote Exec.

type ExecResult

type ExecResult struct {
	// Command is the command that was executed.
	Command string

	// Code is return code that execution of the command resulted in.
	Code int
}

ExecResult is used internally to send the result of a command execution from a goroutine to SSH request handler and back to the calling client

type GetServerInfoFn

type GetServerInfoFn func() (services.Server, error)

GetServerInfoFn is function that returns server info

type Heartbeat

type Heartbeat struct {
	HeartbeatConfig

	*log.Entry
	// contains filtered or unexported fields
}

Heartbeat keeps heartbeat state, it is implemented according to actor model - all interactions with it are to be done with signals

func NewHeartbeat

func NewHeartbeat(cfg HeartbeatConfig) (*Heartbeat, error)

NewHeartbeat returns a new instance of heartbeat

func (*Heartbeat) Close

func (h *Heartbeat) Close() error

Close closes all timers and goroutines, note that this function is equivalent of cancelling of the context passed in configuration and can be used interchangeably

func (*Heartbeat) ForceSend

func (h *Heartbeat) ForceSend(timeout time.Duration) error

ForceSend forces send cycle, used in tests, returns nil in case of success, error otherwise

func (*Heartbeat) Run

func (h *Heartbeat) Run() error

Run periodically calls to announce presence, should be called explicitly in a separate goroutine

type HeartbeatConfig

type HeartbeatConfig struct {
	// Mode sets one of the proxy, auth or node moes
	Mode HeartbeatMode
	// Context is parent context that signals
	// heartbeat cancel
	Context context.Context
	// Component is a name of component used in logs
	Component string
	// Announcer is used to announce presence
	Announcer auth.Announcer
	// GetServerInfo returns server information
	GetServerInfo GetServerInfoFn
	// ServerTTL is a server TTL used in announcements
	ServerTTL time.Duration
	// KeepAlivePeriod is a period between lights weight
	// keep alive calls, that only update TTLs and don't consume
	// bandwidh, also is used to derive time between
	// failed attempts as well for auth and proxy modes
	KeepAlivePeriod time.Duration
	// AnnouncePeriod is a period between announce calls,
	// when client sends full server specification
	// to the presence service
	AnnouncePeriod time.Duration
	// CheckPeriod is a period to check for updates
	CheckPeriod time.Duration
	// Clock is a clock used to override time in tests
	Clock clockwork.Clock
	// OnHeartbeat is called after every heartbeat. A non-nil error is passed
	// when a heartbeat fails.
	OnHeartbeat func(error)
}

HeartbeatConfig is a heartbeat configuration

func (*HeartbeatConfig) CheckAndSetDefaults

func (cfg *HeartbeatConfig) CheckAndSetDefaults() error

CheckAndSetDefaults checks and sets default values

type HeartbeatMode

type HeartbeatMode int

HeartbeatMode represents the mode of the heartbeat node, proxy or auth server

const (
	// HeartbeatModeNode sets heartbeat to node
	// updates that support keep alives
	HeartbeatModeNode HeartbeatMode = iota
	// HeartbeatModeProxy sets heartbeat to proxy
	// that does not support keep alives
	HeartbeatModeProxy HeartbeatMode = iota
	// HeartbeatModeAuth sets heartbeat to auth
	// that does not support keep alives
	HeartbeatModeAuth HeartbeatMode = iota
)

func (HeartbeatMode) CheckAndSetDefaults

func (h HeartbeatMode) CheckAndSetDefaults() error

CheckAndSetDefaults checks values and sets defaults

func (HeartbeatMode) String

func (h HeartbeatMode) String() string

String returns user-friendly representation of the mode

type IdentityContext

type IdentityContext struct {
	// TeleportUser is the Teleport user associated with the connection.
	TeleportUser string

	// Login is the operating system user associated with the connection.
	Login string

	// Certificate is the SSH user certificate bytes marshalled in the OpenSSH
	// authorized_keys format.
	Certificate []byte

	// CertAuthority is the Certificate Authority that signed the Certificate.
	CertAuthority services.CertAuthority

	// RoleSet is the roles this Teleport user is associated with. RoleSet is
	// used to check RBAC permissions.
	RoleSet services.RoleSet

	// CertValidBefore is set to the expiry time of a certificate, or
	// empty, if cert does not expire
	CertValidBefore time.Time

	// RouteToCluster is derived from the certificate
	RouteToCluster string
}

IdentityContext holds all identity information associated with the user logged on the connection.

func (IdentityContext) GetCertificate

func (c IdentityContext) GetCertificate() (*ssh.Certificate, error)

GetCertificate parses the SSH certificate bytes and returns a *ssh.Certificate.

type KeepAliveParams

type KeepAliveParams struct {
	// Conns is the list of connections to send keep-alive connections to. All
	// connections must respond to the keep-alive to not be considered missed.
	Conns []RequestSender

	// Interval is the interval to send keep-alive messsages at.
	Interval time.Duration

	// MaxCount is the number of keep-alive messages that can be missed before
	// the connection is disconnected.
	MaxCount int64

	// CloseContext is used by the server to notify the keep-alive loop to stop.
	CloseContext context.Context

	// CloseCancel is used by the keep-alive loop to notify the server to stop.
	CloseCancel context.CancelFunc
}

KeepAliveParams configures the keep-alive loop.

type KeepAliveState

type KeepAliveState int

KeepAliveState represents state of the heartbeat

const (
	// HeartbeatStateInit is set when
	// the state has not been collected yet,
	// or the state is not fetched
	HeartbeatStateInit KeepAliveState = iota
	// HeartbeatStateAnnounce is set when full
	// state has to be announced back to the auth server
	HeartbeatStateAnnounce KeepAliveState = iota
	// HeartbeatStateAnnounceWait is set after successful
	// announce, heartbeat will wait until server updates
	// information, or time for next announce comes
	HeartbeatStateAnnounceWait KeepAliveState = iota
	// HeartbeatStateKeepAlive is set when
	// only sending keep alives is necessary
	HeartbeatStateKeepAlive KeepAliveState = iota
	// HeartbeatStateKeepAliveWait is set when
	// heartbeat will waiting until it's time to send keep alive
	HeartbeatStateKeepAliveWait KeepAliveState = iota
)

func (KeepAliveState) String

func (k KeepAliveState) String() string

type LookupGroup

type LookupGroup func(string) (*user.Group, error)

LookupGroup is used to mock the value returned by user.LookupGroup(string).

type LookupUser

type LookupUser func(string) (*user.User, error)

LookupUser is used to mock the value returned by user.Lookup(string).

type Monitor

type Monitor struct {
	// MonitorConfig is a connection monitori configuration
	MonitorConfig
}

Monitor moniotiors connection activity and disconnects connections with expired certificates or with periods of inactivity

func NewMonitor

func NewMonitor(cfg MonitorConfig) (*Monitor, error)

NewMonitor returns a new monitor

func (*Monitor) Start

func (w *Monitor) Start()

Start starts monitoring connection

type MonitorConfig

type MonitorConfig struct {
	// DisconnectExpiredCert is a point in time when
	// the certificate should be disconnected
	DisconnectExpiredCert time.Time
	// ClientIdleTimeout is a timeout of inactivity
	// on the wire
	ClientIdleTimeout time.Duration
	// Clock is a clock, realtime or fixed in tests
	Clock clockwork.Clock
	// Tracker is activity tracker
	Tracker ActivityTracker
	// Conn is a connection to close
	Conn TrackingConn
	// Context is an external context to cancel the operation
	Context context.Context
	// Login is linux box login
	Login string
	// TeleportUser is a teleport user name
	TeleportUser string
	// ServerID is a session server ID
	ServerID string
	// Audit is audit log
	Audit events.IAuditLog
	// Entry is a logging entry
	Entry *log.Entry
}

MonitorConfig is a wiretap configuration

func (*MonitorConfig) CheckAndSetDefaults

func (m *MonitorConfig) CheckAndSetDefaults() error

CheckAndSetDefaults checks values and sets defaults

type RequestSender

type RequestSender interface {
	// SendRequest is used to send a out-of-band request.
	SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
}

RequestSender is an interface that implements SendRequest. It is used so server and client connections can be passed to functions to send requests.

type Server

type Server interface {
	// ID is the unique ID of the server.
	ID() string

	// HostUUID is the UUID of the underlying host. For the the forwarding
	// server this is the proxy the forwarding server is running in.
	HostUUID() string

	// GetNamespace returns the namespace the server was created in.
	GetNamespace() string

	// AdvertiseAddr is the publicly addressable address of this server.
	AdvertiseAddr() string

	// Component is the type of server, forwarding or regular.
	Component() string

	// PermitUserEnvironment returns if reading environment variables upon
	// startup is allowed.
	PermitUserEnvironment() bool

	// EmitAuditEvent emits an Audit Event to the Auth Server.
	EmitAuditEvent(events.Event, events.EventFields)

	// GetAuditLog returns the Audit Log for this cluster.
	GetAuditLog() events.IAuditLog

	// GetAccessPoint returns an auth.AccessPoint for this cluster.
	GetAccessPoint() auth.AccessPoint

	// GetSessionServer returns a session server.
	GetSessionServer() rsession.Service

	// GetDataDir returns data directory of the server
	GetDataDir() string

	// GetPAM returns PAM configuration for this server.
	GetPAM() (*pam.Config, error)

	// GetClock returns a clock setup for the server
	GetClock() clockwork.Clock

	// GetInfo returns a services.Server that represents this server.
	GetInfo() services.Server

	// UseTunnel used to determine if this node has connected to this cluster
	// using reverse tunnel.
	UseTunnel() bool

	// GetBPF returns the BPF service used for enhanced session recording.
	GetBPF() bpf.BPF
}

Server is regular or forwarding SSH server.

type ServerContext

type ServerContext struct {
	// ConnectionContext is the parent context which manages connection-level
	// resources.
	*sshutils.ConnectionContext
	*log.Entry

	sync.RWMutex

	// Identity holds the identity of the user that is currently logged in on
	// the Conn.
	Identity IdentityContext

	// ExecResultCh is a Go channel which will be used to send and receive the
	// result of a "exec" request.
	ExecResultCh chan ExecResult

	// SubsystemResultCh is a Go channel which will be used to send and receive
	// the result of a "subsystem" request.
	SubsystemResultCh chan SubsystemResult

	// IsTestStub is set to true by tests.
	IsTestStub bool

	// ExecRequest is the command to be executed within this session context.
	ExecRequest Exec

	// ClusterName is the name of the cluster current user is authenticated with.
	ClusterName string

	// ClusterConfig holds the cluster configuration at the time this context was
	// created.
	ClusterConfig services.ClusterConfig

	// RemoteClient holds a SSH client to a remote server. Only used by the
	// recording proxy.
	RemoteClient *ssh.Client

	// RemoteSession holds a SSH session to a remote server. Only used by the
	// recording proxy.
	RemoteSession *ssh.Session

	// ChannelType holds the type of the channel. For example "session" or
	// "direct-tcpip". Used to create correct subcommand during re-exec.
	ChannelType string

	// SrcAddr is the source address of the request. This the originator IP
	// address and port in a SSH "direct-tcpip" request. This value is only
	// populated for port forwarding requests.
	SrcAddr string

	// DstAddr is the destination address of the request. This is the host and
	// port to connect to in a "direct-tcpip" request. This value is only
	// populated for port forwarding requests.
	DstAddr string
	// contains filtered or unexported fields
}

ServerContext holds session specific context, such as SSH auth agents, PTYs, and other resources. SessionContext also holds a ServerContext which can be used to access resources on the underlying server. SessionContext can also be used to attach resources that should be closed once the session closes.

func NewServerContext

func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, srv Server, identityContext IdentityContext) (context.Context, *ServerContext, error)

NewServerContext creates a new *ServerContext which is used to pass and manage resources, and an associated context.Context which is canceled when the ServerContext is closed. The ctx parameter should be a child of the ctx associated with the scope of the parent ConnectionContext to ensure that cancellation of the ConnectionContext propagates to the ServerContext.

func (*ServerContext) AddCloser

func (c *ServerContext) AddCloser(closer io.Closer)

AddCloser adds any closer in ctx that will be called whenever server closes session channel

func (*ServerContext) CancelFunc

func (c *ServerContext) CancelFunc() context.CancelFunc

CancelFunc gets the context.CancelFunc associated with this context. Not a substitute for calling the ServerContext.Close method.

func (*ServerContext) Close

func (c *ServerContext) Close() error

func (*ServerContext) CreateOrJoinSession

func (c *ServerContext) CreateOrJoinSession(reg *SessionRegistry) error

CreateOrJoinSession will look in the SessionRegistry for the session ID. If no session is found, a new one is created. If one is found, it is returned.

func (*ServerContext) ExecCommand

func (c *ServerContext) ExecCommand() (*execCommand, error)

ExecCommand takes a *ServerContext and extracts the parts needed to create an *execCommand which can be re-sent to Teleport.

func (*ServerContext) GetClientLastActive

func (c *ServerContext) GetClientLastActive() time.Time

GetClientLastActive returns time when client was last active

func (*ServerContext) GetEnv

func (c *ServerContext) GetEnv(key string) (string, bool)

GetEnv returns a environment variable within this context.

func (*ServerContext) GetServer

func (c *ServerContext) GetServer() Server

GetServer returns the underlying server which this context was created in.

func (*ServerContext) GetTerm

func (c *ServerContext) GetTerm() Terminal

GetTerm returns a Terminal.

func (*ServerContext) ID

func (c *ServerContext) ID() int

ID returns ID of this context

func (*ServerContext) Parent

Parent grants access to the connection-level context of which this is a subcontext. Useful for unambiguously accessing methods which this subcontext overrides (e.g. child.Parent().SetEnv(...)).

func (*ServerContext) ProxyPublicAddress

func (c *ServerContext) ProxyPublicAddress() string

ProxyPublicAddress tries to get the public address from the first available proxy. if public_address is not set, fall back to the hostname of the first proxy we get back.

func (*ServerContext) SendExecResult

func (c *ServerContext) SendExecResult(r ExecResult)

SendExecResult sends the result of execution of the "exec" command over the ExecResultCh.

func (*ServerContext) SendSubsystemResult

func (c *ServerContext) SendSubsystemResult(r SubsystemResult)

SendSubsystemResult sends the result of running the subsystem over the SubsystemResultCh.

func (*ServerContext) SessionID

func (c *ServerContext) SessionID() rsession.ID

SessionID returns the ID of the session in the context.

func (*ServerContext) SetEnv

func (c *ServerContext) SetEnv(key, val string)

SetEnv sets a environment variable within this context.

func (*ServerContext) SetTerm

func (c *ServerContext) SetTerm(t Terminal)

SetTerm set a Terminal.

func (*ServerContext) String

func (c *ServerContext) String() string

func (*ServerContext) UpdateClientActivity

func (c *ServerContext) UpdateClientActivity()

UpdateClientActivity sets last recorded client activity associated with this context either channel or session

func (*ServerContext) VisitEnv

func (c *ServerContext) VisitEnv(visit func(key, val string))

VisitEnv grants visitor-style access to env variables.

type SessionRegistry

type SessionRegistry struct {
	sync.Mutex
	// contains filtered or unexported fields
}

SessionRegistry holds a map of all active sessions on a given SSH server

func NewSessionRegistry

func NewSessionRegistry(srv Server) (*SessionRegistry, error)

func (*SessionRegistry) Close

func (s *SessionRegistry) Close()

func (*SessionRegistry) NotifyWinChange

func (s *SessionRegistry) NotifyWinChange(params rsession.TerminalParams, ctx *ServerContext) error

NotifyWinChange is called to notify all members in the party that the PTY size has changed. The notification is sent as a global SSH request and it is the responsibility of the client to update it's window size upon receipt.

func (*SessionRegistry) OpenExecSession

func (s *SessionRegistry) OpenExecSession(channel ssh.Channel, req *ssh.Request, ctx *ServerContext) error

OpenExecSession opens an non-interactive exec session.

func (*SessionRegistry) OpenSession

func (s *SessionRegistry) OpenSession(ch ssh.Channel, req *ssh.Request, ctx *ServerContext) error

OpenSession either joins an existing session or starts a new session.

type Subsystem

type Subsystem interface {
	// Start starts subsystem
	Start(*ssh.ServerConn, ssh.Channel, *ssh.Request, *ServerContext) error

	// Wait is returned by subystem when it's completed
	Wait() error
}

Subsystem represents SSH subsytem - special command executed in the context of the session.

type SubsystemResult

type SubsystemResult struct {
	// Name holds the name of the subsystem that was executed.
	Name string

	// Err holds the result of execution of the subsystem.
	Err error
}

SubsystemResult is a result of execution of the subsystem.

type TermHandlers

type TermHandlers struct {
	SessionRegistry *SessionRegistry
}

TermHandlers are common terminal handling functions used by both the regular and forwarding server.

func (*TermHandlers) HandleExec

func (t *TermHandlers) HandleExec(ch ssh.Channel, req *ssh.Request, ctx *ServerContext) error

HandleExec handles requests of type "exec" which can execute with or without a TTY. Result of execution is propagated back on the ExecResult channel of the context.

func (*TermHandlers) HandlePTYReq

func (t *TermHandlers) HandlePTYReq(ch ssh.Channel, req *ssh.Request, ctx *ServerContext) error

HandlePTYReq handles requests of type "pty-req" which allocate a TTY for "exec" or "shell" requests. The "pty-req" includes the size of the TTY as well as the terminal type requested.

func (*TermHandlers) HandleShell

func (t *TermHandlers) HandleShell(ch ssh.Channel, req *ssh.Request, ctx *ServerContext) error

HandleShell handles requests of type "shell" which request a interactive shell be created within a TTY.

func (*TermHandlers) HandleWinChange

func (t *TermHandlers) HandleWinChange(ch ssh.Channel, req *ssh.Request, ctx *ServerContext) error

HandleWinChange handles requests of type "window-change" which update the size of the PTY running on the server and update any other members in the party.

type Terminal

type Terminal interface {
	// AddParty adds another participant to this terminal. We will keep the
	// Terminal open until all participants have left.
	AddParty(delta int)

	// Run will run the terminal.
	Run() error

	// Wait will block until the terminal is complete.
	Wait() (*ExecResult, error)

	// Continue will resume execution of the process after it completes its
	// pre-processing routine (placed in a cgroup).
	Continue()

	// Kill will force kill the terminal.
	Kill() error

	// PTY returns the PTY backing the terminal.
	PTY() io.ReadWriter

	// TTY returns the TTY backing the terminal.
	TTY() *os.File

	// PID returns the PID of the Teleport process that was re-execed.
	PID() int

	// Close will free resources associated with the terminal.
	Close() error

	// GetWinSize returns the window size of the terminal.
	GetWinSize() (*term.Winsize, error)

	// SetWinSize sets the window size of the terminal.
	SetWinSize(params rsession.TerminalParams) error

	// GetTerminalParams is a fast call to get cached terminal parameters
	// and avoid extra system call.
	GetTerminalParams() rsession.TerminalParams

	// SetTerminalModes sets the terminal modes from "pty-req"
	SetTerminalModes(ssh.TerminalModes)

	// GetTermType gets the terminal type set in "pty-req"
	GetTermType() string

	// SetTermType sets the terminal type from "pty-req"
	SetTermType(string)
}

Terminal defines an interface of handy functions for managing a (local or remote) PTY, such as resizing windows, executing commands with a PTY, and cleaning up.

func NewTerminal

func NewTerminal(ctx *ServerContext) (Terminal, error)

NewTerminal returns a new terminal. Terminal can be local or remote depending on cluster configuration.

type TrackingConn

type TrackingConn interface {
	// LocalAddr returns local address
	LocalAddr() net.Addr
	// RemoteAddr returns remote address
	RemoteAddr() net.Addr
	// Close closes the connection
	Close() error
}

TrackingConn is an interface representing tracking connection

type TrackingReader

type TrackingReader struct {
	// contains filtered or unexported fields
}

TrackingReader wraps the writer and every time write occurs, updates the activity in the server context

func NewTrackingReader

func NewTrackingReader(ctx *ServerContext, r io.Reader) *TrackingReader

NewTrackingReader returns a new instance of activity tracking reader.

func (*TrackingReader) Read

func (a *TrackingReader) Read(b []byte) (int, error)

Read passes the read through to internal reader, and updates activity of the server context

Directories

Path Synopsis
Package regular implements SSH server that supports multiplexing tunneling, SSH connections proxying and only supports Key based auth
Package regular implements SSH server that supports multiplexing tunneling, SSH connections proxying and only supports Key based auth

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL