Allow multiple retries for interactive password input

Restic used to quit if the repository password was typed incorrectly once.
Restic will now ask the user again for the repository password if typed incorrectly.
The user will now get three tries to input the correct password before restic quits.
This commit is contained in:
Gary Kim 2019-06-12 18:40:05 +08:00
parent 5bd5db4294
commit fea2464d4d
No known key found for this signature in database
GPG key ID: 9349B59FB54594AC
3 changed files with 32 additions and 7 deletions

View file

@ -0,0 +1,7 @@
Enhancement: Allow multiple retries for interactive password input
Restic used to quit if the repository password was typed incorrectly once.
Restic will now ask the user again for the repository password if typed incorrectly.
The user will now get three tries to input the correct password before restic quits.
https://github.com/restic/restic/issues/2306

View file

@ -319,7 +319,7 @@ func ReadPassword(opts GlobalOptions, prompt string) (string, error) {
}
if len(password) == 0 {
return "", errors.Fatal("an empty password is not a password")
return "", errors.New("an empty password is not a password")
}
return password, nil
@ -365,14 +365,32 @@ func OpenRepository(opts GlobalOptions) (*repository.Repository, error) {
s := repository.New(be)
opts.password, err = ReadPassword(opts, "enter password for repository: ")
if err != nil {
return nil, err
passwordTriesLeft := 1
if stdinIsTerminal() && opts.password == "" {
passwordTriesLeft = 3
}
err = s.SearchKey(opts.ctx, opts.password, maxKeys, opts.KeyHint)
for ; passwordTriesLeft > 0; passwordTriesLeft-- {
opts.password, err = ReadPassword(opts, "enter password for repository: ")
if err != nil && passwordTriesLeft > 1 {
opts.password = ""
fmt.Printf("%s. Try again\n", err)
}
if err != nil {
continue
}
err = s.SearchKey(opts.ctx, opts.password, maxKeys, opts.KeyHint)
if err != nil && passwordTriesLeft > 1 {
opts.password = ""
fmt.Printf("%s. Try again\n", err)
}
}
if err != nil {
return nil, err
if errors.IsFatal(err) {
return nil, err
}
return nil, errors.Fatalf("%s", err)
}
if stdoutIsTerminal() && !opts.JSON {

View file

@ -18,7 +18,7 @@ import (
var (
// ErrNoKeyFound is returned when no key for the repository could be decrypted.
ErrNoKeyFound = errors.Fatal("wrong password or no key found")
ErrNoKeyFound = errors.New("wrong password or no key found")
// ErrMaxKeysReached is returned when the maximum number of keys was checked and no key could be found.
ErrMaxKeysReached = errors.Fatal("maximum number of keys reached")