OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ssh | 5 package ssh |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "crypto" | 9 "crypto" |
10 "crypto/cipher" | 10 "crypto/cipher" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that impl
ementations | 23 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that impl
ementations |
24 // MUST be able to process (plus a few more kilobytes for padding and ma
c). The RFC | 24 // MUST be able to process (plus a few more kilobytes for padding and ma
c). The RFC |
25 // indicates implementations SHOULD be able to handle larger packet size
s, but then | 25 // indicates implementations SHOULD be able to handle larger packet size
s, but then |
26 // waffles on about reasonable limits. | 26 // waffles on about reasonable limits. |
27 // | 27 // |
28 // OpenSSH caps their maxPacket at 256kb so we choose to do the same. | 28 // OpenSSH caps their maxPacket at 256kb so we choose to do the same. |
29 maxPacket = 256 * 1024 | 29 maxPacket = 256 * 1024 |
30 ) | 30 ) |
31 | 31 |
32 // conn represents an ssh transport that implements packet based | 32 // packetConn represents a transport that implements packet based |
33 // operations. | 33 // operations. |
34 type conn interface { | 34 type packetConn interface { |
35 // Encrypt and send a packet of data to the remote peer. | 35 // Encrypt and send a packet of data to the remote peer. |
36 writePacket(packet []byte) error | 36 writePacket(packet []byte) error |
37 | 37 |
38 » // Close closes the connection. | 38 » // Read a packet from the connection |
| 39 » readPacket() ([]byte, error) |
| 40 |
| 41 » // Close closes the write-side of the connection. |
39 Close() error | 42 Close() error |
40 } | 43 } |
41 | 44 |
42 // transport represents the SSH connection to the remote peer. | 45 // transport represents the SSH connection to the remote peer. |
43 type transport struct { | 46 type transport struct { |
44 reader | 47 reader |
45 writer | 48 writer |
46 | 49 |
47 net.Conn | 50 net.Conn |
48 } | 51 } |
(...skipping 18 matching lines...) Expand all Loading... |
67 seqNum uint32 | 70 seqNum uint32 |
68 mac hash.Hash | 71 mac hash.Hash |
69 cipher cipher.Stream | 72 cipher cipher.Stream |
70 | 73 |
71 cipherAlgo string | 74 cipherAlgo string |
72 macAlgo string | 75 macAlgo string |
73 compressionAlgo string | 76 compressionAlgo string |
74 } | 77 } |
75 | 78 |
76 // Read and decrypt a single packet from the remote peer. | 79 // Read and decrypt a single packet from the remote peer. |
77 func (r *reader) readOnePacket() ([]byte, error) { | 80 func (r *reader) readPacket() ([]byte, error) { |
78 var lengthBytes = make([]byte, 5) | 81 var lengthBytes = make([]byte, 5) |
79 var macSize uint32 | 82 var macSize uint32 |
80 if _, err := io.ReadFull(r, lengthBytes); err != nil { | 83 if _, err := io.ReadFull(r, lengthBytes); err != nil { |
81 return nil, err | 84 return nil, err |
82 } | 85 } |
83 | 86 |
84 r.cipher.XORKeyStream(lengthBytes, lengthBytes) | 87 r.cipher.XORKeyStream(lengthBytes, lengthBytes) |
85 | 88 |
86 if r.mac != nil { | 89 if r.mac != nil { |
87 r.mac.Reset() | 90 r.mac.Reset() |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 } | 124 } |
122 } | 125 } |
123 | 126 |
124 r.seqNum++ | 127 r.seqNum++ |
125 return packet[:length-paddingLength-1], nil | 128 return packet[:length-paddingLength-1], nil |
126 } | 129 } |
127 | 130 |
128 // Read and decrypt next packet discarding debug and noop messages. | 131 // Read and decrypt next packet discarding debug and noop messages. |
129 func (t *transport) readPacket() ([]byte, error) { | 132 func (t *transport) readPacket() ([]byte, error) { |
130 for { | 133 for { |
131 » » packet, err := t.readOnePacket() | 134 » » packet, err := t.reader.readPacket() |
132 if err != nil { | 135 if err != nil { |
133 return nil, err | 136 return nil, err |
134 } | 137 } |
135 if len(packet) == 0 { | 138 if len(packet) == 0 { |
136 return nil, errors.New("ssh: zero length packet") | 139 return nil, errors.New("ssh: zero length packet") |
137 } | 140 } |
138 if packet[0] != msgIgnore && packet[0] != msgDebug { | 141 if packet[0] != msgIgnore && packet[0] != msgDebug { |
139 return packet, nil | 142 return packet, nil |
140 } | 143 } |
141 } | 144 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 if !ok { | 321 if !ok { |
319 return nil, errors.New("ssh: failed to read version string") | 322 return nil, errors.New("ssh: failed to read version string") |
320 } | 323 } |
321 | 324 |
322 // There might be a '\r' on the end which we should remove. | 325 // There might be a '\r' on the end which we should remove. |
323 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r'
{ | 326 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r'
{ |
324 versionString = versionString[:len(versionString)-1] | 327 versionString = versionString[:len(versionString)-1] |
325 } | 328 } |
326 return versionString, nil | 329 return versionString, nil |
327 } | 330 } |
OLD | NEW |