Skip to content

Commit

Permalink
Add IncludeInsecureCiphers option to FTP backend. (#205)
Browse files Browse the repository at this point in the history
* Add IncludeInsecureCiphers option to FTP backend.

* fix tests and add doc

* added comment fixes #204

* fixed changelog header
  • Loading branch information
funkyshu authored Oct 16, 2024
1 parent a405c69 commit f5ad8dc
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]

## [6.20.0] - 2024-10-15
### Added
- Add IncludeInsecureCiphers option to FTP backend. Fixes #204.

## [6.19.0] - 2024-09-13
### Added
- Add ability to set file permissions after writing an SFTP file. Resolves #202.
Expand Down
3 changes: 3 additions & 0 deletions backend/ftp/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ These methods are chainable:
Protocol: ftp.ProtocolFTPES,
DialTimeout: 15 * time.Second,
DebugWriter: os.Stdout,
IncludeInsecureCiphers: true,
},
)
Expand Down Expand Up @@ -148,5 +149,7 @@ DebugWriter *io.Writer* - captures FTP command details to any writer.
DialTimeout *time.Duration - sets timeout for connecting only.
DisableEPSV bool - Extended Passive mode (EPSV) is attempted by default. Set to true to use regular Passive mode (PASV).
IncludeInsecureCiphers bool - If set to true, includes insecure cipher suites in the TLS configuration.
*/
package ftp
29 changes: 23 additions & 6 deletions backend/ftp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import (

// Options struct implements the vfs.Options interface, providing optional parameters for creating and ftp filesystem.
type Options struct {
Password string // env var VFS_FTP_PASSWORD
Protocol string // env var VFS_FTP_PROTOCOL
DisableEPSV *bool // env var VFS_DISABLE_EPSV
DebugWriter io.Writer
TLSConfig *tls.Config
DialTimeout time.Duration
Password string // env var VFS_FTP_PASSWORD
Protocol string // env var VFS_FTP_PROTOCOL
DisableEPSV *bool // env var VFS_DISABLE_EPSV
DebugWriter io.Writer
TLSConfig *tls.Config
DialTimeout time.Duration
IncludeInsecureCiphers bool
}

const (
Expand Down Expand Up @@ -162,6 +163,22 @@ func fetchTLSConfig(auth utils.Authority, opts Options) *tls.Config {
ServerName: auth.Host(),
}

if opts.IncludeInsecureCiphers {
var suites []uint16

// get default cipher suites
for _, suite := range tls.CipherSuites() {
suites = append(suites, suite.ID)
}

// add insecure cipher suites
for _, suite := range tls.InsecureCipherSuites() {
suites = append(suites, suite.ID)
}

tlsConfig.CipherSuites = suites
}

// override with Options, if any
if opts.TLSConfig != nil {
tlsConfig = opts.TLSConfig
Expand Down
46 changes: 41 additions & 5 deletions backend/ftp/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,11 @@ func (s *optionsSuite) TestFetchTLSConfig() {
}

tests := []struct {
description string
authority string
options Options
expected *tls.Config
description string
authority string
options Options
expected *tls.Config
expectInsecureCipherSuites bool
}{
{
description: "check defaults",
Expand All @@ -239,15 +240,50 @@ func (s *optionsSuite) TestFetchTLSConfig() {
},
expected: cfg,
},
{
description: "include insecure cipher suites",
authority: "[email protected]",
options: Options{
IncludeInsecureCiphers: true,
},
expected: &tls.Config{
MinVersion: tls.VersionTLS12,
InsecureSkipVerify: true, //nolint:gosec
ClientSessionCache: tls.NewLRUClientSessionCache(0),
ServerName: "host.com",
},
expectInsecureCipherSuites: true,
},
}

for i := range tests {
auth, err := utils.NewAuthority(tests[i].authority)
s.NoError(err, tests[i].description)

tlsCfg := fetchTLSConfig(auth, tests[i].options)
s.Equal(tests[i].expected, tlsCfg, tests[i].description)
s.Equal(tests[i].expected.MinVersion, tlsCfg.MinVersion, tests[i].description)
s.Equal(tests[i].expected.InsecureSkipVerify, tlsCfg.InsecureSkipVerify, tests[i].description)
s.Equal(tests[i].expected.ClientSessionCache, tlsCfg.ClientSessionCache, tests[i].description)
s.Equal(tests[i].expected.ServerName, tlsCfg.ServerName, tests[i].description)
s.Equal(tests[i].expected.SessionTicketsDisabled, tlsCfg.SessionTicketsDisabled, tests[i].description)

if tests[i].expectInsecureCipherSuites {
s.NotEmpty(tlsCfg.CipherSuites, tests[i].description)
s.True(containsInsecureCipherSuites(tlsCfg.CipherSuites), tests[i].description)
}
}
}

func containsInsecureCipherSuites(suites []uint16) bool {
insecureSuites := tls.InsecureCipherSuites()
for _, s := range suites {
for _, insecureSuite := range insecureSuites {
if s == insecureSuite.ID {
return true
}
}
}
return false
}

func (s *optionsSuite) TestFetchProtocol() {
Expand Down

0 comments on commit f5ad8dc

Please sign in to comment.