Add new option --repository-file (default: $RESTIC_REPOSITORY_FILE)

As an alternative to -r, this allows to read the repository URL
from a file in order to prevent certain types of information leaks,
especially for URLs containing credentials.

Fixes #1458, fixes #2900.
This commit is contained in:
Andreas Oberritter 2020-08-30 23:20:57 +02:00 committed by Michael Eischer
parent 34ea960559
commit 97f7855de3
4 changed files with 48 additions and 4 deletions

View File

@ -0,0 +1,10 @@
Enhancement: New option --repository-file
We've added a new command-line option --repository-file as an alternative
to -r. This allows to read the repository URL from a file in order to
prevent certain types of information leaks, especially for URLs containing
credentials.
https://github.com/restic/restic/issues/1458
https://github.com/restic/restic/issues/2900
https://github.com/restic/restic/pull/2910

View File

@ -52,7 +52,12 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
return err
}
be, err := create(gopts.Repo, gopts.extended)
repo, err := ReadRepo(gopts)
if err != nil {
return err
}
be, err := create(repo, gopts.extended)
if err != nil {
return errors.Fatalf("create repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
}

View File

@ -49,6 +49,7 @@ type backendWrapper func(r restic.Backend) (restic.Backend, error)
// GlobalOptions hold all global options for restic.
type GlobalOptions struct {
Repo string
RepositoryFile string
PasswordFile string
PasswordCommand string
KeyHint string
@ -101,6 +102,7 @@ func init() {
f := cmdRoot.PersistentFlags()
f.StringVarP(&globalOptions.Repo, "repo", "r", os.Getenv("RESTIC_REPOSITORY"), "`repository` to backup to or restore from (default: $RESTIC_REPOSITORY)")
f.StringVarP(&globalOptions.RepositoryFile, "repository-file", "", os.Getenv("RESTIC_REPOSITORY_FILE"), "`file` to read the repository location from (default: $RESTIC_REPOSITORY_FILE)")
f.StringVarP(&globalOptions.PasswordFile, "password-file", "p", os.Getenv("RESTIC_PASSWORD_FILE"), "`file` to read the repository password from (default: $RESTIC_PASSWORD_FILE)")
f.StringVarP(&globalOptions.KeyHint, "key-hint", "", os.Getenv("RESTIC_KEY_HINT"), "`key` ID of key to try decrypting first (default: $RESTIC_KEY_HINT)")
f.StringVarP(&globalOptions.PasswordCommand, "password-command", "", os.Getenv("RESTIC_PASSWORD_COMMAND"), "shell `command` to obtain the repository password from (default: $RESTIC_PASSWORD_COMMAND)")
@ -382,15 +384,41 @@ func ReadPasswordTwice(gopts GlobalOptions, prompt1, prompt2 string) (string, er
return pw1, nil
}
func ReadRepo(opts GlobalOptions) (string, error) {
if opts.Repo == "" && opts.RepositoryFile == "" {
return "", errors.Fatal("Please specify repository location (-r or --repository-file)")
}
repo := opts.Repo
if opts.RepositoryFile != "" {
if repo != "" {
return "", errors.Fatal("Options -r and --repository-file are mutually exclusive, please specify only one")
}
s, err := textfile.Read(opts.RepositoryFile)
if os.IsNotExist(errors.Cause(err)) {
return "", errors.Fatalf("%s does not exist", opts.RepositoryFile)
}
if err != nil {
return "", err
}
repo = strings.TrimSpace(string(s))
}
return repo, nil
}
const maxKeys = 20
// OpenRepository reads the password and opens the repository.
func OpenRepository(opts GlobalOptions) (*repository.Repository, error) {
if opts.Repo == "" {
return nil, errors.Fatal("Please specify repository location (-r)")
repo, err := ReadRepo(opts)
if err != nil {
return nil, err
}
be, err := open(opts.Repo, opts, opts.extended)
be, err := open(repo, opts, opts.extended)
if err != nil {
return nil, err
}

View File

@ -407,6 +407,7 @@ environment variables. The following lists these environment variables:
.. code-block:: console
RESTIC_REPOSITORY_FILE Name of a file containing the location of the repository (replaces --repository-file)
RESTIC_REPOSITORY Location of repository (replaces -r)
RESTIC_PASSWORD_FILE Location of password file (replaces --password-file)
RESTIC_PASSWORD The actual password for the repository