Skip to content

Commit

Permalink
Merge pull request #14 from rany2/master
Browse files Browse the repository at this point in the history
 Fix #13 and enhancements
  • Loading branch information
Snawoot authored Mar 6, 2021
2 parents 335894d + 5774d89 commit a95a651
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@
# vendor/
bin/
*.snap

# hola-proxy binary
hola-proxy
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ dk - Denmark
es - Spain
fi - Finland
fr - France
gb - United Kingdom (Great Britain)
gr - Greece
hk - Hong Kong
hr - Croatia
hu - Hungary
id - Indonesia
ie - Ireland
Expand Down Expand Up @@ -125,21 +127,21 @@ $ ~/go/bin/hola-proxy -country de
Or run proxy on residental IP:

```
$ ~/go/bin/hola-proxy -country de -proxy-type peer
$ ~/go/bin/hola-proxy -country de -proxy-type lum
```

Also it is possible to export proxy addresses and credentials:

```
$ ~/go/bin/hola-proxy -country de -list-proxies -limit 3
Login: user-uuid-f4c2c3a8657640048e7243a807867d52
Password: e194c4f457e0
Proxy-Authorization: basic dXNlci11dWlkLWY0YzJjM2E4NjU3NjQwMDQ4ZTcyNDNhODA3ODY3ZDUyOmUxOTRjNGY0NTdlMA==
Login: user-uuid-0a67c797b3214cbdb432b089c4b801cd
Password: cd123c465901
Proxy-Authorization: basic dXNlci11dWlkLTBhNjdjNzk3YjMyMTRjYmRiNDMyYjA4OWM0YjgwMWNkOmNkMTIzYzQ2NTkwMQ==
Host,IP address,Direct port,Peer port,Vendor
zagent90.hola.org,185.72.246.203,22222,22223,nqhost
zagent249.hola.org,165.22.80.107,22222,22223,digitalocean
zagent248.hola.org,165.22.65.3,22222,22223,digitalocean
host,ip_address,direct,peer,hola,trial,trial_peer,vendor
zagent783.hola.org,165.22.22.6,22222,22223,22224,22225,22226,digitalocean
zagent830.hola.org,104.248.24.64,22222,22223,22224,22225,22226,digitalocean
zagent248.hola.org,165.22.65.3,22222,22223,22224,22225,22226,digitalocean
```

## Synopsis
Expand All @@ -158,14 +160,15 @@ Usage of /home/user/go/bin/hola-proxy:
-list-proxies
output proxy list and exit
-proxy-type string
proxy type: direct or peer (default "direct")
proxy type: direct or peer or lum (default "direct")
-resolver string
DNS/DoH/DoT resolver to workaround Hola blocked hosts. See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format. (default "https://cloudflare-dns.com/dns-query")
-rotate duration
rotate user ID once per given period (default 1h0m0s)
-timeout duration
timeout for network operations (default 10s)
-use-trial
use trial ports instead of regular ports
-verbosity int
logging verbosity (10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical) (default 20)
```
5 changes: 3 additions & 2 deletions credservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const API_CALL_ATTEMPTS = 3

func CredService(interval, timeout time.Duration,
country string,
proxytype string,
logger *CondLogger) (auth AuthProvider,
tunnels *ZGetTunnelsResponse,
err error) {
Expand All @@ -25,7 +26,7 @@ func CredService(interval, timeout time.Duration,

for i := 0; i < API_CALL_ATTEMPTS ; i++ {
ctx, _ := context.WithTimeout(context.Background(), timeout)
tunnels, user_uuid, err = Tunnels(ctx, country, DEFAULT_LIST_LIMIT)
tunnels, user_uuid, err = Tunnels(ctx, country, proxytype, DEFAULT_LIST_LIMIT)
if err == nil {
break
}
Expand All @@ -49,7 +50,7 @@ func CredService(interval, timeout time.Duration,
logger.Info("Rotating credentials...")
for i := 0; i < API_CALL_ATTEMPTS ; i++ {
ctx, _ := context.WithTimeout(context.Background(), timeout)
tuns, user_uuid, err = Tunnels(ctx, country, DEFAULT_LIST_LIMIT)
tuns, user_uuid, err = Tunnels(ctx, country, proxytype, DEFAULT_LIST_LIMIT)
if err == nil {
break
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.13

require (
github.com/AdguardTeam/dnsproxy v0.25.0
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e
github.com/google/uuid v1.1.1
github.com/miekg/dns v1.1.29
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ github.com/ameshkov/dnscrypt v1.1.0/go.mod h1:ikduAxNLCTEfd1AaCgpIA5TgroIVQ8JY3V
github.com/ameshkov/dnsstamps v1.0.1 h1:LhGvgWDzhNJh+kBQd/AfUlq1vfVe109huiXw4JhnPug=
github.com/ameshkov/dnsstamps v1.0.1/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
github.com/beefsack/go-rate v0.0.0-20180408011153-efa7637bb9b6/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ=
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
24 changes: 20 additions & 4 deletions holaapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
"bytes"
"strconv"
"math/rand"
"github.com/campoy/unique"
)

const USER_AGENT = "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
const EXT_VER = "1.164.641"
const USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36"
const EXT_VER = "1.181.350"
const EXT_BROWSER = "chrome"
const PRODUCT = "cws"
const CCGI_URL = "https://client.hola.org/client_cgi/"
Expand Down Expand Up @@ -96,6 +97,13 @@ func VPNCountries(ctx context.Context) (res CountryList, err error) {
return nil, err
}
err = json.Unmarshal(data, &res)
for _, a := range res {
if a == "uk" {
res = append(res, "gb")
}
}
less := func(i, j int) bool { return res[i] < res[j] }
unique.Slice(&res, less)
return
}

Expand All @@ -118,10 +126,17 @@ func zgettunnels(ctx context.Context,
user_uuid string,
session_key int64,
country string,
proxy_type string,
limit uint) (res *ZGetTunnelsResponse, reterr error) {
var tunnels ZGetTunnelsResponse
params := make(url.Values)
params.Add("country", country)
if proxy_type == "lum" {
params.Add("country", country + ".pool_lum_" + country + "_shared")
} else if proxy_type == "peer" {
params.Add("country", country + ".peer")
} else {
params.Add("country", country)
}
params.Add("limit", strconv.FormatInt(int64(limit), 10))
params.Add("ping_id", strconv.FormatFloat(rand.Float64(), 'f', -1, 64))
params.Add("ext_ver", EXT_VER)
Expand All @@ -142,6 +157,7 @@ func zgettunnels(ctx context.Context,

func Tunnels(ctx context.Context,
country string,
proxy_type string,
limit uint) (res *ZGetTunnelsResponse, user_uuid string, reterr error) {
u := uuid.New()
user_uuid = hex.EncodeToString(u[:])
Expand All @@ -150,6 +166,6 @@ func Tunnels(ctx context.Context,
reterr = err
return
}
res, reterr = zgettunnels(ctx, user_uuid, initres.Key, country, limit)
res, reterr = zgettunnels(ctx, user_uuid, initres.Key, country, proxy_type, limit)
return
}
14 changes: 9 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func arg_fail(msg string) {

type CLIArgs struct {
country string
list_countries, list_proxies bool
list_countries, list_proxies, use_trial bool
limit uint
bind_address string
verbosity int
Expand All @@ -57,14 +57,18 @@ func parse_args() CLIArgs {
"(10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical)")
flag.DurationVar(&args.timeout, "timeout", 10 * time.Second, "timeout for network operations")
flag.DurationVar(&args.rotate, "rotate", 1 * time.Hour, "rotate user ID once per given period")
flag.StringVar(&args.proxy_type, "proxy-type", "direct", "proxy type: direct or peer")
flag.StringVar(&args.proxy_type, "proxy-type", "direct", "proxy type: direct or peer or lum")
flag.StringVar(&args.resolver, "resolver", "https://cloudflare-dns.com/dns-query",
"DNS/DoH/DoT resolver to workaround Hola blocked hosts. " +
"See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format.")
flag.BoolVar(&args.use_trial, "use-trial", false, "use trial ports instead of regular ports")
flag.Parse()
if args.country == "" {
arg_fail("Country can't be empty string.")
}
if args.proxy_type == "" {
arg_fail("Proxy type can't be an empty string.")
}
if args.list_countries && args.list_proxies {
arg_fail("list-countries and list-proxies flags are mutually exclusive")
}
Expand All @@ -77,7 +81,7 @@ func run() int {
return print_countries(args.timeout)
}
if args.list_proxies {
return print_proxies(args.country, args.limit, args.timeout)
return print_proxies(args.country, args.proxy_type, args.limit, args.timeout)
}

logWriter := NewLogWriter(os.Stderr)
Expand All @@ -99,13 +103,13 @@ func run() int {
return 6
}
mainLogger.Info("Initializing configuration provider...")
auth, tunnels, err := CredService(args.rotate, args.timeout, args.country, credLogger)
auth, tunnels, err := CredService(args.rotate, args.timeout, args.country, args.proxy_type, credLogger)
if err != nil {
mainLogger.Critical("Unable to instantiate credential service: %v", err)
logWriter.Close()
return 4
}
endpoint, err := get_endpoint(tunnels, args.proxy_type)
endpoint, err := get_endpoint(tunnels, args.proxy_type, args.use_trial)
if err != nil {
mainLogger.Critical("Unable to determine proxy endpoint: %v", err)
logWriter.Close()
Expand Down
25 changes: 18 additions & 7 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ func print_countries(timeout time.Duration) int {
return 0
}

func print_proxies(country string, limit uint, timeout time.Duration) int {
func print_proxies(country string, proxy_type string, limit uint, timeout time.Duration) int {
ctx, _ := context.WithTimeout(context.Background(), timeout)
tunnels, user_uuid, err := Tunnels(ctx, country, limit)
tunnels, user_uuid, err := Tunnels(ctx, country, proxy_type, limit)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return 3
Expand All @@ -77,21 +77,24 @@ func print_proxies(country string, limit uint, timeout time.Duration) int {
fmt.Println("Proxy-Authorization:",
basic_auth_header(login, password))
fmt.Println("")
wr.Write([]string{"Host", "IP address", "Direct port", "Peer port", "Vendor"})
wr.Write([]string{"host", "ip_address", "direct", "peer", "hola", "trial", "trial_peer", "vendor"})
for host, ip := range tunnels.IPList {
if (PROTOCOL_WHITELIST[tunnels.Protocol[host]]) {
wr.Write([]string{host,
ip,
strconv.FormatUint(uint64(tunnels.Port.Direct), 10),
strconv.FormatUint(uint64(tunnels.Port.Peer), 10),
strconv.FormatUint(uint64(tunnels.Port.Hola), 10),
strconv.FormatUint(uint64(tunnels.Port.Trial), 10),
strconv.FormatUint(uint64(tunnels.Port.TrialPeer), 10),
tunnels.Vendor[host]})
}
}
wr.Flush()
return 0
}

func get_endpoint(tunnels *ZGetTunnelsResponse, typ string) (string, error) {
func get_endpoint(tunnels *ZGetTunnelsResponse, typ string, trial bool) (string, error) {
var hostname string
for k, _ := range tunnels.IPList {
hostname = k
Expand All @@ -102,9 +105,17 @@ func get_endpoint(tunnels *ZGetTunnelsResponse, typ string) (string, error) {
}
var port uint16
if typ == "direct" {
port = tunnels.Port.Direct
} else if typ == "peer" {
port = tunnels.Port.Peer
if trial {
port = tunnels.Port.Trial
} else {
port = tunnels.Port.Direct
}
} else if typ == "peer" || typ == "lum" {
if trial {
port = tunnels.Port.TrialPeer
} else {
port = tunnels.Port.Peer
}
} else {
return "", errors.New("Unsupported port type")
}
Expand Down

0 comments on commit a95a651

Please sign in to comment.