From 75b288015ac94e66e3d6715fb68a9b41bf046ec2 Mon Sep 17 00:00:00 2001 From: Julian Kornberger Date: Mon, 22 Jun 2020 20:02:02 +0000 Subject: [PATCH] ssh: Make error message deterministic By using a slice instead of a map for tried authentication methods the order is always the same. Small slices are also faster than maps. Before the change sometimes I get the error: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain and sometimes: ssh: handshake failed: ssh: unable to authenticate, attempted methods [publickey none], no supported methods remain Change-Id: I06507d57e9eef497ff05bce088d52607e69dde3e GitHub-Last-Rev: 3a46aae4c6e3e5f52ca4b04384b3cc4efc039aa6 GitHub-Pull-Request: golang/crypto#142 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/239171 Reviewed-by: Han-Wen Nienhuys Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot --- ssh/client_auth.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ssh/client_auth.go b/ssh/client_auth.go index 0590070..f326565 100644 --- a/ssh/client_auth.go +++ b/ssh/client_auth.go @@ -36,7 +36,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { // during the authentication phase the client first attempts the "none" method // then any untried methods suggested by the server. - tried := make(map[string]bool) + var tried []string var lastMethods []string sessionID := c.transport.getSessionID() @@ -49,7 +49,9 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { // success return nil } else if ok == authFailure { - tried[auth.method()] = true + if m := auth.method(); !contains(tried, m) { + tried = append(tried, m) + } } if methods == nil { methods = lastMethods @@ -61,7 +63,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { findNext: for _, a := range config.Auth { candidateMethod := a.method() - if tried[candidateMethod] { + if contains(tried, candidateMethod) { continue } for _, meth := range methods { @@ -72,16 +74,16 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { } } } - return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried)) + return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried) } -func keys(m map[string]bool) []string { - s := make([]string, 0, len(m)) - - for key := range m { - s = append(s, key) +func contains(list []string, e string) bool { + for _, s := range list { + if s == e { + return true + } } - return s + return false } // An AuthMethod represents an instance of an RFC 4252 authentication method.