mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 09:41:44 +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
|
This flag supplies a program which should supply the config password
|
||||||
when run. This is an alternative to rclone prompting for the 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
|
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
|
of arguments. If one of the arguments has a space in then enclose it
|
||||||
|
|
|
@ -10,6 +10,10 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
configfile.Install()
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigLoad(t *testing.T) {
|
func TestConfigLoad(t *testing.T) {
|
||||||
oldConfigPath := config.GetConfigPath()
|
oldConfigPath := config.GetConfigPath()
|
||||||
assert.NoError(t, config.SetConfigPath("./testdata/plain.conf"))
|
assert.NoError(t, config.SetConfigPath("./testdata/plain.conf"))
|
||||||
|
@ -17,7 +21,6 @@ func TestConfigLoad(t *testing.T) {
|
||||||
assert.NoError(t, config.SetConfigPath(oldConfigPath))
|
assert.NoError(t, config.SetConfigPath(oldConfigPath))
|
||||||
}()
|
}()
|
||||||
config.ClearConfigPassword()
|
config.ClearConfigPassword()
|
||||||
configfile.Install()
|
|
||||||
sections := config.Data().GetSectionList()
|
sections := config.Data().GetSectionList()
|
||||||
var expect = []string{"RCLONE_ENCRYPT_V0", "nounc", "unc"}
|
var expect = []string{"RCLONE_ENCRYPT_V0", "nounc", "unc"}
|
||||||
assert.Equal(t, expect, sections)
|
assert.Equal(t, expect, sections)
|
||||||
|
|
|
@ -310,8 +310,20 @@ func ClearConfigPassword() {
|
||||||
// changeConfigPassword will query the user twice
|
// changeConfigPassword will query the user twice
|
||||||
// for a password. If the same password is entered
|
// for a password. If the same password is entered
|
||||||
// twice the key is updated.
|
// twice the key is updated.
|
||||||
|
//
|
||||||
|
// This will use --password-command if configured to read the password.
|
||||||
func changeConfigPassword() {
|
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 {
|
if err != nil {
|
||||||
fmt.Printf("Failed to set config password: %v\n", err)
|
fmt.Printf("Failed to set config password: %v\n", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -46,3 +48,32 @@ func TestPassword(t *testing.T) {
|
||||||
hashedKeyCompare(t, "abcdef", "ABCDEF", false)
|
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