diff --git a/common/auth/auth.go b/common/auth/auth.go index 024b381c3..b1be60d11 100644 --- a/common/auth/auth.go +++ b/common/auth/auth.go @@ -1,38 +1,30 @@ package auth -type Authenticator interface { - Verify(user string, pass string) bool - Users() []string -} +import "github.com/sagernet/sing/common" type User struct { - Username string `json:"username"` - Password string `json:"password"` -} - -type inMemoryAuthenticator struct { - storage map[string]string - usernames []string + Username string + Password string } -func (au *inMemoryAuthenticator) Verify(username string, password string) bool { - realPass, ok := au.storage[username] - return ok && realPass == password +type Authenticator struct { + userMap map[string][]string } -func (au *inMemoryAuthenticator) Users() []string { return au.usernames } - -func NewAuthenticator(users []User) Authenticator { +func NewAuthenticator(users []User) *Authenticator { if len(users) == 0 { return nil } - au := &inMemoryAuthenticator{ - storage: make(map[string]string), - usernames: make([]string, 0, len(users)), + au := &Authenticator{ + userMap: make(map[string][]string), } for _, user := range users { - au.storage[user.Username] = user.Password - au.usernames = append(au.usernames, user.Username) + au.userMap[user.Username] = append(au.userMap[user.Username], user.Password) } return au } + +func (au *Authenticator) Verify(username string, password string) bool { + passwordList, ok := au.userMap[username] + return ok && common.Contains(passwordList, password) +} diff --git a/protocol/http/handshake.go b/protocol/http/handshake.go index d60656f37..a6ab6fef4 100644 --- a/protocol/http/handshake.go +++ b/protocol/http/handshake.go @@ -21,7 +21,7 @@ import ( type Handler = N.TCPConnectionHandler -func HandleConnection(ctx context.Context, conn net.Conn, reader *std_bufio.Reader, authenticator auth.Authenticator, handler Handler, metadata M.Metadata) error { +func HandleConnection(ctx context.Context, conn net.Conn, reader *std_bufio.Reader, authenticator *auth.Authenticator, handler Handler, metadata M.Metadata) error { var httpClient *http.Client for { request, err := ReadRequest(reader) diff --git a/protocol/socks/handshake.go b/protocol/socks/handshake.go index 39f4cb783..a8736ff47 100644 --- a/protocol/socks/handshake.go +++ b/protocol/socks/handshake.go @@ -93,7 +93,7 @@ func ClientHandshake5(conn io.ReadWriter, command byte, destination M.Socksaddr, return response, err } -func HandleConnection(ctx context.Context, conn net.Conn, authenticator auth.Authenticator, handler Handler, metadata M.Metadata) error { +func HandleConnection(ctx context.Context, conn net.Conn, authenticator *auth.Authenticator, handler Handler, metadata M.Metadata) error { version, err := rw.ReadByte(conn) if err != nil { return err @@ -101,7 +101,7 @@ func HandleConnection(ctx context.Context, conn net.Conn, authenticator auth.Aut return HandleConnection0(ctx, conn, version, authenticator, handler, metadata) } -func HandleConnection0(ctx context.Context, conn net.Conn, version byte, authenticator auth.Authenticator, handler Handler, metadata M.Metadata) error { +func HandleConnection0(ctx context.Context, conn net.Conn, version byte, authenticator *auth.Authenticator, handler Handler, metadata M.Metadata) error { switch version { case socks4.Version: request, err := socks4.ReadRequest0(conn)