Initial commit: Null DRM Official
Capture, decrypt, and restream toolkit with compiled-in app modules (RTE, TG4, BBC), on-device MITM proxy, streamd control plane, and www. BBC module.yaml is published (clear streams); other module values stay local.
This commit is contained in:
commit
2fa8f2435f
121 changed files with 17802 additions and 0 deletions
77
apps/proxy/device/utls_dial.go
Normal file
77
apps/proxy/device/utls_dial.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
utls "github.com/refraction-networking/utls"
|
||||
)
|
||||
|
||||
// dialTLSChrome dials addr with a Chrome-like ClientHello so CDNs (Fastly)
|
||||
// are less likely to HTTP 403 Go's default TLS fingerprint.
|
||||
// Handshakes as HTTP/1.1 only so net/http can use the returned conn.
|
||||
func dialTLSChrome(ctx context.Context, dialCtx func(context.Context, string, string) (net.Conn, error), network, addr string) (net.Conn, error) {
|
||||
host := serverNameFromAddr(addr)
|
||||
raw, err := dialCtx(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg := &utls.Config{
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: true,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
spec, err := utls.UTLSIdToSpec(utls.HelloChrome_120)
|
||||
if err != nil {
|
||||
_ = raw.Close()
|
||||
return dialTLSStd(ctx, dialCtx, network, addr)
|
||||
}
|
||||
for i := range spec.Extensions {
|
||||
if alpn, ok := spec.Extensions[i].(*utls.ALPNExtension); ok {
|
||||
alpn.AlpnProtocols = []string{"http/1.1"}
|
||||
}
|
||||
}
|
||||
uConn := utls.UClient(raw, cfg, utls.HelloCustom)
|
||||
if err := uConn.ApplyPreset(&spec); err != nil {
|
||||
_ = raw.Close()
|
||||
return nil, fmt.Errorf("utls preset %s: %w", host, err)
|
||||
}
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
deadline = time.Now().Add(15 * time.Second)
|
||||
}
|
||||
_ = raw.SetDeadline(deadline)
|
||||
if err := uConn.Handshake(); err != nil {
|
||||
_ = raw.Close()
|
||||
return nil, fmt.Errorf("utls handshake %s: %w", host, err)
|
||||
}
|
||||
_ = raw.SetDeadline(time.Time{})
|
||||
return uConn, nil
|
||||
}
|
||||
|
||||
func dialTLSStd(ctx context.Context, dialCtx func(context.Context, string, string) (net.Conn, error), network, addr string) (net.Conn, error) {
|
||||
host := serverNameFromAddr(addr)
|
||||
raw, err := dialCtx(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg := &tls.Config{ServerName: host, InsecureSkipVerify: true, NextProtos: []string{"http/1.1"}}
|
||||
c := tls.Client(raw, cfg)
|
||||
if err := c.HandshakeContext(ctx); err != nil {
|
||||
_ = raw.Close()
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func serverNameFromAddr(addr string) string {
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return strings.TrimSpace(addr)
|
||||
}
|
||||
return host
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue