go.crypto/ssh: import gosshnew.

See https://groups.google.com/d/msg/Golang-nuts/AoVxQ4bB5XQ/i8kpMxdbVlEJ

R=hanwen
CC=golang-codereviews
https://golang.org/cl/86190043
diff --git a/ssh/test/agent_unix_test.go b/ssh/test/agent_unix_test.go
new file mode 100644
index 0000000..26c88eb
--- /dev/null
+++ b/ssh/test/agent_unix_test.go
@@ -0,0 +1,50 @@
+// Copyright 2014 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.
+
+// +build darwin freebsd linux netbsd openbsd
+
+package test
+
+import (
+	"bytes"
+	"testing"
+
+	"code.google.com/p/go.crypto/ssh"
+	"code.google.com/p/go.crypto/ssh/agent"
+)
+
+func TestAgentForward(t *testing.T) {
+	server := newServer(t)
+	defer server.Shutdown()
+	conn := server.Dial(clientConfig())
+	defer conn.Close()
+
+	keyring := agent.NewKeyring()
+	keyring.Add(testPrivateKeys["dsa"], nil, "")
+	pub := testPublicKeys["dsa"]
+
+	sess, err := conn.NewSession()
+	if err != nil {
+		t.Fatalf("NewSession: %v", err)
+	}
+	if err := agent.RequestAgentForwarding(sess); err != nil {
+		t.Fatalf("RequestAgentForwarding: %v", err)
+	}
+
+	if err := agent.ForwardToAgent(conn, keyring); err != nil {
+		t.Fatalf("SetupForwardKeyring: %v", err)
+	}
+	out, err := sess.CombinedOutput("ssh-add -L")
+	if err != nil {
+		t.Fatalf("running ssh-add: %v, out %s", err, out)
+	}
+	key, _, _, _, err := ssh.ParseAuthorizedKey(out)
+	if err != nil {
+		t.Fatalf("ParseAuthorizedKey(%q): %v", out, err)
+	}
+
+	if !bytes.Equal(key.Marshal(), pub.Marshal()) {
+		t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub))
+	}
+}
diff --git a/ssh/test/cert_test.go b/ssh/test/cert_test.go
new file mode 100644
index 0000000..d4f7226
--- /dev/null
+++ b/ssh/test/cert_test.go
@@ -0,0 +1,47 @@
+// Copyright 2014 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.
+
+// +build darwin freebsd linux netbsd openbsd
+
+package test
+
+import (
+	"crypto/rand"
+	"testing"
+
+	"code.google.com/p/go.crypto/ssh"
+)
+
+func TestCertLogin(t *testing.T) {
+	s := newServer(t)
+	defer s.Shutdown()
+
+	// Use a key different from the default.
+	clientKey := testSigners["dsa"]
+	caAuthKey := testSigners["ecdsa"]
+	cert := &ssh.Certificate{
+		Key:             clientKey.PublicKey(),
+		ValidPrincipals: []string{username()},
+		CertType:        ssh.UserCert,
+		ValidBefore:     ssh.CertTimeInfinity,
+	}
+	if err := cert.SignCert(rand.Reader, caAuthKey); err != nil {
+		t.Fatalf("SetSignature: %v", err)
+	}
+
+	certSigner, err := ssh.NewCertSigner(cert, clientKey)
+	if err != nil {
+		t.Fatalf("NewCertSigner: %v", err)
+	}
+
+	conf := &ssh.ClientConfig{
+		User: username(),
+	}
+	conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner))
+	client, err := s.TryDial(conf)
+	if err != nil {
+		t.Fatalf("TryDial: %v", err)
+	}
+	client.Close()
+}
diff --git a/ssh/test/forward_unix_test.go b/ssh/test/forward_unix_test.go
index 3a57c10..881a9da 100644
--- a/ssh/test/forward_unix_test.go
+++ b/ssh/test/forward_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin freebsd linux netbsd openbsd plan9
+// +build darwin freebsd linux netbsd openbsd
 
 package test
 
diff --git a/ssh/test/session_test.go b/ssh/test/session_test.go
index bd7307d..d8d35a5 100644
--- a/ssh/test/session_test.go
+++ b/ssh/test/session_test.go
@@ -11,6 +11,7 @@
 import (
 	"bytes"
 	"code.google.com/p/go.crypto/ssh"
+	"errors"
 	"io"
 	"strings"
 	"testing"
@@ -38,12 +39,13 @@
 	defer server.Shutdown()
 
 	conf := clientConfig()
-	k := conf.HostKeyChecker.(*storedHostKey)
+	hostDB := hostKeyDB()
+	conf.HostKeyCallback = hostDB.Check
 
 	// change the keys.
-	k.keys[ssh.KeyAlgoRSA][25]++
-	k.keys[ssh.KeyAlgoDSA][25]++
-	k.keys[ssh.KeyAlgoECDSA256][25]++
+	hostDB.keys[ssh.KeyAlgoRSA][25]++
+	hostDB.keys[ssh.KeyAlgoDSA][25]++
+	hostDB.keys[ssh.KeyAlgoECDSA256][25]++
 
 	conn, err := server.TryDial(conf)
 	if err == nil {
@@ -54,6 +56,53 @@
 	}
 }
 
+func TestRunCommandStdin(t *testing.T) {
+	server := newServer(t)
+	defer server.Shutdown()
+	conn := server.Dial(clientConfig())
+	defer conn.Close()
+
+	session, err := conn.NewSession()
+	if err != nil {
+		t.Fatalf("session failed: %v", err)
+	}
+	defer session.Close()
+
+	r, w := io.Pipe()
+	defer r.Close()
+	defer w.Close()
+	session.Stdin = r
+
+	err = session.Run("true")
+	if err != nil {
+		t.Fatalf("session failed: %v", err)
+	}
+}
+
+func TestRunCommandStdinError(t *testing.T) {
+	server := newServer(t)
+	defer server.Shutdown()
+	conn := server.Dial(clientConfig())
+	defer conn.Close()
+
+	session, err := conn.NewSession()
+	if err != nil {
+		t.Fatalf("session failed: %v", err)
+	}
+	defer session.Close()
+
+	r, w := io.Pipe()
+	defer r.Close()
+	session.Stdin = r
+	pipeErr := errors.New("closing write end of pipe")
+	w.CloseWithError(pipeErr)
+
+	err = session.Run("true")
+	if err != pipeErr {
+		t.Fatalf("expected %v, found %v", pipeErr, err)
+	}
+}
+
 func TestRunCommandFailed(t *testing.T) {
 	server := newServer(t)
 	defer server.Shutdown()
@@ -107,7 +156,7 @@
 		t.Fatalf("unable to acquire stdout pipe: %s", err)
 	}
 
-	err = session.Start("dd if=/dev/urandom bs=2048 count=1")
+	err = session.Start("dd if=/dev/urandom bs=2048 count=1024")
 	if err != nil {
 		t.Fatalf("unable to execute remote command: %s", err)
 	}
@@ -118,11 +167,53 @@
 		t.Fatalf("error reading from remote stdout: %s", err)
 	}
 
-	if n != 2048 {
+	if n != 2048*1024 {
 		t.Fatalf("Expected %d bytes but read only %d from remote command", 2048, n)
 	}
 }
 
+func TestKeyChange(t *testing.T) {
+	server := newServer(t)
+	defer server.Shutdown()
+	conf := clientConfig()
+	hostDB := hostKeyDB()
+	conf.HostKeyCallback = hostDB.Check
+	conf.RekeyThreshold = 1024
+	conn := server.Dial(conf)
+	defer conn.Close()
+
+	for i := 0; i < 4; i++ {
+		session, err := conn.NewSession()
+		if err != nil {
+			t.Fatalf("unable to create new session: %s", err)
+		}
+
+		stdout, err := session.StdoutPipe()
+		if err != nil {
+			t.Fatalf("unable to acquire stdout pipe: %s", err)
+		}
+
+		err = session.Start("dd if=/dev/urandom bs=1024 count=1")
+		if err != nil {
+			t.Fatalf("unable to execute remote command: %s", err)
+		}
+		buf := new(bytes.Buffer)
+		n, err := io.Copy(buf, stdout)
+		if err != nil {
+			t.Fatalf("error reading from remote stdout: %s", err)
+		}
+
+		want := int64(1024)
+		if n != want {
+			t.Fatalf("Expected %d bytes but read only %d from remote command", want, n)
+		}
+	}
+
+	if changes := hostDB.checkCount; changes < 4 {
+		t.Errorf("got %d key changes, want 4", changes)
+	}
+}
+
 func TestInvalidTerminalMode(t *testing.T) {
 	server := newServer(t)
 	defer server.Shutdown()
@@ -183,3 +274,44 @@
 		t.Fatalf("terminal mode failure: expected -echo in stty output, got %s", sttyOutput)
 	}
 }
+
+func TestCiphers(t *testing.T) {
+	var config ssh.Config
+	config.SetDefaults()
+	cipherOrder := config.Ciphers
+
+	for _, ciph := range cipherOrder {
+		server := newServer(t)
+		defer server.Shutdown()
+		conf := clientConfig()
+		conf.Ciphers = []string{ciph}
+		// Don't fail if sshd doesnt have the cipher.
+		conf.Ciphers = append(conf.Ciphers, cipherOrder...)
+		conn, err := server.TryDial(conf)
+		if err == nil {
+			conn.Close()
+		} else {
+			t.Fatalf("failed for cipher %q", ciph)
+		}
+	}
+}
+
+func TestMACs(t *testing.T) {
+	var config ssh.Config
+	config.SetDefaults()
+	macOrder := config.MACs
+
+	for _, mac := range macOrder {
+		server := newServer(t)
+		defer server.Shutdown()
+		conf := clientConfig()
+		conf.MACs = []string{mac}
+		// Don't fail if sshd doesnt have the MAC.
+		conf.MACs = append(conf.MACs, macOrder...)
+		if conn, err := server.TryDial(conf); err == nil {
+			conn.Close()
+		} else {
+			t.Fatalf("failed for MAC %q", mac)
+		}
+	}
+}
diff --git a/ssh/test/tcpip_test.go b/ssh/test/tcpip_test.go
index ee06b60..a2eb935 100644
--- a/ssh/test/tcpip_test.go
+++ b/ssh/test/tcpip_test.go
@@ -9,39 +9,38 @@
 // direct-tcpip functional tests
 
 import (
+	"io"
 	"net"
-	"net/http"
 	"testing"
 )
 
-func TestTCPIPHTTP(t *testing.T) {
-	// google.com will generate at least one redirect, possibly three
-	// depending on your location.
-	doTest(t, "http://google.com")
-}
-
-func TestTCPIPHTTPS(t *testing.T) {
-	doTest(t, "https://encrypted.google.com/")
-}
-
-func doTest(t *testing.T, url string) {
+func TestDial(t *testing.T) {
 	server := newServer(t)
 	defer server.Shutdown()
-	conn := server.Dial(clientConfig())
-	defer conn.Close()
+	sshConn := server.Dial(clientConfig())
+	defer sshConn.Close()
 
-	tr := &http.Transport{
-		Dial: func(n, addr string) (net.Conn, error) {
-			return conn.Dial(n, addr)
-		},
-	}
-	client := &http.Client{
-		Transport: tr,
-	}
-	resp, err := client.Get(url)
+	l, err := net.Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("unable to proxy: %s", err)
+		t.Fatalf("Listen: %v", err)
 	}
-	// got a body without error
-	t.Log(resp)
+	defer l.Close()
+
+	go func() {
+		for {
+			c, err := l.Accept()
+			if err != nil {
+				break
+			}
+
+			io.WriteString(c, c.RemoteAddr().String())
+			c.Close()
+		}
+	}()
+
+	conn, err := sshConn.Dial("tcp", l.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	defer conn.Close()
 }
diff --git a/ssh/test/test_unix_test.go b/ssh/test/test_unix_test.go
index 86df3f4..f44c65d 100644
--- a/ssh/test/test_unix_test.go
+++ b/ssh/test/test_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin freebsd linux netbsd openbsd plan9
+// +build darwin freebsd linux netbsd openbsd
 
 package test
 
@@ -11,7 +11,6 @@
 import (
 	"bytes"
 	"fmt"
-	"io"
 	"io/ioutil"
 	"log"
 	"net"
@@ -23,13 +22,14 @@
 	"text/template"
 
 	"code.google.com/p/go.crypto/ssh"
+	"code.google.com/p/go.crypto/ssh/testdata"
 )
 
 const sshd_config = `
 Protocol 2
-HostKey {{.Dir}}/ssh_host_rsa_key
-HostKey {{.Dir}}/ssh_host_dsa_key
-HostKey {{.Dir}}/ssh_host_ecdsa_key
+HostKey {{.Dir}}/id_rsa
+HostKey {{.Dir}}/id_dsa
+HostKey {{.Dir}}/id_ecdsa
 Pidfile {{.Dir}}/sshd.pid
 #UsePrivilegeSeparation no
 KeyRegenerationInterval 3600
@@ -41,41 +41,14 @@
 StrictModes no
 RSAAuthentication yes
 PubkeyAuthentication yes
-AuthorizedKeysFile	{{.Dir}}/authorized_keys
+AuthorizedKeysFile	{{.Dir}}/id_user.pub
+TrustedUserCAKeys {{.Dir}}/id_ecdsa.pub
 IgnoreRhosts yes
 RhostsRSAAuthentication no
 HostbasedAuthentication no
 `
 
-var (
-	configTmpl   template.Template
-	privateKey   ssh.Signer
-	hostKeyRSA   ssh.Signer
-	hostKeyECDSA ssh.Signer
-	hostKeyDSA   ssh.Signer
-)
-
-func init() {
-	template.Must(configTmpl.Parse(sshd_config))
-
-	for n, k := range map[string]*ssh.Signer{
-		"ssh_host_ecdsa_key": &hostKeyECDSA,
-		"ssh_host_rsa_key":   &hostKeyRSA,
-		"ssh_host_dsa_key":   &hostKeyDSA,
-	} {
-		var err error
-		*k, err = ssh.ParsePrivateKey([]byte(keys[n]))
-		if err != nil {
-			panic(fmt.Sprintf("ParsePrivateKey(%q): %v", n, err))
-		}
-	}
-
-	var err error
-	privateKey, err = ssh.ParsePrivateKey([]byte(testClientPrivateKey))
-	if err != nil {
-		panic(fmt.Sprintf("ParsePrivateKey: %v", err))
-	}
-}
+var configTmpl = template.Must(template.New("").Parse(sshd_config))
 
 type server struct {
 	t          *testing.T
@@ -107,36 +80,44 @@
 type storedHostKey struct {
 	// keys map from an algorithm string to binary key data.
 	keys map[string][]byte
+
+	// checkCount counts the Check calls. Used for testing
+	// rekeying.
+	checkCount int
 }
 
 func (k *storedHostKey) Add(key ssh.PublicKey) {
 	if k.keys == nil {
 		k.keys = map[string][]byte{}
 	}
-	k.keys[key.PublicKeyAlgo()] = ssh.MarshalPublicKey(key)
+	k.keys[key.Type()] = key.Marshal()
 }
 
-func (k *storedHostKey) Check(addr string, remote net.Addr, algo string, key []byte) error {
-	if k.keys == nil || bytes.Compare(key, k.keys[algo]) != 0 {
+func (k *storedHostKey) Check(addr string, remote net.Addr, key ssh.PublicKey) error {
+	k.checkCount++
+	algo := key.Type()
+
+	if k.keys == nil || bytes.Compare(key.Marshal(), k.keys[algo]) != 0 {
 		return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo])
 	}
 	return nil
 }
 
-func clientConfig() *ssh.ClientConfig {
-	keyChecker := storedHostKey{}
-	keyChecker.Add(hostKeyECDSA.PublicKey())
-	keyChecker.Add(hostKeyRSA.PublicKey())
-	keyChecker.Add(hostKeyDSA.PublicKey())
+func hostKeyDB() *storedHostKey {
+	keyChecker := &storedHostKey{}
+	keyChecker.Add(testPublicKeys["ecdsa"])
+	keyChecker.Add(testPublicKeys["rsa"])
+	keyChecker.Add(testPublicKeys["dsa"])
+	return keyChecker
+}
 
-	kc := new(keychain)
-	kc.keys = append(kc.keys, privateKey)
+func clientConfig() *ssh.ClientConfig {
 	config := &ssh.ClientConfig{
 		User: username(),
-		Auth: []ssh.ClientAuth{
-			ssh.ClientAuthKeyring(kc),
+		Auth: []ssh.AuthMethod{
+			ssh.PublicKeys(testSigners["user"]),
 		},
-		HostKeyChecker: &keyChecker,
+		HostKeyCallback: hostKeyDB().Check,
 	}
 	return config
 }
@@ -171,7 +152,7 @@
 	return c1.(*net.UnixConn), c2.(*net.UnixConn), nil
 }
 
-func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.ClientConn, error) {
+func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) {
 	sshd, err := exec.LookPath("sshd")
 	if err != nil {
 		s.t.Skipf("skipping test: %v", err)
@@ -197,10 +178,14 @@
 		s.t.Fatalf("s.cmd.Start: %v", err)
 	}
 	s.clientConn = c1
-	return ssh.Client(c1, config)
+	conn, chans, reqs, err := ssh.NewClientConn(c1, "", config)
+	if err != nil {
+		return nil, err
+	}
+	return ssh.NewClient(conn, chans, reqs), nil
 }
 
-func (s *server) Dial(config *ssh.ClientConfig) *ssh.ClientConn {
+func (s *server) Dial(config *ssh.ClientConfig) *ssh.Client {
 	conn, err := s.TryDial(config)
 	if err != nil {
 		s.t.Fail()
@@ -226,6 +211,17 @@
 	s.cleanup()
 }
 
+func writeFile(path string, contents []byte) {
+	f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600)
+	if err != nil {
+		panic(err)
+	}
+	defer f.Close()
+	if _, err := f.Write(contents); err != nil {
+		panic(err)
+	}
+}
+
 // newServer returns a new mock ssh server.
 func newServer(t *testing.T) *server {
 	dir, err := ioutil.TempDir("", "sshtest")
@@ -244,15 +240,10 @@
 	}
 	f.Close()
 
-	for k, v := range keys {
-		f, err := os.OpenFile(filepath.Join(dir, k), os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if _, err := f.Write([]byte(v)); err != nil {
-			t.Fatal(err)
-		}
-		f.Close()
+	for k, v := range testdata.PEMBytes {
+		filename := "id_" + k
+		writeFile(filepath.Join(dir, filename), v)
+		writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k]))
 	}
 
 	return &server{
@@ -265,32 +256,3 @@
 		},
 	}
 }
-
-// keychain implements the ClientKeyring interface.
-type keychain struct {
-	keys []ssh.Signer
-}
-
-func (k *keychain) Key(i int) (ssh.PublicKey, error) {
-	if i < 0 || i >= len(k.keys) {
-		return nil, nil
-	}
-	return k.keys[i].PublicKey(), nil
-}
-
-func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
-	return k.keys[i].Sign(rand, data)
-}
-
-func (k *keychain) loadPEM(file string) error {
-	buf, err := ioutil.ReadFile(file)
-	if err != nil {
-		return err
-	}
-	key, err := ssh.ParsePrivateKey(buf)
-	if err != nil {
-		return err
-	}
-	k.keys = append(k.keys, key)
-	return nil
-}
diff --git a/ssh/test/testdata_test.go b/ssh/test/testdata_test.go
new file mode 100644
index 0000000..7f50fbe
--- /dev/null
+++ b/ssh/test/testdata_test.go
@@ -0,0 +1,64 @@
+// Copyright 2014 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.
+
+// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places:
+// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three
+// instances.
+
+package test
+
+import (
+	"crypto/rand"
+	"fmt"
+
+	"code.google.com/p/go.crypto/ssh"
+	"code.google.com/p/go.crypto/ssh/testdata"
+)
+
+var (
+	testPrivateKeys map[string]interface{}
+	testSigners     map[string]ssh.Signer
+	testPublicKeys  map[string]ssh.PublicKey
+)
+
+func init() {
+	var err error
+
+	n := len(testdata.PEMBytes)
+	testPrivateKeys = make(map[string]interface{}, n)
+	testSigners = make(map[string]ssh.Signer, n)
+	testPublicKeys = make(map[string]ssh.PublicKey, n)
+	for t, k := range testdata.PEMBytes {
+		testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k)
+		if err != nil {
+			panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err))
+		}
+		testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t])
+		if err != nil {
+			panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err))
+		}
+		testPublicKeys[t] = testSigners[t].PublicKey()
+	}
+
+	// Create a cert and sign it for use in tests.
+	testCert := &ssh.Certificate{
+		Nonce:           []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
+		ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage
+		ValidAfter:      0,                              // unix epoch
+		ValidBefore:     ssh.CertTimeInfinity,           // The end of currently representable time.
+		Reserved:        []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
+		Key:             testPublicKeys["ecdsa"],
+		SignatureKey:    testPublicKeys["rsa"],
+		Permissions: ssh.Permissions{
+			CriticalOptions: map[string]string{},
+			Extensions:      map[string]string{},
+		},
+	}
+	testCert.SignCert(rand.Reader, testSigners["rsa"])
+	testPrivateKeys["cert"] = testPrivateKeys["ecdsa"]
+	testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"])
+	if err != nil {
+		panic(fmt.Sprintf("Unable to create certificate signer: %v", err))
+	}
+}