Files
golib/ftpclient/config.go
Nicolas JUHEL 22b364593e Package certificates:
- rework package to allow convert config to model and retrive config from model
- add sub package to manage cipher, curves, auth client, tls version, certificates, root ca...
- add some small test (can be expande to having more coverage)
- optimize some code

Package httpcli:
- update code following change in certificates

Package httpserver:
- update code following change in certificates

Package Config/Components:
- update code following change in certificates

Package FTPClient:
- update code following change in certificates

Package Nats:
- update code following change in certificates
2024-12-04 17:30:22 +01:00

162 lines
5.4 KiB
Go

/*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
package ftpclient
import (
"context"
"fmt"
"time"
libval "github.com/go-playground/validator/v10"
libftp "github.com/jlaffaye/ftp"
libtls "github.com/nabbar/golib/certificates"
)
type ConfigTimeZone struct {
Name string `mapstructure:"name" json:"name" yaml:"name" toml:"name"`
Offset int `mapstructure:"offset" json:"offset" yaml:"offset" toml:"offset"`
}
type Config struct {
// Hostname define the host/port to connect to server.
Hostname string `mapstructure:"hostname" json:"hostname" yaml:"hostname" toml:"hostname" validate:"required,hostname_rfc1123"`
// Login define the login to use in login command.
Login string `mapstructure:"login" json:"login" yaml:"login" toml:"login"`
// Password defined the password to use in the login command.
Password string `mapstructure:"password" json:"password" yaml:"password" toml:"password"`
// ConnTimeout define a timeout duration for each connection (this is a global connection : connection, store contents, read content, ...).
ConnTimeout time.Duration `mapstructure:"conn_timeout" json:"conn_timeout" yaml:"conn_timeout" toml:"conn_timeout"`
// TimeZone force the time zone to use for the connection to the server.
TimeZone ConfigTimeZone `mapstructure:"timezone" json:"timezone" yaml:"timezone" toml:"timezone"`
// DisableUTF8 disable the UTF8 translation into the connection to the server.
DisableUTF8 bool `mapstructure:"disable_utf8" json:"disable_utf8" yaml:"disable_utf8" toml:"disable_utf8"`
// DisableEPSV disable the EPSV command into the connection to the server. (cf RFC 2428).
DisableEPSV bool `mapstructure:"disable_epsv" json:"disable_epsv" yaml:"disable_epsv" toml:"disable_epsv"`
// DisableMLSD disable the MLSD command into the connection to the server. (cf RFC 3659)
DisableMLSD bool `mapstructure:"disable_mlsd" json:"disable_mlsd" yaml:"disable_mlsd" toml:"disable_mlsd"`
// EnableMDTM enable the MDTM command into the connection to the server. (cf RFC 3659)
EnableMDTM bool `mapstructure:"enable_mdtm" json:"enable_mdtm" yaml:"enable_mdtm" toml:"enable_mdtm"`
// ForceTLS defined if the TLS connection must be forced or not.
ForceTLS bool `mapstructure:"force_tls" json:"force_tls" yaml:"force_tls" toml:"force_tls"`
// TLS define the client TLS config used if needed or forced
TLS libtls.Config `mapstructure:"tls" json:"tls" yaml:"tls" toml:"tls"`
fctx func() context.Context
ftls func() libtls.TLSConfig
}
// Validate allow checking if the config' struct is valid with the awaiting model
func (c *Config) Validate() error {
var e = ErrorValidatorError.Error(nil)
if err := libval.New().Struct(c); err != nil {
if er, ok := err.(*libval.InvalidValidationError); ok {
e.Add(er)
}
for _, er := range err.(libval.ValidationErrors) {
//nolint #goerr113
e.Add(fmt.Errorf("config field '%s' is not validated by constraint '%s'", er.Namespace(), er.ActualTag()))
}
}
if !e.HasParent() {
e = nil
}
return e
}
func (c *Config) RegisterContext(fct func() context.Context) {
c.fctx = fct
}
func (c *Config) RegisterDefaultTLS(fct func() libtls.TLSConfig) {
c.ftls = fct
}
func (c *Config) New() (*libftp.ServerConn, error) {
var opt = make([]libftp.DialOption, 0)
if tls := c.TLS.NewFrom(c.ftls()); tls == nil {
return nil, fmt.Errorf("no tls configured")
} else if c.ForceTLS {
opt = append(opt, libftp.DialWithExplicitTLS(tls.TlsConfig("")))
} else {
opt = append(opt, libftp.DialWithTLS(tls.TlsConfig("")))
}
if c.fctx != nil {
opt = append(opt, libftp.DialWithContext(c.fctx()))
}
if c.ConnTimeout != 0 {
opt = append(opt, libftp.DialWithTimeout(c.ConnTimeout))
}
if c.TimeZone.Name != "" {
tz := time.FixedZone(c.TimeZone.Name, c.TimeZone.Offset)
opt = append(opt, libftp.DialWithLocation(tz))
}
if c.DisableUTF8 {
opt = append(opt, libftp.DialWithDisabledUTF8(true))
}
if c.DisableEPSV {
opt = append(opt, libftp.DialWithDisabledEPSV(true))
}
if c.DisableMLSD {
opt = append(opt, libftp.DialWithDisabledMLSD(true))
}
if c.EnableMDTM {
opt = append(opt, libftp.DialWithWritingMDTM(true))
}
if cli, err := libftp.Dial(c.Hostname, opt...); err != nil {
return nil, ErrorFTPConnection.Error(err)
} else if c.Login == "" && c.Password == "" {
return cli, nil
} else if err = cli.Login(c.Login, c.Password); err != nil {
return cli, ErrorFTPLogin.Error(err)
} else {
return cli, nil
}
}