mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-22 07:30:25 +00:00
backports from main
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
c2de3c3efc
commit
3169197252
7 changed files with 66 additions and 31 deletions
1
go.mod
1
go.mod
|
@ -185,6 +185,7 @@ require (
|
||||||
replace (
|
replace (
|
||||||
github.com/fclairamb/ftpserverlib => github.com/drakkan/ftpserverlib v0.0.0-20240603150004-6a8f643fbf2e
|
github.com/fclairamb/ftpserverlib => github.com/drakkan/ftpserverlib v0.0.0-20240603150004-6a8f643fbf2e
|
||||||
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20240430173938-7ba8270c8e7f
|
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20240430173938-7ba8270c8e7f
|
||||||
|
github.com/pires/go-proxyproto => github.com/drakkan/go-proxyproto v0.0.0-20240811060125-2e92d08b5373
|
||||||
github.com/robfig/cron/v3 => github.com/drakkan/cron/v3 v3.0.0-20230222140221-217a1e4d96c0
|
github.com/robfig/cron/v3 => github.com/drakkan/cron/v3 v3.0.0-20230222140221-217a1e4d96c0
|
||||||
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20240726170110-f4e4a4627441
|
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20240726170110-f4e4a4627441
|
||||||
)
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -119,6 +119,8 @@ github.com/drakkan/ftp v0.0.0-20240430173938-7ba8270c8e7f h1:S9JUlrOzjK58UKoLqqb
|
||||||
github.com/drakkan/ftp v0.0.0-20240430173938-7ba8270c8e7f/go.mod h1:4p8lUl4vQ80L598CygL+3IFtm+3nggvvW/palOlViwE=
|
github.com/drakkan/ftp v0.0.0-20240430173938-7ba8270c8e7f/go.mod h1:4p8lUl4vQ80L598CygL+3IFtm+3nggvvW/palOlViwE=
|
||||||
github.com/drakkan/ftpserverlib v0.0.0-20240603150004-6a8f643fbf2e h1:VBpqQeChkGXSV1FXCtvd3BJTyB+DcMgiu7SfkpsGuKw=
|
github.com/drakkan/ftpserverlib v0.0.0-20240603150004-6a8f643fbf2e h1:VBpqQeChkGXSV1FXCtvd3BJTyB+DcMgiu7SfkpsGuKw=
|
||||||
github.com/drakkan/ftpserverlib v0.0.0-20240603150004-6a8f643fbf2e/go.mod h1:aAwyOAC6IIe+IZeeGD1QjuE3GGDzqW/c5Xtn+Dp0JUM=
|
github.com/drakkan/ftpserverlib v0.0.0-20240603150004-6a8f643fbf2e/go.mod h1:aAwyOAC6IIe+IZeeGD1QjuE3GGDzqW/c5Xtn+Dp0JUM=
|
||||||
|
github.com/drakkan/go-proxyproto v0.0.0-20240811060125-2e92d08b5373 h1:0ltrbDRr7KT2aSgj2IXOzRraH2xdR+CWZjm5uC4ChXU=
|
||||||
|
github.com/drakkan/go-proxyproto v0.0.0-20240811060125-2e92d08b5373/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY=
|
||||||
github.com/drakkan/webdav v0.0.0-20240503091431-218ec83910bb h1:067/Uo8cfeY7QC0yzWCr/RImuNcM0rLWAsBUyMks59o=
|
github.com/drakkan/webdav v0.0.0-20240503091431-218ec83910bb h1:067/Uo8cfeY7QC0yzWCr/RImuNcM0rLWAsBUyMks59o=
|
||||||
github.com/drakkan/webdav v0.0.0-20240503091431-218ec83910bb/go.mod h1:zOVb1QDhwwqWn2L2qZ0U3swMSO4GTSNyIwXCGO/UGWE=
|
github.com/drakkan/webdav v0.0.0-20240503091431-218ec83910bb/go.mod h1:zOVb1QDhwwqWn2L2qZ0U3swMSO4GTSNyIwXCGO/UGWE=
|
||||||
github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001 h1:/ZshrfQzayqRSBDodmp3rhNCHJCff+utvgBuWRbiqu4=
|
github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001 h1:/ZshrfQzayqRSBDodmp3rhNCHJCff+utvgBuWRbiqu4=
|
||||||
|
@ -300,8 +302,6 @@ github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
|
||||||
github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
|
||||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
|
|
@ -631,7 +631,7 @@ func (c *Configuration) GetProxyListener(listener net.Listener) (*proxyproto.Lis
|
||||||
|
|
||||||
return &proxyproto.Listener{
|
return &proxyproto.Listener{
|
||||||
Listener: listener,
|
Listener: listener,
|
||||||
Policy: getProxyPolicy(c.proxyAllowed, c.proxySkipped, defaultPolicy),
|
ConnPolicy: getProxyPolicy(c.proxyAllowed, c.proxySkipped, defaultPolicy),
|
||||||
ReadHeaderTimeout: 10 * time.Second,
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -806,13 +806,13 @@ func (c *Configuration) ExecutePostConnectHook(ipAddr, protocol string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProxyPolicy(allowed, skipped []func(net.IP) bool, def proxyproto.Policy) proxyproto.PolicyFunc {
|
func getProxyPolicy(allowed, skipped []func(net.IP) bool, def proxyproto.Policy) proxyproto.ConnPolicyFunc {
|
||||||
return func(upstream net.Addr) (proxyproto.Policy, error) {
|
return func(connPolicyOptions proxyproto.ConnPolicyOptions) (proxyproto.Policy, error) {
|
||||||
upstreamIP, err := util.GetIPFromNetAddr(upstream)
|
upstreamIP, err := util.GetIPFromNetAddr(connPolicyOptions.Upstream)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Something is wrong with the source IP, better reject the
|
// Something is wrong with the source IP, better reject the
|
||||||
// connection if a proxy header is found.
|
// connection.
|
||||||
return proxyproto.REJECT, err
|
return proxyproto.REJECT, proxyproto.ErrInvalidUpstream
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, skippedFrom := range skipped {
|
for _, skippedFrom := range skipped {
|
||||||
|
@ -831,7 +831,7 @@ func getProxyPolicy(allowed, skipped []func(net.IP) bool, def proxyproto.Policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
if def == proxyproto.REQUIRE {
|
if def == proxyproto.REQUIRE {
|
||||||
return proxyproto.REJECT, nil
|
return proxyproto.REJECT, proxyproto.ErrInvalidUpstream
|
||||||
}
|
}
|
||||||
return def, nil
|
return def, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1041,9 +1041,13 @@ func TestQuotaScansRole(t *testing.T) {
|
||||||
|
|
||||||
func TestProxyPolicy(t *testing.T) {
|
func TestProxyPolicy(t *testing.T) {
|
||||||
addr := net.TCPAddr{}
|
addr := net.TCPAddr{}
|
||||||
|
downstream := net.TCPAddr{IP: net.ParseIP("1.1.1.1")}
|
||||||
p := getProxyPolicy(nil, nil, proxyproto.IGNORE)
|
p := getProxyPolicy(nil, nil, proxyproto.IGNORE)
|
||||||
policy, err := p(&addr)
|
policy, err := p(proxyproto.ConnPolicyOptions{
|
||||||
assert.Error(t, err)
|
Upstream: &addr,
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, proxyproto.ErrInvalidUpstream)
|
||||||
assert.Equal(t, proxyproto.REJECT, policy)
|
assert.Equal(t, proxyproto.REJECT, policy)
|
||||||
ip1 := net.ParseIP("10.8.1.1")
|
ip1 := net.ParseIP("10.8.1.1")
|
||||||
ip2 := net.ParseIP("10.8.1.2")
|
ip2 := net.ParseIP("10.8.1.2")
|
||||||
|
@ -1053,30 +1057,54 @@ func TestProxyPolicy(t *testing.T) {
|
||||||
skipped, err := util.ParseAllowedIPAndRanges([]string{ip2.String(), ip3.String()})
|
skipped, err := util.ParseAllowedIPAndRanges([]string{ip2.String(), ip3.String()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
p = getProxyPolicy(allowed, skipped, proxyproto.IGNORE)
|
p = getProxyPolicy(allowed, skipped, proxyproto.IGNORE)
|
||||||
policy, err = p(&net.TCPAddr{IP: ip1})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: ip1},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.USE, policy)
|
assert.Equal(t, proxyproto.USE, policy)
|
||||||
policy, err = p(&net.TCPAddr{IP: ip2})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: ip2},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.SKIP, policy)
|
assert.Equal(t, proxyproto.SKIP, policy)
|
||||||
policy, err = p(&net.TCPAddr{IP: ip3})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: ip3},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.SKIP, policy)
|
assert.Equal(t, proxyproto.SKIP, policy)
|
||||||
policy, err = p(&net.TCPAddr{IP: net.ParseIP("10.8.1.4")})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: net.ParseIP("10.8.1.4")},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.IGNORE, policy)
|
assert.Equal(t, proxyproto.IGNORE, policy)
|
||||||
p = getProxyPolicy(allowed, skipped, proxyproto.REQUIRE)
|
p = getProxyPolicy(allowed, skipped, proxyproto.REQUIRE)
|
||||||
policy, err = p(&net.TCPAddr{IP: ip1})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: ip1},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.REQUIRE, policy)
|
assert.Equal(t, proxyproto.REQUIRE, policy)
|
||||||
policy, err = p(&net.TCPAddr{IP: ip2})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: ip2},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.SKIP, policy)
|
assert.Equal(t, proxyproto.SKIP, policy)
|
||||||
policy, err = p(&net.TCPAddr{IP: ip3})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
|
Upstream: &net.TCPAddr{IP: ip3},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, proxyproto.SKIP, policy)
|
assert.Equal(t, proxyproto.SKIP, policy)
|
||||||
policy, err = p(&net.TCPAddr{IP: net.ParseIP("10.8.1.5")})
|
policy, err = p(proxyproto.ConnPolicyOptions{
|
||||||
assert.NoError(t, err)
|
Upstream: &net.TCPAddr{IP: net.ParseIP("10.8.1.5")},
|
||||||
|
Downstream: &downstream,
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, proxyproto.ErrInvalidUpstream)
|
||||||
assert.Equal(t, proxyproto.REJECT, policy)
|
assert.Equal(t, proxyproto.REJECT, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,12 +1119,12 @@ func TestProxyProtocolVersion(t *testing.T) {
|
||||||
c.ProxyProtocol = 1
|
c.ProxyProtocol = 1
|
||||||
proxyListener, err := c.GetProxyListener(nil)
|
proxyListener, err := c.GetProxyListener(nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, proxyListener.Policy)
|
assert.NotNil(t, proxyListener.ConnPolicy)
|
||||||
|
|
||||||
c.ProxyProtocol = 2
|
c.ProxyProtocol = 2
|
||||||
proxyListener, err = c.GetProxyListener(nil)
|
proxyListener, err = c.GetProxyListener(nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, proxyListener.Policy)
|
assert.NotNil(t, proxyListener.ConnPolicy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStartupHook(t *testing.T) {
|
func TestStartupHook(t *testing.T) {
|
||||||
|
|
|
@ -9031,9 +9031,8 @@ func TestHTTPFs(t *testing.T) {
|
||||||
|
|
||||||
func TestProxyProtocol(t *testing.T) {
|
func TestProxyProtocol(t *testing.T) {
|
||||||
resp, err := httpclient.Get(fmt.Sprintf("http://%v", httpProxyAddr))
|
resp, err := httpclient.Get(fmt.Sprintf("http://%v", httpProxyAddr))
|
||||||
if assert.NoError(t, err) {
|
if !assert.Error(t, err) {
|
||||||
defer resp.Body.Close()
|
resp.Body.Close()
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1196,11 +1196,8 @@ func TestProxyProtocol(t *testing.T) {
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
assert.NoError(t, checkBasicSFTP(client))
|
assert.NoError(t, checkBasicSFTP(client))
|
||||||
}
|
}
|
||||||
conn, client, err = getSftpClientWithAddr(user, usePubKey, "127.0.0.1:2224")
|
_, _, err = getSftpClientWithAddr(user, usePubKey, "127.0.0.1:2224")
|
||||||
if assert.NoError(t, err) {
|
assert.Error(t, err)
|
||||||
defer client.Close()
|
|
||||||
defer conn.Close()
|
|
||||||
}
|
|
||||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = os.RemoveAll(user.GetHomeDir())
|
err = os.RemoveAll(user.GetHomeDir())
|
||||||
|
|
|
@ -394,7 +394,17 @@ func (fs *AzureBlobFs) Chtimes(name string, _, mtime time.Time, isUploading bool
|
||||||
if metadata == nil {
|
if metadata == nil {
|
||||||
metadata = make(map[string]*string)
|
metadata = make(map[string]*string)
|
||||||
}
|
}
|
||||||
metadata[lastModifiedField] = to.Ptr(strconv.FormatInt(mtime.UnixMilli(), 10))
|
found := false
|
||||||
|
for k := range metadata {
|
||||||
|
if strings.ToLower(k) == lastModifiedField {
|
||||||
|
metadata[k] = to.Ptr(strconv.FormatInt(mtime.UnixMilli(), 10))
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
metadata[lastModifiedField] = to.Ptr(strconv.FormatInt(mtime.UnixMilli(), 10))
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(fs.ctxTimeout))
|
ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(fs.ctxTimeout))
|
||||||
defer cancelFn()
|
defer cancelFn()
|
||||||
|
|
Loading…
Reference in a new issue