Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(956)

Side by Side Diff: ssh/transport.go

Issue 14494058: code review 14494058: go.crypto/ssh: support rekeying in both directions. (Closed)
Patch Set: diff -r 5ff5636e18c9 https://code.google.com/p/go.crypto Created 10 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« ssh/handshake_test.go ('K') | « ssh/test/test_unix_test.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/cipher" 9 "crypto/cipher"
10 "crypto/subtle" 10 "crypto/subtle"
11 "encoding/binary" 11 "encoding/binary"
12 "errors" 12 "errors"
13 "hash" 13 "hash"
14 "io" 14 "io"
15 "net"
16 "sync" 15 "sync"
17 ) 16 )
18 17
19 const ( 18 const (
20 packetSizeMultiple = 16 // TODO(huin) this should be determined by the c ipher. 19 packetSizeMultiple = 16 // TODO(huin) this should be determined by the c ipher.
21 20
22 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that impl ementations 21 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that impl ementations
23 // MUST be able to process (plus a few more kilobytes for padding and ma c). The RFC 22 // MUST be able to process (plus a few more kilobytes for padding and ma c). The RFC
24 // indicates implementations SHOULD be able to handle larger packet size s, but then 23 // indicates implementations SHOULD be able to handle larger packet size s, but then
25 // waffles on about reasonable limits. 24 // waffles on about reasonable limits.
(...skipping 13 matching lines...) Expand all
39 38
40 // Close closes the write-side of the connection. 39 // Close closes the write-side of the connection.
41 Close() error 40 Close() error
42 } 41 }
43 42
44 // transport represents the SSH connection to the remote peer. 43 // transport represents the SSH connection to the remote peer.
45 type transport struct { 44 type transport struct {
46 reader 45 reader
47 writer 46 writer
48 47
49 » net.Conn 48 » io.Closer
50 49
51 // Initial H used for the session ID. Once assigned this does 50 // Initial H used for the session ID. Once assigned this does
52 // not change, even during subsequent key exchanges. 51 // not change, even during subsequent key exchanges.
53 sessionID []byte 52 sessionID []byte
54 } 53 }
55 54
55 func (t *transport) SessionID() []byte {
dfc 2013/10/22 22:07:02 does this need to return a copy of the sessionID ?
hanwen-google 2013/10/23 00:15:17 not necessarily, but it is safer and cost is negli
56 if t.sessionID == nil {
57 panic("session ID not set yet")
58 }
59 return t.sessionID
60 }
61
56 // reader represents the incoming connection state. 62 // reader represents the incoming connection state.
57 type reader struct { 63 type reader struct {
58 io.Reader 64 io.Reader
59 common 65 common
60 } 66 }
61 67
62 // writer represents the outgoing connection state. 68 // writer represents the outgoing connection state.
63 type writer struct { 69 type writer struct {
64 sync.Mutex // protects writer.Writer from concurrent writes 70 sync.Mutex // protects writer.Writer from concurrent writes
65 *bufio.Writer 71 *bufio.Writer
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 169 }
164 default: 170 default:
165 return nil, errors.New("ssh: got bogus newkeys message." ) 171 return nil, errors.New("ssh: got bogus newkeys message." )
166 } 172 }
167 } 173 }
168 return packet, nil 174 return packet, nil
169 } 175 }
170 176
171 // Read and decrypt next packet discarding debug and noop messages. 177 // Read and decrypt next packet discarding debug and noop messages.
172 func (t *transport) readPacket() ([]byte, error) { 178 func (t *transport) readPacket() ([]byte, error) {
173 » for { 179 » packet, err := t.reader.readPacket()
174 » » packet, err := t.reader.readPacket() 180 » if err == nil && len(packet) == 0 {
175 » » if err != nil { 181 » » err = errors.New("ssh: zero length packet")
176 » » » return nil, err 182 » }
177 » » }
178 » » if len(packet) == 0 {
179 » » » return nil, errors.New("ssh: zero length packet")
180 » » }
181 183
182 » » if packet[0] != msgIgnore && packet[0] != msgDebug { 184 » return packet, err
183 » » » return packet, nil
184 » » }
185 » }
186 » panic("unreachable")
187 } 185 }
188 186
189 // Encrypt and send a packet of data to the remote peer. 187 // Encrypt and send a packet of data to the remote peer.
190 func (w *writer) writePacket(packet []byte) error { 188 func (w *writer) writePacket(packet []byte) error {
191 changeKeys := len(packet) > 0 && packet[0] == msgNewKeys 189 changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
192 190
193 if len(packet) > maxPacket { 191 if len(packet) > maxPacket {
194 return errors.New("ssh: packet too large") 192 return errors.New("ssh: packet too large")
195 } 193 }
196 w.Mutex.Lock() 194 w.Mutex.Lock()
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 select { 258 select {
261 case k := <-w.pendingKeyChange: 259 case k := <-w.pendingKeyChange:
262 err = w.setupKeys(w.dir, k) 260 err = w.setupKeys(w.dir, k)
263 default: 261 default:
264 panic("ssh: no key material for msgNewKeys") 262 panic("ssh: no key material for msgNewKeys")
265 } 263 }
266 } 264 }
267 return err 265 return err
268 } 266 }
269 267
270 func newTransport(conn net.Conn, rand io.Reader, isClient bool) *transport { 268 func newTransport(conn io.ReadWriteCloser, rand io.Reader, isClient bool) *trans port {
dfc 2013/10/22 22:07:02 s/conn/rwc/
hanwen-google 2013/10/23 00:15:17 Done.
271 t := &transport{ 269 t := &transport{
272 reader: reader{ 270 reader: reader{
273 Reader: bufio.NewReader(conn), 271 Reader: bufio.NewReader(conn),
274 common: common{ 272 common: common{
275 cipher: noneCipher{}, 273 cipher: noneCipher{},
276 pendingKeyChange: make(chan *kexResult, 1), 274 pendingKeyChange: make(chan *kexResult, 1),
277 }, 275 },
278 }, 276 },
279 writer: writer{ 277 writer: writer{
280 Writer: bufio.NewWriter(conn), 278 Writer: bufio.NewWriter(conn),
281 rand: rand, 279 rand: rand,
282 common: common{ 280 common: common{
283 cipher: noneCipher{}, 281 cipher: noneCipher{},
284 pendingKeyChange: make(chan *kexResult, 1), 282 pendingKeyChange: make(chan *kexResult, 1),
285 }, 283 },
286 }, 284 },
287 » » Conn: conn, 285 » » Closer: conn,
288 } 286 }
289 if isClient { 287 if isClient {
290 t.reader.dir = serverKeys 288 t.reader.dir = serverKeys
291 t.writer.dir = clientKeys 289 t.writer.dir = clientKeys
292 } else { 290 } else {
293 t.reader.dir = clientKeys 291 t.reader.dir = clientKeys
294 t.writer.dir = serverKeys 292 t.writer.dir = serverKeys
295 } 293 }
296 294
297 return t 295 return t
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 if !ok { 415 if !ok {
418 return nil, errors.New("ssh: overflow reading version string") 416 return nil, errors.New("ssh: overflow reading version string")
419 } 417 }
420 418
421 // There might be a '\r' on the end which we should remove. 419 // There might be a '\r' on the end which we should remove.
422 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' { 420 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' {
423 versionString = versionString[:len(versionString)-1] 421 versionString = versionString[:len(versionString)-1]
424 } 422 }
425 return versionString, nil 423 return versionString, nil
426 } 424 }
OLDNEW
« ssh/handshake_test.go ('K') | « ssh/test/test_unix_test.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b