From 2074867fab2667a186c7161569eb05832b1b2ab3 Mon Sep 17 00:00:00 2001 From: Zach Cheung Date: Thu, 22 Dec 2022 04:25:36 -0800 Subject: [PATCH] Fix #31: add FTPS / FTP Over TLS support --- go.mod | 2 ++ go.sum | 4 ++-- storage/ftp.go | 39 +++++++++++++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 490837bd..10356679 100644 --- a/go.mod +++ b/go.mod @@ -87,3 +87,5 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/jlaffaye/ftp => github.com/ncw/ftp v0.0.0-20221014105808-5da37698fc59 diff --git a/go.sum b/go.sum index 23536ba8..cd4221a9 100644 --- a/go.sum +++ b/go.sum @@ -96,8 +96,6 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/jlaffaye/ftp v0.1.0 h1:DLGExl5nBoSFoNshAUHwXAezXwXBvFdx7/qwhucWNSE= -github.com/jlaffaye/ftp v0.1.0/go.mod h1:hhq4G4crv+nW2qXtNYcuzLeOudG92Ps37HEKeg2e3lE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= @@ -122,6 +120,8 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/ncw/ftp v0.0.0-20221014105808-5da37698fc59 h1:2n3UlsEVEA86+YzzwcMetWKaFMK4H8HuLxmglvu8JUM= +github.com/ncw/ftp v0.0.0-20221014105808-5da37698fc59/go.mod h1:hhq4G4crv+nW2qXtNYcuzLeOudG92Ps37HEKeg2e3lE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0= diff --git a/storage/ftp.go b/storage/ftp.go index 42db2d9d..180c6495 100644 --- a/storage/ftp.go +++ b/storage/ftp.go @@ -1,6 +1,7 @@ package storage import ( + "crypto/tls" "fmt" "net/textproto" "os" @@ -24,13 +25,19 @@ import ( // timeout: 30 // username: // password: +// tls: +// explicit_tls: +// no_check_certificate: type FTP struct { Base - path string - host string - port string - username string - password string + path string + host string + port string + username string + password string + tls bool + explicitTLS bool + skipVerifyTLSCert bool client *ftp.ServerConn } @@ -45,13 +52,33 @@ func (s *FTP) open() error { s.path = s.viper.GetString("path") s.username = s.viper.GetString("username") s.password = s.viper.GetString("password") + s.tls = s.viper.GetBool("tls") + s.explicitTLS = s.viper.GetBool("explicit_tls") + s.skipVerifyTLSCert = s.viper.GetBool("no_check_certificate") if len(s.host) == 0 || len(s.username) == 0 || len(s.password) == 0 { return fmt.Errorf("FTP host, username or password is empty") } + var options []ftp.DialOption timeout := s.viper.GetDuration("timeout") * time.Second - client, err := ftp.Dial(s.host+":"+s.port, ftp.DialWithTimeout(timeout)) + options = append(options, ftp.DialWithTimeout(timeout)) + + // FTP Over TLS / FTPS + var tlsConfig *tls.Config + if s.tls || s.explicitTLS { + tlsConfig = &tls.Config{ + ServerName: s.host, + InsecureSkipVerify: s.skipVerifyTLSCert, + } + } + if s.tls { + options = append(options, ftp.DialWithTLS(tlsConfig)) + } else if s.explicitTLS { + options = append(options, ftp.DialWithExplicitTLS(tlsConfig)) + } + + client, err := ftp.Dial(s.host+":"+s.port, options...) if err != nil { return err }