diff --git a/go.mod b/go.mod index 946138b2..cf803e90 100644 --- a/go.mod +++ b/go.mod @@ -3,24 +3,24 @@ module github.com/drakkan/sftpgo/v2 go 1.18 require ( - cloud.google.com/go/storage v1.26.0 + cloud.google.com/go/storage v1.27.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1 github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387 - github.com/aws/aws-sdk-go-v2 v1.16.15 - github.com/aws/aws-sdk-go-v2/config v1.17.6 - github.com/aws/aws-sdk-go-v2/credentials v1.12.19 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.16 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.32 - github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.18 - github.com/aws/aws-sdk-go-v2/service/s3 v1.27.10 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.0 - github.com/aws/aws-sdk-go-v2/service/sts v1.16.18 + github.com/aws/aws-sdk-go-v2 v1.16.16 + github.com/aws/aws-sdk-go-v2/config v1.17.7 + github.com/aws/aws-sdk-go-v2/credentials v1.12.20 + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.33 + github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.19 + github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.1 + github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 github.com/cockroachdb/cockroach-go/v2 v2.2.16 github.com/coreos/go-oidc/v3 v3.4.0 github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001 - github.com/fclairamb/ftpserverlib v0.19.1 + github.com/fclairamb/ftpserverlib v0.20.0 github.com/fclairamb/go-log v0.4.1 github.com/go-acme/lego/v4 v4.8.0 github.com/go-chi/chi/v5 v5.0.8-0.20220512131524-9e71a0d4b3d6 @@ -31,7 +31,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.3.0 github.com/grandcat/zeroconf v1.0.0 - github.com/hashicorp/go-hclog v1.3.0 + github.com/hashicorp/go-hclog v1.3.1 github.com/hashicorp/go-plugin v1.4.5 github.com/hashicorp/go-retryablehttp v0.7.1 github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126 @@ -68,9 +68,9 @@ require ( golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 golang.org/x/net v0.0.0-20220909164309-bea034e7d591 golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 - golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 - golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 - google.golang.org/api v0.96.0 + golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af + google.golang.org/api v0.97.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) @@ -81,16 +81,16 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.1 // indirect github.com/ajg/form v1.5.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.22 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.23 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.17 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.16 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.16 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.11.22 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5 // indirect github.com/aws/smithy-go v1.13.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect @@ -156,7 +156,7 @@ require ( golang.org/x/tools v0.1.12 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa // indirect + google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737 // indirect google.golang.org/grpc v1.49.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -166,7 +166,6 @@ require ( ) replace ( - github.com/fclairamb/ftpserverlib => github.com/drakkan/ftpserverlib v0.0.0-20220917142547-394d5e183aeb github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20220831070616-b69bc2ec2993 golang.org/x/net => github.com/drakkan/net v0.0.0-20220916171046-9879e3f5b22a diff --git a/go.sum b/go.sum index 85533d24..33936b0c 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.26.0 h1:lYAGjknyDJirSzfwUlkv4Nsnj7od7foxQNH/fqZqles= -cloud.google.com/go/storage v1.26.0/go.mod h1:mk/N7YwIKEWyTvXAWQCIeiCTdLoRH6Pd5xmSnolQLTI= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= @@ -143,66 +143,66 @@ github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= -github.com/aws/aws-sdk-go-v2 v1.16.15 h1:2sInOWGE4HV54R90Pj8QgqBBw3Qf1I0husqbqjPZzys= -github.com/aws/aws-sdk-go-v2 v1.16.15/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= +github.com/aws/aws-sdk-go-v2 v1.16.16 h1:M1fj4FE2lB4NzRb9Y0xdWsn2P0+2UHVxwKyOa4YJNjk= +github.com/aws/aws-sdk-go-v2 v1.16.16/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 h1:tcFliCWne+zOuUfKNRn8JdFBuWPDuISDH08wD2ULkhk= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8/go.mod h1:JTnlBSot91steJeti4ryyu/tLd4Sk84O5W22L7O2EQU= github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= -github.com/aws/aws-sdk-go-v2/config v1.17.6 h1:0xHMch3eQ2C8CByMEi0iJOLF+pTLoAQeHVfhFxN7eyk= -github.com/aws/aws-sdk-go-v2/config v1.17.6/go.mod h1:CrxsoI/AcKUoWyL9Zo0YaDxRlBfSnDZKBYKDdkNYDQ0= +github.com/aws/aws-sdk-go-v2/config v1.17.7 h1:odVM52tFHhpqZBKNjVW5h+Zt1tKHbhdTQRb+0WHrNtw= +github.com/aws/aws-sdk-go-v2/config v1.17.7/go.mod h1:dN2gja/QXxFF15hQreyrqYhLBaQo1d9ZKe/v/uplQoI= github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g= -github.com/aws/aws-sdk-go-v2/credentials v1.12.19 h1:fYtSz4Fd0lUavtj4FAtvol9G2k0lh1TK4LfeP1hdnLw= -github.com/aws/aws-sdk-go-v2/credentials v1.12.19/go.mod h1:fRQMbLwSHPr0XRzuez6x7BX5+0nNQs5BzG+oR4bQKyY= +github.com/aws/aws-sdk-go-v2/credentials v1.12.20 h1:9+ZhlDY7N9dPnUmf7CDfW9In4sW5Ff3bh7oy4DzS1IE= +github.com/aws/aws-sdk-go-v2/credentials v1.12.20/go.mod h1:UKY5HyIux08bbNA7Blv4PcXQ8cTkGh7ghHMFklaviR4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.16 h1:LX38v4cqSqrBETHUBnc8B+N6p5YA41GaPQ3jwICjetI= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.16/go.mod h1:lnJ8tKos2s7JeBdLVFknwVSlQZAKzkgrFNQmUaTWwRQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 h1:r08j4sbZu/RVi+BNxkBJwPMUYY3P8mgSDuKkZ/ZN1lE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17/go.mod h1:yIkQcCDYNsZfXpd5UX2Cy+sWA1jPgIhGTw9cOBzfVnQ= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.32 h1:7VX09WtXhjIcJ+CKwYgFsVjypiqg29awSaMH1RQ++Eg= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.32/go.mod h1:zNsdxtYDwAWcxWMgH9+s1U0OOW+jrPLK6HHNw6r76l4= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.33 h1:fAoVmNGhir6BR+RU0/EI+6+D7abM+MCwWf8v4ip5jNI= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.33/go.mod h1:84XgODVR8uRhmOnUkKGUZKqIMxmjmLOR8Uyp7G/TPwc= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.22 h1:pE27/u2A7JlwICjOvONQDob8PToShRTkuiUE74ymVWg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.22/go.mod h1:/vNv5Al0bpiF8YdX2Ov6Xy05VTiXsql94yUqJMYaj0w= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 h1:s4g/wnzMf+qepSNgTvaQQHNxyMLKSawNhKCPNy++2xY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.16 h1:L5LKGHHXOl4t7+5QZMTl38GIzSAq07XUTRtEquiHGMA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.16/go.mod h1:62dsXI0BqTIGomDl8Hpm33dv0OntGaVblri3ZRParVQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 h1:/K482T5A3623WJgWT8w1yRAFK4RzGzEl7y39yhtn9eA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.23 h1:Sy266MXyLZZbObFhStGF9dyJm5nFyA8LINTgNm4Q6Ds= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.23/go.mod h1:XtEkQMmxls+Tb5dZLmpa1QAk0OzSIFDAXanC9Jkf81E= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.13 h1:ZrdsZJfzniYAF3Au4ngj7vWxJS1ZHGYCE0YlATcWYUg= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.13/go.mod h1:QyDZ5fgUmZFZztFpVcR7w4HV8vwO0ze1OM9rPy6jkEI= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 h1:wj5Rwc05hvUSvKuOF29IYb9QrCLjU+rHAy/x/o0DK2c= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 h1:ZSIPAkAsCCjYrhqfw2+lNzWDzxzHXEckFkTePL5RSWQ= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14/go.mod h1:AyGgqiKv9ECM6IZeNQtdT8NnMvUb3/2wokeq2Fgryto= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 h1:Lh1AShsuIJTwMkoxVCAYPJgNG5H+eN6SmoUn8nOZ5wE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9/go.mod h1:a9j48l6yL5XINLHLcOKInjdvknN+vWqPBxqeIDw7ktw= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.17 h1:rf0/i+3BMiQZjcQzhjTz3sAXouSl1dcnCrd8mroC4CE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.17/go.mod h1:Uo/4yJjc7RDB7R5q9JA7aQqFXasu/lAJke8mulo2dA8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 h1:BBYoNQt2kUZUUK4bIPsKrCcjVPUMNsgQpNAwhznK/zo= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18/go.mod h1:NS55eQ4YixUJPTC+INxi2/jCqe1y2Uw3rnh9wEOVJxY= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.16 h1:9jysIwpUt7KGdsKOl+zA+0pG+7MpSsi0KQUcbE48n38= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.16/go.mod h1:faBcf/4ZB4FRc17geaXWOxgzktotyJgBcUBZoHqvdfM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 h1:Jrd/oMh0PKQc6+BowB+pLEwLIgaQF29eYbe7E1Av9Ug= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17/go.mod h1:4nYOrY41Lrbk2170/BGkcJKBhws9Pfn8MG3aGqjjeFI= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.16 h1:jnGshlNJoVF3x8e5EbsFakNKeNUc0Pf3EQvU076bkKU= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.16/go.mod h1:tMN4hfJxozc/lHWA8Ug/eXEg4ZSm5c4sPB9WE/mdDuw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17 h1:HfVVR1vItaG6le+Bpw6P4midjBDMKnjMyZnw9MXYUcE= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17/go.mod h1:YqMdV+gEKCQ59NrB7rzrJdALeBIsYiVi8Inj3+KcqHI= github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.18 h1:VoxHI3YKYQ1ewtBnfSUsZ8he0tdot/mZuE/vP4qJgBw= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.18/go.mod h1:zan7AawF2v5WynzqKdF0aeYWZboYiOZ7vMWlhSGLCwQ= +github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.19 h1:6rxMT+zWZh2+0F1XHdDWCSzuMQIJI+tGlfrFi6V/UlU= +github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.19/go.mod h1:wGzRNLBD3V8/KKoBSYz0OWv1dnQNvqTyb193fS97dXQ= github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak= -github.com/aws/aws-sdk-go-v2/service/s3 v1.27.10 h1:fR5Z06dU41kkSdmSOtHiROealTOu5aNkwidOQ+lT0KQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.27.10/go.mod h1:B+5EUmLgCYrXHxgQ3nTUu3RUbxnrN1JMa41LSXm7lXw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 h1:3/gm/JTX9bX8CpzTgIlrtYpB3EVBDxyg/GY/QdcIEZw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11/go.mod h1:fmgDANqTUCxciViKl9hb/zD5LFbvPINFRgWhDbR+vZo= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.0 h1:Lh1yssM4dinNZuESsXnbi+pID8hoviejLZdLmT175i8= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.0/go.mod h1:z0y2iDaghoq7uv6kndhrJCTzgVckv8Aak8kpnu2kYjs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.1 h1:eMsEmvJR6zQ1lDi59RDtCc62x9fKs1kv2b8A8nPpWmY= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.1/go.mod h1:HEBBc70BYi5eUvxBqC3xXjU/04NO96X/XNUe5qhC7Bc= github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw= github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM= github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0= github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.22 h1:LrEyMbp0gMiXVaXpJ67jJkkqKCxivZvOd6wgXem0bWA= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.22/go.mod h1:B2nDzX7lppT8j4EV2/WhT20SnRDp/LdNyqxyGYY46Ow= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.4 h1:d7Wh4xMQVVYfrJ1KHFGQ6jY/O51LjnTCWJgh85RT+TQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.4/go.mod h1:mOofcMJCDSJwmtZykUE/i6tWGNwMnkextriwzY1zcbc= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 h1:pwvCchFUEnlceKIgPUouBJwK81aCkQ8UDMORfeFtW10= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.23/go.mod h1:/w0eg9IhFGjGyyncHIQrXtU8wvNsTJOP0R6PPj0wf80= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5 h1:GUnZ62TevLqIoDyHeiWj2P7EqaosgakBKVvWriIdLQY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5/go.mod h1:csZuQY65DAdFBt1oIjO5hhBR49kQqop4+lcuCjf2arA= github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.18 h1:TqEvnK8OceCKNQaDK9d5Ir2bOtC0S0dRQCwSbkV1rz0= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.18/go.mod h1:AE4zMc8qCw1JnDvy0ZrDVb/OXRuuweG3BcT2Nv7Qh3E= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 h1:9pPi0PsFNAGILFfPCk8Y0iyEBGc6lu6OQ97U7hmdesg= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.19/go.mod h1:h4J3oPZQbxLhzGnk+j9dfYHi5qIOVJ5kczZd658/ydM= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA= github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= @@ -268,8 +268,6 @@ github.com/drakkan/crypto v0.0.0-20220831070616-b69bc2ec2993 h1:P9lP7U92yt5GETGd github.com/drakkan/crypto v0.0.0-20220831070616-b69bc2ec2993/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/ftpserverlib v0.0.0-20220917142547-394d5e183aeb h1:sd63fxu7eKejDU0fBiGvVejeEEXNcGv6SVmXrFsDaKM= -github.com/drakkan/ftpserverlib v0.0.0-20220917142547-394d5e183aeb/go.mod h1:Nwsxl2ZzyPiSCgB1rZGnEscTenwkxPhCn1D+Hm/k9JA= github.com/drakkan/net v0.0.0-20220916171046-9879e3f5b22a h1:DXelKiOuwaiblhsGccshNDZLf5etRwx3IWInVf2f3Z8= github.com/drakkan/net v0.0.0-20220916171046-9879e3f5b22a/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001 h1:/ZshrfQzayqRSBDodmp3rhNCHJCff+utvgBuWRbiqu4= @@ -286,6 +284,8 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fclairamb/ftpserverlib v0.20.0 h1:9NjQPxo3T0XQCyzSXZJ0XBH4mk4Qv4Lpw3GNVabvnpU= +github.com/fclairamb/ftpserverlib v0.20.0/go.mod h1:7pR5Ckeygw3T006z1ND6HYSbJz+fTvkFAXlF6snW4yI= github.com/fclairamb/go-log v0.4.1 h1:rLtdSG9x2pK41AIAnE8WYpl05xBJfw1ZyYxZaXFcBsM= github.com/fclairamb/go-log v0.4.1/go.mod h1:sw1KvnkZ4wKCYkvy4SL3qVZcJSWFP8Ure4pM3z+KNn4= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -464,8 +464,8 @@ 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 v1.3.0 h1:G0ACM8Z2WilWgPv3Vdzwm3V0BQu/kSmrkVtpe1fy9do= -github.com/hashicorp/go-hclog v1.3.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= +github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo= github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= @@ -980,8 +980,8 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc= -golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1000,8 +1000,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1123,8 +1123,8 @@ google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69 google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.96.0 h1:F60cuQPJq7K7FzsxMYHAUJSiXh2oKctHxBMbDygxhfM= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0 h1:x/vEL1XDF/2V4xzdNgFPaKHluRESo2aTsL7QzHnBtGQ= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= 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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1229,8 +1229,8 @@ google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa h1:VWkrxnAx2C2hirAP+W5ADU7e/+93Yhk//ioKd2XFyDI= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737 h1:K1zaaMdYBXRyX+cwFnxj7M6zwDyumLQMZ5xqwGvjreQ= +google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737/go.mod h1:2r/26NEF3bFmT3eC3aZreahSal0C3Shl8Gi6vyDYqOQ= 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/httpclient/httpclient.go b/httpclient/httpclient.go index 3c10617c..cd9530b1 100644 --- a/httpclient/httpclient.go +++ b/httpclient/httpclient.go @@ -74,7 +74,6 @@ type Config struct { // Headers defines a list of http headers to add to each request Headers []Header `json:"headers" mapstructure:"headers"` customTransport *http.Transport - tlsConfig *tls.Config } const logSender = "httpclient" @@ -83,6 +82,9 @@ var httpConfig Config // Initialize configures HTTP clients func (c *Config) Initialize(configDir string) error { + if c.Timeout <= 0 { + return fmt.Errorf("invalid timeout: %v", c.Timeout) + } rootCAs, err := c.loadCACerts(configDir) if err != nil { return err @@ -98,7 +100,6 @@ func (c *Config) Initialize(configDir string) error { } customTransport.TLSClientConfig.InsecureSkipVerify = c.SkipTLSVerify c.customTransport = customTransport - c.tlsConfig = customTransport.TLSClientConfig err = c.loadCertificates(configDir) if err != nil { @@ -170,8 +171,13 @@ func (c *Config) loadCertificates(configDir string) error { if err != nil { return fmt.Errorf("unable to load key pair %#v, %#v: %v", cert, key, err) } + x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0]) + if err == nil { + logger.Debug(logSender, "", "adding leaf certificate for key pair %q, %q", cert, key) + tlsCert.Leaf = x509Cert + } logger.Debug(logSender, "", "client certificate %#v and key %#v successfully loaded", cert, key) - c.tlsConfig.Certificates = append(c.tlsConfig.Certificates, tlsCert) + c.customTransport.TLSClientConfig.Certificates = append(c.customTransport.TLSClientConfig.Certificates, tlsCert) } return nil } @@ -189,7 +195,7 @@ func GetHTTPClient() *http.Client { func GetRetraybleHTTPClient() *retryablehttp.Client { client := retryablehttp.NewClient() client.HTTPClient.Timeout = time.Duration(httpConfig.Timeout * float64(time.Second)) - client.HTTPClient.Transport.(*http.Transport).TLSClientConfig = httpConfig.tlsConfig + client.HTTPClient.Transport.(*http.Transport).TLSClientConfig = httpConfig.customTransport.TLSClientConfig client.Logger = &logger.LeveledLogger{Sender: "RetryableHTTPClient"} client.RetryWaitMin = time.Duration(httpConfig.RetryWaitMin) * time.Second client.RetryWaitMax = time.Duration(httpConfig.RetryWaitMax) * time.Second diff --git a/httpd/httpd.go b/httpd/httpd.go index 0a04db0a..20cc81ba 100644 --- a/httpd/httpd.go +++ b/httpd/httpd.go @@ -164,6 +164,7 @@ const ( webClientForgotPwdPathDefault = "/web/client/forgot-password" webClientResetPwdPathDefault = "/web/client/reset-password" webClientViewPDFPathDefault = "/web/client/viewpdf" + webClientGetPDFPathDefault = "/web/client/getpdf" webStaticFilesPathDefault = "/static" webOpenAPIPathDefault = "/openapi" // MaxRestoreSize defines the max size for the loaddata input file @@ -245,6 +246,7 @@ var ( webClientForgotPwdPath string webClientResetPwdPath string webClientViewPDFPath string + webClientGetPDFPath string webStaticFilesPath string webOpenAPIPath string // max upload size for http clients, 1GB by default @@ -959,6 +961,7 @@ func updateWebClientURLs(baseURL string) { webClientForgotPwdPath = path.Join(baseURL, webClientForgotPwdPathDefault) webClientResetPwdPath = path.Join(baseURL, webClientResetPwdPathDefault) webClientViewPDFPath = path.Join(baseURL, webClientViewPDFPathDefault) + webClientGetPDFPath = path.Join(baseURL, webClientGetPDFPathDefault) } func updateWebAdminURLs(baseURL string) { diff --git a/httpd/httpd_test.go b/httpd/httpd_test.go index 6add6b45..4b37c096 100644 --- a/httpd/httpd_test.go +++ b/httpd/httpd_test.go @@ -180,6 +180,7 @@ const ( webClientForgotPwdPath = "/web/client/forgot-password" webClientResetPwdPath = "/web/client/reset-password" webClientViewPDFPath = "/web/client/viewpdf" + webClientGetPDFPath = "/web/client/getpdf" httpBaseURL = "http://127.0.0.1:8081" defaultRemoteAddr = "127.0.0.1:1234" sftpServerAddr = "127.0.0.1:8022" @@ -9706,6 +9707,13 @@ func TestMaxSessions(t *testing.T) { checkResponseCode(t, http.StatusTooManyRequests, rr) assert.Contains(t, rr.Body.String(), "too many open sessions") + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=file", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusTooManyRequests, rr) + assert.Contains(t, rr.Body.String(), "too many open sessions") + // test reset password smtpCfg := smtp.Config{ Host: "127.0.0.1", @@ -11740,16 +11748,105 @@ func TestWebClientViewPDF(t *testing.T) { rr := executeRequest(req) checkResponseCode(t, http.StatusBadRequest, rr) + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath, nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusBadRequest, rr) + req, err = http.NewRequest(http.MethodGet, webClientViewPDFPath+"?path=test.pdf", nil) assert.NoError(t, err) setJWTCookieForReq(req, webToken) rr = executeRequest(req) checkResponseCode(t, http.StatusOK, rr) + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=test.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusBadRequest, rr) + assert.Contains(t, rr.Body.String(), "Unable to get file") + + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2F", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusBadRequest, rr) + assert.Contains(t, rr.Body.String(), "Invalid file") + + err = os.WriteFile(filepath.Join(user.GetHomeDir(), "test.pdf"), []byte("some text data"), 0666) + assert.NoError(t, err) + + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2Ftest.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusBadRequest, rr) + assert.Contains(t, rr.Body.String(), "Invalid PDF file") + + err = createTestFile(filepath.Join(user.GetHomeDir(), "test.pdf"), 1024) + assert.NoError(t, err) + + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2Ftest.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusBadRequest, rr) + assert.Contains(t, rr.Body.String(), "does not look like a PDF") + + fakePDF := []byte(`%PDF-1.6`) + for i := 0; i < 128; i++ { + fakePDF = append(fakePDF, []byte(fmt.Sprintf("%d", i))...) + } + err = os.WriteFile(filepath.Join(user.GetHomeDir(), "test.pdf"), fakePDF, 0666) + assert.NoError(t, err) + + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2Ftest.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusOK, rr) + + user.Filters.FilePatterns = []sdk.PatternsFilter{ + { + Path: "/", + DeniedPatterns: []string{"*.pdf"}, + }, + } + _, _, err = httpdtest.UpdateUser(user, http.StatusOK, "") + assert.NoError(t, err) + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2Ftest.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusForbidden, rr) + assert.Contains(t, rr.Body.String(), "Unable to get a reader for the file") + + user.Filters.FilePatterns = []sdk.PatternsFilter{ + { + Path: "/", + DeniedPatterns: []string{"*.txt"}, + }, + } + user.Filters.DeniedProtocols = []string{common.ProtocolHTTP} + _, _, err = httpdtest.UpdateUser(user, http.StatusOK, "") + assert.NoError(t, err) + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2Ftest.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusForbidden, rr) + _, err = httpdtest.RemoveUser(user, http.StatusOK) assert.NoError(t, err) err = os.RemoveAll(user.GetHomeDir()) assert.NoError(t, err) + + req, err = http.NewRequest(http.MethodGet, webClientGetPDFPath+"?path=%2Ftest.pdf", nil) + assert.NoError(t, err) + setJWTCookieForReq(req, webToken) + rr = executeRequest(req) + checkResponseCode(t, http.StatusNotFound, rr) } func TestWebEditFile(t *testing.T) { diff --git a/httpd/internal_test.go b/httpd/internal_test.go index f359b2eb..40151335 100644 --- a/httpd/internal_test.go +++ b/httpd/internal_test.go @@ -2154,6 +2154,13 @@ func TestWebUserInvalidClaims(t *testing.T) { server.handleClientGetShares(rr, req) assert.Equal(t, http.StatusForbidden, rr.Code) assert.Contains(t, rr.Body.String(), "Invalid token claims") + + rr = httptest.NewRecorder() + req, _ = http.NewRequest(http.MethodGet, webClientViewPDFPath, nil) + req.Header.Set("Cookie", fmt.Sprintf("jwt=%v", token["access_token"])) + server.handleClientGetPDF(rr, req) + assert.Equal(t, http.StatusForbidden, rr.Code) + assert.Contains(t, rr.Body.String(), "Invalid token claims") } func TestInvalidClaims(t *testing.T) { diff --git a/httpd/server.go b/httpd/server.go index 6a9037c0..eb1ee767 100644 --- a/httpd/server.go +++ b/httpd/server.go @@ -1422,7 +1422,7 @@ func (s *httpdServer) setupWebClientRoutes() { s.jwtAuthenticatorPartial(tokenAudienceWebClientPartial)). Post(webClientTwoFactorRecoveryPath, s.handleWebClientTwoFactorRecoveryPost) } - // share API exposed to external users + // share routes exposed to external users s.router.Get(webClientPubSharesPath+"/{id}", s.downloadFromShare) s.router.Get(webClientPubSharesPath+"/{id}/browse", s.handleShareGetFiles) s.router.Get(webClientPubSharesPath+"/{id}/upload", s.handleClientUploadToShare) @@ -1440,6 +1440,7 @@ func (s *httpdServer) setupWebClientRoutes() { router.Get(webClientLogoutPath, s.handleWebClientLogout) router.With(s.checkSecondFactorRequirement, s.refreshCookie).Get(webClientFilesPath, s.handleClientGetFiles) router.With(s.checkSecondFactorRequirement, s.refreshCookie).Get(webClientViewPDFPath, s.handleClientViewPDF) + router.With(s.checkSecondFactorRequirement, s.refreshCookie).Get(webClientGetPDFPath, s.handleClientGetPDF) router.With(s.checkSecondFactorRequirement, s.refreshCookie, verifyCSRFHeader).Get(webClientFilePath, getUserFile) router.With(s.checkSecondFactorRequirement, s.checkHTTPUserPerm(sdk.WebClientWriteDisabled), verifyCSRFHeader). Post(webClientFilePath, uploadUserFile) diff --git a/httpd/webclient.go b/httpd/webclient.go index 6839f694..075ad730 100644 --- a/httpd/webclient.go +++ b/httpd/webclient.go @@ -36,6 +36,7 @@ import ( "github.com/drakkan/sftpgo/v2/common" "github.com/drakkan/sftpgo/v2/dataprovider" + "github.com/drakkan/sftpgo/v2/logger" "github.com/drakkan/sftpgo/v2/mfa" "github.com/drakkan/sftpgo/v2/smtp" "github.com/drakkan/sftpgo/v2/util" @@ -757,9 +758,8 @@ func (s *httpdServer) handleShareGetFiles(w http.ResponseWriter, r *http.Request s.renderSharedFilesPage(w, r, share.GetRelativePath(name), "", share) return } - inline := r.URL.Query().Get("inline") != "" dataprovider.UpdateShareLastUse(&share, 1) //nolint:errcheck - if status, err := downloadFile(w, r, connection, name, info, inline, &share); err != nil { + if status, err := downloadFile(w, r, connection, name, info, false, &share); err != nil { dataprovider.UpdateShareLastUse(&share, -1) //nolint:errcheck if status > 0 { s.renderSharedFilesPage(w, r, path.Dir(share.GetRelativePath(name)), err.Error(), share) @@ -892,8 +892,7 @@ func (s *httpdServer) handleClientGetFiles(w http.ResponseWriter, r *http.Reques s.renderFilesPage(w, r, name, "", user, len(s.binding.WebClientIntegrations) > 0) return } - inline := r.URL.Query().Get("inline") != "" - if status, err := downloadFile(w, r, connection, name, info, inline, nil); err != nil && status != 0 { + if status, err := downloadFile(w, r, connection, name, info, false, nil); err != nil && status != 0 { if status > 0 { if status == http.StatusRequestedRangeNotSatisfiable { s.renderClientMessagePage(w, r, http.StatusText(status), "", status, err, "") @@ -1291,9 +1290,80 @@ func (s *httpdServer) handleClientViewPDF(w http.ResponseWriter, r *http.Request name = util.CleanPath(name) data := viewPDFPage{ Title: path.Base(name), - URL: fmt.Sprintf("%v?path=%v&inline=1", webClientFilesPath, url.QueryEscape(name)), + URL: fmt.Sprintf("%s?path=%s&_=%d", webClientGetPDFPath, url.QueryEscape(name), time.Now().UTC().Unix()), StaticURL: webStaticFilesPath, Branding: s.binding.Branding.WebClient, } renderClientTemplate(w, templateClientViewPDF, data) } + +func (s *httpdServer) handleClientGetPDF(w http.ResponseWriter, r *http.Request) { + r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize) + claims, err := getTokenClaims(r) + if err != nil || claims.Username == "" { + s.renderClientForbiddenPage(w, r, "Invalid token claims") + return + } + name := r.URL.Query().Get("path") + if name == "" { + s.renderClientBadRequestPage(w, r, errors.New("no file specified")) + return + } + name = util.CleanPath(name) + user, err := dataprovider.GetUserWithGroupSettings(claims.Username) + if err != nil { + s.renderClientMessagePage(w, r, "Unable to retrieve your user", "", getRespStatus(err), nil, "") + return + } + + connID := xid.New().String() + protocol := getProtocolFromRequest(r) + connectionID := fmt.Sprintf("%v_%v", protocol, connID) + if err := checkHTTPClientUser(&user, r, connectionID, false); err != nil { + s.renderClientForbiddenPage(w, r, err.Error()) + return + } + connection := &Connection{ + BaseConnection: common.NewBaseConnection(connID, protocol, util.GetHTTPLocalAddress(r), + r.RemoteAddr, user), + request: r, + } + if err = common.Connections.Add(connection); err != nil { + s.renderClientMessagePage(w, r, "Unable to add connection", "", http.StatusTooManyRequests, err, "") + return + } + defer common.Connections.Remove(connection.GetID()) + + info, err := connection.Stat(name, 0) + if err != nil { + s.renderClientMessagePage(w, r, "Unable to get file", "", getRespStatus(err), err, "") + return + } + if info.IsDir() { + s.renderClientMessagePage(w, r, "Invalid file", fmt.Sprintf("%q is not a file", name), + http.StatusBadRequest, nil, "") + return + } + connection.User.CheckFsRoot(connection.ID) //nolint:errcheck + reader, err := connection.getFileReader(name, 0, r.Method) + if err != nil { + s.renderClientMessagePage(w, r, fmt.Sprintf("Unable to get a reader for the file %q", name), "", + getRespStatus(err), err, "") + return + } + defer reader.Close() + + var b bytes.Buffer + _, err = io.CopyN(&b, reader, 128) + if err != nil { + s.renderClientMessagePage(w, r, "Invalid PDF file", fmt.Sprintf("Unable to validate the file %q as PDF", name), + http.StatusBadRequest, nil, "") + return + } + if ctype := http.DetectContentType(b.Bytes()); ctype != "application/pdf" { + connection.Log(logger.LevelDebug, "detected %q content type, expected PDF, file %q", ctype, name) + s.renderClientBadRequestPage(w, r, fmt.Errorf("the file %q does not look like a PDF", name)) + return + } + downloadFile(w, r, connection, name, info, true, nil) //nolint:errcheck +} diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 683ed9f6..daa10144 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -26,7 +26,7 @@ info: SFTPGo supports groups to simplify the administration of multiple accounts by letting you assign settings once to a group, instead of multiple times to each individual user. The SFTPGo WebClient allows end users to change their credentials, browse and manage their files in the browser and setup two-factor authentication which works with Authy, Google Authenticator and other compatible apps. From the WebClient each authorized user can also create HTTP/S links to externally share files and folders securely, by setting limits to the number of downloads/uploads, protecting the share with a password, limiting access by source IP address, setting an automatic expiration date. - version: 2.3.5 + version: 2.3.5-dev contact: name: API support url: 'https://github.com/drakkan/sftpgo' diff --git a/templates/webclient/files.html b/templates/webclient/files.html index 38c59cc6..0f7835d2 100644 --- a/templates/webclient/files.html +++ b/templates/webclient/files.html @@ -1039,9 +1039,8 @@ along with this program. If not, see . case "bmp": case "svg": case "ico": - var view_url = row['url']+"&inline=1"; var title = escapeHTMLForceSafe(row["name"]) - return ``; + return ``; case "mp4": case "mov": var name = b64EncodeUnicode(row["name"]); diff --git a/version/version.go b/version/version.go index ed562ac4..ed4ccdd7 100644 --- a/version/version.go +++ b/version/version.go @@ -17,7 +17,7 @@ package version import "strings" -const version = "2.3.5" +const version = "2.3.5-dev" var ( commit = ""