diff --git a/ssh/client_auth.go b/ssh/client_auth.go index 5b7aa30..c41e163 100644 --- a/ssh/client_auth.go +++ b/ssh/client_auth.go @@ -41,15 +41,17 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { tried[auth.method()] = true auth = nil + + findNext: for _, a := range config.Auth { candidateMethod := a.method() + if tried[candidateMethod] { + continue + } for _, meth := range methods { - if meth != candidateMethod { - continue - } - if !tried[meth] { + if meth == candidateMethod { auth = a - break + break findNext } } } diff --git a/ssh/client_auth_test.go b/ssh/client_auth_test.go index 3173255..e6b979f 100644 --- a/ssh/client_auth_test.go +++ b/ssh/client_auth_test.go @@ -111,6 +111,29 @@ func TestAuthMethodPassword(t *testing.T) { } } +func TestAuthMethodFallback(t *testing.T) { + var passwordCalled bool + config := &ClientConfig{ + User: "testuser", + Auth: []AuthMethod{ + PublicKeys(testSigners["rsa"]), + PasswordCallback( + func() (string, error) { + passwordCalled = true + return "WRONG", nil + }), + }, + } + + if err := tryAuth(t, config); err != nil { + t.Fatalf("unable to dial remote side: %s", err) + } + + if passwordCalled { + t.Errorf("password auth tried before public-key auth.") + } +} + func TestAuthMethodWrongPassword(t *testing.T) { config := &ClientConfig{ User: "testuser",