What
authMethods in internal/uploader/connection.go offers exactly two SSH authentication methods:
methods = append(methods, ssh.PublicKeys(signer)) // if private-key is set
methods = append(methods, ssh.Password(h.password)) // if password is set
ssh.KeyboardInteractive is never offered.
Why it matters
password and keyboard-interactive are two distinct SSH authentication methods. A server can accept one and refuse the other. The configuration that breaks easySFTP is common and not exotic:
PasswordAuthentication no
KbdInteractiveAuthentication yes
sshd built with PAM frequently ends up here, and several managed and shared hosting providers ship it. The user has a correct password, the server accepts that password over ssh and over FileZilla (both of which try keyboard-interactive), and easySFTP fails with ssh: unable to authenticate. From the user's side this looks like "easySFTP does not work with my host", and session.go's isRetryableConnect correctly refuses to retry it, so the failure is immediate and opaque.
For a project whose stated goal is being a serious option for SFTP deploys, and whose audience explicitly includes shared hosting (see docs/providers.md), this is one of the more likely reasons a first run fails.
Suggested direction
Append a keyboard-interactive method whenever a password is configured, answering every prompt with that password. This is what OpenSSH effectively does for the single-prompt case and what most SFTP clients do:
if h.password != "" {
methods = append(methods, ssh.Password(h.password))
methods = append(methods, ssh.KeyboardInteractive(
func(name, instruction string, questions []string, echos []bool) ([]string, error) {
answers := make([]string, len(questions))
for i := range answers {
answers[i] = h.password
}
return answers, nil
}))
}
Points that need a deliberate decision, not just the code:
- Genuine multi-factor prompts. If the server asks for a TOTP code, answering with the password is wrong and the run fails anyway, just one round-trip later. That is acceptable (unattended CI cannot satisfy an interactive second factor either way), but the failure message should be clear about it rather than saying "authentication failed".
- Echoing prompts. Answering a prompt whose
echos[i] is true (a non-secret question) with the password is arguably wrong. Returning an empty answer for echoed prompts is the safer reading.
- Whether this should be opt-in. Given the "usability and user choice over enforced opinions" principle in CLAUDE.md and the fact that offering an extra method costs nothing when the server does not advertise it, on-by-default looks right, but that is the call to make in the PR.
Related
Adjacent gaps, deliberately not folded into this issue: SSH agent forwarding and OpenSSH certificate authentication are both unsupported. Neither has the same "correct credentials are rejected" failure signature, so they are lower priority.
What
authMethodsininternal/uploader/connection.gooffers exactly two SSH authentication methods:ssh.KeyboardInteractiveis never offered.Why it matters
passwordandkeyboard-interactiveare two distinct SSH authentication methods. A server can accept one and refuse the other. The configuration that breaks easySFTP is common and not exotic:sshd built with PAM frequently ends up here, and several managed and shared hosting providers ship it. The user has a correct password, the server accepts that password over
sshand over FileZilla (both of which try keyboard-interactive), and easySFTP fails withssh: unable to authenticate. From the user's side this looks like "easySFTP does not work with my host", andsession.go'sisRetryableConnectcorrectly refuses to retry it, so the failure is immediate and opaque.For a project whose stated goal is being a serious option for SFTP deploys, and whose audience explicitly includes shared hosting (see
docs/providers.md), this is one of the more likely reasons a first run fails.Suggested direction
Append a keyboard-interactive method whenever a password is configured, answering every prompt with that password. This is what OpenSSH effectively does for the single-prompt case and what most SFTP clients do:
Points that need a deliberate decision, not just the code:
echos[i]is true (a non-secret question) with the password is arguably wrong. Returning an empty answer for echoed prompts is the safer reading.Related
Adjacent gaps, deliberately not folded into this issue: SSH agent forwarding and OpenSSH certificate authentication are both unsupported. Neither has the same "correct credentials are rejected" failure signature, so they are lower priority.