forked from TrueCloudLab/rclone
sftp: implement keyboard interactive authentication - fixes #4177
Some ssh servers are set up with keyboard interactive authentication which previously the sftp backkend was ignoring.
This commit is contained in:
parent
a64fc05385
commit
ba51409c3c
1 changed files with 25 additions and 2 deletions
|
@ -584,18 +584,41 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshConfig.Auth = append(sshConfig.Auth, ssh.Password(clearpass))
|
sshConfig.Auth = append(sshConfig.Auth,
|
||||||
|
ssh.Password(clearpass),
|
||||||
|
ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
|
||||||
|
return f.keyboardInteractiveReponse(user, instruction, questions, echos, clearpass)
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config for password if none was defined and we're allowed to
|
// Config for password if none was defined and we're allowed to
|
||||||
// We don't ask now; we ask if the ssh connection succeeds
|
// We don't ask now; we ask if the ssh connection succeeds
|
||||||
if opt.Pass == "" && opt.AskPassword {
|
if opt.Pass == "" && opt.AskPassword {
|
||||||
sshConfig.Auth = append(sshConfig.Auth, ssh.PasswordCallback(f.getPass))
|
sshConfig.Auth = append(sshConfig.Auth,
|
||||||
|
ssh.PasswordCallback(f.getPass),
|
||||||
|
ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
|
||||||
|
pass, _ := f.getPass()
|
||||||
|
return f.keyboardInteractiveReponse(user, instruction, questions, echos, pass)
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewFsWithConnection(ctx, f, name, root, m, opt, sshConfig)
|
return NewFsWithConnection(ctx, f, name, root, m, opt, sshConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do the keyboard interactive challenge
|
||||||
|
//
|
||||||
|
// Just send the password back for all questions
|
||||||
|
func (f *Fs) keyboardInteractiveReponse(user, instruction string, questions []string, echos []bool, pass string) ([]string, error) {
|
||||||
|
fs.Debugf(f, "keyboard interactive auth requested")
|
||||||
|
answers := make([]string, len(questions))
|
||||||
|
for i := range answers {
|
||||||
|
answers[i] = pass
|
||||||
|
}
|
||||||
|
return answers, nil
|
||||||
|
}
|
||||||
|
|
||||||
// If we're in password mode and ssh connection succeeds then this
|
// If we're in password mode and ssh connection succeeds then this
|
||||||
// callback is called. First time around we ask the user, and then
|
// callback is called. First time around we ask the user, and then
|
||||||
// save it so on reconnection we give back the previous string.
|
// save it so on reconnection we give back the previous string.
|
||||||
|
|
Loading…
Reference in a new issue