mirror of
https://github.com/Snawoot/hola-proxy.git
synced 2026-04-05 15:08:12 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9e2a2d5df | ||
|
|
98784aada9 | ||
|
|
518098ac2b | ||
|
|
60eee4ad84 | ||
|
|
223105b010 | ||
|
|
b93ba7718c |
14
extver.go
14
extver.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -15,6 +16,10 @@ var (
|
||||
defaultProdVersion = "113.0"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoVerData = errors.New("no version data returned")
|
||||
)
|
||||
|
||||
type StoreExtUpdateResponse struct {
|
||||
XMLName xml.Name `xml:"gupdate"`
|
||||
App *struct {
|
||||
@@ -85,7 +90,7 @@ func GetExtVer(ctx context.Context,
|
||||
}
|
||||
|
||||
reader := io.LimitReader(resp.Body, 64*1024)
|
||||
var respData StoreExtUpdateResponse
|
||||
var respData *StoreExtUpdateResponse
|
||||
|
||||
dec := xml.NewDecoder(reader)
|
||||
err = dec.Decode(&respData)
|
||||
@@ -93,5 +98,10 @@ func GetExtVer(ctx context.Context,
|
||||
return "", fmt.Errorf("unmarshaling of chrome web store response failed: %w", err)
|
||||
}
|
||||
|
||||
return respData.App.UpdateCheck.Version, nil
|
||||
if respData != nil && respData.App != nil &&
|
||||
respData.App.UpdateCheck != nil && respData.App.UpdateCheck.Version != "" {
|
||||
return respData.App.UpdateCheck.Version, nil
|
||||
}
|
||||
|
||||
return "", ErrNoVerData
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ func httpClientWithProxy(agent *FallbackAgent) *http.Client {
|
||||
rootCAs = tlsConfig.RootCAs
|
||||
}
|
||||
if agent != nil {
|
||||
dialer = NewProxyDialer(agent.NetAddr(), agent.Hostname(), rootCAs, nil, dialer)
|
||||
dialer = NewProxyDialer(agent.NetAddr(), agent.Hostname(), rootCAs, nil, true, dialer)
|
||||
}
|
||||
t.DialContext = dialer.DialContext
|
||||
return &http.Client{
|
||||
|
||||
8
main.go
8
main.go
@@ -64,6 +64,7 @@ type CLIArgs struct {
|
||||
maxPause time.Duration
|
||||
backoffInitial time.Duration
|
||||
backoffDeadline time.Duration
|
||||
hideSNI bool
|
||||
}
|
||||
|
||||
func parse_args() CLIArgs {
|
||||
@@ -93,6 +94,7 @@ func parse_args() CLIArgs {
|
||||
"Format: <http|https|socks5|socks5h>://[login:password@]host[:port] "+
|
||||
"Examples: http://user:password@192.168.1.1:3128, socks5://10.0.0.1:1080")
|
||||
flag.StringVar(&args.caFile, "cafile", "", "use custom CA certificate bundle file")
|
||||
flag.BoolVar(&args.hideSNI, "hide-SNI", true, "hide SNI in TLS sessions with proxy server")
|
||||
flag.Parse()
|
||||
if args.country == "" {
|
||||
arg_fail("Country can't be empty string.")
|
||||
@@ -183,7 +185,7 @@ func run() int {
|
||||
defer cl()
|
||||
extVer, err := GetExtVer(ctx, nil, HolaExtStoreID, dialer)
|
||||
if err != nil {
|
||||
mainLogger.Critical("Can't detect latest API version. Try to specify -ext-ver parameter")
|
||||
mainLogger.Critical("Can't detect latest API version. Try to specify -ext-ver parameter. Error: %v", err)
|
||||
return 8
|
||||
}
|
||||
args.extVer = extVer
|
||||
@@ -215,8 +217,8 @@ func run() int {
|
||||
mainLogger.Critical("Unable to determine proxy endpoint: %v", err)
|
||||
return 5
|
||||
}
|
||||
handlerDialer := NewProxyDialer(endpoint.NetAddr(), endpoint.TLSName, caPool, auth, dialer)
|
||||
requestDialer := NewPlaintextDialer(endpoint.NetAddr(), endpoint.TLSName, caPool, dialer)
|
||||
handlerDialer := NewProxyDialer(endpoint.NetAddr(), endpoint.TLSName, caPool, auth, args.hideSNI, dialer)
|
||||
requestDialer := NewPlaintextDialer(endpoint.NetAddr(), endpoint.TLSName, caPool, args.hideSNI, dialer)
|
||||
mainLogger.Info("Endpoint: %s", endpoint.URL().String())
|
||||
mainLogger.Info("Starting proxy server...")
|
||||
handler := NewProxyHandler(handlerDialer, requestDialer, auth, resolver, proxyLogger)
|
||||
|
||||
10
plaintext.go
10
plaintext.go
@@ -13,14 +13,16 @@ type PlaintextDialer struct {
|
||||
tlsServerName string
|
||||
next ContextDialer
|
||||
caPool *x509.CertPool
|
||||
hideSNI bool
|
||||
}
|
||||
|
||||
func NewPlaintextDialer(address, tlsServerName string, caPool *x509.CertPool, next ContextDialer) *PlaintextDialer {
|
||||
func NewPlaintextDialer(address, tlsServerName string, caPool *x509.CertPool, hideSNI bool, next ContextDialer) *PlaintextDialer {
|
||||
return &PlaintextDialer{
|
||||
fixedAddress: address,
|
||||
tlsServerName: tlsServerName,
|
||||
next: next,
|
||||
caPool: caPool,
|
||||
hideSNI: hideSNI,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +42,12 @@ func (d *PlaintextDialer) DialContext(ctx context.Context, network, address stri
|
||||
// Custom cert verification logic:
|
||||
// DO NOT send SNI extension of TLS ClientHello
|
||||
// DO peer certificate verification against specified servername
|
||||
sni := d.tlsServerName
|
||||
if d.hideSNI {
|
||||
sni = ""
|
||||
}
|
||||
conn = tls.Client(conn, &tls.Config{
|
||||
ServerName: "",
|
||||
ServerName: sni,
|
||||
InsecureSkipVerify: true,
|
||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||
opts := x509.VerifyOptions{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: hola-proxy
|
||||
version: '1.9.0'
|
||||
version: '1.10.0'
|
||||
summary: Standalone Hola proxy client.
|
||||
description: |
|
||||
Standalone Hola proxy client. Just run it and it'll start plain HTTP proxy server forwarding traffic via Hola proxies of your choice.
|
||||
|
||||
12
upstream.go
12
upstream.go
@@ -39,15 +39,17 @@ type ProxyDialer struct {
|
||||
auth AuthProvider
|
||||
next ContextDialer
|
||||
caPool *x509.CertPool
|
||||
hideSNI bool
|
||||
}
|
||||
|
||||
func NewProxyDialer(address, tlsServerName string, caPool *x509.CertPool, auth AuthProvider, nextDialer ContextDialer) *ProxyDialer {
|
||||
func NewProxyDialer(address, tlsServerName string, caPool *x509.CertPool, auth AuthProvider, hideSNI bool, nextDialer ContextDialer) *ProxyDialer {
|
||||
return &ProxyDialer{
|
||||
address: address,
|
||||
tlsServerName: tlsServerName,
|
||||
auth: auth,
|
||||
next: nextDialer,
|
||||
caPool: caPool,
|
||||
hideSNI: hideSNI,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +83,7 @@ func ProxyDialerFromURL(u *url.URL, caPool *x509.CertPool, next ContextDialer) (
|
||||
return authHeader
|
||||
}
|
||||
}
|
||||
return NewProxyDialer(address, tlsServerName, caPool, auth, next), nil
|
||||
return NewProxyDialer(address, tlsServerName, caPool, auth, false, next), nil
|
||||
}
|
||||
|
||||
func (d *ProxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
@@ -100,8 +102,12 @@ func (d *ProxyDialer) DialContext(ctx context.Context, network, address string)
|
||||
// Custom cert verification logic:
|
||||
// DO NOT send SNI extension of TLS ClientHello
|
||||
// DO peer certificate verification against specified servername
|
||||
sni := d.tlsServerName
|
||||
if d.hideSNI {
|
||||
sni = ""
|
||||
}
|
||||
conn = tls.Client(conn, &tls.Config{
|
||||
ServerName: "",
|
||||
ServerName: sni,
|
||||
InsecureSkipVerify: true,
|
||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||
opts := x509.VerifyOptions{
|
||||
|
||||
Reference in New Issue
Block a user