Documentation ¶
Overview ¶
Package ssh implements an SSH client and server.
SSH is a transport security protocol, an authentication protocol and a family of application protocols. The most typical application level protocol is a remote shell and this is specifically implemented. However, the multiplexed nature of SSH is exposed to users that wish to support others.
An SSH server is represented by a ServerConfig, which holds certificate details and handles authentication of ServerConns.
config := new(ServerConfig) config.PubKeyCallback = pubKeyAuth config.PasswordCallback = passwordAuth pemBytes, err := ioutil.ReadFile("id_rsa") if err != nil { panic("Failed to load private key") } err = config.SetRSAPrivateKey(pemBytes) if err != nil { panic("Failed to parse private key") }
Once a ServerConfig has been configured, connections can be accepted.
listener := Listen("tcp", "0.0.0.0:2022", config) sConn, err := listener.Accept() if err != nil { panic("failed to accept incoming connection") } err = sConn.Handshake(conn) if err != nil { panic("failed to handshake") }
An SSH connection multiplexes several channels, which must be accepted themselves:
for { channel, err := sConn.Accept() if err != nil { panic("error from Accept") } ... }
Accept reads from the connection, demultiplexes packets to their corresponding channels and returns when a new channel request is seen. Some goroutine must always be calling Accept; otherwise no messages will be forwarded to the channels.
Channels have a type, depending on the application level protocol intended. In the case of a shell, the type is "session" and ServerShell may be used to present a simple terminal interface.
if channel.ChannelType() != "session" { c.Reject(UnknownChannelType, "unknown channel type") return } channel.Accept() shell := NewServerShell(channel, "> ") go func() { defer channel.Close() for { line, err := shell.ReadLine() if err != nil { break } println(line) } return }()
An SSH client is represented with a ClientConn. Currently only the "password" authentication method is supported.
config := &ClientConfig{ User: "username", Auth: []ClientAuth{ ... }, } client, err := Dial("yourserver.com:22", config)
Each ClientConn can support multiple interactive sessions, represented by a Session.
session, err := client.NewSession()
Once a Session is created, you can execute a single command on the remote side using the Exec method.
if err := session.Exec("/usr/bin/whoami"); err != nil { panic("Failed to exec: " + err.String()) } reader := bufio.NewReader(session.Stdin) line, _, _ := reader.ReadLine() fmt.Println(line) session.Close()
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Channel ¶
type Channel interface { // Accept accepts the channel creation request. Accept() error // Reject rejects the channel creation request. After calling this, no // other methods on the Channel may be called. If they are then the // peer is likely to signal a protocol error and drop the connection. Reject(reason RejectionReason, message string) error // Read may return a ChannelRequest as an error. Read(data []byte) (int, error) Write(data []byte) (int, error) Close() error // AckRequest either sends an ack or nack to the channel request. AckRequest(ok bool) error // ChannelType returns the type of the channel, as supplied by the // client. ChannelType() string // ExtraData returns the arbitary payload for this channel, as supplied // by the client. This data is specific to the channel type. ExtraData() []byte }
A Channel is an ordered, reliable, duplex stream that is multiplexed over an SSH connection.
type ChannelRequest ¶
ChannelRequest represents a request sent on a channel, outside of the normal stream of bytes. It may result from calling Read on a Channel.
func (ChannelRequest) Error ¶
func (c ChannelRequest) Error() string
type ClientAuth ¶
type ClientAuth interface {
// contains filtered or unexported methods
}
A ClientAuth represents an instance of an RFC 4252 authentication method.
func ClientAuthPassword ¶
func ClientAuthPassword(impl ClientPassword) ClientAuth
ClientAuthPassword returns a ClientAuth using password authentication.
func ClientAuthPublickey ¶
func ClientAuthPublickey(impl ClientKeyring) ClientAuth
ClientAuthPublickey returns a ClientAuth using public key authentication.
type ClientConfig ¶
type ClientConfig struct { // Rand provides the source of entropy for key exchange. If Rand is // nil, the cryptographic random reader in package crypto/rand will // be used. Rand io.Reader // The username to authenticate. User string // A slice of ClientAuth methods. Only the first instance // of a particular RFC 4252 method will be used during authentication. Auth []ClientAuth // Cryptographic-related configuration. Crypto CryptoConfig }
A ClientConfig structure is used to configure a ClientConn. After one has been passed to an SSH function it must not be modified.
type ClientConn ¶
type ClientConn struct {
// contains filtered or unexported fields
}
ClientConn represents the client side of an SSH connection.
func Client ¶
func Client(c net.Conn, config *ClientConfig) (*ClientConn, error)
Client returns a new SSH client connection using c as the underlying transport.
func Dial ¶
func Dial(network, addr string, config *ClientConfig) (*ClientConn, error)
Dial connects to the given network address using net.Dial and then initiates a SSH handshake, returning the resulting client connection.
func (*ClientConn) Dial ¶
func (c *ClientConn) Dial(n, addr string) (net.Conn, error)
Dial initiates a connection to the addr from the remote host. addr is resolved using net.ResolveTCPAddr before connection. This could allow an observer to observe the DNS name of the remote host. Consider using ssh.DialTCP to avoid this.
type ClientKeyring ¶
type ClientKeyring interface { // Key returns the i'th rsa.Publickey or dsa.Publickey, or nil if // no key exists at i. Key(i int) (key interface{}, err error) // Sign returns a signature of the given data using the i'th key // and the supplied random source. Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) }
ClientKeyring implements access to a client key ring.
type ClientPassword ¶
type ClientPassword interface { // Password returns the password to use for user. Password(user string) (password string, err error) }
A ClientPassword implements access to a client's passwords.
type CryptoConfig ¶
type CryptoConfig struct { // The allowed cipher algorithms. If unspecified then DefaultCipherOrder is // used. Ciphers []string }
Cryptographic configuration common to both ServerConfig and ClientConfig.
type Listener ¶
A Listener implements a network listener (net.Listener) for SSH connections.
func Listen ¶
func Listen(network, addr string, config *ServerConfig) (*Listener, error)
Listen creates an SSH listener accepting connections on the given network address using net.Listen.
func (*Listener) Accept ¶
func (l *Listener) Accept() (*ServerConn, error)
Accept waits for and returns the next incoming SSH connection. The receiver should call Handshake() in another goroutine to avoid blocking the accepter.
type ParseError ¶
type ParseError struct {
// contains filtered or unexported fields
}
ParseError results from a malformed SSH message.
func (ParseError) Error ¶
func (p ParseError) Error() string
type RejectionReason ¶
type RejectionReason int
RejectionReason is an enumeration used when rejecting channel creation requests. See RFC 4254, section 5.1.
const ( Prohibited RejectionReason = iota + 1 ConnectionFailed UnknownChannelType ResourceShortage )
type ServerConfig ¶
type ServerConfig struct { // Rand provides the source of entropy for key exchange. If Rand is // nil, the cryptographic random reader in package crypto/rand will // be used. Rand io.Reader // NoClientAuth is true if clients are allowed to connect without // authenticating. NoClientAuth bool // PasswordCallback, if non-nil, is called when a user attempts to // authenticate using a password. It may be called concurrently from // several goroutines. PasswordCallback func(user, password string) bool // PubKeyCallback, if non-nil, is called when a client attempts public // key authentication. It must return true iff the given public key is // valid for the given user. PubKeyCallback func(user, algo string, pubkey []byte) bool // Cryptographic-related configuration. Crypto CryptoConfig // contains filtered or unexported fields }
func (*ServerConfig) SetRSAPrivateKey ¶
func (s *ServerConfig) SetRSAPrivateKey(pemBytes []byte) error
SetRSAPrivateKey sets the private key for a Server. A Server must have a private key configured in order to accept connections. The private key must be in the form of a PEM encoded, PKCS#1, RSA private key. The file "id_rsa" typically contains such a key.
type ServerConn ¶
type ServerConn struct {
// contains filtered or unexported fields
}
A ServerConn represents an incomming connection.
func Server ¶
func Server(c net.Conn, config *ServerConfig) *ServerConn
Server returns a new SSH server connection using c as the underlying transport.
func (*ServerConn) Accept ¶
func (s *ServerConn) Accept() (Channel, error)
Accept reads and processes messages on a ServerConn. It must be called in order to demultiplex messages to any resulting Channels.
func (*ServerConn) Handshake ¶
func (s *ServerConn) Handshake() error
Handshake performs an SSH transport and client authentication on the given ServerConn.
type ServerShell ¶
type ServerShell struct {
// contains filtered or unexported fields
}
ServerShell contains the state for running a VT100 terminal that is capable of reading lines of input.
func NewServerShell ¶
func NewServerShell(c Channel, prompt string) *ServerShell
NewServerShell runs a VT100 terminal on the given channel. prompt is a string that is written at the start of each input line. For example: "> ".
func (*ServerShell) ReadLine ¶
func (ss *ServerShell) ReadLine() (line string, err error)
ReadLine returns a line of input from the terminal.
type UnexpectedMessageError ¶
type UnexpectedMessageError struct {
// contains filtered or unexported fields
}
UnexpectedMessageError results when the SSH message that we received didn't match what we wanted.
func (UnexpectedMessageError) Error ¶
func (u UnexpectedMessageError) Error() string