diff --git a/config/config.go b/config/config.go index ffda6f92..4798c01c 100644 --- a/config/config.go +++ b/config/config.go @@ -143,8 +143,9 @@ type AutherConfig struct { } type AuthConfig struct { - Username string `json:"username"` + Username string `yaml:",omitempty" json:"username,omitempty"` Password string `yaml:",omitempty" json:"password,omitempty"` + File string `yaml:",omitempty" json:"file,omitempty"` } type SelectorConfig struct { diff --git a/config/parsing/auth/parse.go b/config/parsing/auth/parse.go index 6a2047fa..9cd9f2a9 100644 --- a/config/parsing/auth/parse.go +++ b/config/parsing/auth/parse.go @@ -1,8 +1,12 @@ package auth import ( + "bufio" "crypto/tls" + "io" "net/url" + "os" + "strings" "github.com/go-gost/core/auth" "github.com/go-gost/core/logger" @@ -98,7 +102,20 @@ func ParseAutherFromAuth(au *config.AuthConfig) auth.Authenticator { } func Info(cfg *config.AuthConfig) *url.Userinfo { - if cfg == nil || cfg.Username == "" { + if cfg == nil { + return nil + } + + if cfg.File != "" { + if f, _ := os.Open(cfg.File); f != nil { + defer f.Close() + if infos, _ := parseInfo(f, 1); len(infos) > 0 { + return infos[0] + } + } + } + + if cfg.Username == "" { return nil } @@ -108,6 +125,39 @@ func Info(cfg *config.AuthConfig) *url.Userinfo { return url.UserPassword(cfg.Username, cfg.Password) } +func parseInfo(r io.Reader, max int) (infos []*url.Userinfo, err error) { + if r == nil { + return + } + + scanner := bufio.NewScanner(r) + for scanner.Scan() { + // line := strings.Replace(scanner.Text(), "\t", " ", -1) + line := strings.TrimSpace(scanner.Text()) + if n := strings.IndexByte(line, '#'); n == 0 { + continue + } + sp := strings.SplitN(line, " ", 2) + if len(sp) == 1 { + if k := strings.TrimSpace(sp[0]); k != "" { + infos = append(infos, url.User(k)) + } + } + if len(sp) == 2 { + if k := strings.TrimSpace(sp[0]); k != "" { + infos = append(infos, url.UserPassword(k, strings.TrimSpace(sp[1]))) + } + } + + if max > 0 && len(infos) >= max { + break + } + } + + err = scanner.Err() + return +} + func List(name string, names ...string) []auth.Authenticator { var authers []auth.Authenticator if auther := registry.AutherRegistry().Get(name); auther != nil {