diff --git a/ssh/agent/client_test.go b/ssh/agent/client_test.go index 2ca92a48e1..80c8bde58b 100644 --- a/ssh/agent/client_test.go +++ b/ssh/agent/client_test.go @@ -330,9 +330,11 @@ func TestServerResponseTooLarge(t *testing.T) { n, err := b.Write(ssh.Marshal(response)) if n < 4 { if runtime.GOOS == "plan9" { - if e1, ok := err.(*net.OpError); ok { - if e2, ok := e1.Err.(*os.PathError); ok { - switch e2.Err.Error() { + var opErr *net.OpError + if errors.As(err, &opErr) { + var pathErr *os.PathError + if errors.As(opErr.Err, &pathErr) { + switch pathErr.Err.Error() { case "Hangup", "i/o on hungup channel": // syscall.Pwrite returns -1 in this case even when some data did get written. return diff --git a/ssh/cipher.go b/ssh/cipher.go index ad2b370578..56a721a586 100644 --- a/ssh/cipher.go +++ b/ssh/cipher.go @@ -494,7 +494,8 @@ func (e cbcError) Error() string { return string(e) } func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) { p, err := c.readCipherPacketLeaky(seqNum, r) if err != nil { - if _, ok := err.(cbcError); ok { + var cbcErr cbcError + if errors.As(err, &cbcErr) { // Verification error: read a fixed amount of // data, to make distinguishing between // failing MAC and failing length check more diff --git a/ssh/client_auth.go b/ssh/client_auth.go index 4f2f75c367..ea49e00aef 100644 --- a/ssh/client_auth.go +++ b/ssh/client_auth.go @@ -73,7 +73,8 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions) if err != nil { // On disconnect, return error immediately - if _, ok := err.(*disconnectMsg); ok { + var disc *disconnectMsg + if errors.As(err, &disc) { return err } // We return the error later if there is no other method left to diff --git a/ssh/keys.go b/ssh/keys.go index 47a07539d9..0ae496096a 100644 --- a/ssh/keys.go +++ b/ssh/keys.go @@ -1342,7 +1342,7 @@ func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, // detect an incorrect password. In these cases decrypted DER bytes is // random noise. If the parsing of the key returns an asn1.StructuralError // we return x509.IncorrectPasswordError. - if _, ok := err.(asn1.StructuralError); ok { + if errors.As(err, &asn1.StructuralError{}) { return nil, x509.IncorrectPasswordError } @@ -1548,12 +1548,13 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv privKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock) if err != nil { - if err, ok := err.(*PassphraseMissingError); ok { + var pmErr *PassphraseMissingError + if errors.As(err, &pmErr) { pub, errPub := ParsePublicKey(w.PubKey) if errPub != nil { return nil, fmt.Errorf("ssh: failed to parse embedded public key: %v", errPub) } - err.PublicKey = pub + pmErr.PublicKey = pub } return nil, err } diff --git a/ssh/server.go b/ssh/server.go index 064dcbaf5a..0af72b30f1 100644 --- a/ssh/server.go +++ b/ssh/server.go @@ -670,7 +670,8 @@ userAuthLoop: candidate.user = s.user candidate.pubKeyData = pubKeyData candidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey) - _, isPartialSuccessError := candidate.result.(*PartialSuccessError) + var partialSuccessErr *PartialSuccessError + isPartialSuccessError := errors.As(candidate.result, &partialSuccessErr) if isPartialSuccessError && config.VerifiedPublicKeyCallback != nil { return nil, errors.New("ssh: invalid library usage: PublicKeyCallback must not return partial success when VerifiedPublicKeyCallback is defined") } @@ -695,7 +696,8 @@ userAuthLoop: if len(payload) > 0 { return nil, parseError(msgUserAuthRequest) } - _, isPartialSuccessError := candidate.result.(*PartialSuccessError) + var partialSuccessErr *PartialSuccessError + isPartialSuccessError := errors.As(candidate.result, &partialSuccessErr) if candidate.result == nil || isPartialSuccessError { okMsg := userAuthPubKeyOkMsg{ Algo: algo, @@ -823,7 +825,8 @@ userAuthLoop: var failureMsg userAuthFailureMsg - if partialSuccess, ok := authErr.(*PartialSuccessError); ok { + var partialSuccess *PartialSuccessError + if errors.As(authErr, &partialSuccess) { // After a partial success error we don't allow changing the user // name and execute the NoClientAuthCallback. partialSuccessReturned = true