mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 06:06:27 +08:00
config: use --password-command to set config file password if supplied
Before this change, rclone ignored the --password-command on the rclone config setting except when decrypting an existing config file. This change allows for offloading the password storage/generation into external hardware key or other protected password storage. Fixes #7859
This commit is contained in:
parent
c9c283533c
commit
ffb2e2a6de
|
@ -1928,7 +1928,8 @@ The default is `.partial`.
|
|||
|
||||
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.
|
||||
or setting the `RCLONE_CONFIG_PASS` variable. It is also used when
|
||||
setting the config password for the first time.
|
||||
|
||||
The argument to this should be a command with a space separated list
|
||||
of arguments. If one of the arguments has a space in then enclose it
|
||||
|
|
|
@ -10,6 +10,10 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func init() {
|
||||
configfile.Install()
|
||||
}
|
||||
|
||||
func TestConfigLoad(t *testing.T) {
|
||||
oldConfigPath := config.GetConfigPath()
|
||||
assert.NoError(t, config.SetConfigPath("./testdata/plain.conf"))
|
||||
|
@ -17,7 +21,6 @@ func TestConfigLoad(t *testing.T) {
|
|||
assert.NoError(t, config.SetConfigPath(oldConfigPath))
|
||||
}()
|
||||
config.ClearConfigPassword()
|
||||
configfile.Install()
|
||||
sections := config.Data().GetSectionList()
|
||||
var expect = []string{"RCLONE_ENCRYPT_V0", "nounc", "unc"}
|
||||
assert.Equal(t, expect, sections)
|
||||
|
|
|
@ -310,8 +310,20 @@ func ClearConfigPassword() {
|
|||
// changeConfigPassword will query the user twice
|
||||
// for a password. If the same password is entered
|
||||
// twice the key is updated.
|
||||
//
|
||||
// This will use --password-command if configured to read the password.
|
||||
func changeConfigPassword() {
|
||||
err := SetConfigPassword(ChangePassword("NEW configuration"))
|
||||
pass, err := GetPasswordCommand(context.Background())
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to read new password with --password-command: %v\n", err)
|
||||
return
|
||||
}
|
||||
if pass == "" {
|
||||
pass = ChangePassword("NEW configuration")
|
||||
} else {
|
||||
fmt.Printf("Read password using --password-command\n")
|
||||
}
|
||||
err = SetConfigPassword(pass)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to set config password: %v\n", err)
|
||||
return
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -46,3 +48,32 @@ func TestPassword(t *testing.T) {
|
|||
hashedKeyCompare(t, "abcdef", "ABCDEF", false)
|
||||
|
||||
}
|
||||
|
||||
func TestChangeConfigPassword(t *testing.T) {
|
||||
ci := fs.GetConfig(context.Background())
|
||||
|
||||
var err error
|
||||
oldConfigPath := GetConfigPath()
|
||||
assert.NoError(t, SetConfigPath("./testdata/encrypted.conf"))
|
||||
defer func() {
|
||||
assert.NoError(t, SetConfigPath(oldConfigPath))
|
||||
ClearConfigPassword()
|
||||
ci.PasswordCommand = nil
|
||||
}()
|
||||
|
||||
// Get rid of any config password
|
||||
ClearConfigPassword()
|
||||
|
||||
// Set correct password using --password command
|
||||
ci.PasswordCommand = fs.SpaceSepList{"echo", "asdf"}
|
||||
changeConfigPassword()
|
||||
err = Data().Load()
|
||||
require.NoError(t, err)
|
||||
sections := Data().GetSectionList()
|
||||
var expect = []string{"nounc", "unc"}
|
||||
assert.Equal(t, expect, sections)
|
||||
|
||||
keys := Data().GetKeyList("nounc")
|
||||
expect = []string{"type", "nounc"}
|
||||
assert.Equal(t, expect, keys)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user