mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-11-23 04:30:19 +01:00
parent
3b777e1c19
commit
54cacb5487
7 changed files with 97 additions and 48 deletions
|
@ -87,7 +87,7 @@ https://transfer.sh/1lDau/test.txt --> https://transfer.sh/inline/1lDau/test.txt
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Parameter | Description | Value | Env
|
Parameter | Description | Value | Env
|
||||||
--- | --- | --- | ---
|
--- |---------------------------------------------------------------------------------------------| --- |-----------------------------
|
||||||
listener | port to use for http (:80) | | LISTENER |
|
listener | port to use for http (:80) | | LISTENER |
|
||||||
profile-listener | port to use for profiler (:6060) | | PROFILE_LISTENER |
|
profile-listener | port to use for profiler (:6060) | | PROFILE_LISTENER |
|
||||||
force-https | redirect to https | false | FORCE_HTTPS
|
force-https | redirect to https | false | FORCE_HTTPS
|
||||||
|
@ -97,6 +97,7 @@ tls-cert-file | path to tls certificate | | TLS_CERT_FILE |
|
||||||
tls-private-key | path to tls private key | | TLS_PRIVATE_KEY |
|
tls-private-key | path to tls private key | | TLS_PRIVATE_KEY |
|
||||||
http-auth-user | user for basic http auth on upload | | HTTP_AUTH_USER |
|
http-auth-user | user for basic http auth on upload | | HTTP_AUTH_USER |
|
||||||
http-auth-pass | pass for basic http auth on upload | | HTTP_AUTH_PASS |
|
http-auth-pass | pass for basic http auth on upload | | HTTP_AUTH_PASS |
|
||||||
|
http-auth-htpasswd | htpasswd file path for basic http auth on upload | | HTTP_AUTH_HTPASSWD |
|
||||||
ip-whitelist | comma separated list of ips allowed to connect to the service | | IP_WHITELIST |
|
ip-whitelist | comma separated list of ips allowed to connect to the service | | IP_WHITELIST |
|
||||||
ip-blacklist | comma separated list of ips not allowed to connect to the service | | IP_BLACKLIST |
|
ip-blacklist | comma separated list of ips not allowed to connect to the service | | IP_BLACKLIST |
|
||||||
temp-path | path to temp folder | system temp | TEMP_PATH |
|
temp-path | path to temp folder | system temp | TEMP_PATH |
|
||||||
|
|
10
cmd/cmd.go
10
cmd/cmd.go
|
@ -270,6 +270,12 @@ var globalFlags = []cli.Flag{
|
||||||
Value: "",
|
Value: "",
|
||||||
EnvVar: "HTTP_AUTH_PASS",
|
EnvVar: "HTTP_AUTH_PASS",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "http-auth-htpasswd",
|
||||||
|
Usage: "htpasswd file http basic auth",
|
||||||
|
Value: "",
|
||||||
|
EnvVar: "HTTP_AUTH_HTPASSWD",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "ip-whitelist",
|
Name: "ip-whitelist",
|
||||||
Usage: "comma separated list of ips allowed to connect to the service",
|
Usage: "comma separated list of ips allowed to connect to the service",
|
||||||
|
@ -440,6 +446,10 @@ func New() *Cmd {
|
||||||
options = append(options, server.HTTPAuthCredentials(httpAuthUser, httpAuthPass))
|
options = append(options, server.HTTPAuthCredentials(httpAuthUser, httpAuthPass))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if httpAuthHtpasswd := c.String("http-auth-htpasswd"); httpAuthHtpasswd != "" {
|
||||||
|
options = append(options, server.HTTPAuthHtpasswd(httpAuthHtpasswd))
|
||||||
|
}
|
||||||
|
|
||||||
applyIPFilter := false
|
applyIPFilter := false
|
||||||
ipFilterOptions := server.IPFilterOptions{}
|
ipFilterOptions := server.IPFilterOptions{}
|
||||||
if ipWhitelist := c.String("ip-whitelist"); ipWhitelist != "" {
|
if ipWhitelist := c.String("ip-whitelist"); ipWhitelist != "" {
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
tls-private-key = mkOption { type = types.nullOr types.str; description = "path to tls private key "; };
|
tls-private-key = mkOption { type = types.nullOr types.str; description = "path to tls private key "; };
|
||||||
http-auth-user = mkOption { type = types.nullOr types.str; description = "user for basic http auth on upload"; };
|
http-auth-user = mkOption { type = types.nullOr types.str; description = "user for basic http auth on upload"; };
|
||||||
http-auth-pass = mkOption { type = types.nullOr types.str; description = "pass for basic http auth on upload"; };
|
http-auth-pass = mkOption { type = types.nullOr types.str; description = "pass for basic http auth on upload"; };
|
||||||
|
http-auth-htpasswd = mkOption { type = types.nullOr types.str; description = "htpasswd file path for basic http auth on upload"; };
|
||||||
ip-whitelist = mkOption { type = types.nullOr types.str; description = "comma separated list of ips allowed to connect to the service"; };
|
ip-whitelist = mkOption { type = types.nullOr types.str; description = "comma separated list of ips allowed to connect to the service"; };
|
||||||
ip-blacklist = mkOption { type = types.nullOr types.str; description = "comma separated list of ips not allowed to connect to the service"; };
|
ip-blacklist = mkOption { type = types.nullOr types.str; description = "comma separated list of ips not allowed to connect to the service"; };
|
||||||
temp-path = mkOption { type = types.nullOr types.str; description = "path to temp folder"; };
|
temp-path = mkOption { type = types.nullOr types.str; description = "path to temp folder"; };
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -19,6 +19,7 @@ require (
|
||||||
github.com/microcosm-cc/bluemonday v1.0.23
|
github.com/microcosm-cc/bluemonday v1.0.23
|
||||||
github.com/russross/blackfriday/v2 v2.1.0
|
github.com/russross/blackfriday/v2 v2.1.0
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
|
github.com/tg123/go-htpasswd v1.2.1
|
||||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
||||||
github.com/urfave/cli v1.22.12
|
github.com/urfave/cli v1.22.12
|
||||||
golang.org/x/crypto v0.6.0
|
golang.org/x/crypto v0.6.0
|
||||||
|
@ -33,6 +34,7 @@ require (
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute v1.18.0 // indirect
|
cloud.google.com/go/compute v1.18.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
|
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/calebcase/tmpfile v1.0.3 // indirect
|
github.com/calebcase/tmpfile v1.0.3 // indirect
|
||||||
github.com/cloudflare/circl v1.1.0 // indirect
|
github.com/cloudflare/circl v1.1.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -9,6 +9,8 @@ cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXW
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
|
||||||
|
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230124153114-0acdc8ae009b/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
github.com/ProtonMail/go-crypto v0.0.0-20230124153114-0acdc8ae009b/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||||
|
@ -179,6 +181,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/tg123/go-htpasswd v1.2.1 h1:i4wfsX1KvvkyoMiHZzjS0VzbAPWfxzI8INcZAKtutoU=
|
||||||
|
github.com/tg123/go-htpasswd v1.2.1/go.mod h1:erHp1B86KXdwQf1X5ZrLb7erXZnWueEQezb2dql4q58=
|
||||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
|
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
|
||||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
||||||
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
|
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
|
||||||
|
|
|
@ -57,6 +57,7 @@ import (
|
||||||
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/constants"
|
"github.com/ProtonMail/gopenpgp/v2/constants"
|
||||||
"github.com/dutchcoders/transfer.sh/server/storage"
|
"github.com/dutchcoders/transfer.sh/server/storage"
|
||||||
|
"github.com/tg123/go-htpasswd"
|
||||||
|
|
||||||
web "github.com/dutchcoders/transfer.sh-web"
|
web "github.com/dutchcoders/transfer.sh-web"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -1319,11 +1320,21 @@ func ipFilterHandler(h http.Handler, ipFilterOptions *IPFilterOptions) http.Hand
|
||||||
|
|
||||||
func (s *Server) basicAuthHandler(h http.Handler) http.HandlerFunc {
|
func (s *Server) basicAuthHandler(h http.Handler) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if s.AuthUser == "" || s.AuthPass == "" {
|
if s.AuthUser == "" || s.AuthPass == "" || s.AuthHtpasswd == "" {
|
||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.htpasswdFile == nil && s.AuthHtpasswd != "" {
|
||||||
|
htpasswdFile, err := htpasswd.New(s.AuthHtpasswd, htpasswd.DefaultSystems, nil)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.htpasswdFile = htpasswdFile
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("WWW-Authenticate", "Basic realm=\"Restricted\"")
|
w.Header().Set("WWW-Authenticate", "Basic realm=\"Restricted\"")
|
||||||
|
|
||||||
username, password, authOK := r.BasicAuth()
|
username, password, authOK := r.BasicAuth()
|
||||||
|
@ -1332,7 +1343,16 @@ func (s *Server) basicAuthHandler(h http.Handler) http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if username != s.AuthUser || password != s.AuthPass {
|
var authorized bool
|
||||||
|
if username == s.AuthUser && password == s.AuthPass {
|
||||||
|
authorized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.htpasswdFile != nil && !authorized {
|
||||||
|
authorized = s.htpasswdFile.Match(username, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !authorized {
|
||||||
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ import (
|
||||||
"github.com/VojtechVitek/ratelimit/memory"
|
"github.com/VojtechVitek/ratelimit/memory"
|
||||||
gorillaHandlers "github.com/gorilla/handlers"
|
gorillaHandlers "github.com/gorilla/handlers"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/tg123/go-htpasswd"
|
||||||
"golang.org/x/crypto/acme/autocert"
|
"golang.org/x/crypto/acme/autocert"
|
||||||
|
|
||||||
web "github.com/dutchcoders/transfer.sh-web"
|
web "github.com/dutchcoders/transfer.sh-web"
|
||||||
|
@ -299,6 +300,13 @@ func HTTPAuthCredentials(user string, pass string) OptionFn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTPAuthHtpasswd sets basic http auth htpasswd file
|
||||||
|
func HTTPAuthHtpasswd(htpasswdPath string) OptionFn {
|
||||||
|
return func(srvr *Server) {
|
||||||
|
srvr.AuthHtpasswd = htpasswdPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FilterOptions sets ip filtering
|
// FilterOptions sets ip filtering
|
||||||
func FilterOptions(options IPFilterOptions) OptionFn {
|
func FilterOptions(options IPFilterOptions) OptionFn {
|
||||||
for i, allowedIP := range options.AllowedIPs {
|
for i, allowedIP := range options.AllowedIPs {
|
||||||
|
@ -318,6 +326,9 @@ func FilterOptions(options IPFilterOptions) OptionFn {
|
||||||
type Server struct {
|
type Server struct {
|
||||||
AuthUser string
|
AuthUser string
|
||||||
AuthPass string
|
AuthPass string
|
||||||
|
AuthHtpasswd string
|
||||||
|
|
||||||
|
htpasswdFile *htpasswd.File
|
||||||
|
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue