OSDN Git Service

Thanos did someting
[bytom/vapor.git] / vendor / golang.org / x / crypto / ssh / transport.go
diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go
deleted file mode 100644 (file)
index f9780e0..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ssh
-
-import (
-       "bufio"
-       "errors"
-       "io"
-       "log"
-)
-
-// debugTransport if set, will print packet types as they go over the
-// wire. No message decoding is done, to minimize the impact on timing.
-const debugTransport = false
-
-const (
-       gcmCipherID    = "aes128-gcm@openssh.com"
-       aes128cbcID    = "aes128-cbc"
-       tripledescbcID = "3des-cbc"
-)
-
-// packetConn represents a transport that implements packet based
-// operations.
-type packetConn interface {
-       // Encrypt and send a packet of data to the remote peer.
-       writePacket(packet []byte) error
-
-       // Read a packet from the connection. The read is blocking,
-       // i.e. if error is nil, then the returned byte slice is
-       // always non-empty.
-       readPacket() ([]byte, error)
-
-       // Close closes the write-side of the connection.
-       Close() error
-}
-
-// transport is the keyingTransport that implements the SSH packet
-// protocol.
-type transport struct {
-       reader connectionState
-       writer connectionState
-
-       bufReader *bufio.Reader
-       bufWriter *bufio.Writer
-       rand      io.Reader
-       isClient  bool
-       io.Closer
-}
-
-// packetCipher represents a combination of SSH encryption/MAC
-// protocol.  A single instance should be used for one direction only.
-type packetCipher interface {
-       // writePacket encrypts the packet and writes it to w. The
-       // contents of the packet are generally scrambled.
-       writePacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error
-
-       // readPacket reads and decrypts a packet of data. The
-       // returned packet may be overwritten by future calls of
-       // readPacket.
-       readPacket(seqnum uint32, r io.Reader) ([]byte, error)
-}
-
-// connectionState represents one side (read or write) of the
-// connection. This is necessary because each direction has its own
-// keys, and can even have its own algorithms
-type connectionState struct {
-       packetCipher
-       seqNum           uint32
-       dir              direction
-       pendingKeyChange chan packetCipher
-}
-
-// prepareKeyChange sets up key material for a keychange. The key changes in
-// both directions are triggered by reading and writing a msgNewKey packet
-// respectively.
-func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
-       if ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult); err != nil {
-               return err
-       } else {
-               t.reader.pendingKeyChange <- ciph
-       }
-
-       if ciph, err := newPacketCipher(t.writer.dir, algs.w, kexResult); err != nil {
-               return err
-       } else {
-               t.writer.pendingKeyChange <- ciph
-       }
-
-       return nil
-}
-
-func (t *transport) printPacket(p []byte, write bool) {
-       if len(p) == 0 {
-               return
-       }
-       who := "server"
-       if t.isClient {
-               who = "client"
-       }
-       what := "read"
-       if write {
-               what = "write"
-       }
-
-       log.Println(what, who, p[0])
-}
-
-// Read and decrypt next packet.
-func (t *transport) readPacket() (p []byte, err error) {
-       for {
-               p, err = t.reader.readPacket(t.bufReader)
-               if err != nil {
-                       break
-               }
-               if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) {
-                       break
-               }
-       }
-       if debugTransport {
-               t.printPacket(p, false)
-       }
-
-       return p, err
-}
-
-func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
-       packet, err := s.packetCipher.readPacket(s.seqNum, r)
-       s.seqNum++
-       if err == nil && len(packet) == 0 {
-               err = errors.New("ssh: zero length packet")
-       }
-
-       if len(packet) > 0 {
-               switch packet[0] {
-               case msgNewKeys:
-                       select {
-                       case cipher := <-s.pendingKeyChange:
-                               s.packetCipher = cipher
-                       default:
-                               return nil, errors.New("ssh: got bogus newkeys message.")
-                       }
-
-               case msgDisconnect:
-                       // Transform a disconnect message into an
-                       // error. Since this is lowest level at which
-                       // we interpret message types, doing it here
-                       // ensures that we don't have to handle it
-                       // elsewhere.
-                       var msg disconnectMsg
-                       if err := Unmarshal(packet, &msg); err != nil {
-                               return nil, err
-                       }
-                       return nil, &msg
-               }
-       }
-
-       // The packet may point to an internal buffer, so copy the
-       // packet out here.
-       fresh := make([]byte, len(packet))
-       copy(fresh, packet)
-
-       return fresh, err
-}
-
-func (t *transport) writePacket(packet []byte) error {
-       if debugTransport {
-               t.printPacket(packet, true)
-       }
-       return t.writer.writePacket(t.bufWriter, t.rand, packet)
-}
-
-func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error {
-       changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
-
-       err := s.packetCipher.writePacket(s.seqNum, w, rand, packet)
-       if err != nil {
-               return err
-       }
-       if err = w.Flush(); err != nil {
-               return err
-       }
-       s.seqNum++
-       if changeKeys {
-               select {
-               case cipher := <-s.pendingKeyChange:
-                       s.packetCipher = cipher
-               default:
-                       panic("ssh: no key material for msgNewKeys")
-               }
-       }
-       return err
-}
-
-func newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport {
-       t := &transport{
-               bufReader: bufio.NewReader(rwc),
-               bufWriter: bufio.NewWriter(rwc),
-               rand:      rand,
-               reader: connectionState{
-                       packetCipher:     &streamPacketCipher{cipher: noneCipher{}},
-                       pendingKeyChange: make(chan packetCipher, 1),
-               },
-               writer: connectionState{
-                       packetCipher:     &streamPacketCipher{cipher: noneCipher{}},
-                       pendingKeyChange: make(chan packetCipher, 1),
-               },
-               Closer: rwc,
-       }
-       t.isClient = isClient
-
-       if isClient {
-               t.reader.dir = serverKeys
-               t.writer.dir = clientKeys
-       } else {
-               t.reader.dir = clientKeys
-               t.writer.dir = serverKeys
-       }
-
-       return t
-}
-
-type direction struct {
-       ivTag     []byte
-       keyTag    []byte
-       macKeyTag []byte
-}
-
-var (
-       serverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}}
-       clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
-)
-
-// generateKeys generates key material for IV, MAC and encryption.
-func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) {
-       cipherMode := cipherModes[algs.Cipher]
-       macMode := macModes[algs.MAC]
-
-       iv = make([]byte, cipherMode.ivSize)
-       key = make([]byte, cipherMode.keySize)
-       macKey = make([]byte, macMode.keySize)
-
-       generateKeyMaterial(iv, d.ivTag, kex)
-       generateKeyMaterial(key, d.keyTag, kex)
-       generateKeyMaterial(macKey, d.macKeyTag, kex)
-       return
-}
-
-// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
-// described in RFC 4253, section 6.4. direction should either be serverKeys
-// (to setup server->client keys) or clientKeys (for client->server keys).
-func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
-       iv, key, macKey := generateKeys(d, algs, kex)
-
-       if algs.Cipher == gcmCipherID {
-               return newGCMCipher(iv, key, macKey)
-       }
-
-       if algs.Cipher == aes128cbcID {
-               return newAESCBCCipher(iv, key, macKey, algs)
-       }
-
-       if algs.Cipher == tripledescbcID {
-               return newTripleDESCBCCipher(iv, key, macKey, algs)
-       }
-
-       c := &streamPacketCipher{
-               mac: macModes[algs.MAC].new(macKey),
-               etm: macModes[algs.MAC].etm,
-       }
-       c.macResult = make([]byte, c.mac.Size())
-
-       var err error
-       c.cipher, err = cipherModes[algs.Cipher].createStream(key, iv)
-       if err != nil {
-               return nil, err
-       }
-
-       return c, nil
-}
-
-// generateKeyMaterial fills out with key material generated from tag, K, H
-// and sessionId, as specified in RFC 4253, section 7.2.
-func generateKeyMaterial(out, tag []byte, r *kexResult) {
-       var digestsSoFar []byte
-
-       h := r.Hash.New()
-       for len(out) > 0 {
-               h.Reset()
-               h.Write(r.K)
-               h.Write(r.H)
-
-               if len(digestsSoFar) == 0 {
-                       h.Write(tag)
-                       h.Write(r.SessionID)
-               } else {
-                       h.Write(digestsSoFar)
-               }
-
-               digest := h.Sum(nil)
-               n := copy(out, digest)
-               out = out[n:]
-               if len(out) > 0 {
-                       digestsSoFar = append(digestsSoFar, digest...)
-               }
-       }
-}
-
-const packageVersion = "SSH-2.0-Go"
-
-// Sends and receives a version line.  The versionLine string should
-// be US ASCII, start with "SSH-2.0-", and should not include a
-// newline. exchangeVersions returns the other side's version line.
-func exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) {
-       // Contrary to the RFC, we do not ignore lines that don't
-       // start with "SSH-2.0-" to make the library usable with
-       // nonconforming servers.
-       for _, c := range versionLine {
-               // The spec disallows non US-ASCII chars, and
-               // specifically forbids null chars.
-               if c < 32 {
-                       return nil, errors.New("ssh: junk character in version line")
-               }
-       }
-       if _, err = rw.Write(append(versionLine, '\r', '\n')); err != nil {
-               return
-       }
-
-       them, err = readVersion(rw)
-       return them, err
-}
-
-// maxVersionStringBytes is the maximum number of bytes that we'll
-// accept as a version string. RFC 4253 section 4.2 limits this at 255
-// chars
-const maxVersionStringBytes = 255
-
-// Read version string as specified by RFC 4253, section 4.2.
-func readVersion(r io.Reader) ([]byte, error) {
-       versionString := make([]byte, 0, 64)
-       var ok bool
-       var buf [1]byte
-
-       for len(versionString) < maxVersionStringBytes {
-               _, err := io.ReadFull(r, buf[:])
-               if err != nil {
-                       return nil, err
-               }
-               // The RFC says that the version should be terminated with \r\n
-               // but several SSH servers actually only send a \n.
-               if buf[0] == '\n' {
-                       ok = true
-                       break
-               }
-
-               // non ASCII chars are disallowed, but we are lenient,
-               // since Go doesn't use null-terminated strings.
-
-               // The RFC allows a comment after a space, however,
-               // all of it (version and comments) goes into the
-               // session hash.
-               versionString = append(versionString, buf[0])
-       }
-
-       if !ok {
-               return nil, errors.New("ssh: overflow reading version string")
-       }
-
-       // There might be a '\r' on the end which we should remove.
-       if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' {
-               versionString = versionString[:len(versionString)-1]
-       }
-       return versionString, nil
-}