diff --git a/backend/sftp/sftp.go b/backend/sftp/sftp.go index 7e5be399c..660e2a02f 100644 --- a/backend/sftp/sftp.go +++ b/backend/sftp/sftp.go @@ -69,6 +69,9 @@ func init() { Name: "pass", Help: "SSH password, leave blank to use ssh-agent.", IsPassword: true, + }, { + Name: "key_pem", + Help: "Raw PEM-encoded private key, If specified, will override key_file parameter.", }, { Name: "key_file", Help: "Path to PEM-encoded private key file, leave blank or set key-use-agent to use ssh-agent.", @@ -172,6 +175,7 @@ type Options struct { User string `config:"user"` Port string `config:"port"` Pass string `config:"pass"` + KeyPem string `config:"key_pem"` KeyFile string `config:"key_file"` KeyFilePass string `config:"key_file_pass"` KeyUseAgent bool `config:"key_use_agent"` @@ -390,6 +394,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) { } keyFile := env.ShellExpand(opt.KeyFile) + //keyPem := env.ShellExpand(opt.KeyPem) // Add ssh agent-auth if no password or file specified if (opt.Pass == "" && keyFile == "" && !opt.AskPassword) || opt.KeyUseAgent { sshAgentClient, _, err := sshagent.New() @@ -427,10 +432,20 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) { } // Load key file if specified - if keyFile != "" { - key, err := ioutil.ReadFile(keyFile) - if err != nil { - return nil, errors.Wrap(err, "failed to read private key file") + if keyFile != "" || opt.KeyPem != "" { + var key []byte + if opt.KeyPem == "" { + key, err = ioutil.ReadFile(keyFile) + if err != nil { + return nil, errors.Wrap(err, "failed to read private key file") + } + } else { + // wrap in quotes because the config is a coming as a literal without them. + opt.KeyPem, err = strconv.Unquote("\"" + opt.KeyPem + "\"") + if err != nil { + return nil, errors.Wrap(err, "pem key not formatted properly") + } + key = []byte(opt.KeyPem) } clearpass := "" if opt.KeyFilePass != "" { diff --git a/docs/content/sftp.md b/docs/content/sftp.md index bc8a17253..f99926a34 100644 --- a/docs/content/sftp.md +++ b/docs/content/sftp.md @@ -107,10 +107,20 @@ The SFTP remote supports three authentication methods: Key files should be PEM-encoded private key files. For instance `/home/$USER/.ssh/id_rsa`. Only unencrypted OpenSSH or PEM encrypted files are supported. -If you don't specify `pass` or `key_file` then rclone will attempt to contact an ssh-agent. +The key file can be specified in either an external file (key_file) or contained within the +rclone config file (key_pem). If using key_pem in the config file, the entry should be on a +single line with new line ('\n' or '\r\n') separating lines. i.e. + +key_pem = -----BEGIN RSA PRIVATE KEY-----\nMaMbaIXtE\n0gAMbMbaSsd\nMbaass\n-----END RSA PRIVATE KEY----- + +This will generate it correctly for key_pem for use in the config: + + awk '{printf "%s\\n", $0}' < ~/.ssh/id_rsa + +If you don't specify `pass`, `key_file`, or `key_pem` then rclone will attempt to contact an ssh-agent. You can also specify `key_use_agent` to force the usage of an ssh-agent. In this case -`key_file` can also be specified to force the usage of a specific key in the ssh-agent. +`key_file` or `key_pem` can also be specified to force the usage of a specific key in the ssh-agent. Using an ssh-agent is the only way to load encrypted OpenSSH keys at the moment.