ssh: wrap errors from client handshake
When an error is returned by a user defined host key callback, it is now possible to handle it using standard Go mechanisms such as errors.Is or errors.As. Fixes golang/go#61309 Change-Id: I4269c5f8eacd8e7e8d85070ad249f0e27777b15f GitHub-Last-Rev: d2a34d5c8225d6aaaee287ce3ea8b218fbe210d4 GitHub-Pull-Request: golang/crypto#266 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/508876 Run-TryBot: Nicola Murino <nicola.murino@gmail.com> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Muhammad Shulhan <m.shulhan@gmail.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Nicola Murino <nicola.murino@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
committed by
Gopher Robot
parent
bda2f3f5cf
commit
7e6fbd82c8
+1
-1
@@ -82,7 +82,7 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan
|
|||||||
|
|
||||||
if err := conn.clientHandshake(addr, &fullConf); err != nil {
|
if err := conn.clientHandshake(addr, &fullConf); err != nil {
|
||||||
c.Close()
|
c.Close()
|
||||||
return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err)
|
return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %w", err)
|
||||||
}
|
}
|
||||||
conn.mux = newMux(conn.transport)
|
conn.mux = newMux(conn.transport)
|
||||||
return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
|
return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
|
||||||
|
|||||||
+23
-2
@@ -7,6 +7,9 @@ package ssh
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -207,9 +210,12 @@ func TestBannerCallback(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewClientConn(t *testing.T) {
|
func TestNewClientConn(t *testing.T) {
|
||||||
|
errHostKeyMismatch := errors.New("host key mismatch")
|
||||||
|
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
name string
|
||||||
user string
|
user string
|
||||||
|
simulateHostKeyMismatch HostKeyCallback
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "good user field for ConnMetadata",
|
name: "good user field for ConnMetadata",
|
||||||
@@ -219,6 +225,13 @@ func TestNewClientConn(t *testing.T) {
|
|||||||
name: "empty user field for ConnMetadata",
|
name: "empty user field for ConnMetadata",
|
||||||
user: "",
|
user: "",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "host key mismatch",
|
||||||
|
user: "testuser",
|
||||||
|
simulateHostKeyMismatch: func(hostname string, remote net.Addr, key PublicKey) error {
|
||||||
|
return fmt.Errorf("%w: %s", errHostKeyMismatch, bytes.TrimSpace(MarshalAuthorizedKey(key)))
|
||||||
|
},
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
c1, c2, err := netPipe()
|
c1, c2, err := netPipe()
|
||||||
@@ -243,8 +256,16 @@ func TestNewClientConn(t *testing.T) {
|
|||||||
},
|
},
|
||||||
HostKeyCallback: InsecureIgnoreHostKey(),
|
HostKeyCallback: InsecureIgnoreHostKey(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tt.simulateHostKeyMismatch != nil {
|
||||||
|
clientConf.HostKeyCallback = tt.simulateHostKeyMismatch
|
||||||
|
}
|
||||||
|
|
||||||
clientConn, _, _, err := NewClientConn(c2, "", clientConf)
|
clientConn, _, _, err := NewClientConn(c2, "", clientConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if tt.simulateHostKeyMismatch != nil && errors.Is(err, errHostKeyMismatch) {
|
||||||
|
return
|
||||||
|
}
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user