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 (
	
	
	
	
	
	

	_ 
	_ 
	_ 
)
These are string constants in the SSH protocol.
const (
	compressionNone = "none"
	serviceUserAuth = "ssh-userauth"
	serviceSSH      = "ssh-connection"
)
supportedCiphers lists ciphers we support but might not recommend.
var supportedCiphers = []string{
	"aes128-ctr", "aes192-ctr", "aes256-ctr",
	"aes128-gcm@openssh.com",
	chacha20Poly1305ID,
	"arcfour256", "arcfour128", "arcfour",
	aes128cbcID,
	tripledescbcID,
}
preferredCiphers specifies the default preference for ciphers.
var preferredCiphers = []string{
	"aes128-gcm@openssh.com",
	chacha20Poly1305ID,
	"aes128-ctr", "aes192-ctr", "aes256-ctr",
}
supportedKexAlgos specifies the supported key-exchange algorithms in preference order.
P384 and P521 are not constant-time yet, but since we don't reuse ephemeral keys, using them for ECDH should be OK.
serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden for the server half.
var serverForbiddenKexAlgos = map[string]struct{}{
	kexAlgoDHGEXSHA1:   {}, // server half implementation is only minimal to satisfy the automated tests
	kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests
}
preferredKexAlgos specifies the default preference for key-exchange algorithms in preference order.
supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods of authenticating servers) in preference order.
supportedMACs specifies a default set of MAC algorithms in preference order. This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed because they have reached the end of their useful life.
var supportedMACs = []string{
	"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96",
}

var supportedCompressions = []string{compressionNone}
unexpectedMessageError results when the SSH message that we received didn't match what we wanted.
func (,  uint8) error {
	return fmt.Errorf("ssh: unexpected message type %d (expected %d)", , )
}
parseError results from a malformed SSH message.
func ( uint8) error {
	return fmt.Errorf("ssh: parse error in message type %d", )
}

func ( string,  []string,  []string) ( string,  error) {
	for ,  := range  {
		for ,  := range  {
			if  ==  {
				return , nil
			}
		}
	}
	return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", , , )
}
directionAlgorithms records algorithm choices in one direction (either read or write)
rekeyBytes returns a rekeying intervals in bytes.
According to RFC4344 block ciphers should rekey after 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is 128.
	switch .Cipher {
	case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcmCipherID, aes128cbcID:
		return 16 * (1 << 32)

	}
For others, stick with RFC4253 recommendation to rekey after 1 Gb of data.
	return 1 << 30
}

type algorithms struct {
	kex     string
	hostKey string
	w       directionAlgorithms
	r       directionAlgorithms
}

func ( bool, ,  *kexInitMsg) ( *algorithms,  error) {
	 := &algorithms{}

	.kex,  = findCommon("key exchange", .KexAlgos, .KexAlgos)
	if  != nil {
		return
	}

	.hostKey,  = findCommon("host key", .ServerHostKeyAlgos, .ServerHostKeyAlgos)
	if  != nil {
		return
	}

	,  := &.w, &.r
	if  {
		,  = , 
	}

	.Cipher,  = findCommon("client to server cipher", .CiphersClientServer, .CiphersClientServer)
	if  != nil {
		return
	}

	.Cipher,  = findCommon("server to client cipher", .CiphersServerClient, .CiphersServerClient)
	if  != nil {
		return
	}

	.MAC,  = findCommon("client to server MAC", .MACsClientServer, .MACsClientServer)
	if  != nil {
		return
	}

	.MAC,  = findCommon("server to client MAC", .MACsServerClient, .MACsServerClient)
	if  != nil {
		return
	}

	.Compression,  = findCommon("client to server compression", .CompressionClientServer, .CompressionClientServer)
	if  != nil {
		return
	}

	.Compression,  = findCommon("server to client compression", .CompressionServerClient, .CompressionServerClient)
	if  != nil {
		return
	}

	return , nil
}
If rekeythreshold is too small, we can't make any progress sending stuff.
Config contains configuration data common to both ServerConfig and ClientConfig.
Rand provides the source of entropy for cryptographic primitives. If Rand is nil, the cryptographic random reader in package crypto/rand will be used.
The maximum number of bytes sent or received after which a new key is negotiated. It must be at least 256. If unspecified, a size suitable for the chosen cipher is used.
The allowed key exchanges algorithms. If unspecified then a default set of algorithms is used.
The allowed cipher algorithms. If unspecified then a sensible default is used.
The allowed MAC algorithms. If unspecified then a sensible default is used.
	MACs []string
}
SetDefaults sets sensible values for unset fields in config. This is exported for testing: Configs passed to SSH functions are copied and have default values set automatically.
func ( *Config) () {
	if .Rand == nil {
		.Rand = rand.Reader
	}
	if .Ciphers == nil {
		.Ciphers = preferredCiphers
	}
	var  []string
	for ,  := range .Ciphers {
reject the cipher if we have no cipherModes definition
			 = append(, )
		}
	}
	.Ciphers = 

	if .KeyExchanges == nil {
		.KeyExchanges = preferredKexAlgos
	}

	if .MACs == nil {
		.MACs = supportedMACs
	}

cipher specific default
Avoid weirdness if somebody uses -1 as a threshold.
buildDataSignedForAuth returns the data that is signed in order to prove possession of a private key. See RFC 4252, section 7.
func ( []byte,  userAuthRequestMsg, ,  []byte) []byte {
	 := struct {
		 []byte
		    byte
		    string
		 string
		  string
		    bool
		    []byte
		  []byte
	}{
		,
		msgUserAuthRequest,
		.User,
		.Service,
		.Method,
		true,
		,
		,
	}
	return Marshal()
}

func ( []byte,  uint16) []byte {
	return append(, byte(>>8), byte())
}

func ( []byte,  uint32) []byte {
	return append(, byte(>>24), byte(>>16), byte(>>8), byte())
}

func ( []byte,  uint64) []byte {
	return append(,
		byte(>>56), byte(>>48), byte(>>40), byte(>>32),
		byte(>>24), byte(>>16), byte(>>8), byte())
}

func ( []byte,  int) []byte {
	return appendU32(, uint32())
}

func ( []byte,  string) []byte {
	 = appendU32(, uint32(len()))
	 = append(, ...)
	return 
}

func ( []byte,  bool) []byte {
	if  {
		return append(, 1)
	}
	return append(, 0)
}
newCond is a helper to hide the fact that there is no usable zero value for sync.Cond.
func () *sync.Cond { return sync.NewCond(new(sync.Mutex)) }
window represents the buffer available to clients wishing to write to a channel.
type window struct {
	*sync.Cond
	win          uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1
	writeWaiters int
	closed       bool
}
add adds win to the amount of window available for consumers.
a zero sized window adjust is a noop.
	if  == 0 {
		return true
	}
	.L.Lock()
	if .win+ <  {
		.L.Unlock()
		return false
	}
It is unusual that multiple goroutines would be attempting to reserve window space, but not guaranteed. Use broadcast to notify all waiters that additional window is available.
	.Broadcast()
	.L.Unlock()
	return true
}
close sets the window to closed, so all reservations fail immediately.
func ( *window) () {
	.L.Lock()
	.closed = true
	.Broadcast()
	.L.Unlock()
}
reserve reserves win from the available window capacity. If no capacity remains, reserve will block. reserve may return less than requested.
func ( *window) ( uint32) (uint32, error) {
	var  error
	.L.Lock()
	.writeWaiters++
	.Broadcast()
	for .win == 0 && !.closed {
		.Wait()
	}
	.writeWaiters--
	if .win <  {
		 = .win
	}
	.win -= 
	if .closed {
		 = io.EOF
	}
	.L.Unlock()
	return , 
}
waitWriterBlocked waits until some goroutine is blocked for further writes. It is used in tests only.
func ( *window) () {
	.Cond.L.Lock()
	for .writeWaiters == 0 {
		.Cond.Wait()
	}
	.Cond.L.Unlock()