From 7fd5558400a32ba40ea701fa1bf4317cf7329027 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Thu, 9 Jun 2022 09:48:39 +0200 Subject: [PATCH] parse IP proxy header also if listening on UNIX domain socket Fixes #867 Signed-off-by: Nicola Murino --- docs/repo.md | 2 +- httpd/httpd.go | 5 +++++ httpd/internal_test.go | 12 ++++++++++++ httpd/server.go | 9 +++++++-- webdavd/internal_test.go | 12 ++++++++++++ webdavd/server.go | 8 ++++++-- webdavd/webdavd.go | 5 +++++ 7 files changed, 48 insertions(+), 5 deletions(-) diff --git a/docs/repo.md b/docs/repo.md index f0b76330..d74c6884 100644 --- a/docs/repo.md +++ b/docs/repo.md @@ -1,6 +1,6 @@ # SFTPGo repositories -These repository are available through Oregon State University's free mirror service. Special thanks to Lance Albertson, Director of the Oregon State University Open Source Lab, who helped me with the initial setup. +These repositories are available through Oregon State University's free mirroring service. Special thanks to Lance Albertson, Director of the Oregon State University Open Source Lab, who helped me with the initial setup. ## APT repo diff --git a/httpd/httpd.go b/httpd/httpd.go index fd151dc2..8bc5eaab 100644 --- a/httpd/httpd.go +++ b/httpd/httpd.go @@ -476,6 +476,11 @@ func (b *Binding) checkBranding() { } func (b *Binding) parseAllowedProxy() error { + if filepath.IsAbs(b.Address) && len(b.ProxyAllowed) > 0 { + // unix domain socket + b.allowHeadersFrom = []func(net.IP) bool{func(ip net.IP) bool { return true }} + return nil + } allowedFuncs, err := util.ParseAllowedIPAndRanges(b.ProxyAllowed) if err != nil { return err diff --git a/httpd/internal_test.go b/httpd/internal_test.go index fa054163..2fb63fd6 100644 --- a/httpd/internal_test.go +++ b/httpd/internal_test.go @@ -1532,6 +1532,18 @@ func TestJWTTokenCleanup(t *testing.T) { stopCleanupTicker() } +func TestAllowedProxyUnixDomainSocket(t *testing.T) { + b := Binding{ + Address: filepath.Join(os.TempDir(), "sock"), + ProxyAllowed: []string{"127.0.0.1", "127.0.1.1"}, + } + err := b.parseAllowedProxy() + assert.NoError(t, err) + if assert.Len(t, b.allowHeadersFrom, 1) { + assert.True(t, b.allowHeadersFrom[0](nil)) + } +} + func TestProxyHeaders(t *testing.T) { username := "adminTest" password := "testPwd" diff --git a/httpd/server.go b/httpd/server.go index 0e6b1819..aae8c4db 100644 --- a/httpd/server.go +++ b/httpd/server.go @@ -9,6 +9,7 @@ import ( "log" "net" "net/http" + "path/filepath" "strings" "time" @@ -972,9 +973,13 @@ func (s *httpdServer) updateContextFromCookie(r *http.Request) *http.Request { func (s *httpdServer) checkConnection(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr) - ip := net.ParseIP(ipAddr) + var ip net.IP + isUnixSocket := filepath.IsAbs(s.binding.Address) + if !isUnixSocket { + ip = net.ParseIP(ipAddr) + } areHeadersAllowed := false - if ip != nil { + if isUnixSocket || ip != nil { for _, allow := range s.binding.allowHeadersFrom { if allow(ip) { parsedIP := util.GetRealIP(r, s.binding.ClientIPProxyHeader, s.binding.ClientIPHeaderDepth) diff --git a/webdavd/internal_test.go b/webdavd/internal_test.go index ce544634..85883e99 100644 --- a/webdavd/internal_test.go +++ b/webdavd/internal_test.go @@ -412,6 +412,18 @@ func TestUserInvalidParams(t *testing.T) { writeLog(req, http.StatusOK, nil) } +func TestAllowedProxyUnixDomainSocket(t *testing.T) { + b := Binding{ + Address: filepath.Join(os.TempDir(), "sock"), + ProxyAllowed: []string{"127.0.0.1", "127.0.1.1"}, + } + err := b.parseAllowedProxy() + assert.NoError(t, err) + if assert.Len(t, b.allowHeadersFrom, 1) { + assert.True(t, b.allowHeadersFrom[0](nil)) + } +} + func TestRemoteAddress(t *testing.T) { remoteAddr1 := "100.100.100.100" remoteAddr2 := "172.172.172.172" diff --git a/webdavd/server.go b/webdavd/server.go index ee7c339e..e3e6c29c 100644 --- a/webdavd/server.go +++ b/webdavd/server.go @@ -331,8 +331,12 @@ func (s *webDavServer) validateUser(user *dataprovider.User, r *http.Request, lo func (s *webDavServer) checkRemoteAddress(r *http.Request) string { ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr) - ip := net.ParseIP(ipAddr) - if ip != nil { + var ip net.IP + isUnixSocket := filepath.IsAbs(s.binding.Address) + if !isUnixSocket { + ip = net.ParseIP(ipAddr) + } + if isUnixSocket || ip != nil { for _, allow := range s.binding.allowHeadersFrom { if allow(ip) { parsedIP := util.GetRealIP(r, s.binding.ClientIPProxyHeader, s.binding.ClientIPHeaderDepth) diff --git a/webdavd/webdavd.go b/webdavd/webdavd.go index c73d0118..3b7d4ab2 100644 --- a/webdavd/webdavd.go +++ b/webdavd/webdavd.go @@ -109,6 +109,11 @@ type Binding struct { } func (b *Binding) parseAllowedProxy() error { + if filepath.IsAbs(b.Address) && len(b.ProxyAllowed) > 0 { + // unix domain socket + b.allowHeadersFrom = []func(net.IP) bool{func(ip net.IP) bool { return true }} + return nil + } allowedFuncs, err := util.ParseAllowedIPAndRanges(b.ProxyAllowed) if err != nil { return err