3737 Port int `envconfig:"PLUGIN_PORT"`
3838 Username string `envconfig:"PLUGIN_USERNAME"`
3939 Password string `envconfig:"PLUGIN_PASSWORD"`
40+ Key string `envconfig:"PLUGIN_KEY"`
41+ KeyPath string `envconfig:"PLUGIN_KEY_PATH"`
42+ Passphrase string `envconfig:"PLUGIN_PASSPHRASE"`
4043 Files []string `envconfig:"PLUGIN_FILES"`
4144 Destination string `envconfig:"PLUGIN_DESTINATION_PATH"`
4245 }
@@ -130,8 +133,8 @@ func verifyArgs(args *Args) error {
130133 return fmt .Errorf ("no username provided: %w" , errConfiguration )
131134 }
132135
133- if args .Password == "" {
134- return fmt .Errorf ("no password provided: %w" , errConfiguration )
136+ if args .Password == "" && args . Key == "" && args . KeyPath == "" {
137+ return fmt .Errorf ("no password or key provided: %w" , errConfiguration )
135138 }
136139
137140 if args .Host == "" {
@@ -171,12 +174,15 @@ func findFileUploads(args *Args) ([]string, error) {
171174}
172175
173176func createSftpClient (args * Args ) (* sftp.Client , error ) {
177+ authMethods , err := createSftpAuthMethods (args )
178+ if err != nil {
179+ return nil , err
180+ }
181+
174182 server := fmt .Sprintf ("%s:%d" , args .Host , args .Port )
175183 config := & ssh.ClientConfig {
176- User : args .Username ,
177- Auth : []ssh.AuthMethod {
178- ssh .Password (args .Password ),
179- },
184+ User : args .Username ,
185+ Auth : authMethods ,
180186 HostKeyCallback : ssh .InsecureIgnoreHostKey (),
181187 }
182188
@@ -197,6 +203,54 @@ func createSftpClient(args *Args) (*sftp.Client, error) {
197203 return client , nil
198204}
199205
206+ func createSftpAuthMethods (args * Args ) ([]ssh.AuthMethod , error ) {
207+ var methods []ssh.AuthMethod
208+
209+ if args .Password != "" {
210+ methods = append (methods , ssh .Password (args .Password ))
211+ }
212+
213+ if args .Key != "" {
214+ signer , err := parsePrivateKey ([]byte (args .Key ), []byte (args .Passphrase ))
215+ if err != nil {
216+ return nil , err
217+ }
218+ methods = append (methods , ssh .PublicKeys (signer ))
219+ }
220+
221+ if args .KeyPath != "" {
222+ buffer , err := os .ReadFile (args .KeyPath )
223+ if err != nil {
224+ return nil , fmt .Errorf ("could not read private key: %w" , err )
225+ }
226+ signer , err := parsePrivateKey (buffer , []byte (args .Passphrase ))
227+ if err != nil {
228+ return nil , err
229+ }
230+ methods = append (methods , ssh .PublicKeys (signer ))
231+ }
232+
233+ if len (methods ) > 0 {
234+ return methods , nil
235+ } else {
236+ return nil , fmt .Errorf ("could not determinate an sftp auth method" )
237+ }
238+ }
239+
240+ func parsePrivateKey (key []byte , passphrase []byte ) (ssh.Signer , error ) {
241+ var signer ssh.Signer
242+ var err error
243+ if len (passphrase ) > 0 {
244+ signer , err = ssh .ParsePrivateKeyWithPassphrase (key , passphrase )
245+ } else {
246+ signer , err = ssh .ParsePrivateKey (key )
247+ }
248+ if err != nil {
249+ return nil , fmt .Errorf ("could not parse private key: %w" , err )
250+ }
251+ return signer , nil
252+ }
253+
200254func createDirectory (client * sftp.Client , directory string ) error {
201255 if directory == defaultDirectory {
202256 return nil
0 commit comments