move server version setting to common section
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
7b5ad6c38d
commit
d3f42e39db
22 changed files with 86 additions and 91 deletions
4
go.mod
4
go.mod
|
@ -53,7 +53,7 @@ require (
|
|||
github.com/rs/xid v1.5.0
|
||||
github.com/rs/zerolog v1.32.0
|
||||
github.com/sftpgo/sdk v0.1.6-0.20240426175227-52f492b8b83b
|
||||
github.com/shirou/gopsutil/v3 v3.24.3
|
||||
github.com/shirou/gopsutil/v3 v3.24.4
|
||||
github.com/spf13/afero v1.11.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/viper v1.18.2
|
||||
|
@ -73,7 +73,7 @@ require (
|
|||
golang.org/x/sys v0.19.0
|
||||
golang.org/x/term v0.19.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/api v0.176.1
|
||||
google.golang.org/api v0.177.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
)
|
||||
|
||||
|
|
9
go.sum
9
go.sum
|
@ -353,8 +353,8 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
|||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/sftpgo/sdk v0.1.6-0.20240426175227-52f492b8b83b h1:BazWPub9GBUKvfM2O6MHhAwd9JbPD1i3UudhmHfGc2w=
|
||||
github.com/sftpgo/sdk v0.1.6-0.20240426175227-52f492b8b83b/go.mod h1:AWoY2YYe/P1ymfTlRER/meERQjCcZZTbgVPGcPQgaqc=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU=
|
||||
github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
|
@ -482,7 +482,6 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -512,8 +511,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
google.golang.org/api v0.176.1 h1:DJSXnV6An+NhJ1J+GWtoF2nHEuqB1VNoTfnIbjNvwD4=
|
||||
google.golang.org/api v0.176.1/go.mod h1:j2MaSDYcvYV1lkZ1+SMW4IeF90SrEyFA+tluDYWRrFg=
|
||||
google.golang.org/api v0.177.0 h1:8a0p/BbPa65GlqGWtUKxot4p0TV8OGOfyTjtmkXNXmk=
|
||||
google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
|
|
@ -489,7 +489,7 @@ func (c *Configuration) setup() (*account, *lego.Client, error) {
|
|||
config := lego.NewConfig(&account)
|
||||
config.CADirURL = c.CAEndpoint
|
||||
config.Certificate.KeyType = certcrypto.KeyType(c.KeyType)
|
||||
config.UserAgent = fmt.Sprintf("SFTPGo/%v", version.Get().Version)
|
||||
config.UserAgent = version.GetServerVersion("/", false)
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
acmeLog(logger.LevelError, "unable to get ACME client: %v", err)
|
||||
|
@ -555,7 +555,7 @@ func (c *Configuration) register(client *lego.Client) (*registration.Resource, e
|
|||
func (c *Configuration) tryRecoverRegistration(privateKey crypto.PrivateKey) (*registration.Resource, error) {
|
||||
config := lego.NewConfig(&account{key: privateKey})
|
||||
config.CADirURL = c.CAEndpoint
|
||||
config.UserAgent = fmt.Sprintf("SFTPGo/%v", version.Get().Version)
|
||||
config.UserAgent = version.GetServerVersion("/", false)
|
||||
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
|
|
|
@ -42,6 +42,7 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/plugin"
|
||||
"github.com/drakkan/sftpgo/v2/internal/smtp"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/version"
|
||||
"github.com/drakkan/sftpgo/v2/internal/vfs"
|
||||
)
|
||||
|
||||
|
@ -168,6 +169,7 @@ var (
|
|||
func Initialize(c Configuration, isShared int) error {
|
||||
isShuttingDown.Store(false)
|
||||
util.SetUmask(c.Umask)
|
||||
version.SetConfig(c.ServerVersion)
|
||||
Config = c
|
||||
Config.Actions.ExecuteOn = util.RemoveDuplicates(Config.Actions.ExecuteOn, true)
|
||||
Config.Actions.ExecuteSync = util.RemoveDuplicates(Config.Actions.ExecuteSync, true)
|
||||
|
@ -577,6 +579,8 @@ type Configuration struct {
|
|||
RateLimitersConfig []RateLimiterConfig `json:"rate_limiters" mapstructure:"rate_limiters"`
|
||||
// Umask for new uploads. Leave blank to use the system default.
|
||||
Umask string `json:"umask" mapstructure:"umask"`
|
||||
// Defines the server version
|
||||
ServerVersion string `json:"server_version" mapstructure:"server_version"`
|
||||
// Metadata configuration
|
||||
Metadata MetadataConfig `json:"metadata" mapstructure:"metadata"`
|
||||
idleTimeoutAsDuration time.Duration
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/kms"
|
||||
"github.com/drakkan/sftpgo/v2/internal/plugin"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/version"
|
||||
"github.com/drakkan/sftpgo/v2/internal/vfs"
|
||||
)
|
||||
|
||||
|
@ -1768,6 +1769,21 @@ func TestALPNProtocols(t *testing.T) {
|
|||
assert.Equal(t, []string{"h2", "http/1.1"}, protocols)
|
||||
}
|
||||
|
||||
func TestServerVersion(t *testing.T) {
|
||||
appName := "SFTPGo"
|
||||
version.SetConfig("")
|
||||
v := version.GetServerVersion("_", false)
|
||||
assert.Equal(t, fmt.Sprintf("%s_%s", appName, version.Get().Version), v)
|
||||
v = version.GetServerVersion("-", true)
|
||||
assert.Equal(t, fmt.Sprintf("%s-%s-", appName, version.Get().Version), v)
|
||||
version.SetConfig("short")
|
||||
v = version.GetServerVersion("_", false)
|
||||
assert.Equal(t, appName, v)
|
||||
v = version.GetServerVersion("_", true)
|
||||
assert.Equal(t, appName+"_", v)
|
||||
version.SetConfig("")
|
||||
}
|
||||
|
||||
func BenchmarkBcryptHashing(b *testing.B) {
|
||||
bcryptPassword := "bcryptpassword"
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
|
|
@ -41,7 +41,6 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/smtp"
|
||||
"github.com/drakkan/sftpgo/v2/internal/telemetry"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/version"
|
||||
"github.com/drakkan/sftpgo/v2/internal/webdavd"
|
||||
)
|
||||
|
||||
|
@ -58,7 +57,6 @@ const (
|
|||
|
||||
var (
|
||||
globalConf globalConfig
|
||||
defaultFTPDBanner = fmt.Sprintf("SFTPGo %v ready", version.Get().Version)
|
||||
defaultInstallCodeHint = "Installation code"
|
||||
defaultSFTPDBinding = sftpd.Binding{
|
||||
Address: "",
|
||||
|
@ -231,6 +229,7 @@ func Init() {
|
|||
},
|
||||
RateLimitersConfig: []common.RateLimiterConfig{defaultRateLimiter},
|
||||
Umask: "",
|
||||
ServerVersion: "",
|
||||
Metadata: common.MetadataConfig{
|
||||
Read: 0,
|
||||
},
|
||||
|
@ -254,7 +253,6 @@ func Init() {
|
|||
SFTPD: sftpd.Configuration{
|
||||
Bindings: []sftpd.Binding{defaultSFTPDBinding},
|
||||
MaxAuthTries: 0,
|
||||
Banner: "",
|
||||
HostKeys: []string{},
|
||||
HostCertificates: []string{},
|
||||
HostKeyAlgorithms: []string{},
|
||||
|
@ -272,7 +270,6 @@ func Init() {
|
|||
},
|
||||
FTPD: ftpd.Configuration{
|
||||
Bindings: []ftpd.Binding{defaultFTPDBinding},
|
||||
Banner: defaultFTPDBanner,
|
||||
BannerFile: "",
|
||||
ActiveTransfersPortNon20: true,
|
||||
PassivePortRange: ftpd.PortRange{
|
||||
|
@ -757,9 +754,6 @@ func isExternalAuthScopeValid() bool {
|
|||
}
|
||||
|
||||
func resetInvalidConfigs() {
|
||||
if strings.TrimSpace(globalConf.FTPD.Banner) == "" {
|
||||
globalConf.FTPD.Banner = defaultFTPDBanner
|
||||
}
|
||||
if strings.TrimSpace(globalConf.HTTPDConfig.Setup.InstallationCodeHint) == "" {
|
||||
globalConf.HTTPDConfig.Setup.InstallationCodeHint = defaultInstallCodeHint
|
||||
}
|
||||
|
@ -1996,6 +1990,7 @@ func setViperDefaults() {
|
|||
viper.SetDefault("common.defender.entries_soft_limit", globalConf.Common.DefenderConfig.EntriesSoftLimit)
|
||||
viper.SetDefault("common.defender.entries_hard_limit", globalConf.Common.DefenderConfig.EntriesHardLimit)
|
||||
viper.SetDefault("common.umask", globalConf.Common.Umask)
|
||||
viper.SetDefault("common.server_version", globalConf.Common.ServerVersion)
|
||||
viper.SetDefault("common.metadata.read", globalConf.Common.Metadata.Read)
|
||||
viper.SetDefault("acme.email", globalConf.ACME.Email)
|
||||
viper.SetDefault("acme.key_type", globalConf.ACME.KeyType)
|
||||
|
@ -2008,7 +2003,6 @@ func setViperDefaults() {
|
|||
viper.SetDefault("acme.http01_challenge.proxy_header", globalConf.ACME.HTTP01Challenge.ProxyHeader)
|
||||
viper.SetDefault("acme.tls_alpn01_challenge.port", globalConf.ACME.TLSALPN01Challenge.Port)
|
||||
viper.SetDefault("sftpd.max_auth_tries", globalConf.SFTPD.MaxAuthTries)
|
||||
viper.SetDefault("sftpd.banner", globalConf.SFTPD.Banner)
|
||||
viper.SetDefault("sftpd.host_keys", globalConf.SFTPD.HostKeys)
|
||||
viper.SetDefault("sftpd.host_certificates", globalConf.SFTPD.HostCertificates)
|
||||
viper.SetDefault("sftpd.host_key_algorithms", globalConf.SFTPD.HostKeyAlgorithms)
|
||||
|
@ -2023,7 +2017,6 @@ func setViperDefaults() {
|
|||
viper.SetDefault("sftpd.keyboard_interactive_authentication", globalConf.SFTPD.KeyboardInteractiveAuthentication)
|
||||
viper.SetDefault("sftpd.keyboard_interactive_auth_hook", globalConf.SFTPD.KeyboardInteractiveHook)
|
||||
viper.SetDefault("sftpd.password_authentication", globalConf.SFTPD.PasswordAuthentication)
|
||||
viper.SetDefault("ftpd.banner", globalConf.FTPD.Banner)
|
||||
viper.SetDefault("ftpd.banner_file", globalConf.FTPD.BannerFile)
|
||||
viper.SetDefault("ftpd.active_transfers_port_non_20", globalConf.FTPD.ActiveTransfersPortNon20)
|
||||
viper.SetDefault("ftpd.passive_port_range.start", globalConf.FTPD.PassivePortRange.Start)
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/sftpgo/sdk/kms"
|
||||
|
@ -31,7 +30,6 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/common"
|
||||
"github.com/drakkan/sftpgo/v2/internal/config"
|
||||
"github.com/drakkan/sftpgo/v2/internal/dataprovider"
|
||||
"github.com/drakkan/sftpgo/v2/internal/ftpd"
|
||||
"github.com/drakkan/sftpgo/v2/internal/httpclient"
|
||||
"github.com/drakkan/sftpgo/v2/internal/httpd"
|
||||
"github.com/drakkan/sftpgo/v2/internal/mfa"
|
||||
|
@ -124,42 +122,6 @@ func TestReadEnvFiles(t *testing.T) {
|
|||
os.RemoveAll(envd)
|
||||
}
|
||||
|
||||
func TestEmptyBanner(t *testing.T) {
|
||||
reset()
|
||||
|
||||
confName := tempConfigName + ".json"
|
||||
configFilePath := filepath.Join(configDir, confName)
|
||||
err := config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
sftpdConf := config.GetSFTPDConfig()
|
||||
sftpdConf.Banner = " "
|
||||
c := make(map[string]sftpd.Configuration)
|
||||
c["sftpd"] = sftpdConf
|
||||
jsonConf, _ := json.Marshal(c)
|
||||
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, confName)
|
||||
assert.NoError(t, err)
|
||||
sftpdConf = config.GetSFTPDConfig()
|
||||
assert.Empty(t, strings.TrimSpace(sftpdConf.Banner))
|
||||
err = os.Remove(configFilePath)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ftpdConf := config.GetFTPDConfig()
|
||||
ftpdConf.Banner = " "
|
||||
c1 := make(map[string]ftpd.Configuration)
|
||||
c1["ftpd"] = ftpdConf
|
||||
jsonConf, _ = json.Marshal(c1)
|
||||
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, confName)
|
||||
assert.NoError(t, err)
|
||||
ftpdConf = config.GetFTPDConfig()
|
||||
assert.NotEmpty(t, strings.TrimSpace(ftpdConf.Banner))
|
||||
err = os.Remove(configFilePath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEnabledSSHCommands(t *testing.T) {
|
||||
reset()
|
||||
|
||||
|
|
|
@ -262,10 +262,7 @@ type ServiceStatus struct {
|
|||
type Configuration struct {
|
||||
// Addresses and ports to bind to
|
||||
Bindings []Binding `json:"bindings" mapstructure:"bindings"`
|
||||
// Greeting banner displayed when a connection first comes in
|
||||
Banner string `json:"banner" mapstructure:"banner"`
|
||||
// the contents of the specified file, if any, are diplayed when someone connects to the server.
|
||||
// If set, it overrides the banner string provided by the banner option
|
||||
// The contents of the specified file, if any, are diplayed when someone connects to the server.
|
||||
BannerFile string `json:"banner_file" mapstructure:"banner_file"`
|
||||
// If files containing a certificate and matching private key for the server are provided the server will accept
|
||||
// both plain FTP an explicit FTP over TLS.
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/common"
|
||||
"github.com/drakkan/sftpgo/v2/internal/dataprovider"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/version"
|
||||
"github.com/drakkan/sftpgo/v2/internal/vfs"
|
||||
)
|
||||
|
||||
|
@ -440,7 +441,7 @@ func TestInitialization(t *testing.T) {
|
|||
c.CertificateKeyFile = ""
|
||||
c.BannerFile = "afile"
|
||||
server := NewServer(c, configDir, binding, 0)
|
||||
assert.Equal(t, "", server.initialMsg)
|
||||
assert.Equal(t, version.GetServerVersion("_", false), server.initialMsg)
|
||||
_, err = server.GetTLSConfig()
|
||||
assert.Error(t, err)
|
||||
|
||||
|
|
|
@ -48,10 +48,11 @@ type Server struct {
|
|||
// NewServer returns a new FTP server driver
|
||||
func NewServer(config *Configuration, configDir string, binding Binding, id int) *Server {
|
||||
binding.setCiphers()
|
||||
vers := version.GetServerVersion("_", false)
|
||||
server := &Server{
|
||||
config: config,
|
||||
initialMsg: config.Banner,
|
||||
statusBanner: fmt.Sprintf("SFTPGo %v FTP Server", version.Get().Version),
|
||||
initialMsg: vers,
|
||||
statusBanner: fmt.Sprintf("%s FTP Server", vers),
|
||||
binding: binding,
|
||||
ID: id,
|
||||
}
|
||||
|
|
|
@ -1087,6 +1087,7 @@ func (s *httpdServer) updateContextFromCookie(r *http.Request) *http.Request {
|
|||
|
||||
func (s *httpdServer) parseHeaders(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Server", version.GetServerVersion("/", false))
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
var ip net.IP
|
||||
isUnixSocket := filepath.IsAbs(s.binding.Address)
|
||||
|
|
|
@ -16,7 +16,6 @@ package httpd
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
|
@ -118,11 +117,10 @@ func hasPrefixAndSuffix(key, prefix, suffix string) bool {
|
|||
}
|
||||
|
||||
func getCommonBasePage(r *http.Request) commonBasePage {
|
||||
v := version.Get()
|
||||
return commonBasePage{
|
||||
CSPNonce: secure.CSPNonce(r.Context()),
|
||||
StaticURL: webStaticFilesPath,
|
||||
Version: fmt.Sprintf("v%v-%v", v.Version, v.CommitHash),
|
||||
Version: version.GetServerVersion(" ", true),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/logger"
|
||||
"github.com/drakkan/sftpgo/v2/internal/sftpd"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/version"
|
||||
"github.com/drakkan/sftpgo/v2/internal/webdavd"
|
||||
)
|
||||
|
||||
|
@ -232,9 +231,6 @@ func configurePortableFTPService(port int, cert, key string) {
|
|||
} else {
|
||||
ftpConf.Bindings[0].Port = 0
|
||||
}
|
||||
if ftpConf.Banner == "" {
|
||||
ftpConf.Banner = fmt.Sprintf("SFTPGo portable %v ready", version.Get().Version)
|
||||
}
|
||||
ftpConf.Bindings[0].CertificateFile = cert
|
||||
ftpConf.Bindings[0].CertificateKeyFile = key
|
||||
config.SetFTPDConfig(ftpConf)
|
||||
|
|
|
@ -107,8 +107,6 @@ func (b *Binding) HasProxy() bool {
|
|||
|
||||
// Configuration for the SFTP server
|
||||
type Configuration struct {
|
||||
// Identification string used by the server
|
||||
Banner string `json:"banner" mapstructure:"banner"`
|
||||
// Addresses and ports to bind to
|
||||
Bindings []Binding `json:"bindings" mapstructure:"bindings"`
|
||||
// Maximum number of authentication attempts permitted per connection.
|
||||
|
@ -227,13 +225,6 @@ func (c *Configuration) ShouldBind() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (c *Configuration) getServerVersion() string {
|
||||
if c.Banner == "short" {
|
||||
return "SSH-2.0-SFTPGo"
|
||||
}
|
||||
return fmt.Sprintf("SSH-2.0-SFTPGo_%v", version.Get().Version)
|
||||
}
|
||||
|
||||
func (c *Configuration) getServerConfig() *ssh.ServerConfig {
|
||||
serverConfig := &ssh.ServerConfig{
|
||||
NoClientAuth: false,
|
||||
|
@ -251,7 +242,7 @@ func (c *Configuration) getServerConfig() *ssh.ServerConfig {
|
|||
|
||||
return sp, nil
|
||||
},
|
||||
ServerVersion: c.getServerVersion(),
|
||||
ServerVersion: fmt.Sprintf("SSH-2.0-%s", version.GetServerVersion("_", false)),
|
||||
}
|
||||
|
||||
if c.PasswordAuthentication {
|
||||
|
|
|
@ -323,9 +323,8 @@ func (c *Config) getMailClientOptions() []mail.Option {
|
|||
|
||||
func (c *Config) getSMTPClientAndMsg(to, bcc []string, subject, body string, contentType EmailContentType,
|
||||
attachments ...*mail.File) (*mail.Client, *mail.Msg, error) {
|
||||
version := version.Get()
|
||||
msg := mail.NewMsg()
|
||||
msg.SetUserAgent(fmt.Sprintf("SFTPGo-%s-%s", version.Version, version.CommitHash))
|
||||
msg.SetUserAgent(version.GetServerVersion(" ", true))
|
||||
|
||||
var from string
|
||||
if c.From != "" {
|
||||
|
|
|
@ -17,7 +17,10 @@ package version
|
|||
|
||||
import "strings"
|
||||
|
||||
const version = "2.5.99-dev"
|
||||
const (
|
||||
version = "2.5.99-dev"
|
||||
appName = "SFTPGo"
|
||||
)
|
||||
|
||||
var (
|
||||
commit = ""
|
||||
|
@ -25,6 +28,10 @@ var (
|
|||
info Info
|
||||
)
|
||||
|
||||
var (
|
||||
config string
|
||||
)
|
||||
|
||||
// Info defines version details
|
||||
type Info struct {
|
||||
Version string `json:"version"`
|
||||
|
@ -69,3 +76,33 @@ func AddFeature(feature string) {
|
|||
func Get() Info {
|
||||
return info
|
||||
}
|
||||
|
||||
// SetConfig sets the version configuration
|
||||
func SetConfig(val string) {
|
||||
config = val
|
||||
}
|
||||
|
||||
// GetServerVersion returns the server version according to the configuration
|
||||
// and the provided parameters.
|
||||
func GetServerVersion(separator string, addHash bool) string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString(appName)
|
||||
if config != "short" {
|
||||
sb.WriteString(separator)
|
||||
sb.WriteString(info.Version)
|
||||
}
|
||||
if addHash {
|
||||
sb.WriteString(separator)
|
||||
sb.WriteString(info.CommitHash)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// GetVersionHash returns the server identification string with the commit hash.
|
||||
func GetVersionHash() string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString(appName)
|
||||
sb.WriteString("-")
|
||||
sb.WriteString(info.CommitHash)
|
||||
return sb.String()
|
||||
}
|
||||
|
|
|
@ -1133,11 +1133,10 @@ func checkDirectoryMarkers(contentType string, metadata map[string]*string) bool
|
|||
}
|
||||
|
||||
func getAzContainerClientOptions() *container.ClientOptions {
|
||||
version := version.Get()
|
||||
return &container.ClientOptions{
|
||||
ClientOptions: azcore.ClientOptions{
|
||||
Telemetry: policy.TelemetryOptions{
|
||||
ApplicationID: fmt.Sprintf("SFTPGo-%s", version.CommitHash),
|
||||
ApplicationID: version.GetVersionHash(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ func NewS3Fs(connectionID, localTempDir, mountPath string, s3Config S3FsConfig)
|
|||
awsConfig.Credentials = creds
|
||||
}
|
||||
fs.svc = s3.NewFromConfig(awsConfig, func(o *s3.Options) {
|
||||
o.AppID = fmt.Sprintf("SFTPGo-%s", version.Get().CommitHash)
|
||||
o.AppID = version.GetVersionHash()
|
||||
o.UsePathStyle = fs.config.ForcePathStyle
|
||||
if fs.config.Endpoint != "" {
|
||||
o.BaseEndpoint = aws.String(fs.config.Endpoint)
|
||||
|
|
|
@ -977,7 +977,7 @@ func (c *sftpConnection) openConnNoLock() error {
|
|||
return nil
|
||||
},
|
||||
Timeout: 15 * time.Second,
|
||||
ClientVersion: fmt.Sprintf("SSH-2.0-SFTPGo_%v", version.Get().Version),
|
||||
ClientVersion: fmt.Sprintf("SSH-2.0-%s", version.GetServerVersion("_", false)),
|
||||
}
|
||||
signer, err := c.getKeySigner()
|
||||
if err != nil {
|
||||
|
|
|
@ -41,6 +41,7 @@ import (
|
|||
"github.com/drakkan/sftpgo/v2/internal/metric"
|
||||
"github.com/drakkan/sftpgo/v2/internal/plugin"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/version"
|
||||
)
|
||||
|
||||
type webDavServer struct {
|
||||
|
@ -165,6 +166,7 @@ func (s *webDavServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}()
|
||||
|
||||
w.Header().Set("Server", version.GetServerVersion("/", false))
|
||||
ipAddr := s.checkRemoteAddress(r)
|
||||
|
||||
common.Connections.AddClientConnection(ipAddr)
|
||||
|
@ -194,7 +196,7 @@ func (s *webDavServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
user, isCached, lockSystem, loginMethod, err := s.authenticate(r, ipAddr)
|
||||
if err != nil {
|
||||
if !s.binding.DisableWWWAuthHeader {
|
||||
w.Header().Set("WWW-Authenticate", "Basic realm=\"SFTPGo WebDAV\"")
|
||||
w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=\"%s WebDAV\"", version.GetServerVersion("_", false)))
|
||||
}
|
||||
http.Error(w, fmt.Sprintf("Authentication error: %v", err), http.StatusUnauthorized)
|
||||
return
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"allowlist_status": 0,
|
||||
"allow_self_connections": 0,
|
||||
"umask": "",
|
||||
"server_version": "",
|
||||
"metadata": {
|
||||
"read": 0
|
||||
},
|
||||
|
@ -83,7 +84,6 @@
|
|||
}
|
||||
],
|
||||
"max_auth_tries": 0,
|
||||
"banner": "",
|
||||
"host_keys": [],
|
||||
"host_certificates": [],
|
||||
"host_key_algorithms": [],
|
||||
|
@ -129,7 +129,6 @@
|
|||
"debug": false
|
||||
}
|
||||
],
|
||||
"banner": "",
|
||||
"banner_file": "",
|
||||
"active_transfers_port_non_20": true,
|
||||
"passive_port_range": {
|
||||
|
|
|
@ -881,7 +881,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div id="kt_app_footer" class="app-footer">
|
||||
<div class="app-container container-fluid d-flex flex-column flex-md-row flex-center flex-md-stack py-3 align-items-center justify-content-center">
|
||||
<div class="text-gray-900 order-2 order-md-1">
|
||||
<span class="text-gray-700 fw-semibold me-1">SFTPGo {{.Version}}</span>
|
||||
<span class="text-gray-700 fw-semibold me-1">{{.Version}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue