diff --git a/cmd/config/config.go b/cmd/config/config.go index ed5700327..d998b8e6e 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -20,7 +20,9 @@ import ( func init() { cmd.Root.AddCommand(configCommand) + configCommand.AddCommand(configDecrypt) configCommand.AddCommand(configEditCommand) + configCommand.AddCommand(configEncrypt) configCommand.AddCommand(configFileCommand) configCommand.AddCommand(configTouchCommand) configCommand.AddCommand(configPathsCommand) @@ -49,6 +51,36 @@ password to protect your configuration. }, } +var configDecrypt = &cobra.Command{ + Use: "decrypt", + Short: `Decrypt the Rclone configuration file.`, + Run: func(command *cobra.Command, args []string) { + config.LoadedData() + config.ClearConfigPassword() + config.SaveConfig() + }, +} + +var configEncrypt = &cobra.Command{ + Use: "encrypt", + Short: `Encrypt the Rclone configuration file.`, + Long: ` + Encrypts the config file. You can set a password via the prompt or + pass your password directly as an argument. After encryption you will be + asked to enter a password when using Rclone. Passwords are not recoverable. +`, + Run: func(command *cobra.Command, args []string) { + if len(args) == 0 { + passwd := config.ChangePassword("NEW configuration") + config.SetConfigPassword(passwd) + } else { + cmd.CheckArgs(1, 1, command, args) + config.SetConfigPassword(args[0]) + } + config.SaveConfig() + }, +} + var configEditCommand = &cobra.Command{ Use: "edit", Short: configCommand.Short, diff --git a/fs/config/crypt.go b/fs/config/crypt.go index 6792811dc..03b6eb437 100644 --- a/fs/config/crypt.go +++ b/fs/config/crypt.go @@ -289,7 +289,7 @@ func SetConfigPassword(password string) error { return nil } -// ClearConfigPassword sets the current the password to empty +// ClearConfigPassword sets the current password to empty func ClearConfigPassword() { configKey = nil } diff --git a/fs/config/rc.go b/fs/config/rc.go index 78f6d4866..f55cc69cc 100644 --- a/fs/config/rc.go +++ b/fs/config/rc.go @@ -30,6 +30,62 @@ func rcDump(ctx context.Context, in rc.Params) (out rc.Params, err error) { return DumpRcBlob(), nil } +func init() { + rc.Add(rc.Call{ + Path: "config/decrypt", + Fn: rcDecrypt, + Title: "Decrypts the Rclone config file.", + AuthRequired: true, + Help: `Decrypt the Rclone configuration file. Requires login.`, + }) +} + +// Decrypt the Rclone config file +func rcDecrypt(ctx context.Context, in rc.Params) (out rc.Params, err error) { + ClearConfigPassword() + SaveConfig() + return nil, nil +} + +func init() { + rc.Add(rc.Call{ + Path: "config/encrypt", + Fn: rcEncrypt, + Title: "Encrypts the Rclone config file.", + AuthRequired: false, + Help: ` +Parameters: +- password: password to use for encryption + +Returns nil for success or a JSON object on error: +- error: error_message + +Encrypts the config file. After encryption you will need to be logged in to use Rclone. +Passwords are not recoverable. +`, + }) +} + +// Encrypts the Rclone config file +func rcEncrypt(ctx context.Context, in rc.Params) (out rc.Params, err error) { + + passwd, err := in.GetString("password") + if err != nil { + out = rc.Params{ + "error": err, + } + } else if passwd == "" { + out = rc.Params{ + "error": "password paramater not supplied", + } + } else { + SetConfigPassword(passwd) + SaveConfig() + out = nil + } + return out, nil +} + func init() { rc.Add(rc.Call{ Path: "config/get", diff --git a/fs/config/ui.go b/fs/config/ui.go index 60b5b3bc6..9aa754121 100644 --- a/fs/config/ui.go +++ b/fs/config/ui.go @@ -755,8 +755,9 @@ func SetPassword() { fmt.Println("Password changed") continue case 'u': - configKey = nil + ClearConfigPassword() SaveConfig() + fmt.Println("Configuration decrypted") continue case 'q': return