Skip to content

Commit

Permalink
improve making account
Browse files Browse the repository at this point in the history
  • Loading branch information
uoosef committed Jan 24, 2024
1 parent de0b962 commit f596465
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 22 deletions.
11 changes: 8 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ require (
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/bepass-org/proxy v0.0.0-20240103080554-a7e12466f91f
github.com/go-ini/ini v1.67.0
golang.org/x/crypto v0.13.0
golang.org/x/net v0.15.0
golang.org/x/sys v0.12.0
github.com/refraction-networking/utls v1.6.1
golang.org/x/crypto v0.17.0
golang.org/x/net v0.17.0
golang.org/x/sys v0.15.0
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259
)

require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/quic-go/quic-go v0.37.4 // indirect
github.com/stretchr/testify v1.8.4 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
)
38 changes: 32 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/bepass-org/proxy v0.0.0-20240103080554-a7e12466f91f h1:pzRqHgMut0aqeU9q6Qp9mZsc7CFsEL57SQzKZP60u1I=
github.com/bepass-org/proxy v0.0.0-20240103080554-a7e12466f91f/go.mod h1:RlF0oO3D6Ju6VYjtL1I6lVLdc3l8jA4ggleJc8S+P0Y=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
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/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
github.com/refraction-networking/utls v1.6.1 h1:n1JG5karzdGWsI6iZmGrOv3SNzR4c+4M8J6KWGsk3lA=
github.com/refraction-networking/utls v1.6.1/go.mod h1:+EbcQOvQvXoFV9AEKbuGlljt1doLRKAVY1jJHe9EtDo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
37 changes: 24 additions & 13 deletions warp/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package warp

import (
"bytes"
"crypto/tls"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -53,18 +54,24 @@ func makeDefaultHeaders() map[string]string {
}

func makeClient() *http.Client {
return &http.Client{Transport: &http.Transport{
// Match app's TLS config or API will reject us with code 403 error 1020
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
MaxVersion: tls.VersionTLS12},
ForceAttemptHTTP2: false,
// From http.DefaultTransport
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}}
// Create a custom dialer using the TLS config
plainDialer := &net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 5 * time.Second,
}
tlsDialer := Dialer{}
// Create a custom HTTP transport
transport := &http.Transport{
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return tlsDialer.TLSDial(plainDialer, network, addr)
},
}

// Create a custom HTTP client using the transport
return &http.Client{
Transport: transport,
// Other client configurations can be added here
}
}

func MergeMaps(maps ...map[string]string) map[string]string {
Expand Down Expand Up @@ -466,6 +473,10 @@ func getWireguardConfig(privateKey, address1, address2, publicKey, endpoint stri
buffer.WriteString(fmt.Sprintf("PublicKey = %s\n", publicKey))
buffer.WriteString("AllowedIPs = 0.0.0.0/0\n")
buffer.WriteString("AllowedIPs = ::/0\n")
ip, err := randomIPFromRange("162.159.192.0/24")
if err == nil {
endpoint = ip.String() + ":8854"
}
buffer.WriteString(fmt.Sprintf("Endpoint = %s\n", endpoint))

return buffer.String()
Expand Down
233 changes: 233 additions & 0 deletions warp/tls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package warp

import (
"crypto/rand"
"fmt"
tls "github.com/refraction-networking/utls"
"io"
"net"
)

// Dialer is a struct that holds various options for custom dialing.
type Dialer struct {
}

const (
extensionServerName uint16 = 0x0
utlsExtensionSNICurve uint16 = 0x15
)

func hostnameInSNI(name string) string {
return name
}

// SNIExtension implements server_name (0)
type SNIExtension struct {
*tls.GenericExtension
ServerName string // not an array because go crypto/tls doesn't support multiple SNIs
}

// Len returns the length of the SNIExtension.
func (e *SNIExtension) Len() int {
// Literal IP addresses, absolute FQDNs, and empty strings are not permitted as SNI values.
// See RFC 6066, Section 3.
hostName := hostnameInSNI(e.ServerName)
if len(hostName) == 0 {
return 0
}
return 4 + 2 + 1 + 2 + len(hostName)
}

// Read reads the SNIExtension.
func (e *SNIExtension) Read(b []byte) (int, error) {
// Literal IP addresses, absolute FQDNs, and empty strings are not permitted as SNI values.
// See RFC 6066, Section 3.
hostName := hostnameInSNI(e.ServerName)
if len(hostName) == 0 {
return 0, io.EOF
}
if len(b) < e.Len() {
return 0, io.ErrShortBuffer
}
// RFC 3546, section 3.1
b[0] = byte(extensionServerName >> 8)
b[1] = byte(extensionServerName)
b[2] = byte((len(hostName) + 5) >> 8)
b[3] = byte(len(hostName) + 5)
b[4] = byte((len(hostName) + 3) >> 8)
b[5] = byte(len(hostName) + 3)
// b[6] Server Name Type: host_name (0)
b[7] = byte(len(hostName) >> 8)
b[8] = byte(len(hostName))
copy(b[9:], hostName)
return e.Len(), io.EOF
}

// SNICurveExtension implements SNICurve (0x15) extension
type SNICurveExtension struct {
*tls.GenericExtension
SNICurveLen int
WillPad bool // set false to disable extension
}

// Len returns the length of the SNICurveExtension.
func (e *SNICurveExtension) Len() int {
if e.WillPad {
return 4 + e.SNICurveLen
}
return 0
}

// Read reads the SNICurveExtension.
func (e *SNICurveExtension) Read(b []byte) (n int, err error) {
if !e.WillPad {
return 0, io.EOF
}
if len(b) < e.Len() {
return 0, io.ErrShortBuffer
}
// https://tools.ietf.org/html/rfc7627
b[0] = byte(utlsExtensionSNICurve >> 8)
b[1] = byte(utlsExtensionSNICurve)
b[2] = byte(e.SNICurveLen >> 8)
b[3] = byte(e.SNICurveLen)
y := make([]byte, 1200)
copy(b[4:], y)
return e.Len(), io.EOF
}

// makeTLSHelloPacketWithSNICurve creates a TLS hello packet with SNICurve.
func (d *Dialer) makeTLSHelloPacketWithSNICurve(plainConn net.Conn, config *tls.Config, sni string) (*tls.UConn, error) {
SNICurveSize := 1200

utlsConn := tls.UClient(plainConn, config, tls.HelloCustom)
spec := tls.ClientHelloSpec{
TLSVersMax: tls.VersionTLS12,
TLSVersMin: tls.VersionTLS12,
CipherSuites: []uint16{
tls.GREASE_PLACEHOLDER,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_AES_128_GCM_SHA256, // tls 1.3
tls.FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
},
Extensions: []tls.TLSExtension{
&SNICurveExtension{
SNICurveLen: SNICurveSize,
WillPad: true,
},
&tls.SupportedCurvesExtension{Curves: []tls.CurveID{tls.X25519, tls.CurveP256}},
&tls.SupportedPointsExtension{SupportedPoints: []byte{0}}, // uncompressed
&tls.SessionTicketExtension{},
&tls.ALPNExtension{AlpnProtocols: []string{"http/1.1"}},
&tls.SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256,
tls.ECDSAWithP384AndSHA384,
tls.ECDSAWithP521AndSHA512,
tls.PSSWithSHA256,
tls.PSSWithSHA384,
tls.PSSWithSHA512,
tls.PKCS1WithSHA256,
tls.PKCS1WithSHA384,
tls.PKCS1WithSHA512,
tls.ECDSAWithSHA1,
tls.PKCS1WithSHA1}},
&tls.KeyShareExtension{KeyShares: []tls.KeyShare{
{Group: tls.CurveID(tls.GREASE_PLACEHOLDER), Data: []byte{0}},
{Group: tls.X25519},
}},
&tls.PSKKeyExchangeModesExtension{Modes: []uint8{1}}, // pskModeDHE
&SNIExtension{
ServerName: sni,
},
},
GetSessionID: nil,
}
err := utlsConn.ApplyPreset(&spec)

if err != nil {
return nil, fmt.Errorf("uTlsConn.Handshake() error: %+v", err)
}

err = utlsConn.Handshake()

if err != nil {
return nil, fmt.Errorf("uTlsConn.Handshake() error: %+v", err)
}

return utlsConn, nil
}

func randomIPFromRange(cidr string) (net.IP, error) {

GENERATE:

ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}

// The number of leading 1s in the mask
ones, _ := ipnet.Mask.Size()
quotient := ones / 8
remainder := ones % 8

// create random 4-byte byte slice
r := make([]byte, 4)
_, err = rand.Read(r)
if err != nil {
return nil, err
}

for i := 0; i <= quotient; i++ {
if i == quotient {
shifted := byte(r[i]) >> remainder
r[i] = ^ipnet.IP[i] & shifted
} else {
r[i] = ipnet.IP[i]
}
}
ip = net.IPv4(r[0], r[1], r[2], r[3])

if ip.Equal(ipnet.IP) /*|| ip.Equal(broadcast) */ {
// we got unlucky. The host portion of our ipv4 address was
// either all 0s (the network address) or all 1s (the broadcast address)
goto GENERATE
}
return ip, nil
}

// TLSDial dials a TLS connection.
func (d *Dialer) TLSDial(plainDialer *net.Dialer, network, addr string) (net.Conn, error) {
sni, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
ip, err := randomIPFromRange("141.101.113.0/24")
if err != nil {
return nil, err
}
plainConn, err := plainDialer.Dial(network, ip.String()+":443")
if err != nil {
return nil, err
}

config := tls.Config{
ServerName: sni,
InsecureSkipVerify: true,
NextProtos: nil,
MinVersion: tls.VersionTLS10,
}

utlsConn, handshakeErr := d.makeTLSHelloPacketWithSNICurve(plainConn, &config, sni)
if handshakeErr != nil {
_ = plainConn.Close()
fmt.Println(handshakeErr)
return nil, handshakeErr
}
return utlsConn, nil
}

0 comments on commit f596465

Please sign in to comment.