mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-05-26 23:19:47 +00:00
feat(socks): add socks5 user and password
This commit is contained in:
@@ -40,6 +40,8 @@ type config struct {
|
||||
clientID string
|
||||
socksPort int
|
||||
socksHost string
|
||||
socksUser string
|
||||
socksPass string
|
||||
keyHex string
|
||||
debug bool
|
||||
dataDir string
|
||||
@@ -172,6 +174,8 @@ func parseFlagsFrom(args []string, errorHandling flag.ErrorHandling) (config, er
|
||||
fs.StringVar(&cfg.clientID, "client-id", "", "Client ID: binds one srv to one cnc (required)")
|
||||
fs.IntVar(&cfg.socksPort, "socks-port", 0, "SOCKS5 port (client only)")
|
||||
fs.StringVar(&cfg.socksHost, "socks-host", "", "SOCKS5 listen host (client only)")
|
||||
fs.StringVar(&cfg.socksUser, "socks-user", "", "SOCKS5 username for incoming connections (client only, optional)")
|
||||
fs.StringVar(&cfg.socksPass, "socks-pass", "", "SOCKS5 password for incoming connections (client only, optional)")
|
||||
fs.StringVar(&cfg.keyHex, "key", "", "Shared encryption key (hex)")
|
||||
fs.BoolVar(&cfg.debug, "debug", false, "Enable verbose logging")
|
||||
fs.StringVar(&cfg.dataDir, "data", "", "Path to data directory")
|
||||
@@ -250,6 +254,8 @@ func toSessionConfig(cfg config) session.Config {
|
||||
KeyHex: cfg.keyHex,
|
||||
SOCKSHost: cfg.socksHost,
|
||||
SOCKSPort: cfg.socksPort,
|
||||
SOCKSUser: cfg.socksUser,
|
||||
SOCKSPass: cfg.socksPass,
|
||||
DNSServer: cfg.dnsServer,
|
||||
SOCKSProxyAddr: cfg.socksProxyAddr,
|
||||
SOCKSProxyPort: cfg.socksProxyPort,
|
||||
|
||||
@@ -118,6 +118,8 @@ type Config struct {
|
||||
KeyHex string
|
||||
SOCKSHost string
|
||||
SOCKSPort int
|
||||
SOCKSUser string
|
||||
SOCKSPass string
|
||||
DNSServer string
|
||||
SOCKSProxyAddr string
|
||||
SOCKSProxyPort int
|
||||
@@ -357,8 +359,8 @@ func Run(ctx context.Context, cfg Config) error {
|
||||
cfg.ClientID,
|
||||
fmt.Sprintf("%s:%d", cfg.SOCKSHost, cfg.SOCKSPort),
|
||||
cfg.DNSServer,
|
||||
"",
|
||||
"",
|
||||
cfg.SOCKSUser,
|
||||
cfg.SOCKSPass,
|
||||
cfg.VideoWidth,
|
||||
cfg.VideoHeight,
|
||||
cfg.VideoFPS,
|
||||
|
||||
@@ -36,6 +36,8 @@ var (
|
||||
ErrUnsupportedAddressType = errors.New("unsupported address type")
|
||||
// ErrRemoteNotReady is returned when the server-side stream fails to signal readiness.
|
||||
ErrRemoteNotReady = errors.New("remote not ready")
|
||||
// ErrSOCKSAuthFailed is returned when username/password authentication is rejected.
|
||||
ErrSOCKSAuthFailed = errors.New("SOCKS5 authentication failed")
|
||||
)
|
||||
|
||||
// Client handles local SOCKS5 connections and tunnels them to the server.
|
||||
@@ -47,6 +49,8 @@ type Client struct {
|
||||
sessMu sync.RWMutex
|
||||
clientID string
|
||||
dnsServer string
|
||||
socksUser string
|
||||
socksPass string
|
||||
}
|
||||
|
||||
// Run starts the client with the specified parameters.
|
||||
@@ -100,8 +104,8 @@ func RunWithReady(
|
||||
clientID string,
|
||||
localAddr string,
|
||||
dnsServer,
|
||||
_ string,
|
||||
_ string,
|
||||
socksUser string,
|
||||
socksPass string,
|
||||
onReady func(),
|
||||
videoWidth int,
|
||||
videoHeight int,
|
||||
@@ -128,7 +132,7 @@ func RunWithReady(
|
||||
return fmt.Errorf("setupCipher failed: %w", err)
|
||||
}
|
||||
|
||||
c := &Client{cipher: cipher, clientID: clientID, dnsServer: dnsServer}
|
||||
c := &Client{cipher: cipher, clientID: clientID, dnsServer: dnsServer, socksUser: socksUser, socksPass: socksPass}
|
||||
|
||||
if err := c.bringUpLink(
|
||||
runCtx, linkName, transportName, carrierName, roomURL, cancel,
|
||||
@@ -411,12 +415,45 @@ func (c *Client) socks5Handshake(conn net.Conn) error {
|
||||
if _, err := io.ReadFull(conn, methods); err != nil {
|
||||
return fmt.Errorf("read socks5 methods: %w", err)
|
||||
}
|
||||
|
||||
if c.socksUser != "" {
|
||||
// RFC 1929: method 0x02 = username/password auth.
|
||||
if _, err := conn.Write([]byte{5, 2}); err != nil {
|
||||
return fmt.Errorf("write socks5 auth method: %w", err)
|
||||
}
|
||||
if err := c.socks5UserPassAuth(conn); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := conn.Write([]byte{5, 0}); err != nil {
|
||||
return fmt.Errorf("write socks5 auth: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) socks5UserPassAuth(conn net.Conn) error {
|
||||
user := []byte(c.socksUser)
|
||||
pass := []byte(c.socksPass)
|
||||
req := make([]byte, 0, 3+len(user)+len(pass))
|
||||
req = append(req, 0x01, byte(len(user)))
|
||||
req = append(req, user...)
|
||||
req = append(req, byte(len(pass)))
|
||||
req = append(req, pass...)
|
||||
if _, err := conn.Write(req); err != nil {
|
||||
return fmt.Errorf("write socks5 user/pass: %w", err)
|
||||
}
|
||||
resp := make([]byte, 2)
|
||||
if _, err := io.ReadFull(conn, resp); err != nil {
|
||||
return fmt.Errorf("read socks5 auth response: %w", err)
|
||||
}
|
||||
if resp[1] != 0x00 {
|
||||
return ErrSOCKSAuthFailed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) socks5Request(conn net.Conn) (string, int, error) {
|
||||
header := make([]byte, 4)
|
||||
if _, err := io.ReadFull(conn, header); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user