[android] stop prompting for a password the server will not take

Any authentication failure on a regular server returned the
password-required marker, so against a server with password
authentication disabled the client asked again after every attempt and
reported each one as a wrong password.

gossh only lists a method under "attempted methods" when the server
offered it. When a supplied password never got attempted, surface the
real error instead of the marker, the same way the desktop client
reports it. A first connect without a password still prompts.
This commit is contained in:
Zoltán Papp
2026-08-11 16:40:12 +02:00
parent c4c8e2fe1e
commit 6a83476831

View File

@@ -151,7 +151,8 @@ func (s *SSHClient) Connect(host string, port int, user, password string) error
// one instead of failing. NetBird servers never use a password, so a
// failure there is genuine.
if err != nil && serverType != detection.ServerTypeNetBirdJWT &&
serverType != detection.ServerTypeNetBirdNoJWT && isAuthFailure(err) {
serverType != detection.ServerTypeNetBirdNoJWT && isAuthFailure(err) &&
passwordCouldHelp(err, password != "") {
return errPasswordRequired
}
if err != nil {
@@ -173,6 +174,18 @@ func isAuthFailure(err error) bool {
return strings.Contains(err.Error(), "unable to authenticate")
}
// passwordCouldHelp reports whether prompting for a password again can change
// the outcome. gossh lists a method under "attempted methods" only when the
// server offered it, so a supplied password that was never attempted means the
// server does not accept passwords and the real error should surface instead.
func passwordCouldHelp(err error, passwordOffered bool) bool {
if !passwordOffered {
return true
}
msg := err.Error()
return strings.Contains(msg, "password") || strings.Contains(msg, "keyboard-interactive")
}
// StartSession requests a PTY and starts an interactive shell. Output from
// the session is forwarded to the listener via OnData.
func (s *SSHClient) StartSession(cols, rows int) error {