123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // 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 ssh
- import (
- "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.
- // It is empty if no authentication is used.
- 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)
- }
|