mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 07:35:07 +00:00
stcp, xtcp, sudp: support allow_users and specified server user (#3472)
This commit is contained in:
@@ -21,57 +21,69 @@ import (
|
||||
"sync"
|
||||
|
||||
libio "github.com/fatedier/golib/io"
|
||||
"github.com/samber/lo"
|
||||
|
||||
utilnet "github.com/fatedier/frp/pkg/util/net"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
)
|
||||
|
||||
type listenerBundle struct {
|
||||
l *utilnet.InternalListener
|
||||
sk string
|
||||
allowUsers []string
|
||||
}
|
||||
|
||||
// Manager for visitor listeners.
|
||||
type Manager struct {
|
||||
visitorListeners map[string]*utilnet.InternalListener
|
||||
skMap map[string]string
|
||||
listeners map[string]*listenerBundle
|
||||
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
visitorListeners: make(map[string]*utilnet.InternalListener),
|
||||
skMap: make(map[string]string),
|
||||
listeners: make(map[string]*listenerBundle),
|
||||
}
|
||||
}
|
||||
|
||||
func (vm *Manager) Listen(name string, sk string) (l *utilnet.InternalListener, err error) {
|
||||
func (vm *Manager) Listen(name string, sk string, allowUsers []string) (l *utilnet.InternalListener, err error) {
|
||||
vm.mu.Lock()
|
||||
defer vm.mu.Unlock()
|
||||
|
||||
if _, ok := vm.visitorListeners[name]; ok {
|
||||
if _, ok := vm.listeners[name]; ok {
|
||||
err = fmt.Errorf("custom listener for [%s] is repeated", name)
|
||||
return
|
||||
}
|
||||
|
||||
l = utilnet.NewInternalListener()
|
||||
vm.visitorListeners[name] = l
|
||||
vm.skMap[name] = sk
|
||||
vm.listeners[name] = &listenerBundle{
|
||||
l: l,
|
||||
sk: sk,
|
||||
allowUsers: allowUsers,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (vm *Manager) NewConn(name string, conn net.Conn, timestamp int64, signKey string,
|
||||
useEncryption bool, useCompression bool,
|
||||
useEncryption bool, useCompression bool, visitorUser string,
|
||||
) (err error) {
|
||||
vm.mu.RLock()
|
||||
defer vm.mu.RUnlock()
|
||||
|
||||
if l, ok := vm.visitorListeners[name]; ok {
|
||||
var sk string
|
||||
if sk = vm.skMap[name]; util.GetAuthKey(sk, timestamp) != signKey {
|
||||
if l, ok := vm.listeners[name]; ok {
|
||||
if util.GetAuthKey(l.sk, timestamp) != signKey {
|
||||
err = fmt.Errorf("visitor connection of [%s] auth failed", name)
|
||||
return
|
||||
}
|
||||
|
||||
if !lo.Contains(l.allowUsers, visitorUser) && !lo.Contains(l.allowUsers, "*") {
|
||||
err = fmt.Errorf("visitor connection of [%s] user [%s] not allowed", name, visitorUser)
|
||||
return
|
||||
}
|
||||
|
||||
var rwc io.ReadWriteCloser = conn
|
||||
if useEncryption {
|
||||
if rwc, err = libio.WithEncryption(rwc, []byte(sk)); err != nil {
|
||||
if rwc, err = libio.WithEncryption(rwc, []byte(l.sk)); err != nil {
|
||||
err = fmt.Errorf("create encryption connection failed: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -79,7 +91,7 @@ func (vm *Manager) NewConn(name string, conn net.Conn, timestamp int64, signKey
|
||||
if useCompression {
|
||||
rwc = libio.WithCompression(rwc)
|
||||
}
|
||||
err = l.PutConn(utilnet.WrapReadWriteCloserToConn(rwc, conn))
|
||||
err = l.l.PutConn(utilnet.WrapReadWriteCloserToConn(rwc, conn))
|
||||
} else {
|
||||
err = fmt.Errorf("custom listener for [%s] doesn't exist", name)
|
||||
return
|
||||
@@ -91,6 +103,5 @@ func (vm *Manager) CloseListener(name string) {
|
||||
vm.mu.Lock()
|
||||
defer vm.mu.Unlock()
|
||||
|
||||
delete(vm.visitorListeners, name)
|
||||
delete(vm.skMap, name)
|
||||
delete(vm.listeners, name)
|
||||
}
|
||||
|
Reference in New Issue
Block a user