241 lines
6.1 KiB
Go
241 lines
6.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/gookit/color"
|
|
"github.com/valyala/fasthttp"
|
|
"github.com/valyala/fastjson"
|
|
)
|
|
|
|
// IPData Contains IP data
|
|
type IPData struct {
|
|
IP string
|
|
CountryC string
|
|
Country string
|
|
RegionC string
|
|
Region string
|
|
ContinentC string
|
|
Continent string
|
|
City string
|
|
}
|
|
|
|
func main() {
|
|
retChan := make(chan string)
|
|
color.Notice.Println("nagato 1.0")
|
|
|
|
go runCmd(retChan, "uname", "-a")
|
|
out := <-retChan
|
|
color.Notice.Print(runtime.Version() + " " + out)
|
|
|
|
// Get status
|
|
go runCmd(retChan, "nordvpn", "status")
|
|
out = <-retChan
|
|
if strings.Contains(out, "Connected") {
|
|
fmt.Print(out)
|
|
go runCmd(retChan, "nordvpn", "disconnect")
|
|
out = <-retChan
|
|
fmt.Println(out)
|
|
if !strings.Contains(out, "disconnected") {
|
|
color.Errorln("nordvpn plz")
|
|
os.Exit(-1)
|
|
}
|
|
} else {
|
|
if !strings.Contains(out, "Disconnected") {
|
|
color.Errorln(out)
|
|
color.Errorln("nordvpn plz")
|
|
os.Exit(-1)
|
|
}
|
|
}
|
|
|
|
// Set killswitch off
|
|
go runCmd(retChan, "nordvpn", "set", "killswitch", "off")
|
|
out = <-retChan
|
|
fmt.Print(out)
|
|
if !(strings.Contains(out, "Kill") && strings.Contains(out, "disabled") && (strings.Contains(out, "success") || strings.Contains(out, "already"))) {
|
|
color.Errorln("nordvpn plz")
|
|
os.Exit(-1)
|
|
}
|
|
|
|
// check IP
|
|
go getIP(retChan)
|
|
out = <-retChan
|
|
if strings.Contains(out, "ERR") {
|
|
color.Errorln(out)
|
|
color.Errorln("Jeff plz")
|
|
os.Exit(-1)
|
|
}
|
|
color.Info.Print(out)
|
|
ip := out
|
|
|
|
// nordvpn connect Switzerland
|
|
go runCmd(retChan, "nordvpn", "connect", "Switzerland")
|
|
out = <-retChan
|
|
fmt.Print(out)
|
|
if !(strings.Contains(out, "connected") && strings.Contains(out, "Switzerland")) {
|
|
color.Errorln("nordvpn plz")
|
|
go runCmd(retChan, "nordvpn", "set", "killswitch", "on")
|
|
fmt.Println(<-retChan)
|
|
os.Exit(-1)
|
|
}
|
|
|
|
// nordvpn killswitch on
|
|
go runCmd(retChan, "nordvpn", "set", "killswitch", "on")
|
|
out = <-retChan
|
|
fmt.Print(out)
|
|
if !(strings.Contains(out, "Kill") && strings.Contains(out, "enabled") && strings.Contains(out, "success")) {
|
|
color.Errorln("nordvpn plz")
|
|
go runCmd(retChan, "nordvpn", "disconnect")
|
|
fmt.Println(<-retChan)
|
|
os.Exit(-1)
|
|
}
|
|
|
|
// nordvpn status
|
|
go runCmd(retChan, "nordvpn", "status")
|
|
out = <-retChan
|
|
fmt.Print(out)
|
|
|
|
// check connection
|
|
retDataChan := make(chan IPData)
|
|
go getIPData(retChan, retDataChan)
|
|
out = <-retChan
|
|
if strings.Contains(out, "ERR") {
|
|
color.Errorln(out)
|
|
color.Errorln("IPLeak plz")
|
|
os.Exit(-1)
|
|
}
|
|
ipData := <-retDataChan
|
|
color.Comment.Printf("%v\n", ipData)
|
|
if strings.Contains(ip, ipData.IP) {
|
|
color.Danger.Println("IP unchanged")
|
|
os.Exit(-1)
|
|
}
|
|
if strings.Contains(ipData.CountryC, "DE") || strings.Contains(ipData.Country, "Ger") {
|
|
color.Danger.Println("BRATWURST")
|
|
os.Exit(-1)
|
|
}
|
|
if strings.Contains(ipData.CountryC, "CH") || strings.Contains(ipData.Country, "Switz") {
|
|
color.Success.Println("SCHOKI")
|
|
}
|
|
|
|
color.Notice.Println("どうぞ")
|
|
}
|
|
|
|
func runCmd(retChan chan<- string, cmds string, args ...string) {
|
|
cmd := exec.Command(cmds, args...)
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil && cmd.ProcessState.ExitCode() != 1 {
|
|
retChan <- fmt.Sprintln(color.Error.Sprint(err))
|
|
return
|
|
}
|
|
retChan <- string(out)
|
|
}
|
|
|
|
func getIP(retChan chan<- string) {
|
|
// get public IP
|
|
req := fasthttp.AcquireRequest()
|
|
resp := fasthttp.AcquireResponse()
|
|
defer fasthttp.ReleaseRequest(req)
|
|
defer fasthttp.ReleaseResponse(resp)
|
|
req.SetRequestURI("https://checkip.amazonaws.com/")
|
|
err := fasthttp.Do(req, resp)
|
|
if err != nil {
|
|
retChan <- "ERR: " + fmt.Sprintln(err)
|
|
return
|
|
}
|
|
if resp.StatusCode() != fasthttp.StatusOK {
|
|
retChan <- fmt.Sprintf("ERR: Status code %d\n", resp.StatusCode())
|
|
return
|
|
}
|
|
contType := resp.Header.Peek("Content-Type")
|
|
if bytes.Index(contType, []byte("text/plain")) != 0 {
|
|
retChan <- fmt.Sprintf("ERR: Unexpected content type %s\n", contType)
|
|
return
|
|
}
|
|
contentEncoding := resp.Header.Peek("Content-Encoding")
|
|
var body []byte
|
|
if bytes.EqualFold(contentEncoding, []byte("gzip")) {
|
|
body, _ = resp.BodyGunzip()
|
|
} else {
|
|
body = resp.Body()
|
|
}
|
|
retChan <- string(body)
|
|
}
|
|
|
|
func getIPData(retChan chan<- string, retDataChan chan<- IPData) {
|
|
req := fasthttp.AcquireRequest()
|
|
resp := fasthttp.AcquireResponse()
|
|
defer fasthttp.ReleaseRequest(req)
|
|
defer fasthttp.ReleaseResponse(resp)
|
|
req.SetRequestURI("https://ipleak.net/json/")
|
|
err := fasthttp.Do(req, resp)
|
|
if err != nil {
|
|
retChan <- "ERR: " + fmt.Sprintln(err)
|
|
return
|
|
}
|
|
if resp.StatusCode() != fasthttp.StatusOK {
|
|
retChan <- fmt.Sprintf("ERR: Status code %d\n", resp.StatusCode())
|
|
return
|
|
}
|
|
contType := resp.Header.Peek("Content-Type")
|
|
if bytes.Index(contType, []byte("application/json")) != 0 {
|
|
retChan <- fmt.Sprintf("ERR: Unexpected content type %s\n", contType)
|
|
return
|
|
}
|
|
contentEncoding := resp.Header.Peek("Content-Encoding")
|
|
var body []byte
|
|
if bytes.EqualFold(contentEncoding, []byte("gzip")) {
|
|
body, _ = resp.BodyGunzip()
|
|
} else {
|
|
body = resp.Body()
|
|
}
|
|
// color.Comment.Println(string(body))
|
|
// parse
|
|
parsed, err := fastjson.ParseBytes(body)
|
|
if err != nil {
|
|
retChan <- "ERR: " + fmt.Sprintln(err)
|
|
return
|
|
}
|
|
readVal := parsed.Get("ip")
|
|
if readVal == nil {
|
|
retChan <- "ERR: Error while parsing JSON"
|
|
return
|
|
}
|
|
ip, err := readVal.StringBytes()
|
|
if err != nil {
|
|
retChan <- "ERR: " + fmt.Sprintln(err)
|
|
return
|
|
}
|
|
data := IPData{}
|
|
data.IP = string(ip)
|
|
if readVal = parsed.Get("country_code"); readVal != nil {
|
|
data.CountryC = string(readVal.GetStringBytes())
|
|
}
|
|
if readVal = parsed.Get("country_name"); readVal != nil {
|
|
data.Country = string(readVal.GetStringBytes())
|
|
}
|
|
if readVal = parsed.Get("region_code"); readVal != nil {
|
|
data.RegionC = string(readVal.GetStringBytes())
|
|
}
|
|
if readVal = parsed.Get("region_name"); readVal != nil {
|
|
data.Region = string(readVal.GetStringBytes())
|
|
}
|
|
if readVal = parsed.Get("continent_code"); readVal != nil {
|
|
data.ContinentC = string(readVal.GetStringBytes())
|
|
}
|
|
if readVal = parsed.Get("continent_name"); readVal != nil {
|
|
data.Continent = string(readVal.GetStringBytes())
|
|
}
|
|
if readVal = parsed.Get("city_name"); readVal != nil {
|
|
data.City = string(readVal.GetStringBytes())
|
|
}
|
|
retChan <- fmt.Sprintln(data.IP)
|
|
retDataChan <- data
|
|
close(retDataChan)
|
|
}
|