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

Side by Side Diff: ssh/transport.go

Issue 14641044: code review 14641044: go.crypto/ssh: put version exchange in function (Closed)
Patch Set: diff -r bb19605bfacc 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
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 "bytes"
9 "crypto/cipher" 10 "crypto/cipher"
10 "crypto/subtle" 11 "crypto/subtle"
11 "encoding/binary" 12 "encoding/binary"
12 "errors" 13 "errors"
14 "fmt"
13 "hash" 15 "hash"
14 "io" 16 "io"
15 "net" 17 "net"
16 "sync" 18 "sync"
17 ) 19 )
18 20
19 const ( 21 const (
20 packetSizeMultiple = 16 // TODO(huin) this should be determined by the c ipher. 22 packetSizeMultiple = 16 // TODO(huin) this should be determined by the c ipher.
21 23
22 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that impl ementations 24 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that impl ementations
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 353
352 digest := h.Sum(nil) 354 digest := h.Sum(nil)
353 n := copy(out, digest) 355 n := copy(out, digest)
354 out = out[n:] 356 out = out[n:]
355 if len(out) > 0 { 357 if len(out) > 0 {
356 digestsSoFar = append(digestsSoFar, digest...) 358 digestsSoFar = append(digestsSoFar, digest...)
357 } 359 }
358 } 360 }
359 } 361 }
360 362
361 // maxVersionStringBytes is the maximum number of bytes that we'll accept as a 363 var packageVersion = []byte("SSH-2.0-Go")
dfc 2013/10/14 00:32:28 I think I want packageVersion to be a string const
hanwen-google 2013/10/14 06:41:44 Done.
362 // version string. In the event that the client is talking a different protocol 364
363 // we need to set a limit otherwise we will keep using more and more memory 365 // Sends a version string. If myVersion is not given, "Go" is used.
364 // while searching for the end of the version handshake. 366 func exchangeVersions(rw io.ReadWriter, myVersion string) (us []byte, them []byt e, err error) {
365 const maxVersionStringBytes = 1024 367 » // We start with exchanging version strings. The read and write are
368 » // not serialized.
369 » if len(myVersion) == 0 {
370 » » us = packageVersion
371 » } else {
372 » » for _, c := range []byte(myVersion) {
373 » » » // The spec disallows non US-ASCII chars, and
374 » » » // specifically forbids null chars.
375 » » » if c < 32 {
376 » » » » return nil, nil, errors.New("ssh: junk character in version string.")
377 » » » }
378 » » }
379
380 » » us = append([]byte("SSH-2.0-"), myVersion...)
381 » }
382 » if _, err = rw.Write(append(us, '\r', '\n')); err != nil {
383 » » return
384 » }
385
386 » them, err = readVersion(rw)
387 » if !bytes.HasPrefix(them, []byte("SSH-2.0-")) {
388 » » return nil, nil, fmt.Errorf("protocol version not supported: %q" , them)
389 » }
390 » return us, them, err
391 }
392
393 // maxVersionStringBytes is the maximum number of bytes that we'll
394 // accept as a version string. RFC 4253 section 4.2 limits this at 255
395 // chars
396 const maxVersionStringBytes = 255
366 397
367 // Read version string as specified by RFC 4253, section 4.2. 398 // Read version string as specified by RFC 4253, section 4.2.
368 func readVersion(r io.Reader) ([]byte, error) { 399 func readVersion(r io.Reader) ([]byte, error) {
369 versionString := make([]byte, 0, 64) 400 versionString := make([]byte, 0, 64)
370 var ok bool 401 var ok bool
371 var buf [1]byte 402 var buf [1]byte
372 forEachByte: 403
373 for len(versionString) < maxVersionStringBytes { 404 for len(versionString) < maxVersionStringBytes {
374 _, err := io.ReadFull(r, buf[:]) 405 _, err := io.ReadFull(r, buf[:])
375 if err != nil { 406 if err != nil {
376 return nil, err 407 return nil, err
377 } 408 }
378 // The RFC says that the version should be terminated with \r\n 409 // The RFC says that the version should be terminated with \r\n
379 // but several SSH servers actually only send a \n. 410 // but several SSH servers actually only send a \n.
380 if buf[0] == '\n' { 411 if buf[0] == '\n' {
381 » » » ok = true 412 » » » // Before the version string (format
382 » » » break forEachByte 413 » » » // SSH-<protocol-version>-<software-version>)
414 » » » // there may be other lines that we ignore.
415 » » » if bytes.HasPrefix(versionString, []byte("SSH-")) {
416 » » » » ok = true
417 » » » » break
418 » » » }
419 » » » versionString = versionString[:0]
420 » » » continue
383 } 421 }
422
423 // non ASCII chars are disallowed, but we are lenient,
424 // since Go doesn't use null-terminated strings.
425
426 // The RFC allows a comment after a space, however,
427 // all of it (version and comments) go into the
428 // session hash.
384 versionString = append(versionString, buf[0]) 429 versionString = append(versionString, buf[0])
385 } 430 }
386 431
387 if !ok { 432 if !ok {
388 » » return nil, errors.New("ssh: failed to read version string") 433 » » return nil, errors.New("ssh: overflow reading version string")
389 } 434 }
390 435
391 // There might be a '\r' on the end which we should remove. 436 // There might be a '\r' on the end which we should remove.
392 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' { 437 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' {
393 versionString = versionString[:len(versionString)-1] 438 versionString = versionString[:len(versionString)-1]
394 } 439 }
395 return versionString, nil 440 return versionString, nil
396 } 441 }
OLDNEW
« ssh/server.go ('K') | « ssh/server.go ('k') | ssh/transport_test.go » ('j') | no next file with comments »

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