connection.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. import (
  6. "fmt"
  7. "net"
  8. )
  9. // OpenChannelError is returned if the other side rejects an
  10. // OpenChannel request.
  11. type OpenChannelError struct {
  12. Reason RejectionReason
  13. Message string
  14. }
  15. func (e *OpenChannelError) Error() string {
  16. return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message)
  17. }
  18. // ConnMetadata holds metadata for the connection.
  19. type ConnMetadata interface {
  20. // User returns the user ID for this connection.
  21. // It is empty if no authentication is used.
  22. User() string
  23. // SessionID returns the sesson hash, also denoted by H.
  24. SessionID() []byte
  25. // ClientVersion returns the client's version string as hashed
  26. // into the session ID.
  27. ClientVersion() []byte
  28. // ServerVersion returns the server's version string as hashed
  29. // into the session ID.
  30. ServerVersion() []byte
  31. // RemoteAddr returns the remote address for this connection.
  32. RemoteAddr() net.Addr
  33. // LocalAddr returns the local address for this connection.
  34. LocalAddr() net.Addr
  35. }
  36. // Conn represents an SSH connection for both server and client roles.
  37. // Conn is the basis for implementing an application layer, such
  38. // as ClientConn, which implements the traditional shell access for
  39. // clients.
  40. type Conn interface {
  41. ConnMetadata
  42. // SendRequest sends a global request, and returns the
  43. // reply. If wantReply is true, it returns the response status
  44. // and payload. See also RFC4254, section 4.
  45. SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
  46. // OpenChannel tries to open an channel. If the request is
  47. // rejected, it returns *OpenChannelError. On success it returns
  48. // the SSH Channel and a Go channel for incoming, out-of-band
  49. // requests. The Go channel must be serviced, or the
  50. // connection will hang.
  51. OpenChannel(name string, data []byte) (Channel, <-chan *Request, error)
  52. // Close closes the underlying network connection
  53. Close() error
  54. // Wait blocks until the connection has shut down, and returns the
  55. // error causing the shutdown.
  56. Wait() error
  57. // TODO(hanwen): consider exposing:
  58. // RequestKeyChange
  59. // Disconnect
  60. }
  61. // DiscardRequests consumes and rejects all requests from the
  62. // passed-in channel.
  63. func DiscardRequests(in <-chan *Request) {
  64. for req := range in {
  65. if req.WantReply {
  66. req.Reply(false, nil)
  67. }
  68. }
  69. }
  70. // A connection represents an incoming connection.
  71. type connection struct {
  72. transport *handshakeTransport
  73. sshConn
  74. // The connection protocol.
  75. *mux
  76. }
  77. func (c *connection) Close() error {
  78. return c.sshConn.conn.Close()
  79. }
  80. // sshconn provides net.Conn metadata, but disallows direct reads and
  81. // writes.
  82. type sshConn struct {
  83. conn net.Conn
  84. user string
  85. sessionID []byte
  86. clientVersion []byte
  87. serverVersion []byte
  88. }
  89. func dup(src []byte) []byte {
  90. dst := make([]byte, len(src))
  91. copy(dst, src)
  92. return dst
  93. }
  94. func (c *sshConn) User() string {
  95. return c.user
  96. }
  97. func (c *sshConn) RemoteAddr() net.Addr {
  98. return c.conn.RemoteAddr()
  99. }
  100. func (c *sshConn) Close() error {
  101. return c.conn.Close()
  102. }
  103. func (c *sshConn) LocalAddr() net.Addr {
  104. return c.conn.LocalAddr()
  105. }
  106. func (c *sshConn) SessionID() []byte {
  107. return dup(c.sessionID)
  108. }
  109. func (c *sshConn) ClientVersion() []byte {
  110. return dup(c.clientVersion)
  111. }
  112. func (c *sshConn) ServerVersion() []byte {
  113. return dup(c.serverVersion)
  114. }