mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 16:34:30 +01:00
config: use the environment variable which goes with --password-command
This commit is contained in:
parent
06df133159
commit
62dbdcdbcc
@ -880,6 +880,14 @@ Rclone will do its best to transfer the best file it has so in
|
||||
practice this should not cause a problem. Think of `--order-by` as
|
||||
being more of a best efforts flag rather than a perfect ordering.
|
||||
|
||||
### --password-command=STRING ###
|
||||
|
||||
This flag supplies a program which should supply the config password
|
||||
when run. This is an alternative to rclone prompting for the password
|
||||
or setting the `RCLONE_CONFIG_PASS` variable.
|
||||
|
||||
See the [Configuration Encryption](#configuration-encryption) for more info.
|
||||
|
||||
### -P, --progress ###
|
||||
|
||||
This flag makes rclone update the stats in a static block in the
|
||||
@ -1361,13 +1369,13 @@ which will retrieve the password and print on standard output. This
|
||||
script should have a fully specified path name and not rely on any
|
||||
environment variables. The script is supplied either via
|
||||
`--password-command="..."` command line argument or via the
|
||||
`RCLONE_CONFIG_PASS_COMMAND` environment variable.
|
||||
`RCLONE_PASSWORD_COMMAND` environment variable.
|
||||
|
||||
One useful example of this is using the `passwordstore` application
|
||||
to retrieve the password:
|
||||
|
||||
```
|
||||
export RCLONE_CONFIG_PASS_COMMAND="pass rclone/config"
|
||||
export RCLONE_PASSWORD_COMMAND="pass rclone/config"
|
||||
```
|
||||
|
||||
If the `passwordstore` password manager holds the password for the
|
||||
@ -1381,11 +1389,11 @@ script method of supplying the password enhances the security of
|
||||
the config password considerably.
|
||||
|
||||
If you are running rclone inside a script, unless you are using the
|
||||
`RCLONE_CONFIG_PASS_COMMAND` method, you might want to disable
|
||||
`--password-command` method, you might want to disable
|
||||
password prompts. To do that, pass the parameter
|
||||
`--ask-password=false` to rclone. This will make rclone fail instead
|
||||
of asking for a password if `RCLONE_CONFIG_PASS` doesn't contain
|
||||
a valid password, and `RCLONE_CONFIG_PASS_COMMAND` has not been supplied.
|
||||
a valid password, and `--password-command` has not been supplied.
|
||||
|
||||
|
||||
Developer options
|
||||
|
@ -275,10 +275,6 @@ func loadConfigFile() (*goconfig.ConfigFile, error) {
|
||||
|
||||
if len(configKey) == 0 {
|
||||
pwc := fs.Config.PasswordCommand
|
||||
|
||||
if pwc == "" {
|
||||
pwc = os.Getenv("RCLONE_CONFIG_PASS_COMMAND")
|
||||
}
|
||||
if pwc != "" {
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
@ -291,7 +287,7 @@ func loadConfigFile() (*goconfig.ConfigFile, error) {
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
// One does not always get the stderr returned in the wrapped error.
|
||||
fs.Errorf(nil, "Using RCLONE_CONFIG_PASS_COMMAND returned: %v", err)
|
||||
fs.Errorf(nil, "Using --password-command returned: %v", err)
|
||||
if ers := strings.TrimSpace(stderr.String()); ers != "" {
|
||||
fs.Errorf(nil, "--password-command stderr: %s", ers)
|
||||
}
|
||||
@ -357,7 +353,7 @@ func loadConfigFile() (*goconfig.ConfigFile, error) {
|
||||
} else {
|
||||
if len(configKey) == 0 {
|
||||
if usingPasswordCommand {
|
||||
return nil, errors.New("using password command derived password, unable to decrypt configuration")
|
||||
return nil, errors.New("using --password-command derived password, unable to decrypt configuration")
|
||||
}
|
||||
if !fs.Config.AskPassword {
|
||||
return nil, errors.New("unable to decrypt configuration and not allowed to ask for password - set RCLONE_CONFIG_PASS to your configuration password")
|
||||
|
@ -270,15 +270,24 @@ func TestConfigLoadEncrypted(t *testing.T) {
|
||||
assert.Equal(t, expect, keys)
|
||||
}
|
||||
|
||||
func expectConfigValid(t *testing.T) {
|
||||
var err error
|
||||
func TestConfigLoadEncryptedWithValidPassCommand(t *testing.T) {
|
||||
oldConfigPath := ConfigPath
|
||||
oldConfig := fs.Config
|
||||
ConfigPath = "./testdata/encrypted.conf"
|
||||
// using fs.Config.PasswordCommand, correct password
|
||||
fs.Config.PasswordCommand = "echo asdf"
|
||||
defer func() {
|
||||
ConfigPath = oldConfigPath
|
||||
configKey = nil // reset password
|
||||
fs.Config = oldConfig
|
||||
fs.Config.PasswordCommand = ""
|
||||
}()
|
||||
|
||||
configKey = nil // reset password
|
||||
|
||||
c, err := loadConfigFile()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Not sure why there is no "RCLONE_ENCRYPT_V0" here...
|
||||
sections := c.GetSectionList()
|
||||
var expect = []string{"nounc", "unc"}
|
||||
assert.Equal(t, expect, sections)
|
||||
@ -288,64 +297,24 @@ func expectConfigValid(t *testing.T) {
|
||||
assert.Equal(t, expect, keys)
|
||||
}
|
||||
|
||||
func expectConfigInvalid(t *testing.T) {
|
||||
var err error
|
||||
|
||||
configKey = nil // reset password
|
||||
|
||||
_, err = loadConfigFile()
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestConfigLoadEncryptedWithValidPassCommand(t *testing.T) {
|
||||
oldConfigPath := ConfigPath
|
||||
oldConfig := fs.Config
|
||||
ConfigPath = "./testdata/encrypted.conf"
|
||||
defer func() {
|
||||
ConfigPath = oldConfigPath
|
||||
configKey = nil // reset password
|
||||
fs.Config = oldConfig
|
||||
}()
|
||||
|
||||
// using fs.Config.PasswordCommand, correct password
|
||||
fs.Config.PasswordCommand = "echo asdf"
|
||||
expectConfigValid(t)
|
||||
|
||||
var err error
|
||||
|
||||
// using "RCLONE_CONFIG_PASS_COMMAND"
|
||||
|
||||
err = os.Setenv("RCLONE_CONFIG_PASS_COMMAND", "echo asdf")
|
||||
require.NoError(t, err)
|
||||
expectConfigValid(t)
|
||||
|
||||
err = os.Unsetenv("RCLONE_CONFIG_PASS_COMMAND")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestConfigLoadEncryptedWithInvalidPassCommand(t *testing.T) {
|
||||
oldConfigPath := ConfigPath
|
||||
oldConfig := fs.Config
|
||||
ConfigPath = "./testdata/encrypted.conf"
|
||||
// using fs.Config.PasswordCommand, incorrect password
|
||||
fs.Config.PasswordCommand = "echo asdf-blurfl"
|
||||
defer func() {
|
||||
ConfigPath = oldConfigPath
|
||||
configKey = nil // reset password
|
||||
fs.Config = oldConfig
|
||||
fs.Config.PasswordCommand = ""
|
||||
}()
|
||||
|
||||
// using fs.Config.PasswordCommand, incorrect password
|
||||
fs.Config.PasswordCommand = "echo asdf-blurfl"
|
||||
expectConfigInvalid(t)
|
||||
fs.Config.PasswordCommand = ""
|
||||
configKey = nil // reset password
|
||||
|
||||
var err error
|
||||
|
||||
err = os.Setenv("RCLONE_CONFIG_PASS_COMMAND", "echo asdf-blurfl")
|
||||
require.NoError(t, err)
|
||||
expectConfigInvalid(t)
|
||||
|
||||
err = os.Unsetenv("RCLONE_CONFIG_PASS_COMMAND")
|
||||
require.NoError(t, err)
|
||||
_, err := loadConfigFile()
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "using --password-command derived password")
|
||||
}
|
||||
|
||||
func TestConfigLoadEncryptedFailures(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user