feat: add clientid key

This commit is contained in:
zarazaex69
2026-05-06 18:23:39 +03:00
parent d1454d2fa6
commit 8be56493f0
5 changed files with 48 additions and 16 deletions

View File

@@ -28,6 +28,7 @@ type config struct {
transport string
carrier string
roomID string
clientID string
provider string
socksPort int
socksHost string
@@ -110,6 +111,7 @@ func parseFlags() config {
flag.StringVar(&cfg.transport, "transport", "", "Transport: datachannel, videochannel, seichannel")
flag.StringVar(&cfg.carrier, "carrier", "", "Carrier: telemost, jazz, wbstream")
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.IntVar(&cfg.socksPort, "socks-port", 0, "SOCKS5 port (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,
Carrier: firstNonEmpty(cfg.carrier, cfg.provider),
RoomID: cfg.roomID,
ClientID: cfg.clientID,
KeyHex: cfg.keyHex,
SOCKSHost: cfg.socksHost,
SOCKSPort: cfg.socksPort,

View File

@@ -77,6 +77,8 @@ var (
ErrSOCKSHostRequired = errors.New("socks host required for cnc mode (use -socks-host)")
// ErrSOCKSPortRequired indicates that socks port is required for cnc mode.
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.
@@ -86,6 +88,7 @@ type Config struct {
Transport string
Carrier string
RoomID string
ClientID string
KeyHex string
SOCKSHost string
SOCKSPort int
@@ -186,6 +189,9 @@ func validateCommon(cfg Config) error {
if cfg.RoomID == "" && cfg.Carrier != "jazz" {
return ErrRoomIDRequired
}
if cfg.ClientID == "" {
return ErrClientIDRequired
}
if cfg.KeyHex == "" {
return ErrKeyRequired
}
@@ -271,6 +277,7 @@ func Run(ctx context.Context, cfg Config) error {
cfg.Carrier,
roomURL,
cfg.KeyHex,
cfg.ClientID,
cfg.DNSServer,
cfg.SOCKSProxyAddr,
cfg.SOCKSProxyPort,
@@ -298,6 +305,7 @@ func Run(ctx context.Context, cfg Config) error {
cfg.Carrier,
roomURL,
cfg.KeyHex,
cfg.ClientID,
fmt.Sprintf("%s:%d", cfg.SOCKSHost, cfg.SOCKSPort),
cfg.DNSServer,
"",

View File

@@ -45,6 +45,7 @@ type Client struct {
conn *muxconn.Conn
session *smux.Session
sessMu sync.RWMutex
clientID string
dnsServer string
}
@@ -55,7 +56,8 @@ func Run(
transportName,
carrierName,
roomURL,
keyHex string,
keyHex,
clientID string,
localAddr string,
dnsServer,
socksUser string,
@@ -74,7 +76,7 @@ func Run(
vp8BatchSize int,
) error {
return RunWithReady(
ctx, linkName, transportName, carrierName, roomURL, keyHex, localAddr,
ctx, linkName, transportName, carrierName, roomURL, keyHex, clientID, localAddr,
dnsServer, socksUser, socksPass, nil,
videoWidth, videoHeight, videoFPS, videoBitrate, videoHW,
videoQRSize, videoQRRecovery, videoCodec, videoTileModule, videoTileRS,
@@ -89,7 +91,8 @@ func RunWithReady(
transportName,
carrierName,
roomURL,
keyHex string,
keyHex,
clientID string,
localAddr string,
dnsServer,
_ string,
@@ -116,7 +119,7 @@ func RunWithReady(
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(
runCtx, linkName, transportName, carrierName, roomURL, cancel,
@@ -356,6 +359,7 @@ 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 {
connectReq, err := json.Marshal(map[string]any{
"cmd": "connect",
"client_id": c.clientID,
"addr": targetAddr,
"port": targetPort,
})

View File

@@ -41,6 +41,7 @@ type Server struct {
sessMu sync.RWMutex
reinstallMu sync.Mutex
wg sync.WaitGroup
clientID string
dnsServer string
resolver *net.Resolver
socksProxyAddr string
@@ -50,6 +51,7 @@ type Server struct {
// ConnectRequest is a message from the client to establish a new connection.
type ConnectRequest struct {
Cmd string `json:"cmd"`
ClientID string `json:"client_id"`
Addr string `json:"addr"`
Port int `json:"port"`
}
@@ -61,7 +63,8 @@ func Run(
transportName,
carrierName,
roomURL,
keyHex string,
keyHex,
clientID string,
dnsServer,
socksProxyAddr string,
socksProxyPort int,
@@ -88,6 +91,7 @@ func Run(
s := &Server{
cipher: cipher,
clientID: clientID,
dnsServer: dnsServer,
socksProxyAddr: socksProxyAddr,
socksProxyPort: socksProxyPort,
@@ -339,6 +343,10 @@ func (s *Server) handleStream(_ context.Context, stream *smux.Stream) {
header = append(header, tmp[:n]...)
if req, ok := parseConnectRequest(header); ok {
_ = stream.SetReadDeadline(time.Time{})
if !s.authorizeRequest(req) {
logger.Warnf("sid=%d rejected: client_id mismatch", stream.ID())
return
}
s.dispatch(stream, req)
return
}
@@ -363,6 +371,10 @@ func parseConnectRequest(buf []byte) (ConnectRequest, bool) {
return req, true
}
func (s *Server) authorizeRequest(req ConnectRequest) bool {
return req.ClientID == s.clientID
}
func (s *Server) dispatch(stream *smux.Stream, req ConnectRequest) {
addr := net.JoinHostPort(req.Addr, strconv.Itoa(req.Port))
logger.Infof("sid=%d connect %s", stream.ID(), addr)

View File

@@ -34,6 +34,7 @@ var (
errAlreadyRunning = errors.New("olcRTC already running")
errCarrierRequired = errors.New("carrier is required")
errRoomIDRequired = errors.New("roomID is required")
errClientIDRequired = errors.New("clientID is required")
errKeyHexRequired = errors.New("keyHex is required")
errNotRunning = errors.New("olcRTC is not running")
errStoppedBeforeReady = errors.New("olcRTC stopped before becoming ready")
@@ -140,21 +141,22 @@ func SetDebug(enabled bool) {
// Start launches the olcRTC client in background.
// carrierName: carrier/provider name ("telemost", "jazz", "wbstream", "wbstream")
// roomID: carrier-specific room ID
// clientID: client identifier that must match the server's -client-id
// keyHex: 64-char hex encryption key
// socksPort: local SOCKS5 proxy port (e.g. 10808)
// 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()
ensureDefaultConfigLocked()
cfg := defaults
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.
func StartWithTransport(
carrierName, transportName, roomID, keyHex string,
carrierName, transportName, roomID, clientID, keyHex string,
socksPort int,
socksUser, socksPass string,
) error {
@@ -164,11 +166,11 @@ func StartWithTransport(
cfg.transport = transportName
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(
carrierName, transportName, roomID, keyHex string,
carrierName, transportName, roomID, clientID, keyHex string,
socksPort int,
socksUser, socksPass string,
cfg mobileConfig,
@@ -189,6 +191,8 @@ func startWithConfig(
return errCarrierRequired
case roomID == "" && carrierName != "jazz":
return errRoomIDRequired
case clientID == "":
return errClientIDRequired
case keyHex == "":
return errKeyHexRequired
}
@@ -213,6 +217,7 @@ func startWithConfig(
carrierName,
roomURL,
keyHex,
clientID,
fmt.Sprintf("127.0.0.1:%d", socksPort),
cfg.dnsServer,
socksUser,