mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-05-26 07:08:11 +00:00
feat: add clientid key
This commit is contained in:
@@ -28,6 +28,7 @@ type config struct {
|
|||||||
transport string
|
transport string
|
||||||
carrier string
|
carrier string
|
||||||
roomID string
|
roomID string
|
||||||
|
clientID string
|
||||||
provider string
|
provider string
|
||||||
socksPort int
|
socksPort int
|
||||||
socksHost string
|
socksHost string
|
||||||
@@ -110,6 +111,7 @@ func parseFlags() config {
|
|||||||
flag.StringVar(&cfg.transport, "transport", "", "Transport: datachannel, videochannel, seichannel")
|
flag.StringVar(&cfg.transport, "transport", "", "Transport: datachannel, videochannel, seichannel")
|
||||||
flag.StringVar(&cfg.carrier, "carrier", "", "Carrier: telemost, jazz, wbstream")
|
flag.StringVar(&cfg.carrier, "carrier", "", "Carrier: telemost, jazz, wbstream")
|
||||||
flag.StringVar(&cfg.roomID, "id", "", "Room ID")
|
flag.StringVar(&cfg.roomID, "id", "", "Room ID")
|
||||||
|
flag.StringVar(&cfg.clientID, "client-id", "", "Client ID: binds one srv to one cnc (required)")
|
||||||
flag.StringVar(&cfg.provider, "provider", "", "Deprecated alias for -carrier")
|
flag.StringVar(&cfg.provider, "provider", "", "Deprecated alias for -carrier")
|
||||||
flag.IntVar(&cfg.socksPort, "socks-port", 0, "SOCKS5 port (client only)")
|
flag.IntVar(&cfg.socksPort, "socks-port", 0, "SOCKS5 port (client only)")
|
||||||
flag.StringVar(&cfg.socksHost, "socks-host", "", "SOCKS5 listen host (client only)")
|
flag.StringVar(&cfg.socksHost, "socks-host", "", "SOCKS5 listen host (client only)")
|
||||||
@@ -178,6 +180,7 @@ func toSessionConfig(cfg config) session.Config {
|
|||||||
Transport: cfg.transport,
|
Transport: cfg.transport,
|
||||||
Carrier: firstNonEmpty(cfg.carrier, cfg.provider),
|
Carrier: firstNonEmpty(cfg.carrier, cfg.provider),
|
||||||
RoomID: cfg.roomID,
|
RoomID: cfg.roomID,
|
||||||
|
ClientID: cfg.clientID,
|
||||||
KeyHex: cfg.keyHex,
|
KeyHex: cfg.keyHex,
|
||||||
SOCKSHost: cfg.socksHost,
|
SOCKSHost: cfg.socksHost,
|
||||||
SOCKSPort: cfg.socksPort,
|
SOCKSPort: cfg.socksPort,
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ var (
|
|||||||
ErrSOCKSHostRequired = errors.New("socks host required for cnc mode (use -socks-host)")
|
ErrSOCKSHostRequired = errors.New("socks host required for cnc mode (use -socks-host)")
|
||||||
// ErrSOCKSPortRequired indicates that socks port is required for cnc mode.
|
// ErrSOCKSPortRequired indicates that socks port is required for cnc mode.
|
||||||
ErrSOCKSPortRequired = errors.New("socks port required for cnc mode (use -socks-port)")
|
ErrSOCKSPortRequired = errors.New("socks port required for cnc mode (use -socks-port)")
|
||||||
|
// ErrClientIDRequired indicates that client ID is required.
|
||||||
|
ErrClientIDRequired = errors.New("client ID required (use -client-id <id>)")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config holds runtime session settings.
|
// Config holds runtime session settings.
|
||||||
@@ -86,6 +88,7 @@ type Config struct {
|
|||||||
Transport string
|
Transport string
|
||||||
Carrier string
|
Carrier string
|
||||||
RoomID string
|
RoomID string
|
||||||
|
ClientID string
|
||||||
KeyHex string
|
KeyHex string
|
||||||
SOCKSHost string
|
SOCKSHost string
|
||||||
SOCKSPort int
|
SOCKSPort int
|
||||||
@@ -186,6 +189,9 @@ func validateCommon(cfg Config) error {
|
|||||||
if cfg.RoomID == "" && cfg.Carrier != "jazz" {
|
if cfg.RoomID == "" && cfg.Carrier != "jazz" {
|
||||||
return ErrRoomIDRequired
|
return ErrRoomIDRequired
|
||||||
}
|
}
|
||||||
|
if cfg.ClientID == "" {
|
||||||
|
return ErrClientIDRequired
|
||||||
|
}
|
||||||
if cfg.KeyHex == "" {
|
if cfg.KeyHex == "" {
|
||||||
return ErrKeyRequired
|
return ErrKeyRequired
|
||||||
}
|
}
|
||||||
@@ -271,6 +277,7 @@ func Run(ctx context.Context, cfg Config) error {
|
|||||||
cfg.Carrier,
|
cfg.Carrier,
|
||||||
roomURL,
|
roomURL,
|
||||||
cfg.KeyHex,
|
cfg.KeyHex,
|
||||||
|
cfg.ClientID,
|
||||||
cfg.DNSServer,
|
cfg.DNSServer,
|
||||||
cfg.SOCKSProxyAddr,
|
cfg.SOCKSProxyAddr,
|
||||||
cfg.SOCKSProxyPort,
|
cfg.SOCKSProxyPort,
|
||||||
@@ -298,6 +305,7 @@ func Run(ctx context.Context, cfg Config) error {
|
|||||||
cfg.Carrier,
|
cfg.Carrier,
|
||||||
roomURL,
|
roomURL,
|
||||||
cfg.KeyHex,
|
cfg.KeyHex,
|
||||||
|
cfg.ClientID,
|
||||||
fmt.Sprintf("%s:%d", cfg.SOCKSHost, cfg.SOCKSPort),
|
fmt.Sprintf("%s:%d", cfg.SOCKSHost, cfg.SOCKSPort),
|
||||||
cfg.DNSServer,
|
cfg.DNSServer,
|
||||||
"",
|
"",
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ type Client struct {
|
|||||||
conn *muxconn.Conn
|
conn *muxconn.Conn
|
||||||
session *smux.Session
|
session *smux.Session
|
||||||
sessMu sync.RWMutex
|
sessMu sync.RWMutex
|
||||||
|
clientID string
|
||||||
dnsServer string
|
dnsServer string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +56,8 @@ func Run(
|
|||||||
transportName,
|
transportName,
|
||||||
carrierName,
|
carrierName,
|
||||||
roomURL,
|
roomURL,
|
||||||
keyHex string,
|
keyHex,
|
||||||
|
clientID string,
|
||||||
localAddr string,
|
localAddr string,
|
||||||
dnsServer,
|
dnsServer,
|
||||||
socksUser string,
|
socksUser string,
|
||||||
@@ -74,7 +76,7 @@ func Run(
|
|||||||
vp8BatchSize int,
|
vp8BatchSize int,
|
||||||
) error {
|
) error {
|
||||||
return RunWithReady(
|
return RunWithReady(
|
||||||
ctx, linkName, transportName, carrierName, roomURL, keyHex, localAddr,
|
ctx, linkName, transportName, carrierName, roomURL, keyHex, clientID, localAddr,
|
||||||
dnsServer, socksUser, socksPass, nil,
|
dnsServer, socksUser, socksPass, nil,
|
||||||
videoWidth, videoHeight, videoFPS, videoBitrate, videoHW,
|
videoWidth, videoHeight, videoFPS, videoBitrate, videoHW,
|
||||||
videoQRSize, videoQRRecovery, videoCodec, videoTileModule, videoTileRS,
|
videoQRSize, videoQRRecovery, videoCodec, videoTileModule, videoTileRS,
|
||||||
@@ -89,7 +91,8 @@ func RunWithReady(
|
|||||||
transportName,
|
transportName,
|
||||||
carrierName,
|
carrierName,
|
||||||
roomURL,
|
roomURL,
|
||||||
keyHex string,
|
keyHex,
|
||||||
|
clientID string,
|
||||||
localAddr string,
|
localAddr string,
|
||||||
dnsServer,
|
dnsServer,
|
||||||
_ string,
|
_ string,
|
||||||
@@ -116,7 +119,7 @@ func RunWithReady(
|
|||||||
return fmt.Errorf("setupCipher failed: %w", err)
|
return fmt.Errorf("setupCipher failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &Client{cipher: cipher, dnsServer: dnsServer}
|
c := &Client{cipher: cipher, clientID: clientID, dnsServer: dnsServer}
|
||||||
|
|
||||||
if err := c.bringUpLink(
|
if err := c.bringUpLink(
|
||||||
runCtx, linkName, transportName, carrierName, roomURL, cancel,
|
runCtx, linkName, transportName, carrierName, roomURL, cancel,
|
||||||
@@ -355,9 +358,10 @@ func (c *Client) tunnel(conn net.Conn, sess *smux.Session, targetAddr string, ta
|
|||||||
|
|
||||||
func (c *Client) sendConnectRequest(stream *smux.Stream, targetAddr string, targetPort int) error {
|
func (c *Client) sendConnectRequest(stream *smux.Stream, targetAddr string, targetPort int) error {
|
||||||
connectReq, err := json.Marshal(map[string]any{
|
connectReq, err := json.Marshal(map[string]any{
|
||||||
"cmd": "connect",
|
"cmd": "connect",
|
||||||
"addr": targetAddr,
|
"client_id": c.clientID,
|
||||||
"port": targetPort,
|
"addr": targetAddr,
|
||||||
|
"port": targetPort,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("sid=%d marshal connect req: %w", stream.ID(), err)
|
return fmt.Errorf("sid=%d marshal connect req: %w", stream.ID(), err)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ type Server struct {
|
|||||||
sessMu sync.RWMutex
|
sessMu sync.RWMutex
|
||||||
reinstallMu sync.Mutex
|
reinstallMu sync.Mutex
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
clientID string
|
||||||
dnsServer string
|
dnsServer string
|
||||||
resolver *net.Resolver
|
resolver *net.Resolver
|
||||||
socksProxyAddr string
|
socksProxyAddr string
|
||||||
@@ -49,9 +50,10 @@ type Server struct {
|
|||||||
|
|
||||||
// ConnectRequest is a message from the client to establish a new connection.
|
// ConnectRequest is a message from the client to establish a new connection.
|
||||||
type ConnectRequest struct {
|
type ConnectRequest struct {
|
||||||
Cmd string `json:"cmd"`
|
Cmd string `json:"cmd"`
|
||||||
Addr string `json:"addr"`
|
ClientID string `json:"client_id"`
|
||||||
Port int `json:"port"`
|
Addr string `json:"addr"`
|
||||||
|
Port int `json:"port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts the server with the specified parameters.
|
// Run starts the server with the specified parameters.
|
||||||
@@ -61,7 +63,8 @@ func Run(
|
|||||||
transportName,
|
transportName,
|
||||||
carrierName,
|
carrierName,
|
||||||
roomURL,
|
roomURL,
|
||||||
keyHex string,
|
keyHex,
|
||||||
|
clientID string,
|
||||||
dnsServer,
|
dnsServer,
|
||||||
socksProxyAddr string,
|
socksProxyAddr string,
|
||||||
socksProxyPort int,
|
socksProxyPort int,
|
||||||
@@ -88,6 +91,7 @@ func Run(
|
|||||||
|
|
||||||
s := &Server{
|
s := &Server{
|
||||||
cipher: cipher,
|
cipher: cipher,
|
||||||
|
clientID: clientID,
|
||||||
dnsServer: dnsServer,
|
dnsServer: dnsServer,
|
||||||
socksProxyAddr: socksProxyAddr,
|
socksProxyAddr: socksProxyAddr,
|
||||||
socksProxyPort: socksProxyPort,
|
socksProxyPort: socksProxyPort,
|
||||||
@@ -339,6 +343,10 @@ func (s *Server) handleStream(_ context.Context, stream *smux.Stream) {
|
|||||||
header = append(header, tmp[:n]...)
|
header = append(header, tmp[:n]...)
|
||||||
if req, ok := parseConnectRequest(header); ok {
|
if req, ok := parseConnectRequest(header); ok {
|
||||||
_ = stream.SetReadDeadline(time.Time{})
|
_ = stream.SetReadDeadline(time.Time{})
|
||||||
|
if !s.authorizeRequest(req) {
|
||||||
|
logger.Warnf("sid=%d rejected: client_id mismatch", stream.ID())
|
||||||
|
return
|
||||||
|
}
|
||||||
s.dispatch(stream, req)
|
s.dispatch(stream, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -363,6 +371,10 @@ func parseConnectRequest(buf []byte) (ConnectRequest, bool) {
|
|||||||
return req, true
|
return req, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) authorizeRequest(req ConnectRequest) bool {
|
||||||
|
return req.ClientID == s.clientID
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) dispatch(stream *smux.Stream, req ConnectRequest) {
|
func (s *Server) dispatch(stream *smux.Stream, req ConnectRequest) {
|
||||||
addr := net.JoinHostPort(req.Addr, strconv.Itoa(req.Port))
|
addr := net.JoinHostPort(req.Addr, strconv.Itoa(req.Port))
|
||||||
logger.Infof("sid=%d connect %s", stream.ID(), addr)
|
logger.Infof("sid=%d connect %s", stream.ID(), addr)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ var (
|
|||||||
errAlreadyRunning = errors.New("olcRTC already running")
|
errAlreadyRunning = errors.New("olcRTC already running")
|
||||||
errCarrierRequired = errors.New("carrier is required")
|
errCarrierRequired = errors.New("carrier is required")
|
||||||
errRoomIDRequired = errors.New("roomID is required")
|
errRoomIDRequired = errors.New("roomID is required")
|
||||||
|
errClientIDRequired = errors.New("clientID is required")
|
||||||
errKeyHexRequired = errors.New("keyHex is required")
|
errKeyHexRequired = errors.New("keyHex is required")
|
||||||
errNotRunning = errors.New("olcRTC is not running")
|
errNotRunning = errors.New("olcRTC is not running")
|
||||||
errStoppedBeforeReady = errors.New("olcRTC stopped before becoming ready")
|
errStoppedBeforeReady = errors.New("olcRTC stopped before becoming ready")
|
||||||
@@ -140,21 +141,22 @@ func SetDebug(enabled bool) {
|
|||||||
// Start launches the olcRTC client in background.
|
// Start launches the olcRTC client in background.
|
||||||
// carrierName: carrier/provider name ("telemost", "jazz", "wbstream", "wbstream")
|
// carrierName: carrier/provider name ("telemost", "jazz", "wbstream", "wbstream")
|
||||||
// roomID: carrier-specific room ID
|
// roomID: carrier-specific room ID
|
||||||
|
// clientID: client identifier that must match the server's -client-id
|
||||||
// keyHex: 64-char hex encryption key
|
// keyHex: 64-char hex encryption key
|
||||||
// socksPort: local SOCKS5 proxy port (e.g. 10808)
|
// socksPort: local SOCKS5 proxy port (e.g. 10808)
|
||||||
// socksUser/socksPass: SOCKS5 credentials (empty = no auth).
|
// socksUser/socksPass: SOCKS5 credentials (empty = no auth).
|
||||||
func Start(carrierName, roomID, keyHex string, socksPort int, socksUser, socksPass string) error {
|
func Start(carrierName, roomID, clientID, keyHex string, socksPort int, socksUser, socksPass string) error {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
ensureDefaultConfigLocked()
|
ensureDefaultConfigLocked()
|
||||||
cfg := defaults
|
cfg := defaults
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
||||||
return startWithConfig(carrierName, cfg.transport, roomID, keyHex, socksPort, socksUser, socksPass, cfg)
|
return startWithConfig(carrierName, cfg.transport, roomID, clientID, keyHex, socksPort, socksUser, socksPass, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartWithTransport launches the client with an explicit transport for this start.
|
// StartWithTransport launches the client with an explicit transport for this start.
|
||||||
func StartWithTransport(
|
func StartWithTransport(
|
||||||
carrierName, transportName, roomID, keyHex string,
|
carrierName, transportName, roomID, clientID, keyHex string,
|
||||||
socksPort int,
|
socksPort int,
|
||||||
socksUser, socksPass string,
|
socksUser, socksPass string,
|
||||||
) error {
|
) error {
|
||||||
@@ -164,11 +166,11 @@ func StartWithTransport(
|
|||||||
cfg.transport = transportName
|
cfg.transport = transportName
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
||||||
return startWithConfig(carrierName, transportName, roomID, keyHex, socksPort, socksUser, socksPass, cfg)
|
return startWithConfig(carrierName, transportName, roomID, clientID, keyHex, socksPort, socksUser, socksPass, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startWithConfig(
|
func startWithConfig(
|
||||||
carrierName, transportName, roomID, keyHex string,
|
carrierName, transportName, roomID, clientID, keyHex string,
|
||||||
socksPort int,
|
socksPort int,
|
||||||
socksUser, socksPass string,
|
socksUser, socksPass string,
|
||||||
cfg mobileConfig,
|
cfg mobileConfig,
|
||||||
@@ -189,6 +191,8 @@ func startWithConfig(
|
|||||||
return errCarrierRequired
|
return errCarrierRequired
|
||||||
case roomID == "" && carrierName != "jazz":
|
case roomID == "" && carrierName != "jazz":
|
||||||
return errRoomIDRequired
|
return errRoomIDRequired
|
||||||
|
case clientID == "":
|
||||||
|
return errClientIDRequired
|
||||||
case keyHex == "":
|
case keyHex == "":
|
||||||
return errKeyHexRequired
|
return errKeyHexRequired
|
||||||
}
|
}
|
||||||
@@ -213,6 +217,7 @@ func startWithConfig(
|
|||||||
carrierName,
|
carrierName,
|
||||||
roomURL,
|
roomURL,
|
||||||
keyHex,
|
keyHex,
|
||||||
|
clientID,
|
||||||
fmt.Sprintf("127.0.0.1:%d", socksPort),
|
fmt.Sprintf("127.0.0.1:%d", socksPort),
|
||||||
cfg.dnsServer,
|
cfg.dnsServer,
|
||||||
socksUser,
|
socksUser,
|
||||||
|
|||||||
Reference in New Issue
Block a user