diff --git a/Dockerfile b/Dockerfile index 57ff7dac..4bc9d6fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,11 +47,6 @@ COPY --from=builder /workspace/sftpgo /usr/local/bin/ # Log to the stdout so the logs will be available using docker logs ENV SFTPGO_LOG_FILE_PATH="" -# templates and static paths are inside the container -ENV SFTPGO_HTTPD__TEMPLATES_PATH=/usr/share/sftpgo/templates -ENV SFTPGO_SMTP__TEMPLATES_PATH=/usr/share/sftpgo/templates -ENV SFTPGO_HTTPD__STATIC_FILES_PATH=/usr/share/sftpgo/static -ENV SFTPGO_HTTPD__OPENAPI_PATH=/usr/share/sftpgo/openapi # Modify the default configuration file RUN sed -i 's|"users_base_dir": "",|"users_base_dir": "/srv/sftpgo/data",|' /etc/sftpgo/sftpgo.json && \ diff --git a/Dockerfile.alpine b/Dockerfile.alpine index a9c9914c..4c14d403 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -52,11 +52,6 @@ COPY --from=builder /workspace/sftpgo /usr/local/bin/ # Log to the stdout so the logs will be available using docker logs ENV SFTPGO_LOG_FILE_PATH="" -# templates and static paths are inside the container -ENV SFTPGO_HTTPD__TEMPLATES_PATH=/usr/share/sftpgo/templates -ENV SFTPGO_SMTP__TEMPLATES_PATH=/usr/share/sftpgo/templates -ENV SFTPGO_HTTPD__STATIC_FILES_PATH=/usr/share/sftpgo/static -ENV SFTPGO_HTTPD__OPENAPI_PATH=/usr/share/sftpgo/openapi # Modify the default configuration file RUN sed -i 's|"users_base_dir": "",|"users_base_dir": "/srv/sftpgo/data",|' /etc/sftpgo/sftpgo.json && \ diff --git a/Dockerfile.distroless b/Dockerfile.distroless index 214b5b4e..97ce4824 100644 --- a/Dockerfile.distroless +++ b/Dockerfile.distroless @@ -46,11 +46,6 @@ COPY --from=builder /etc/mime.types /etc/mime.types # Log to the stdout so the logs will be available using docker logs ENV SFTPGO_LOG_FILE_PATH="" -# templates and static paths are inside the container -ENV SFTPGO_HTTPD__TEMPLATES_PATH=/usr/share/sftpgo/templates -ENV SFTPGO_SMTP__TEMPLATES_PATH=/usr/share/sftpgo/templates -ENV SFTPGO_HTTPD__STATIC_FILES_PATH=/usr/share/sftpgo/static -ENV SFTPGO_HTTPD__OPENAPI_PATH=/usr/share/sftpgo/openapi # These env vars are required to avoid the following error when calling user.Current(): # unable to get the current user: user: Current requires cgo or $USER set in environment ENV USER=sftpgo diff --git a/docs/howto/lets-encrypt-certificate.md b/docs/howto/lets-encrypt-certificate.md index 39769728..e02a58f2 100644 --- a/docs/howto/lets-encrypt-certificate.md +++ b/docs/howto/lets-encrypt-certificate.md @@ -74,10 +74,9 @@ Open the SFTPGo configuration file, search for the `httpd` section and change it "render_openapi": true } ], - "templates_path": "/usr/share/sftpgo/templates", - "static_files_path": "/usr/share/sftpgo/static", - "backups_path": "/srv/sftpgo/backups", - "openapi_path": "/srv/sftpgo/openapi", + "templates_path": "templates", + "static_files_path": "static", + "openapi_path": "openapi", "web_root": "", "certificate_file": "/etc/sftpgo/certs/sftpgo.com.crt", "certificate_key_file": "/etc/sftpgo/certs/sftpgo.com.key", diff --git a/docs/service.md b/docs/service.md index 81579c2b..88c3383a 100644 --- a/docs/service.md +++ b/docs/service.md @@ -36,9 +36,6 @@ sudo install -Dm755 sftpgo /usr/bin/sftpgo # install the default configuration file, edit it if required sudo install -Dm644 sftpgo.json /etc/sftpgo/ # override some configuration keys using environment variables -sudo sh -c 'echo "SFTPGO_HTTPD__TEMPLATES_PATH=/usr/share/sftpgo/templates" > /etc/sftpgo/sftpgo.env' -sudo sh -c 'echo "SFTPGO_HTTPD__STATIC_FILES_PATH=/usr/share/sftpgo/static" >> /etc/sftpgo/sftpgo.env' -sudo sh -c 'echo "SFTPGO_HTTPD__OPENAPI_PATH=/usr/share/sftpgo/openapi" >> /etc/sftpgo/sftpgo.env' sudo sh -c 'echo "SFTPGO_HTTPD__BACKUPS_PATH=/var/lib/sftpgo/backups" >> /etc/sftpgo/sftpgo.env' sudo sh -c 'echo "SFTPGO_DATA_PROVIDER__CREDENTIALS_PATH=/var/lib/sftpgo/credentials" >> /etc/sftpgo/sftpgo.env' # if you use a file based data provider such as sqlite or bolt consider to set the database path too, for example: diff --git a/ftpd/ftpd_test.go b/ftpd/ftpd_test.go index 7d58b876..d9d5874d 100644 --- a/ftpd/ftpd_test.go +++ b/ftpd/ftpd_test.go @@ -611,7 +611,7 @@ func TestListDirWithWildcards(t *testing.T) { testFileSize := int64(65535) err = createTestFile(testFilePath, testFileSize) assert.NoError(t, err) - fileName := "fil*e.dat" + fileName := "file[a-z]e.dat" err = ftpUploadFile(testFilePath, fileName, testFileSize, client, 0) assert.NoError(t, err) localDownloadPath := filepath.Join(homeBasePath, testDLFileName) diff --git a/ftpd/handler.go b/ftpd/handler.go index a99e12db..612924ce 100644 --- a/ftpd/handler.go +++ b/ftpd/handler.go @@ -147,7 +147,7 @@ func (c *Connection) Stat(name string) (os.FileInfo, error) { fi, err := c.DoStat(name, 0, true) if err != nil { - if c.isListDirWithWildcards(path.Base(name), err) { + if c.isListDirWithWildcards(path.Base(name), os.ErrNotExist) { return vfs.NewFileInfo(name, true, 0, time.Now(), false), nil } return nil, err diff --git a/go.mod b/go.mod index a34ccd3d..4fe81dcb 100644 --- a/go.mod +++ b/go.mod @@ -31,11 +31,11 @@ require ( github.com/google/uuid v1.3.0 github.com/grandcat/zeroconf v1.0.0 github.com/hashicorp/go-hclog v1.2.0 - github.com/hashicorp/go-plugin v1.4.3 + github.com/hashicorp/go-plugin v1.4.4 github.com/hashicorp/go-retryablehttp v0.7.1 github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126 github.com/klauspost/compress v1.15.2 - github.com/lestrrat-go/jwx v1.2.23 + github.com/lestrrat-go/jwx v1.2.24 github.com/lib/pq v1.10.5 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mattn/go-sqlite3 v1.14.12 @@ -64,7 +64,7 @@ require ( go.etcd.io/bbolt v1.3.6 go.uber.org/automaxprocs v1.5.1 gocloud.dev v0.25.0 - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 + golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 @@ -163,6 +163,6 @@ require ( replace ( github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 - golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20220412172350-e76a61f8e7d2 + golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20220505051548-eb52ab1741ed golang.org/x/net => github.com/drakkan/net v0.0.0-20220504073018-5d1702f4106f ) diff --git a/go.sum b/go.sum index 19b4428a..4be132b8 100644 --- a/go.sum +++ b/go.sum @@ -251,8 +251,8 @@ github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/drakkan/crypto v0.0.0-20220412172350-e76a61f8e7d2 h1:5XmEywX1u5gPgOC+MJuTwLtjMd6gC6t40W+dBgbriSE= -github.com/drakkan/crypto v0.0.0-20220412172350-e76a61f8e7d2/go.mod h1:SiM6ypd8Xu1xldObYtbDztuUU7xUzMnUULfphXFZmro= +github.com/drakkan/crypto v0.0.0-20220505051548-eb52ab1741ed h1:08cqWe9aKRNPpH5nfTyAVoitSif6pvXbGa9v3+PDAzI= +github.com/drakkan/crypto v0.0.0-20220505051548-eb52ab1741ed/go.mod h1:SiM6ypd8Xu1xldObYtbDztuUU7xUzMnUULfphXFZmro= github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 h1:LPH1dEblAOO/LoG7yHPMtBLXhQmjaga91/DDjWk9jWA= github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU= github.com/drakkan/net v0.0.0-20220504073018-5d1702f4106f h1:BUIQ/l47ZPdruH1S17AdCCq6YNR/DyLpvysRXikD/Xg= @@ -323,7 +323,6 @@ github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22 github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.7.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -446,18 +445,16 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-plugin v1.4.3 h1:DXmvivbWD5qdiBts9TpBC7BYL1Aia5sxbRgQB+v6UZM= -github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= +github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= +github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -518,7 +515,6 @@ github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -575,8 +571,8 @@ github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbq github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= github.com/lestrrat-go/jwx v1.2.6/go.mod h1:tJuGuAI3LC71IicTx82Mz1n3w9woAs2bYJZpkjJQ5aU= -github.com/lestrrat-go/jwx v1.2.23 h1:8oP5fY1yzCRraUNNyfAVdOkLCqY7xMZz11lVcvHqC1Y= -github.com/lestrrat-go/jwx v1.2.23/go.mod h1:sAXjRwzSvCN6soO4RLoWWm1bVPpb8iOuv0IYfH8OWd8= +github.com/lestrrat-go/jwx v1.2.24 h1:N6Qsn6TUsDzz+qgS/1xcfBtkQfnbwW01fLFJpuYgKsg= +github.com/lestrrat-go/jwx v1.2.24/go.mod h1:zoNuZymNl5lgdcu6P7K6ie2QRll5HVfF4xwxBBK1NxY= github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -627,7 +623,6 @@ github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy github.com/minio/sio v0.3.0 h1:syEFBewzOMOYVzSTFpp1MqpSZk8rUNbz8VIIc+PNzus= github.com/minio/sio v0.3.0/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebhw= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -642,7 +637,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= @@ -1114,7 +1108,6 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1209,7 +1202,6 @@ google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72 h1:iif0mpUetMBqcQPUoq+JnCcmzvfpp8wRx515va8wP1c= google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/httpd/httpd.go b/httpd/httpd.go index 181d8e56..864f9e4d 100644 --- a/httpd/httpd.go +++ b/httpd/httpd.go @@ -593,9 +593,9 @@ func (c *Conf) getRedacted() Conf { // Initialize configures and starts the HTTP server func (c *Conf) Initialize(configDir string) error { logger.Info(logSender, "", "initializing HTTP server with config %+v", c.getRedacted()) - staticFilesPath := getConfigPath(c.StaticFilesPath, configDir) - templatesPath := getConfigPath(c.TemplatesPath, configDir) - openAPIPath := getConfigPath(c.OpenAPIPath, configDir) + staticFilesPath := util.FindSharedDataPath(c.StaticFilesPath, configDir) + templatesPath := util.FindSharedDataPath(c.TemplatesPath, configDir) + openAPIPath := util.FindSharedDataPath(c.OpenAPIPath, configDir) if err := c.checkRequiredDirs(staticFilesPath, templatesPath); err != nil { return err } diff --git a/pkgs/build.sh b/pkgs/build.sh index 46a589bc..494246d7 100755 --- a/pkgs/build.sh +++ b/pkgs/build.sh @@ -39,10 +39,7 @@ fi cp ${BASE_DIR}/sftpgo.json . sed -i "s|sftpgo.db|/var/lib/sftpgo/sftpgo.db|" sftpgo.json sed -i "s|\"users_base_dir\": \"\",|\"users_base_dir\": \"/srv/sftpgo/data\",|" sftpgo.json -sed -i "s|\"templates\"|\"/usr/share/sftpgo/templates\"|" sftpgo.json -sed -i "s|\"static\"|\"/usr/share/sftpgo/static\"|" sftpgo.json sed -i "s|\"backups\"|\"/srv/sftpgo/backups\"|" sftpgo.json -sed -i "s|\"openapi\"|\"/usr/share/sftpgo/openapi\"|" sftpgo.json sed -i "s|\"credentials\"|\"/var/lib/sftpgo/credentials\"|" sftpgo.json cat >nfpm.yaml < 2 { return fmt.Errorf("smtp: invalid encryption %v", c.Encryption) } - templatesPath := c.TemplatesPath - if templatesPath == "" || !util.IsFileInputValid(templatesPath) { + templatesPath := util.FindSharedDataPath(c.TemplatesPath, configDir) + if templatesPath == "" { return fmt.Errorf("smtp: invalid templates path %#v", templatesPath) } - if !filepath.IsAbs(templatesPath) { - templatesPath = filepath.Join(configDir, templatesPath) - } loadTemplates(filepath.Join(templatesPath, templateEmailDir)) from = c.From smtpServer = mail.NewSMTPClient() diff --git a/util/util.go b/util/util.go index bff5d61b..1357fbf0 100644 --- a/util/util.go +++ b/util/util.go @@ -346,6 +346,32 @@ func IsFileInputValid(fileInput string) bool { return true } +// FindSharedDataPath searches for the specified directory name in searchDir +// and in system-wide shared data directories. +// If name is an absolute path it is returned unmodified. +func FindSharedDataPath(name, searchDir string) string { + if !IsFileInputValid(name) { + return "" + } + if name != "" && !filepath.IsAbs(name) { + searchList := []string{searchDir} + if runtime.GOOS != osWindows { + searchList = append(searchList, "/usr/share/sftpgo") + searchList = append(searchList, "/usr/local/share/sftpgo") + } + for _, basePath := range searchList { + res := filepath.Join(basePath, name) + _, err := os.Stat(res) + if err == nil { + logger.Debug(logSender, "", "found share data path for name %#v: %#v", name, res) + return res + } + } + return filepath.Join(searchDir, name) + } + return name +} + // CleanDirInput sanitizes user input for directories. // On Windows it removes any trailing `"`. // We try to help windows users that set an invalid path such as "C:\ProgramData\SFTPGO\". diff --git a/vfs/osfs.go b/vfs/osfs.go index 95068252..6266c425 100644 --- a/vfs/osfs.go +++ b/vfs/osfs.go @@ -174,6 +174,9 @@ func (*OsFs) Truncate(name string, size int64) error { func (*OsFs) ReadDir(dirname string) ([]os.FileInfo, error) { f, err := os.Open(dirname) if err != nil { + if isInvalidNameError(err) { + err = os.ErrNotExist + } return nil, err } list, err := f.Readdir(-1) @@ -291,6 +294,9 @@ func (fs *OsFs) ResolvePath(virtualPath string) (string, error) { } r := filepath.Clean(filepath.Join(fs.rootDir, virtualPath)) p, err := filepath.EvalSymlinks(r) + if isInvalidNameError(err) { + err = os.ErrNotExist + } if err != nil && !os.IsNotExist(err) { return "", err } else if os.IsNotExist(err) { diff --git a/vfs/sys_unix.go b/vfs/sys_unix.go index b8283896..aeda5f7d 100644 --- a/vfs/sys_unix.go +++ b/vfs/sys_unix.go @@ -12,3 +12,7 @@ import ( func isCrossDeviceError(err error) bool { return errors.Is(err, unix.EXDEV) } + +func isInvalidNameError(err error) bool { + return false +} diff --git a/vfs/sys_windows.go b/vfs/sys_windows.go index e3ae1142..3ad2b588 100644 --- a/vfs/sys_windows.go +++ b/vfs/sys_windows.go @@ -9,3 +9,10 @@ import ( func isCrossDeviceError(err error) bool { return errors.Is(err, windows.ERROR_NOT_SAME_DEVICE) } + +func isInvalidNameError(err error) bool { + if err == nil { + return false + } + return errors.Is(err, windows.ERROR_INVALID_NAME) +}