OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / golang.org / x / crypto / ssh / connection.go
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 session 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 }