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
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
+138
-6
@@ -11,6 +11,7 @@ package test
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.crypto/ssh"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -38,12 +39,13 @@ func TestHostKeyCheck(t *testing.T) {
|
||||
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 TestHostKeyCheck(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ func TestFuncLargeRead(t *testing.T) {
|
||||
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 @@ func TestFuncLargeRead(t *testing.T) {
|
||||
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 @@ func TestValidTerminalMode(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-26
@@ -9,39 +9,38 @@ package test
|
||||
// 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()
|
||||
}
|
||||
|
||||
+51
-89
@@ -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 @@ package test
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
@@ -23,13 +22,14 @@ import (
|
||||
"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 @@ PermitRootLogin no
|
||||
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 @@ func username() string {
|
||||
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 @@ func unixConnection() (*net.UnixConn, *net.UnixConn, error) {
|
||||
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 @@ func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.ClientConn, error) {
|
||||
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 @@ func (s *server) Shutdown() {
|
||||
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 @@ func newServer(t *testing.T) *server {
|
||||
}
|
||||
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 @@ func newServer(t *testing.T) *server {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user