| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 | // Copyright 2013 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 sshimport (	"fmt"	"net")// OpenChannelError is returned if the other side rejects an// OpenChannel request.type OpenChannelError struct {	Reason  RejectionReason	Message string}func (e *OpenChannelError) Error() string {	return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message)}// ConnMetadata holds metadata for the connection.type ConnMetadata interface {	// User returns the user ID for this connection.	User() string	// SessionID returns the sesson hash, also denoted by H.	SessionID() []byte	// ClientVersion returns the client's version string as hashed	// into the session ID.	ClientVersion() []byte	// ServerVersion returns the server's version string as hashed	// into the session ID.	ServerVersion() []byte	// RemoteAddr returns the remote address for this connection.	RemoteAddr() net.Addr	// LocalAddr returns the local address for this connection.	LocalAddr() net.Addr}// Conn represents an SSH connection for both server and client roles.// Conn is the basis for implementing an application layer, such// as ClientConn, which implements the traditional shell access for// clients.type Conn interface {	ConnMetadata	// SendRequest sends a global request, and returns the	// reply. If wantReply is true, it returns the response status	// and payload. See also RFC4254, section 4.	SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)	// OpenChannel tries to open an channel. If the request is	// rejected, it returns *OpenChannelError. On success it returns	// the SSH Channel and a Go channel for incoming, out-of-band	// requests. The Go channel must be serviced, or the	// connection will hang.	OpenChannel(name string, data []byte) (Channel, <-chan *Request, error)	// Close closes the underlying network connection	Close() error	// Wait blocks until the connection has shut down, and returns the	// error causing the shutdown.	Wait() error	// TODO(hanwen): consider exposing:	//   RequestKeyChange	//   Disconnect}// DiscardRequests consumes and rejects all requests from the// passed-in channel.func DiscardRequests(in <-chan *Request) {	for req := range in {		if req.WantReply {			req.Reply(false, nil)		}	}}// A connection represents an incoming connection.type connection struct {	transport *handshakeTransport	sshConn	// The connection protocol.	*mux}func (c *connection) Close() error {	return c.sshConn.conn.Close()}// sshconn provides net.Conn metadata, but disallows direct reads and// writes.type sshConn struct {	conn net.Conn	user          string	sessionID     []byte	clientVersion []byte	serverVersion []byte}func dup(src []byte) []byte {	dst := make([]byte, len(src))	copy(dst, src)	return dst}func (c *sshConn) User() string {	return c.user}func (c *sshConn) RemoteAddr() net.Addr {	return c.conn.RemoteAddr()}func (c *sshConn) Close() error {	return c.conn.Close()}func (c *sshConn) LocalAddr() net.Addr {	return c.conn.LocalAddr()}func (c *sshConn) SessionID() []byte {	return dup(c.sessionID)}func (c *sshConn) ClientVersion() []byte {	return dup(c.clientVersion)}func (c *sshConn) ServerVersion() []byte {	return dup(c.serverVersion)}
 |