diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index 931988176..edc36f2df 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -249,7 +249,7 @@ func readBackupFromStdin(opts BackupOptions, gopts GlobalOptions, args []string) return errors.Fatal("filename for backup from stdin must not be empty") } - if gopts.password == "" && gopts.PasswordFile == "" { + if gopts.password == "" { return errors.Fatal("unable to read password from stdin when data is to be read from stdin, use --password-file or $RESTIC_PASSWORD") } @@ -322,8 +322,8 @@ func readLinesFromFile(filename string) ([]string, error) { } func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { - if opts.FilesFrom == "-" && gopts.password == "" && gopts.PasswordFile == "" { - return errors.Fatal("no password; either use `--password-file` option or put the password into the RESTIC_PASSWORD environment variable") + if opts.FilesFrom == "-" && gopts.password == "" { + return errors.Fatal("unable to read password from stdin when data is to be read from stdin, use --password-file or $RESTIC_PASSWORD") } fromfile, err := readLinesFromFile(opts.FilesFrom) diff --git a/cmd/restic/cmd_init.go b/cmd/restic/cmd_init.go index 47bbf4812..368cadb88 100644 --- a/cmd/restic/cmd_init.go +++ b/cmd/restic/cmd_init.go @@ -34,13 +34,11 @@ func runInit(gopts GlobalOptions, args []string) error { return errors.Fatalf("create backend at %s failed: %v\n", gopts.Repo, err) } - if gopts.password == "" { - gopts.password, err = ReadPasswordTwice(gopts, - "enter password for new backend: ", - "enter password again: ") - if err != nil { - return err - } + gopts.password, err = ReadPasswordTwice(gopts, + "enter password for new backend: ", + "enter password again: ") + if err != nil { + return err } s := repository.New(be) diff --git a/cmd/restic/cmd_key.go b/cmd/restic/cmd_key.go index fe8272457..5e7ccf35c 100644 --- a/cmd/restic/cmd_key.go +++ b/cmd/restic/cmd_key.go @@ -59,7 +59,12 @@ func getNewPassword(gopts GlobalOptions) (string, error) { return testKeyNewPassword, nil } - return ReadPasswordTwice(gopts, + // Since we already have an open repository, temporary remove the password + // to prompt the user for the passwd. + newopts := gopts + newopts.password = "" + + return ReadPasswordTwice(newopts, "enter password for new key: ", "enter password again: ") } diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 3eabefa29..673d8bcaf 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -53,11 +53,6 @@ var globalOptions = GlobalOptions{ } func init() { - pw := os.Getenv("RESTIC_PASSWORD") - if pw != "" { - globalOptions.password = pw - } - var cancel context.CancelFunc globalOptions.ctx, cancel = context.WithCancel(context.Background()) AddCleanupHandler(func() error { @@ -207,6 +202,20 @@ func Exitf(exitcode int, format string, args ...interface{}) { Exit(exitcode) } +// resolvePassword determines the password to be used for opening the repository. +func resolvePassword(opts GlobalOptions, env string) (string, error) { + if opts.PasswordFile != "" { + s, err := ioutil.ReadFile(opts.PasswordFile) + return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") + } + + if pwd := os.Getenv(env); pwd != "" { + return pwd, nil + } + + return "", nil +} + // readPassword reads the password from the given reader directly. func readPassword(in io.Reader) (password string, err error) { buf := make([]byte, 1000) @@ -238,13 +247,8 @@ func readPasswordTerminal(in *os.File, out io.Writer, prompt string) (password s // ReadPassword reads the password from a password file, the environment // variable RESTIC_PASSWORD or prompts the user. func ReadPassword(opts GlobalOptions, prompt string) (string, error) { - if opts.PasswordFile != "" { - s, err := ioutil.ReadFile(opts.PasswordFile) - return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") - } - - if pwd := os.Getenv("RESTIC_PASSWORD"); pwd != "" { - return pwd, nil + if opts.password != "" { + return opts.password, nil } var ( @@ -303,11 +307,9 @@ func OpenRepository(opts GlobalOptions) (*repository.Repository, error) { s := repository.New(be) - if opts.password == "" { - opts.password, err = ReadPassword(opts, "enter password for repository: ") - if err != nil { - return nil, err - } + opts.password, err = ReadPassword(opts, "enter password for repository: ") + if err != nil { + return nil, err } err = s.SearchKey(context.TODO(), opts.password, maxKeys) diff --git a/cmd/restic/main.go b/cmd/restic/main.go index b53fc986c..195f9e2cc 100644 --- a/cmd/restic/main.go +++ b/cmd/restic/main.go @@ -36,6 +36,13 @@ directories in an encrypted repository stored on different backends. } globalOptions.extended = opts + pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD") + if err != nil { + fmt.Fprintf(os.Stderr, "Resolving password failed: %v\n", err) + Exit(1) + } + globalOptions.password = pwd + // run the debug functions for all subcommands (if build tag "debug" is // enabled) if err := runDebug(); err != nil {