webdav: allow to disable the WWW-Authenticate header
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
fdc10aa6c7
commit
6bfdf941bc
6 changed files with 42 additions and 23 deletions
|
@ -182,6 +182,7 @@ The configuration file contains the following sections:
|
|||
- `proxy_allowed`, list of IP addresses and IP ranges allowed to set client IP proxy header such as `X-Forwarded-For`. Any client IP proxy headers, if set on requests from a connection address not in this list, will be silently ignored. Default: empty.
|
||||
- `client_ip_proxy_header`, string. Defines the allowed client IP proxy header such as `X-Forwarded-For`, `X-Real-IP` etc. Default: empty
|
||||
- `client_ip_header_depth`, integer. Some client IP headers such as `X-Forwarded-For` can contain multiple IP address, this setting define the position to trust starting from the right. For example if we have: `10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1` and the depth is `0`, SFTPGo will use `13.0.0.1` as client IP, if depth is `1`, `12.0.0.1` will be used and so on. Default: `0`.
|
||||
- `disable_www_auth_header`, boolean. Set to `true` to not add the WWW-Authenticate header after an authentication failure, only the `401` status code will be sent. Default: `false`.
|
||||
- `certificate_file`, string. Certificate for WebDAV over HTTPS. This can be an absolute path or a path relative to the config dir.
|
||||
- `certificate_key_file`, string. Private key matching the above certificate. This can be an absolute path or a path relative to the config dir. A certificate and a private key are required to enable HTTPS connections. Certificate and key files can be reloaded on demand sending a `SIGHUP` signal on Unix based systems and a `paramchange` request to the running service on Windows.
|
||||
- `ca_certificates`, list of strings. Set of root certificate authorities to be used to verify client certificates.
|
||||
|
|
|
@ -81,18 +81,19 @@ var (
|
|||
Debug: false,
|
||||
}
|
||||
defaultWebDAVDBinding = webdavd.Binding{
|
||||
Address: "",
|
||||
Port: 0,
|
||||
EnableHTTPS: false,
|
||||
CertificateFile: "",
|
||||
CertificateKeyFile: "",
|
||||
MinTLSVersion: 12,
|
||||
ClientAuthType: 0,
|
||||
TLSCipherSuites: nil,
|
||||
Prefix: "",
|
||||
ProxyAllowed: nil,
|
||||
ClientIPProxyHeader: "",
|
||||
ClientIPHeaderDepth: 0,
|
||||
Address: "",
|
||||
Port: 0,
|
||||
EnableHTTPS: false,
|
||||
CertificateFile: "",
|
||||
CertificateKeyFile: "",
|
||||
MinTLSVersion: 12,
|
||||
ClientAuthType: 0,
|
||||
TLSCipherSuites: nil,
|
||||
Prefix: "",
|
||||
ProxyAllowed: nil,
|
||||
ClientIPProxyHeader: "",
|
||||
ClientIPHeaderDepth: 0,
|
||||
DisableWWWAuthHeader: false,
|
||||
}
|
||||
defaultHTTPDBinding = httpd.Binding{
|
||||
Address: "",
|
||||
|
@ -1193,6 +1194,12 @@ func getWebDAVDBindingFromEnv(idx int) {
|
|||
isSet = true
|
||||
}
|
||||
|
||||
enableHTTPS, ok := lookupBoolFromEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__ENABLE_HTTPS", idx))
|
||||
if ok {
|
||||
binding.EnableHTTPS = enableHTTPS
|
||||
isSet = true
|
||||
}
|
||||
|
||||
certificateFile, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__CERTIFICATE_FILE", idx))
|
||||
if ok {
|
||||
binding.CertificateFile = certificateFile
|
||||
|
@ -1205,12 +1212,6 @@ func getWebDAVDBindingFromEnv(idx int) {
|
|||
isSet = true
|
||||
}
|
||||
|
||||
enableHTTPS, ok := lookupBoolFromEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__ENABLE_HTTPS", idx))
|
||||
if ok {
|
||||
binding.EnableHTTPS = enableHTTPS
|
||||
isSet = true
|
||||
}
|
||||
|
||||
tlsVer, ok := lookupIntFromEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__MIN_TLS_VERSION", idx))
|
||||
if ok {
|
||||
binding.MinTLSVersion = int(tlsVer)
|
||||
|
@ -1229,13 +1230,19 @@ func getWebDAVDBindingFromEnv(idx int) {
|
|||
isSet = true
|
||||
}
|
||||
|
||||
prefix, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__PREFIX", idx))
|
||||
if ok {
|
||||
binding.Prefix = prefix
|
||||
isSet = true
|
||||
}
|
||||
|
||||
if getWebDAVDBindingProxyConfigsFromEnv(idx, &binding) {
|
||||
isSet = true
|
||||
}
|
||||
|
||||
prefix, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__PREFIX", idx))
|
||||
disableWWWAuth, ok := lookupBoolFromEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__DISABLE_WWW_AUTH_HEADER", idx))
|
||||
if ok {
|
||||
binding.Prefix = prefix
|
||||
binding.DisableWWWAuthHeader = disableWWWAuth
|
||||
isSet = true
|
||||
}
|
||||
|
||||
|
|
|
@ -943,6 +943,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
|
|||
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__PREFIX", "/dav2")
|
||||
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__CERTIFICATE_FILE", "webdav.crt")
|
||||
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__CERTIFICATE_KEY_FILE", "webdav.key")
|
||||
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__DISABLE_WWW_AUTH_HEADER", "1")
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__ADDRESS")
|
||||
|
@ -960,6 +961,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
|
|||
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__PREFIX")
|
||||
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__CERTIFICATE_FILE")
|
||||
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__CERTIFICATE_KEY_FILE")
|
||||
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__DISABLE_WWW_AUTH_HEADER")
|
||||
})
|
||||
|
||||
err := config.LoadConfig(configDir, "")
|
||||
|
@ -973,6 +975,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
|
|||
require.Len(t, bindings[0].TLSCipherSuites, 0)
|
||||
require.Empty(t, bindings[0].Prefix)
|
||||
require.Equal(t, 0, bindings[0].ClientIPHeaderDepth)
|
||||
require.False(t, bindings[0].DisableWWWAuthHeader)
|
||||
require.Equal(t, 8000, bindings[1].Port)
|
||||
require.Equal(t, "127.0.0.1", bindings[1].Address)
|
||||
require.False(t, bindings[1].EnableHTTPS)
|
||||
|
@ -984,6 +987,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
|
|||
require.Equal(t, "X-Forwarded-For", bindings[1].ClientIPProxyHeader)
|
||||
require.Equal(t, 2, bindings[1].ClientIPHeaderDepth)
|
||||
require.Empty(t, bindings[1].Prefix)
|
||||
require.False(t, bindings[1].DisableWWWAuthHeader)
|
||||
require.Equal(t, 9000, bindings[2].Port)
|
||||
require.Equal(t, "127.0.1.1", bindings[2].Address)
|
||||
require.True(t, bindings[2].EnableHTTPS)
|
||||
|
@ -994,6 +998,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
|
|||
require.Equal(t, "webdav.crt", bindings[2].CertificateFile)
|
||||
require.Equal(t, "webdav.key", bindings[2].CertificateKeyFile)
|
||||
require.Equal(t, 0, bindings[2].ClientIPHeaderDepth)
|
||||
require.True(t, bindings[2].DisableWWWAuthHeader)
|
||||
}
|
||||
|
||||
func TestHTTPDBindingsFromEnv(t *testing.T) {
|
||||
|
|
|
@ -189,7 +189,9 @@ func (s *webDavServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
user, isCached, lockSystem, loginMethod, err := s.authenticate(r, ipAddr)
|
||||
if err != nil {
|
||||
updateLoginMetrics(&user, ipAddr, loginMethod, err)
|
||||
w.Header().Set("WWW-Authenticate", "Basic realm=\"SFTPGo WebDAV\"")
|
||||
if !s.binding.DisableWWWAuthHeader {
|
||||
w.Header().Set("WWW-Authenticate", "Basic realm=\"SFTPGo WebDAV\"")
|
||||
}
|
||||
http.Error(w, fmt.Sprintf("Authentication error: %v", err), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -122,7 +122,10 @@ type Binding struct {
|
|||
// "10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1" and the depth is 0, SFTPGo will use "13.0.0.1"
|
||||
// as client IP, if depth is 1, "12.0.0.1" will be used and so on
|
||||
ClientIPHeaderDepth int `json:"client_ip_header_depth" mapstructure:"client_ip_header_depth"`
|
||||
allowHeadersFrom []func(net.IP) bool
|
||||
// Do not add the WWW-Authenticate header after an authentication error,
|
||||
// only the 401 status code will be sent
|
||||
DisableWWWAuthHeader bool `json:"disable_www_auth_header" mapstructure:"disable_www_auth_header"`
|
||||
allowHeadersFrom []func(net.IP) bool
|
||||
}
|
||||
|
||||
func (b *Binding) parseAllowedProxy() error {
|
||||
|
|
|
@ -151,7 +151,8 @@
|
|||
"prefix": "",
|
||||
"proxy_allowed": [],
|
||||
"client_ip_proxy_header": "",
|
||||
"client_ip_header_depth": 0
|
||||
"client_ip_header_depth": 0,
|
||||
"disable_www_auth_header": false
|
||||
}
|
||||
],
|
||||
"certificate_file": "",
|
||||
|
|
Loading…
Reference in a new issue