add client ID for plugin service
This commit is contained in:
@ -18,6 +18,7 @@ import (
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
"github.com/go-gost/x/internal/util/forward"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -208,12 +209,14 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, log l
|
||||
|
||||
if auther := target.Options().Auther; auther != nil {
|
||||
username, password, _ := req.BasicAuth()
|
||||
if !auther.Authenticate(ctx, username, password) {
|
||||
ok, id := auther.Authenticate(ctx, username, password)
|
||||
if !ok {
|
||||
resp.StatusCode = http.StatusUnauthorized
|
||||
resp.Header.Set("WWW-Authenticate", "Basic")
|
||||
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)
|
||||
return resp.Write(rw)
|
||||
}
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(id))
|
||||
}
|
||||
|
||||
var cc net.Conn
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
mdata "github.com/go-gost/core/metadata"
|
||||
mdutil "github.com/go-gost/core/metadata/util"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
"github.com/go-gost/x/internal/util/forward"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -205,12 +206,14 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, log l
|
||||
|
||||
if auther := target.Options().Auther; auther != nil {
|
||||
username, password, _ := req.BasicAuth()
|
||||
if !auther.Authenticate(ctx, username, password) {
|
||||
ok, id := auther.Authenticate(ctx, username, password)
|
||||
if !ok {
|
||||
resp.StatusCode = http.StatusUnauthorized
|
||||
resp.Header.Set("WWW-Authenticate", "Basic")
|
||||
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)
|
||||
return resp.Write(rw)
|
||||
}
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(id))
|
||||
}
|
||||
|
||||
var cc net.Conn
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
netpkg "github.com/go-gost/x/internal/net"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
sx "github.com/go-gost/x/internal/util/selector"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -145,6 +146,12 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
|
||||
resp.Header = http.Header{}
|
||||
}
|
||||
|
||||
ok, id := h.authenticate(ctx, conn, req, resp, log)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(id))
|
||||
|
||||
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
|
||||
resp.StatusCode = http.StatusForbidden
|
||||
|
||||
@ -157,10 +164,6 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
|
||||
return resp.Write(conn)
|
||||
}
|
||||
|
||||
if !h.authenticate(ctx, conn, req, resp, log) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if network == "udp" {
|
||||
return h.handleUDP(ctx, conn, log)
|
||||
}
|
||||
@ -266,10 +269,13 @@ func (h *httpHandler) basicProxyAuth(proxyAuth string, log logger.Logger) (usern
|
||||
return cs[:s], cs[s+1:], true
|
||||
}
|
||||
|
||||
func (h *httpHandler) authenticate(ctx context.Context, conn net.Conn, req *http.Request, resp *http.Response, log logger.Logger) (ok bool) {
|
||||
func (h *httpHandler) authenticate(ctx context.Context, conn net.Conn, req *http.Request, resp *http.Response, log logger.Logger) (ok bool, token string) {
|
||||
u, p, _ := h.basicProxyAuth(req.Header.Get("Proxy-Authorization"), log)
|
||||
if h.options.Auther == nil || h.options.Auther.Authenticate(ctx, u, p) {
|
||||
return true
|
||||
if h.options.Auther == nil {
|
||||
return true, ""
|
||||
}
|
||||
if ok, token = h.options.Auther.Authenticate(ctx, u, p); ok {
|
||||
return
|
||||
}
|
||||
|
||||
pr := h.md.probeResistance
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
md "github.com/go-gost/core/metadata"
|
||||
xio "github.com/go-gost/x/internal/io"
|
||||
netpkg "github.com/go-gost/x/internal/net"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
sx "github.com/go-gost/x/internal/util/selector"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -138,12 +139,6 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
|
||||
w.Header().Set(k, h.md.header.Get(k))
|
||||
}
|
||||
|
||||
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
log.Debug("bypass: ", addr)
|
||||
return nil
|
||||
}
|
||||
|
||||
resp := &http.Response{
|
||||
ProtoMajor: 2,
|
||||
ProtoMinor: 0,
|
||||
@ -151,7 +146,15 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
}
|
||||
|
||||
if !h.authenticate(ctx, w, req, resp, log) {
|
||||
ok, id := h.authenticate(ctx, w, req, resp, log)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(id))
|
||||
|
||||
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
log.Debug("bypass: ", addr)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -251,10 +254,13 @@ func (h *http2Handler) basicProxyAuth(proxyAuth string) (username, password stri
|
||||
return cs[:s], cs[s+1:], true
|
||||
}
|
||||
|
||||
func (h *http2Handler) authenticate(ctx context.Context, w http.ResponseWriter, r *http.Request, resp *http.Response, log logger.Logger) (ok bool) {
|
||||
func (h *http2Handler) authenticate(ctx context.Context, w http.ResponseWriter, r *http.Request, resp *http.Response, log logger.Logger) (ok bool, token string) {
|
||||
u, p, _ := h.basicProxyAuth(r.Header.Get("Proxy-Authorization"))
|
||||
if h.options.Auther == nil || h.options.Auther.Authenticate(ctx, u, p) {
|
||||
return true
|
||||
if h.options.Auther == nil {
|
||||
return true, ""
|
||||
}
|
||||
if ok, token = h.options.Auther.Authenticate(ctx, u, p); ok {
|
||||
return
|
||||
}
|
||||
|
||||
pr := h.md.probeResistance
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/go-gost/core/service"
|
||||
"github.com/go-gost/relay"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
"github.com/go-gost/x/registry"
|
||||
xservice "github.com/go-gost/x/service"
|
||||
)
|
||||
@ -200,11 +201,14 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
|
||||
log = log.WithFields(map[string]any{"user": user})
|
||||
}
|
||||
|
||||
if h.options.Auther != nil &&
|
||||
!h.options.Auther.Authenticate(ctx, user, pass) {
|
||||
resp.Status = relay.StatusUnauthorized
|
||||
resp.WriteTo(conn)
|
||||
return ErrUnauthorized
|
||||
if h.options.Auther != nil {
|
||||
ok, id := h.options.Auther.Authenticate(ctx, user, pass)
|
||||
if !ok {
|
||||
resp.Status = relay.StatusUnauthorized
|
||||
resp.WriteTo(conn)
|
||||
return ErrUnauthorized
|
||||
}
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(id))
|
||||
}
|
||||
|
||||
network := networkID.String()
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/gosocks4"
|
||||
netpkg "github.com/go-gost/x/internal/net"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
sx "github.com/go-gost/x/internal/util/selector"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -90,11 +91,14 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
|
||||
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
|
||||
if h.options.Auther != nil &&
|
||||
!h.options.Auther.Authenticate(ctx, string(req.Userid), "") {
|
||||
resp := gosocks4.NewReply(gosocks4.RejectedUserid, nil)
|
||||
log.Trace(resp)
|
||||
return resp.Write(conn)
|
||||
if h.options.Auther != nil {
|
||||
ok, id := h.options.Auther.Authenticate(ctx, string(req.Userid), "")
|
||||
if !ok {
|
||||
resp := gosocks4.NewReply(gosocks4.RejectedUserid, nil)
|
||||
log.Trace(resp)
|
||||
return resp.Write(conn)
|
||||
}
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(id))
|
||||
}
|
||||
|
||||
switch req.Cmd {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/gosocks5"
|
||||
auth_util "github.com/go-gost/x/internal/util/auth"
|
||||
"github.com/go-gost/x/internal/util/socks"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -86,13 +87,17 @@ func (h *socks5Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
|
||||
conn.SetReadDeadline(time.Now().Add(h.md.readTimeout))
|
||||
}
|
||||
|
||||
conn = gosocks5.ServerConn(conn, h.selector)
|
||||
req, err := gosocks5.ReadRequest(conn)
|
||||
sc := gosocks5.ServerConn(conn, h.selector)
|
||||
req, err := gosocks5.ReadRequest(sc)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
log.Trace(req)
|
||||
|
||||
ctx = auth_util.ContextWithID(ctx, auth_util.ID(sc.ID()))
|
||||
|
||||
conn = sc
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
|
||||
address := req.Addr.String()
|
||||
|
@ -46,11 +46,12 @@ func (s *serverSelector) Select(methods ...uint8) (method uint8) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) {
|
||||
func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (string, net.Conn, error) {
|
||||
s.logger.Debugf("%d %d", gosocks5.Ver5, method)
|
||||
switch method {
|
||||
case socks.MethodTLS:
|
||||
conn = tls.Server(conn, s.TLSConfig)
|
||||
return "", conn, nil
|
||||
|
||||
case gosocks5.MethodUserPass, socks.MethodTLSAuth:
|
||||
if method == socks.MethodTLSAuth {
|
||||
@ -60,32 +61,37 @@ func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, erro
|
||||
req, err := gosocks5.ReadUserPassRequest(conn)
|
||||
if err != nil {
|
||||
s.logger.Error(err)
|
||||
return nil, err
|
||||
return "", nil, err
|
||||
}
|
||||
s.logger.Trace(req)
|
||||
|
||||
if s.Authenticator != nil &&
|
||||
!s.Authenticator.Authenticate(context.Background(), req.Username, req.Password) {
|
||||
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
|
||||
if err := resp.Write(conn); err != nil {
|
||||
s.logger.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
s.logger.Info(resp)
|
||||
var id string
|
||||
if s.Authenticator != nil {
|
||||
var ok bool
|
||||
ok, id = s.Authenticator.Authenticate(context.Background(), req.Username, req.Password)
|
||||
if !ok {
|
||||
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
|
||||
if err := resp.Write(conn); err != nil {
|
||||
s.logger.Error(err)
|
||||
return "", nil, err
|
||||
}
|
||||
s.logger.Info(resp)
|
||||
|
||||
return nil, gosocks5.ErrAuthFailure
|
||||
return "", nil, gosocks5.ErrAuthFailure
|
||||
}
|
||||
}
|
||||
|
||||
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded)
|
||||
s.logger.Trace(resp)
|
||||
if err := resp.Write(conn); err != nil {
|
||||
s.logger.Error(err)
|
||||
return nil, err
|
||||
return "", nil, err
|
||||
}
|
||||
return id, conn, nil
|
||||
|
||||
case gosocks5.MethodNoAcceptable:
|
||||
return nil, gosocks5.ErrBadMethod
|
||||
return "", nil, gosocks5.ErrBadMethod
|
||||
default:
|
||||
return "", nil, gosocks5.ErrBadFormat
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ func (h *tunHandler) transportServer(ctx context.Context, tun io.ReadWriter, con
|
||||
ok := true
|
||||
key := bytes.TrimRight((*b)[4:20], "\x00")
|
||||
for _, ip := range peerIPs {
|
||||
if ok = auther.Authenticate(ctx, ip.String(), string(key)); !ok {
|
||||
if ok, _ = auther.Authenticate(ctx, ip.String(), string(key)); !ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user