From c55665be2c85de74fd58118ab6e14a38abcb50b3 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Wed, 5 Jun 2024 22:14:45 +0200 Subject: [PATCH] key add/passwd: handle UTF-16 encoding correctly Just use the exact some function for load a password from a file everywhere. --- changelog/unreleased/issue-4850 | 8 ++++++++ cmd/restic/cmd_key_add.go | 10 ---------- cmd/restic/global.go | 16 +++++++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 changelog/unreleased/issue-4850 diff --git a/changelog/unreleased/issue-4850 b/changelog/unreleased/issue-4850 new file mode 100644 index 000000000..ad065cc21 --- /dev/null +++ b/changelog/unreleased/issue-4850 @@ -0,0 +1,8 @@ +Bugfix: correctly handle UTF-16 password files in `key add/passwd` + +`key add` and `key passwd` did not properly decode UTF-16 encoded password read +from a password file. This has been fix to match the decoding when opening a +repository. + +https://github.com/restic/restic/issues/4850 +https://github.com/restic/restic/pull/4851 diff --git a/cmd/restic/cmd_key_add.go b/cmd/restic/cmd_key_add.go index 9e50aa67d..d38991f09 100644 --- a/cmd/restic/cmd_key_add.go +++ b/cmd/restic/cmd_key_add.go @@ -3,8 +3,6 @@ package main import ( "context" "fmt" - "os" - "strings" "github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/repository" @@ -123,14 +121,6 @@ func getNewPassword(ctx context.Context, gopts GlobalOptions, newPasswordFile st "enter password again: ") } -func loadPasswordFromFile(pwdFile string) (string, error) { - s, err := os.ReadFile(pwdFile) - if os.IsNotExist(err) { - return "", errors.Fatalf("%s does not exist", pwdFile) - } - return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") -} - func switchToNewKeyAndRemoveIfBroken(ctx context.Context, repo *repository.Repository, key *repository.Key, pw string) error { // Verify new key to make sure it really works. A broken key can render the // whole repository inaccessible diff --git a/cmd/restic/global.go b/cmd/restic/global.go index a5250ca38..44b427b30 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -268,11 +268,7 @@ func resolvePassword(opts GlobalOptions, envStr string) (string, error) { return (strings.TrimSpace(string(output))), nil } if opts.PasswordFile != "" { - s, err := textfile.Read(opts.PasswordFile) - if errors.Is(err, os.ErrNotExist) { - return "", errors.Fatalf("%s does not exist", opts.PasswordFile) - } - return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") + return loadPasswordFromFile(opts.PasswordFile) } if pwd := os.Getenv(envStr); pwd != "" { @@ -282,6 +278,16 @@ func resolvePassword(opts GlobalOptions, envStr string) (string, error) { return "", nil } +// loadPasswordFromFile loads a password from a file while stripping a BOM and +// converting the password to UTF-8. +func loadPasswordFromFile(pwdFile string) (string, error) { + s, err := textfile.Read(pwdFile) + if errors.Is(err, os.ErrNotExist) { + return "", errors.Fatalf("%s does not exist", pwdFile) + } + return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") +} + // readPassword reads the password from the given reader directly. func readPassword(in io.Reader) (password string, err error) { sc := bufio.NewScanner(in)