Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package ssh

import (
	
	
	
	
	
	
	
)
Client implements a traditional SSH client that supports shells, subprocesses, TCP port/streamlocal forwarding and tunneled dialing.
type Client struct {
	Conn

	handleForwardsOnce sync.Once // guards calling (*Client).handleForwards

	forwards        forwardList // forwarded tcpip connections from the remote side
	mu              sync.Mutex
	channelHandlers map[string]chan NewChannel
}
HandleChannelOpen returns a channel on which NewChannel requests for the given type are sent. If the type already is being handled, nil is returned. The channel is closed when the connection is closed.
func ( *Client) ( string) <-chan NewChannel {
	.mu.Lock()
	defer .mu.Unlock()
The SSH channel has been closed.
		 := make(chan NewChannel)
		close()
		return 
	}

	 := .channelHandlers[]
	if  != nil {
		return nil
	}

	 = make(chan NewChannel, chanSize)
	.channelHandlers[] = 
	return 
}
NewClient creates a Client on top of the given connection.
func ( Conn,  <-chan NewChannel,  <-chan *Request) *Client {
	 := &Client{
		Conn:            ,
		channelHandlers: make(map[string]chan NewChannel, 1),
	}

	go .handleGlobalRequests()
	go .handleChannelOpens()
	go func() {
		.Wait()
		.forwards.closeAll()
	}()
	return 
}
NewClientConn establishes an authenticated SSH connection using c as the underlying transport. The Request and NewChannel channels must be serviced or the connection will hang.
func ( net.Conn,  string,  *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) {
	 := *
	.SetDefaults()
	if .HostKeyCallback == nil {
		.Close()
		return nil, nil, nil, errors.New("ssh: must specify HostKeyCallback")
	}

	 := &connection{
		sshConn: sshConn{conn: },
	}

	if  := .clientHandshake(, &);  != nil {
		.Close()
		return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", )
	}
	.mux = newMux(.transport)
	return , .mux.incomingChannels, .mux.incomingRequests, nil
}
clientHandshake performs the client side key exchange. See RFC 4253 Section 7.
func ( *connection) ( string,  *ClientConfig) error {
	if .ClientVersion != "" {
		.clientVersion = []byte(.ClientVersion)
	} else {
		.clientVersion = []byte(packageVersion)
	}
	var  error
	.serverVersion,  = exchangeVersions(.sshConn.conn, .clientVersion)
	if  != nil {
		return 
	}

	.transport = newClientTransport(
		newTransport(.sshConn.conn, .Rand, true /* is client */),
		.clientVersion, .serverVersion, , , .sshConn.RemoteAddr())
	if  := .transport.waitSession();  != nil {
		return 
	}

	.sessionID = .transport.getSessionID()
	return .clientAuthenticate()
}
verifyHostKeySignature verifies the host key obtained in the key exchange.
func ( PublicKey,  *kexResult) error {
	, ,  := parseSignatureBody(.Signature)
	if len() > 0 || ! {
		return errors.New("ssh: signature parse error")
	}

	return .Verify(.H, )
}
NewSession opens a new Session for this client. (A session is a remote execution of a program.)
func ( *Client) () (*Session, error) {
	, ,  := .OpenChannel("session", nil)
	if  != nil {
		return nil, 
	}
	return newSession(, )
}

func ( *Client) ( <-chan *Request) {
This handles keepalive messages and matches the behaviour of OpenSSH.
		.Reply(false, nil)
	}
}
handleChannelOpens channel open messages from the remote side.
func ( *Client) ( <-chan NewChannel) {
	for  := range  {
		.mu.Lock()
		 := .channelHandlers[.ChannelType()]
		.mu.Unlock()

		if  != nil {
			 <- 
		} else {
			.Reject(UnknownChannelType, fmt.Sprintf("unknown channel type: %v", .ChannelType()))
		}
	}

	.mu.Lock()
	for ,  := range .channelHandlers {
		close()
	}
	.channelHandlers = nil
	.mu.Unlock()
}
Dial starts a client connection to the given SSH server. It is a convenience function that connects to the given network address, initiates the SSH handshake, and then sets up a Client. For access to incoming channels and requests, use net.Dial with NewClientConn instead.
func (,  string,  *ClientConfig) (*Client, error) {
	,  := net.DialTimeout(, , .Timeout)
	if  != nil {
		return nil, 
	}
	, , ,  := NewClientConn(, , )
	if  != nil {
		return nil, 
	}
	return NewClient(, , ), nil
}
HostKeyCallback is the function type used for verifying server keys. A HostKeyCallback must return nil if the host key is OK, or an error to reject it. It receives the hostname as passed to Dial or NewClientConn. The remote address is the RemoteAddr of the net.Conn underlying the SSH connection.
type HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
BannerCallback is the function type used for treat the banner sent by the server. A BannerCallback receives the message sent by the remote server.
type BannerCallback func(message string) error
A ClientConfig structure is used to configure a Client. It must not be modified after having been passed to an SSH function.
Config contains configuration that is shared between clients and servers.
User contains the username to authenticate as.
Auth contains possible authentication methods to use with the server. Only the first instance of a particular RFC 4252 method will be used during authentication.
HostKeyCallback is called during the cryptographic handshake to validate the server's host key. The client configuration must supply this callback for the connection to succeed. The functions InsecureIgnoreHostKey or FixedHostKey can be used for simplistic host key checks.
BannerCallback is called during the SSH dance to display a custom server's message. The client configuration can supply this callback to handle it as wished. The function BannerDisplayStderr can be used for simplistic display on Stderr.
ClientVersion contains the version identification string that will be used for the connection. If empty, a reasonable default is used.
HostKeyAlgorithms lists the key types that the client will accept from the server as host key, in order of preference. If empty, a reasonable default is used. Any string returned from PublicKey.Type method may be used, or any of the CertAlgoXxxx and KeyAlgoXxxx constants.
Timeout is the maximum amount of time for the TCP connection to establish. A Timeout of zero means no timeout.
InsecureIgnoreHostKey returns a function that can be used for ClientConfig.HostKeyCallback to accept any host key. It should not be used for production code.
func () HostKeyCallback {
	return func( string,  net.Addr,  PublicKey) error {
		return nil
	}
}

type fixedHostKey struct {
	key PublicKey
}

func ( *fixedHostKey) ( string,  net.Addr,  PublicKey) error {
	if .key == nil {
		return fmt.Errorf("ssh: required host key was nil")
	}
	if !bytes.Equal(.Marshal(), .key.Marshal()) {
		return fmt.Errorf("ssh: host key mismatch")
	}
	return nil
}
FixedHostKey returns a function for use in ClientConfig.HostKeyCallback to accept only a specific host key.
func ( PublicKey) HostKeyCallback {
	 := &fixedHostKey{}
	return .check
}
BannerDisplayStderr returns a function that can be used for ClientConfig.BannerCallback to display banners on os.Stderr.
func () BannerCallback {
	return func( string) error {
		,  := os.Stderr.WriteString()

		return 
	}