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