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