Files
gluetun/cmd/ovpnparser/main.go

107 lines
2.3 KiB
Go
Raw Normal View History

2020-05-29 10:13:42 +00:00
package main
import (
"archive/zip"
"bytes"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"sort"
"strings"
"time"
"github.com/qdm12/golibs/network"
)
func main() {
os.Exit(_main())
}
func _main() int {
provider := flag.String("provider", "surfshark", "VPN provider to parse openvpn files for, can be 'surfshark'")
flag.Parse()
var url string
switch *provider {
case "surfshark":
url = "https://account.surfshark.com/api/v1/server/configurations"
default:
fmt.Printf("Provider %q is not supported\n", *provider)
return 1
}
client := network.NewClient(time.Second)
zipBytes, status, err := client.GetContent(url)
if err != nil {
fmt.Println(err)
return 1
} else if status != http.StatusOK {
fmt.Printf("Getting %s results in HTTP status code %d\n", url, status)
return 1
}
contents, err := zipExtractAll(zipBytes)
if err != nil {
fmt.Println(err)
return 1
}
uniqueSubdomains := make(map[string]struct{})
for _, content := range contents {
subdomain, err := extractInformation(content)
if err != nil {
fmt.Println(err)
return 1
}
uniqueSubdomains[subdomain] = struct{}{}
}
subdomains := make([]string, len(uniqueSubdomains))
i := 0
for subdomain := range uniqueSubdomains {
subdomains[i] = subdomain
i++
}
sort.Slice(subdomains, func(i, j int) bool {
return subdomains[i] < subdomains[j]
})
fmt.Println("Subdomains found are: ", strings.Join(subdomains, ","))
return 0
}
func zipExtractAll(zipBytes []byte) (contents [][]byte, err error) {
r, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
if err != nil {
return nil, err
}
contents = make([][]byte, len(r.File))
for i, zf := range r.File {
f, err := zf.Open()
if err != nil {
return nil, err
}
defer f.Close()
contents[i], err = ioutil.ReadAll(f)
if err != nil {
return nil, err
}
if err := f.Close(); err != nil {
return nil, err
}
}
return contents, nil
}
func extractInformation(content []byte) (subdomain string, err error) {
lines := strings.Split(string(content), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "remote ") {
words := strings.Fields(line)
if len(words) < 2 {
return "", fmt.Errorf("not enough words on line %q", line)
}
host := words[1]
return strings.TrimSuffix(host, ".prod.surfshark.com"), nil
}
}
return "", fmt.Errorf("could not find remote line")
}