diff --git a/client/main.go b/client/main.go index 998e00c..5e8a3d2 100644 --- a/client/main.go +++ b/client/main.go @@ -8,7 +8,6 @@ import ( "context" "crypto/md5" "crypto/sha256" - "crypto/tls" "encoding/base64" "encoding/hex" "encoding/json" @@ -486,7 +485,7 @@ func callCaptchaNotRobot(ctx context.Context, sessionToken, hash string, streamI log.Printf("[STREAM %d] [Captcha] Step 2/4: componentDone", streamID) browserFp := generateBrowserFp(profile) - deviceJSON := fmt.Sprintf(`{"screenWidth":1920,"screenHeight":1080,"screenAvailWidth":1920,"screenAvailHeight":1040,"innerWidth":1920,"innerHeight":969,"devicePixelRatio":1,"language":"en-US","languages":["en-US"],"webdriver":false,"hardwareConcurrency":8,"deviceMemory":8,"connectionEffectiveType":"4g","notificationsPermission":"default","userAgent":"%s","platform":"Win32"}`, profile.UserAgent) + deviceJSON := buildCaptchaDeviceJSON(profile) componentDoneData := baseParams + fmt.Sprintf("&browser_fp=%s&device=%s", browserFp, neturl.QueryEscape(deviceJSON)) if _, err := vkReq("captchaNotRobot.componentDone", componentDoneData); err != nil { @@ -1314,13 +1313,6 @@ func dtlsFunc(ctx context.Context, conn net.PacketConn, peer *net.UDPAddr) (net. if err != nil { return nil, err } - config := &dtls.Config{ - Certificates: []tls.Certificate{certificate}, - InsecureSkipVerify: true, - ExtendedMasterSecret: dtls.RequireExtendedMasterSecret, - CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - ConnectionIDGenerator: dtls.OnlySendCIDGenerator(), - } select { case handshakeSem <- struct{}{}: @@ -1331,7 +1323,15 @@ func dtlsFunc(ctx context.Context, conn net.PacketConn, peer *net.UDPAddr) (net. ctx1, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - dtlsConn, err := dtls.Client(conn, peer, config) + dtlsConn, err := dtls.ClientWithOptions( + conn, + peer, + dtls.WithCertificates(certificate), + dtls.WithInsecureSkipVerify(true), + dtls.WithExtendedMasterSecret(dtls.RequireExtendedMasterSecret), + dtls.WithCipherSuites(dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), + dtls.WithConnectionIDGenerator(dtls.OnlySendCIDGenerator()), + ) if err != nil { return nil, err } @@ -1716,7 +1716,6 @@ func main() { direct := flag.Bool("no-dtls", false, "connect without obfuscation. DO NOT USE") debugFlag := flag.Bool("debug", false, "enable debug logging") manualCaptchaFlag := flag.Bool("manual-captcha", false, "skip auto captcha solving, use manual mode immediately") - autoCaptchaSliderPOCFlag := flag.Bool("auto-captcha-slider-poc", false, "compatibility flag: slider POC fallback is now enabled by default before manual fallback") flag.Parse() if *peerAddr == "" { log.Panicf("Need peer address!") @@ -1732,11 +1731,6 @@ func main() { isDebug = *debugFlag manualCaptcha = *manualCaptchaFlag autoCaptchaSliderPOC = !manualCaptcha - if *autoCaptchaSliderPOCFlag && manualCaptcha { - log.Printf("[Captcha] manual-captcha enabled, ignoring -auto-captcha-slider-poc") - } else if *autoCaptchaSliderPOCFlag { - log.Printf("[Captcha] -auto-captcha-slider-poc is now enabled by default") - } var link string var getCreds getCredsFunc diff --git a/client/manual_captcha.go b/client/manual_captcha.go index 50369e2..7455573 100644 --- a/client/manual_captcha.go +++ b/client/manual_captcha.go @@ -74,6 +74,32 @@ func targetOrigin(targetURL *neturl.URL) string { return targetURL.Scheme + "://" + targetURL.Host } +func isSafeLocalRedirectPath(raw string) bool { + if raw == "" || raw[0] != '/' { + return false + } + if len(raw) > 1 && (raw[1] == '/' || raw[1] == '\\') { + return false + } + return true +} + +func rewriteProxyRedirectLocation(raw string, targetURL *neturl.URL) (string, bool) { + if isSafeLocalRedirectPath(raw) { + return raw, true + } + + parsed, err := neturl.Parse(raw) + if err != nil { + return "", false + } + if !strings.EqualFold(parsed.Scheme, targetURL.Scheme) || !strings.EqualFold(parsed.Host, targetURL.Host) { + return "", false + } + + return localCaptchaURLForTarget(parsed), true +} + func rewriteProxyHeaderURL(raw string, targetURL *neturl.URL) string { if raw == "" { return raw @@ -442,10 +468,10 @@ func solveCaptchaViaProxy(redirectURI string, dialer *dnsdialer.Dialer) (string, if res.StatusCode >= 300 && res.StatusCode < 400 { if loc := res.Header.Get("Location"); loc != "" { - if strings.HasPrefix(loc, "/") { - res.Header.Set("Location", loc) - } else if strings.HasPrefix(loc, targetOrigin(targetURL)) { - res.Header.Set("Location", strings.Replace(loc, targetOrigin(targetURL), localCaptchaOrigin(), 1)) + if rewritten, ok := rewriteProxyRedirectLocation(loc, targetURL); ok { + res.Header.Set("Location", rewritten) + } else { + res.Header.Del("Location") } } } diff --git a/client/manual_captcha_test.go b/client/manual_captcha_test.go new file mode 100644 index 0000000..8afbafd --- /dev/null +++ b/client/manual_captcha_test.go @@ -0,0 +1,65 @@ +package main + +import ( + "net/url" + "testing" +) + +func TestRewriteProxyRedirectLocation(t *testing.T) { + t.Parallel() + + targetURL, err := url.Parse("https://id.vk.ru/captcha") + if err != nil { + t.Fatalf("failed to parse target URL: %v", err) + } + + testCases := []struct { + name string + location string + want string + ok bool + }{ + { + name: "keeps safe relative path", + location: "/captcha?step=2", + want: "/captcha?step=2", + ok: true, + }, + { + name: "rewrites same-origin absolute URL", + location: "https://id.vk.ru/captcha?step=2", + want: "http://localhost:8765/captcha?step=2", + ok: true, + }, + { + name: "blocks scheme-relative redirect", + location: "//evil.example/captcha", + ok: false, + }, + { + name: "blocks slash-backslash redirect", + location: `/\evil.example/captcha`, + ok: false, + }, + { + name: "blocks lookalike absolute host", + location: "https://id.vk.ru.evil.example/captcha", + ok: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + got, ok := rewriteProxyRedirectLocation(tc.location, targetURL) + if ok != tc.ok { + t.Fatalf("rewriteProxyRedirectLocation() ok = %v, want %v", ok, tc.ok) + } + if got != tc.want { + t.Fatalf("rewriteProxyRedirectLocation() = %q, want %q", got, tc.want) + } + }) + } +} diff --git a/client/slider_captcha.go b/client/slider_captcha.go index 9b1038a..166a6ab 100644 --- a/client/slider_captcha.go +++ b/client/slider_captcha.go @@ -47,15 +47,13 @@ type captchaCheckResult struct { Status string SuccessToken string ShowCaptchaType string - Redirect string } type sliderCaptchaContent struct { - Extension string - Image image.Image - Size int - Steps []int - Attempts int + Image image.Image + Size int + Steps []int + Attempts int } type sliderCandidate struct { @@ -100,26 +98,12 @@ func (s *captchaNotRobotSession) baseValues() neturl.Values { func (s *captchaNotRobotSession) request(method string, values neturl.Values) (map[string]interface{}, error) { reqURL := "https://api.vk.ru/method/" + method + "?v=5.131" - parsedURL, _ := neturl.Parse(reqURL) - domain := parsedURL.Hostname() req, err := fhttp.NewRequestWithContext(s.ctx, "POST", reqURL, strings.NewReader(values.Encode())) if err != nil { return nil, err } - req.Host = domain - applyBrowserProfileFhttp(req, s.profile) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.Header.Set("Accept", "*/*") - req.Header.Set("Origin", "https://id.vk.ru") - req.Header.Set("Referer", "https://id.vk.ru/") - req.Header.Set("Sec-Fetch-Site", "same-site") - req.Header.Set("Sec-Fetch-Mode", "cors") - req.Header.Set("Sec-Fetch-Dest", "empty") - req.Header.Set("Sec-GPC", "1") - req.Header.Set("Priority", "u=1, i") - httpResp, err := s.client.Do(req) if err != nil { return nil, err @@ -169,24 +153,7 @@ func (s *captchaNotRobotSession) requestComponentDone() error { } func (s *captchaNotRobotSession) requestCheckboxCheck() (*captchaCheckResult, error) { - values := s.baseValues() - values.Set("accelerometer", "[]") - values.Set("gyroscope", "[]") - values.Set("motion", "[]") - values.Set("cursor", "[]") - values.Set("taps", "[]") - values.Set("connectionRtt", "[]") - values.Set("connectionDownlink", "[]") - values.Set("browser_fp", s.browserFp) - values.Set("hash", s.hash) - values.Set("answer", base64.StdEncoding.EncodeToString([]byte("{}"))) - values.Set("debug_info", captchaDebugInfo) - - resp, err := s.request("captchaNotRobot.check", values) - if err != nil { - return nil, fmt.Errorf("check failed: %w", err) - } - return parseCaptchaCheckResult(resp) + return s.requestCheck("[]", base64.StdEncoding.EncodeToString([]byte("{}"))) } func (s *captchaNotRobotSession) requestSliderContent(sliderSettings string) (*sliderCaptchaContent, error) { @@ -208,11 +175,15 @@ func (s *captchaNotRobotSession) requestSliderCheck(activeSteps []int, candidate return nil, err } + return s.requestCheck(generateSliderCursor(candidateIndex, candidateCount), answer) +} + +func (s *captchaNotRobotSession) requestCheck(cursor string, answer string) (*captchaCheckResult, error) { values := s.baseValues() values.Set("accelerometer", "[]") values.Set("gyroscope", "[]") values.Set("motion", "[]") - values.Set("cursor", generateSliderCursor(candidateIndex, candidateCount)) + values.Set("cursor", cursor) values.Set("taps", "[]") values.Set("connectionRtt", "[]") values.Set("connectionDownlink", "[]") @@ -407,7 +378,7 @@ func parseCaptchaBootstrapHTML(html string) (*captchaBootstrap, error) { } func parseCaptchaSettingsFromHTML(html string) (*captchaSettingsResponse, error) { - initRe := regexp.MustCompile(`(?s)window\.init\s*=\s*(\{.*?\})\s*;\s*window\.lang`) + initRe := regexp.MustCompile(`(?s)window\.init\s*=\s*(\{.*?})\s*;\s*window\.lang`) initMatch := initRe.FindStringSubmatch(html) if len(initMatch) < 2 { return &captchaSettingsResponse{SettingsByType: make(map[string]string)}, nil @@ -527,7 +498,6 @@ func parseCaptchaCheckResult(resp map[string]interface{}) (*captchaCheckResult, result.Status, _ = respObj["status"].(string) result.SuccessToken, _ = respObj["success_token"].(string) result.ShowCaptchaType, _ = respObj["show_captcha_type"].(string) - result.Redirect, _ = respObj["redirect"].(string) if result.Status == "" { return nil, fmt.Errorf("check status missing: %v", resp) } @@ -578,11 +548,10 @@ func parseSliderCaptchaContentResponse(resp map[string]interface{}) (*sliderCapt } return &sliderCaptchaContent{ - Extension: extension, - Image: img, - Size: size, - Steps: swaps, - Attempts: attempts, + Image: img, + Size: size, + Steps: swaps, + Attempts: attempts, }, nil } diff --git a/client/slider_captcha_test.go b/client/slider_captcha_test.go index 3db561a..19c2771 100644 --- a/client/slider_captcha_test.go +++ b/client/slider_captcha_test.go @@ -96,10 +96,10 @@ func TestRenderSliderCandidateMatchesSwapLayout(t *testing.T) { t.Parallel() src := image.NewRGBA(image.Rect(0, 0, 20, 20)) - fillRect(src, image.Rect(0, 0, 10, 10), color.RGBA{255, 0, 0, 255}) - fillRect(src, image.Rect(10, 0, 20, 10), color.RGBA{0, 255, 0, 255}) - fillRect(src, image.Rect(0, 10, 10, 20), color.RGBA{0, 0, 255, 255}) - fillRect(src, image.Rect(10, 10, 20, 20), color.RGBA{255, 255, 0, 255}) + fillRect(src, image.Rect(0, 0, 10, 10), color.RGBA{R: 255, A: 255}) + fillRect(src, image.Rect(10, 0, 20, 10), color.RGBA{G: 255, A: 255}) + fillRect(src, image.Rect(0, 10, 10, 20), color.RGBA{B: 255, A: 255}) + fillRect(src, image.Rect(10, 10, 20, 20), color.RGBA{R: 255, G: 255, A: 255}) mapping, err := buildSliderTileMapping(2, []int{0, 1}) if err != nil { @@ -111,10 +111,10 @@ func TestRenderSliderCandidateMatchesSwapLayout(t *testing.T) { t.Fatalf("renderSliderCandidate returned error: %v", err) } - assertPixelEquals(t, rendered.At(2, 2), color.RGBA{0, 255, 0, 255}) - assertPixelEquals(t, rendered.At(12, 2), color.RGBA{255, 0, 0, 255}) - assertPixelEquals(t, rendered.At(2, 12), color.RGBA{0, 0, 255, 255}) - assertPixelEquals(t, rendered.At(12, 12), color.RGBA{255, 255, 0, 255}) + assertPixelEquals(t, rendered.At(2, 2), color.RGBA{G: 255, A: 255}) + assertPixelEquals(t, rendered.At(12, 2), color.RGBA{R: 255, A: 255}) + assertPixelEquals(t, rendered.At(2, 12), color.RGBA{B: 255, A: 255}) + assertPixelEquals(t, rendered.At(12, 12), color.RGBA{R: 255, G: 255, A: 255}) } func TestRankSliderCandidatesPrefersMostCoherentImage(t *testing.T) { @@ -228,7 +228,7 @@ func TestParseSliderCaptchaContentResponse(t *testing.T) { t.Parallel() src := image.NewRGBA(image.Rect(0, 0, 20, 20)) - fillRect(src, src.Bounds(), color.RGBA{12, 34, 56, 255}) + fillRect(src, src.Bounds(), color.RGBA{R: 12, G: 34, B: 56, A: 255}) var buf bytes.Buffer if err := jpeg.Encode(&buf, src, nil); err != nil { diff --git a/go.mod b/go.mod index 34d031c..b89aa57 100644 --- a/go.mod +++ b/go.mod @@ -9,32 +9,32 @@ require ( github.com/cbeuw/connutil v1.0.1 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 - github.com/pion/dtls/v3 v3.0.11 + github.com/pion/dtls/v3 v3.1.2 github.com/pion/logging v0.2.4 github.com/pion/transport/v4 v4.0.1 - github.com/pion/turn/v5 v5.0.2 + github.com/pion/turn/v5 v5.0.3 ) require ( - github.com/andybalholm/brotli v1.2.0 // indirect + github.com/andybalholm/brotli v1.2.1 // indirect github.com/bdandy/go-errors v1.2.2 // indirect github.com/bdandy/go-socks4 v1.2.3 // indirect github.com/bogdanfinn/quic-go-utls v1.0.9-utls // indirect github.com/bogdanfinn/utls v1.7.7-barnius // indirect github.com/bogdanfinn/websocket v1.5.5-barnius // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/klauspost/compress v1.18.2 // indirect - github.com/miekg/dns v1.1.69 // indirect + github.com/klauspost/compress v1.18.5 // indirect + github.com/miekg/dns v1.1.72 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/stun/v3 v3.1.1 // indirect + github.com/pion/stun/v3 v3.1.2 // indirect github.com/quic-go/qpack v0.6.0 // indirect github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect github.com/wlynxg/anet v0.0.5 // indirect - golang.org/x/crypto v0.47.0 // indirect - golang.org/x/mod v0.31.0 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/tools v0.40.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/tools v0.43.0 // indirect ) diff --git a/go.sum b/go.sum index 3303358..e65871c 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= -github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/andybalholm/brotli v1.2.1 h1:R+f5xP285VArJDRgowrfb9DqL18yVK0gKAW/F+eTWro= +github.com/andybalholm/brotli v1.2.1/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/bdandy/go-errors v1.2.2 h1:WdFv/oukjTJCLa79UfkGmwX7ZxONAihKu4V0mLIs11Q= github.com/bdandy/go-errors v1.2.2/go.mod h1:NkYHl4Fey9oRRdbB1CoC6e84tuqQHiqrOcZpqFEkBxM= github.com/bdandy/go-socks4 v1.2.3 h1:Q6Y2heY1GRjCtHbmlKfnwrKVU/k81LS8mRGLRlmDlic= @@ -28,22 +28,22 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= -github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= -github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc= -github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g= -github.com/pion/dtls/v3 v3.0.11 h1:zqn8YhoAU7d9whsWLhNiQlbB8QdpJj8XQVSc5ImUons= -github.com/pion/dtls/v3 v3.0.11/go.mod h1:YEmmBYIoBsY3jmG56dsziTv/Lca9y4Om83370CXfqJ8= +github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= +github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= +github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= +github.com/pion/dtls/v3 v3.1.2 h1:gqEdOUXLtCGW+afsBLO0LtDD8GnuBBjEy6HRtyofZTc= +github.com/pion/dtls/v3 v3.1.2/go.mod h1:Hw/igcX4pdY69z1Hgv5x7wJFrUkdgHwAn/Q/uo7YHRo= github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8= github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/stun/v3 v3.1.1 h1:CkQxveJ4xGQjulGSROXbXq94TAWu8gIX2dT+ePhUkqw= -github.com/pion/stun/v3 v3.1.1/go.mod h1:qC1DfmcCTQjl9PBaMa5wSn3x9IPmKxSdcCsxBcDBndM= +github.com/pion/stun/v3 v3.1.2 h1:86IhD8wFn6IDW4b1/0QzoQS+f5PeA8OHHRn8UZW5ErY= +github.com/pion/stun/v3 v3.1.2/go.mod h1:H7gDic7nNwlUL05pbs6T1dtaBehh/KjupxfWw3ZI7cA= github.com/pion/transport/v4 v4.0.1 h1:sdROELU6BZ63Ab7FrOLn13M6YdJLY20wldXW2Cu2k8o= github.com/pion/transport/v4 v4.0.1/go.mod h1:nEuEA4AD5lPdcIegQDpVLgNoDGreqM/YqmEx3ovP4jM= -github.com/pion/turn/v5 v5.0.2 h1:GHlDk+fiegz+yibb3ch+tK+iPFokoVWiM+aVJakySqA= -github.com/pion/turn/v5 v5.0.2/go.mod h1:cumcsSEF2ytAtDhDwkYgYhv1uJ3AOP7a4pFt0NL/snY= +github.com/pion/turn/v5 v5.0.3 h1:I+Nw0fQgdPWF1SXDj0egWDhCkcff7gWiigdQpOK52Ak= +github.com/pion/turn/v5 v5.0.3/go.mod h1:fs4SogUh/aRGQzonc4Lx3Jp4EU3j3t0PfNDEd9KcD/w= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= @@ -58,28 +58,28 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= -golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20211104170005-ce137452f963/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= -golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= diff --git a/server/main.go b/server/main.go index effce98..751e163 100644 --- a/server/main.go +++ b/server/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "crypto/tls" "flag" "fmt" "log" @@ -53,16 +52,15 @@ func main() { // Everything below is the pion-DTLS API! Thanks for using it ❤️. // - // Prepare the configuration of the DTLS connection - config := &dtls.Config{ - Certificates: []tls.Certificate{certificate}, - ExtendedMasterSecret: dtls.RequireExtendedMasterSecret, - CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - ConnectionIDGenerator: dtls.RandomCIDGenerator(8), - } - // Connect to a DTLS server - listener, err := dtls.Listen("udp", addr, config) + listener, err := dtls.ListenWithOptions( + "udp", + addr, + dtls.WithCertificates(certificate), + dtls.WithExtendedMasterSecret(dtls.RequireExtendedMasterSecret), + dtls.WithCipherSuites(dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), + dtls.WithConnectionIDGenerator(dtls.RandomCIDGenerator(8)), + ) if err != nil { panic(err) }