1
2
3
4
5 package test
6
7 import (
8 "bytes"
9 "fmt"
10 "os"
11 "os/exec"
12 "path/filepath"
13 "runtime"
14 "testing"
15
16 "golang.org/x/crypto/internal/testenv"
17 "golang.org/x/crypto/ssh"
18 "golang.org/x/crypto/ssh/testdata"
19 )
20
21 func sshClient(t *testing.T) string {
22 if testing.Short() {
23 t.Skip("Skipping test that executes OpenSSH in -short mode")
24 }
25 sshCLI := os.Getenv("SSH_CLI_PATH")
26 if sshCLI == "" {
27 sshCLI = "ssh"
28 }
29 var err error
30 sshCLI, err = exec.LookPath(sshCLI)
31 if err != nil {
32 t.Skipf("Can't find an ssh(1) client to test against: %v", err)
33 }
34 return sshCLI
35 }
36
37 func TestSSHCLIAuth(t *testing.T) {
38 if runtime.GOOS == "windows" {
39 t.Skipf("always fails on Windows, see #64403")
40 }
41 sshCLI := sshClient(t)
42 dir := t.TempDir()
43 keyPrivPath := filepath.Join(dir, "rsa")
44
45 for fn, content := range map[string][]byte{
46 keyPrivPath: testdata.PEMBytes["rsa"],
47 keyPrivPath + ".pub": ssh.MarshalAuthorizedKey(testPublicKeys["rsa"]),
48 filepath.Join(dir, "rsa-cert.pub"): testdata.SSHCertificates["rsa-user-testcertificate"],
49 } {
50 if err := os.WriteFile(fn, content, 0600); err != nil {
51 t.Fatalf("WriteFile(%q): %v", fn, err)
52 }
53 }
54
55 certChecker := ssh.CertChecker{
56 IsUserAuthority: func(k ssh.PublicKey) bool {
57 return bytes.Equal(k.Marshal(), testPublicKeys["ca"].Marshal())
58 },
59 UserKeyFallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
60 if conn.User() == "testpubkey" && bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) {
61 return nil, nil
62 }
63
64 return nil, fmt.Errorf("pubkey for %q not acceptable", conn.User())
65 },
66 }
67
68 config := &ssh.ServerConfig{
69 PublicKeyCallback: certChecker.Authenticate,
70 }
71 config.AddHostKey(testSigners["rsa"])
72
73 server, err := newTestServer(config)
74 if err != nil {
75 t.Fatalf("unable to start test server: %v", err)
76 }
77 defer server.Close()
78
79 port, err := server.port()
80 if err != nil {
81 t.Fatalf("unable to get server port: %v", err)
82 }
83
84
85 cmd := testenv.Command(t, sshCLI, "-vvv", "-i", keyPrivPath, "-o", "StrictHostKeyChecking=no",
86 "-p", port, "testpubkey@127.0.0.1", "true")
87 out, err := cmd.CombinedOutput()
88 if err != nil {
89 t.Fatalf("public key authentication failed, error: %v, command output %q", err, string(out))
90 }
91
92
93
94 cmd = testenv.Command(t, sshCLI, "-vvv", "-i", keyPrivPath, "-o", "StrictHostKeyChecking=no",
95 "-p", port, "testcertificate@127.0.0.1", "true")
96 out, err = cmd.CombinedOutput()
97 if err != nil {
98 t.Fatalf("user certificate authentication failed, error: %v, command output %q", err, string(out))
99 }
100 }
101
View as plain text