2022-11-08 12:49:19 +01:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
2023-01-11 06:05:44 +01:00
|
|
|
"bytes"
|
2024-08-18 16:58:35 +02:00
|
|
|
"fmt"
|
2023-01-11 06:05:44 +01:00
|
|
|
"html/template"
|
|
|
|
|
2024-07-08 17:22:48 +02:00
|
|
|
"github.com/rclone/rclone/fs"
|
2022-11-08 12:49:19 +01:00
|
|
|
"github.com/rclone/rclone/fs/config/flags"
|
|
|
|
"github.com/spf13/pflag"
|
|
|
|
)
|
|
|
|
|
2023-01-11 06:05:44 +01:00
|
|
|
// AuthHelp returns text describing the http authentication to add to the command help.
|
|
|
|
func AuthHelp(prefix string) string {
|
2024-04-05 13:27:33 +02:00
|
|
|
help := `#### Authentication
|
2022-11-08 12:49:19 +01:00
|
|
|
|
|
|
|
By default this will serve files without needing a login.
|
|
|
|
|
|
|
|
You can either use an htpasswd file which can take lots of users, or
|
2023-01-11 06:05:44 +01:00
|
|
|
set a single username and password with the ` + "`--{{ .Prefix }}user` and `--{{ .Prefix }}pass`" + ` flags.
|
2022-11-08 12:49:19 +01:00
|
|
|
|
2023-05-26 07:26:13 +02:00
|
|
|
If no static users are configured by either of the above methods, and client
|
|
|
|
certificates are required by the ` + "`--client-ca`" + ` flag passed to the server, the
|
|
|
|
client certificate common name will be considered as the username.
|
|
|
|
|
2023-01-11 06:05:44 +01:00
|
|
|
Use ` + "`--{{ .Prefix }}htpasswd /path/to/htpasswd`" + ` to provide an htpasswd file. This is
|
2022-11-08 12:49:19 +01:00
|
|
|
in standard apache format and supports MD5, SHA1 and BCrypt for basic
|
|
|
|
authentication. Bcrypt is recommended.
|
|
|
|
|
|
|
|
To create an htpasswd file:
|
|
|
|
|
|
|
|
touch htpasswd
|
|
|
|
htpasswd -B htpasswd user
|
|
|
|
htpasswd -B htpasswd anotherUser
|
|
|
|
|
|
|
|
The password file can be updated while rclone is running.
|
|
|
|
|
2023-01-11 06:05:44 +01:00
|
|
|
Use ` + "`--{{ .Prefix }}realm`" + ` to set the authentication realm.
|
2022-11-08 12:49:19 +01:00
|
|
|
|
2023-01-11 06:05:44 +01:00
|
|
|
Use ` + "`--{{ .Prefix }}salt`" + ` to change the password hashing salt from the default.
|
2024-04-05 13:27:33 +02:00
|
|
|
|
2022-11-08 12:49:19 +01:00
|
|
|
`
|
2023-01-11 06:05:44 +01:00
|
|
|
tmpl, err := template.New("auth help").Parse(help)
|
|
|
|
if err != nil {
|
2024-08-18 16:58:35 +02:00
|
|
|
fs.Fatal(nil, fmt.Sprint("Fatal error parsing template", err))
|
2023-01-11 06:05:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
data := struct {
|
|
|
|
Prefix string
|
|
|
|
}{
|
|
|
|
Prefix: prefix,
|
|
|
|
}
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
err = tmpl.Execute(buf, data)
|
|
|
|
if err != nil {
|
2024-08-18 16:58:35 +02:00
|
|
|
fs.Fatal(nil, fmt.Sprint("Fatal error executing template", err))
|
2023-01-11 06:05:44 +01:00
|
|
|
}
|
|
|
|
return buf.String()
|
|
|
|
}
|
2022-11-08 12:49:19 +01:00
|
|
|
|
|
|
|
// CustomAuthFn if used will be used to authenticate user, pass. If an error
|
|
|
|
// is returned then the user is not authenticated.
|
|
|
|
//
|
|
|
|
// If a non nil value is returned then it is added to the context under the key
|
|
|
|
type CustomAuthFn func(user, pass string) (value interface{}, err error)
|
|
|
|
|
2024-07-08 17:22:48 +02:00
|
|
|
// AuthConfigInfo descripts the Options in use
|
|
|
|
var AuthConfigInfo = fs.Options{{
|
|
|
|
Name: "htpasswd",
|
|
|
|
Default: "",
|
|
|
|
Help: "A htpasswd file - if not provided no authentication is done",
|
|
|
|
}, {
|
|
|
|
Name: "realm",
|
|
|
|
Default: "",
|
|
|
|
Help: "Realm for authentication",
|
|
|
|
}, {
|
|
|
|
Name: "user",
|
|
|
|
Default: "",
|
|
|
|
Help: "User name for authentication",
|
|
|
|
}, {
|
|
|
|
Name: "pass",
|
|
|
|
Default: "",
|
|
|
|
Help: "Password for authentication",
|
|
|
|
}, {
|
|
|
|
Name: "salt",
|
|
|
|
Default: "dlPL2MqE",
|
|
|
|
Help: "Password hashing salt",
|
|
|
|
}}
|
|
|
|
|
2022-11-08 12:49:19 +01:00
|
|
|
// AuthConfig contains options for the http authentication
|
|
|
|
type AuthConfig struct {
|
2024-07-08 17:22:48 +02:00
|
|
|
HtPasswd string `config:"htpasswd"` // htpasswd file - if not provided no authentication is done
|
|
|
|
Realm string `config:"realm"` // realm for authentication
|
|
|
|
BasicUser string `config:"user"` // single username for basic auth if not using Htpasswd
|
|
|
|
BasicPass string `config:"pass"` // password for BasicUser
|
|
|
|
Salt string `config:"salt"` // password hashing salt
|
|
|
|
CustomAuthFn CustomAuthFn `json:"-" config:"-"` // custom Auth (not set by command line flags)
|
2022-11-08 12:49:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddFlagsPrefix adds flags to the flag set for AuthConfig
|
|
|
|
func (cfg *AuthConfig) AddFlagsPrefix(flagSet *pflag.FlagSet, prefix string) {
|
2023-07-10 19:34:10 +02:00
|
|
|
flags.StringVarP(flagSet, &cfg.HtPasswd, prefix+"htpasswd", "", cfg.HtPasswd, "A htpasswd file - if not provided no authentication is done", prefix)
|
|
|
|
flags.StringVarP(flagSet, &cfg.Realm, prefix+"realm", "", cfg.Realm, "Realm for authentication", prefix)
|
|
|
|
flags.StringVarP(flagSet, &cfg.BasicUser, prefix+"user", "", cfg.BasicUser, "User name for authentication", prefix)
|
|
|
|
flags.StringVarP(flagSet, &cfg.BasicPass, prefix+"pass", "", cfg.BasicPass, "Password for authentication", prefix)
|
|
|
|
flags.StringVarP(flagSet, &cfg.Salt, prefix+"salt", "", cfg.Salt, "Password hashing salt", prefix)
|
2022-11-08 12:49:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddAuthFlagsPrefix adds flags to the flag set for AuthConfig
|
|
|
|
func AddAuthFlagsPrefix(flagSet *pflag.FlagSet, prefix string, cfg *AuthConfig) {
|
|
|
|
cfg.AddFlagsPrefix(flagSet, prefix)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultAuthCfg returns a new config which can be customized by command line flags
|
2024-07-08 17:22:48 +02:00
|
|
|
//
|
|
|
|
// Note that this needs to be kept in sync with AuthConfigInfo above and
|
|
|
|
// can be removed when all callers have been converted.
|
2022-11-08 12:49:19 +01:00
|
|
|
func DefaultAuthCfg() AuthConfig {
|
|
|
|
return AuthConfig{
|
|
|
|
Salt: "dlPL2MqE",
|
|
|
|
}
|
|
|
|
}
|