diff --git a/changelog/unreleased/issue-2203 b/changelog/unreleased/issue-2203 new file mode 100644 index 000000000..1229c108c --- /dev/null +++ b/changelog/unreleased/issue-2203 @@ -0,0 +1,6 @@ +Bugfix: Fix reading passwords from stdin + +Passwords for the `init`, `key add`, and `key passwd` commands can now be read from +non-terminal stdin. + +https://github.com/restic/restic/issues/2203 diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 57d4e8d8c..87d461296 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "context" "fmt" "io" @@ -273,15 +274,10 @@ func resolvePassword(opts GlobalOptions) (string, error) { // readPassword reads the password from the given reader directly. func readPassword(in io.Reader) (password string, err error) { - buf := make([]byte, 1000) - n, err := io.ReadFull(in, buf) - buf = buf[:n] + sc := bufio.NewScanner(in) + sc.Scan() - if err != nil && errors.Cause(err) != io.ErrUnexpectedEOF { - return "", errors.Wrap(err, "ReadFull") - } - - return strings.TrimRight(string(buf), "\r\n"), nil + return sc.Text(), errors.Wrap(err, "Scan") } // readPasswordTerminal reads the password from the given reader which must be a @@ -336,13 +332,15 @@ func ReadPasswordTwice(gopts GlobalOptions, prompt1, prompt2 string) (string, er if err != nil { return "", err } - pw2, err := ReadPassword(gopts, prompt2) - if err != nil { - return "", err - } + if stdinIsTerminal() { + pw2, err := ReadPassword(gopts, prompt2) + if err != nil { + return "", err + } - if pw1 != pw2 { - return "", errors.Fatal("passwords do not match") + if pw1 != pw2 { + return "", errors.Fatal("passwords do not match") + } } return pw1, nil