summaryrefslogtreecommitdiff
path: root/pkg/standalone
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-06-12 20:35:48 +0200
committerkali kaneko (leap communications) <kali@leap.se>2020-06-12 20:35:48 +0200
commit4faad2cda4938806126c482c7f93b640d68b9fe8 (patch)
treee475b65a59ecdfac09bedc7b2ae380736de09c16 /pkg/standalone
parent0ac0afaaf312a02af01d1c307ecf9b5915f40b0d (diff)
[refactor] rename standalone to just vpn
Diffstat (limited to 'pkg/standalone')
-rw-r--r--pkg/standalone/bonafide/bonafide.go166
-rw-r--r--pkg/standalone/bonafide/bonafide_integration_test.go62
-rw-r--r--pkg/standalone/bonafide/bonafide_test.go220
-rw-r--r--pkg/standalone/bonafide/eip_service.go257
-rw-r--r--pkg/standalone/bonafide/testdata/cert54
-rw-r--r--pkg/standalone/bonafide/testdata/eip-service.json113
-rw-r--r--pkg/standalone/bonafide/testdata/eip-service3.json173
-rw-r--r--pkg/standalone/launcher.go163
-rw-r--r--pkg/standalone/launcher_linux.go224
-rw-r--r--pkg/standalone/main.go86
-rw-r--r--pkg/standalone/status.go90
-rw-r--r--pkg/standalone/vpn.go255
12 files changed, 0 insertions, 1863 deletions
diff --git a/pkg/standalone/bonafide/bonafide.go b/pkg/standalone/bonafide/bonafide.go
deleted file mode 100644
index fd32f2a..0000000
--- a/pkg/standalone/bonafide/bonafide.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package bonafide
-
-import (
- "crypto/tls"
- "crypto/x509"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "time"
-
- "0xacab.org/leap/bitmask-vpn/pkg/config"
-)
-
-const (
- certAPI = config.APIURL + "1/cert"
- certAPI3 = config.APIURL + "3/cert"
- secondsPerHour = 60 * 60
- retryFetchJSONSeconds = 15
-)
-
-type Bonafide struct {
- client httpClient
- eip *eipService
- tzOffsetHours int
-}
-
-type Gateway struct {
- Host string
- IPAddress string
- Location string
- Ports []string
- Protocols []string
- Options map[string]string
-}
-
-type openvpnConfig map[string]interface{}
-
-type httpClient interface {
- Post(url, contentType string, body io.Reader) (resp *http.Response, err error)
-}
-
-type geoLocation struct {
- IPAddress string `json:"ip"`
- Country string `json:"cc"`
- City string `json:"city"`
- Latitude float64 `json:"lat"`
- Longitude float64 `json:"lon"`
- SortedGateways []string `json:"gateways"`
-}
-
-func New() *Bonafide {
- certs := x509.NewCertPool()
- certs.AppendCertsFromPEM(config.CaCert)
- client := &http.Client{
- Transport: &http.Transport{
- TLSClientConfig: &tls.Config{
- RootCAs: certs,
- },
- },
- }
- _, tzOffsetSeconds := time.Now().Zone()
- tzOffsetHours := tzOffsetSeconds / secondsPerHour
-
- return &Bonafide{
- client: client,
- eip: nil,
- tzOffsetHours: tzOffsetHours,
- }
-}
-
-func (b *Bonafide) GetCertPem() ([]byte, error) {
- resp, err := b.client.Post(certAPI, "", nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- if resp.StatusCode == 404 {
- resp, err = b.client.Post(certAPI3, "", nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- }
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("get vpn cert has failed with status: %s", resp.Status)
- }
-
- return ioutil.ReadAll(resp.Body)
-}
-
-func (b *Bonafide) GetGateways(transport string) ([]Gateway, error) {
- if b.eip == nil {
- err := b.fetchEipJSON()
- if err != nil {
- return nil, err
- }
- }
-
- return b.eip.getGateways(transport), nil
-}
-
-func (b *Bonafide) SetDefaultGateway(name string) {
- b.eip.setDefaultGateway(name)
- b.sortGateways()
-}
-
-func (b *Bonafide) GetOpenvpnArgs() ([]string, error) {
- if b.eip == nil {
- err := b.fetchEipJSON()
- if err != nil {
- return nil, err
- }
- }
- return b.eip.getOpenvpnArgs(), nil
-}
-
-func (b *Bonafide) fetchGeolocation() ([]string, error) {
- resp, err := b.client.Post(config.GeolocationAPI, "", nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("get geolocation failed with status: %s", resp.Status)
- }
-
- geo := &geoLocation{}
- dataJSON, err := ioutil.ReadAll(resp.Body)
- err = json.Unmarshal(dataJSON, &geo)
- if err != nil {
- _ = fmt.Errorf("get vpn cert has failed with status: %s", resp.Status)
- return nil, err
- }
-
- return geo.SortedGateways, nil
-
-}
-
-func (b *Bonafide) sortGateways() {
- geolocatedGateways, _ := b.fetchGeolocation()
-
- if len(geolocatedGateways) > 0 {
- b.eip.sortGatewaysByGeolocation(geolocatedGateways)
- } else {
- log.Printf("Falling back to timezone heuristic for gateway selection")
- b.eip.sortGatewaysByTimezone(b.tzOffsetHours)
- }
-}
diff --git a/pkg/standalone/bonafide/bonafide_integration_test.go b/pkg/standalone/bonafide/bonafide_integration_test.go
deleted file mode 100644
index bea00fe..0000000
--- a/pkg/standalone/bonafide/bonafide_integration_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// +build integration
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package bonafide
-
-import (
- "bytes"
- "testing"
-)
-
-const (
- gwIP = "199.58.81.145"
-)
-
-var (
- privateKeyHeader = []byte("-----BEGIN RSA PRIVATE KEY-----")
- certHeader = []byte("-----BEGIN CERTIFICATE-----")
-)
-
-func TestIntegrationGetCert(t *testing.T) {
- b := New()
- cert, err := b.GetCertPem()
- if err != nil {
- t.Fatal("getCert returned an error: ", err)
- }
-
- if !bytes.Contains(cert, privateKeyHeader) {
- t.Errorf("No private key present: \n%q", cert)
- }
-
- if !bytes.Contains(cert, certHeader) {
- t.Errorf("No cert present: \n%q", cert)
- }
-}
-
-func TestGetGateways(t *testing.T) {
- b := New()
- gateways, err := b.GetGateways("openvpn")
- if err != nil {
- t.Fatal("getGateways returned an error: ", err)
- }
-
- for _, gw := range gateways {
- if gw.IPAddress == gwIP {
- return
- }
- }
- t.Errorf("%s not in the list", gwIP)
-}
diff --git a/pkg/standalone/bonafide/bonafide_test.go b/pkg/standalone/bonafide/bonafide_test.go
deleted file mode 100644
index 8fb7f72..0000000
--- a/pkg/standalone/bonafide/bonafide_test.go
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package bonafide
-
-import (
- "io"
- "io/ioutil"
- "net/http"
- "os"
- "reflect"
- "strconv"
- "strings"
- "testing"
-)
-
-const (
- certPath = "testdata/cert"
- eip1Path = "testdata/eip-service.json"
- eipPath = "testdata/eip-service3.json"
-)
-
-type client struct {
- path string
-}
-
-func (c client) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) {
- f, err := os.Open(c.path)
- return &http.Response{
- Body: f,
- StatusCode: 200,
- }, err
-}
-
-func TestGetCert(t *testing.T) {
- b := Bonafide{client: client{certPath}}
- cert, err := b.GetCertPem()
- if err != nil {
- t.Fatal("getCert returned an error: ", err)
- }
-
- f, err := os.Open(certPath)
- if err != nil {
- t.Fatal("Can't open ", certPath, ": ", err)
- }
- defer f.Close()
-
- certData, err := ioutil.ReadAll(f)
- if err != nil {
- t.Fatal("Can't read all: ", err)
- }
- if !reflect.DeepEqual(certData, cert) {
- t.Errorf("cert doesn't match")
- }
-}
-
-func TestGatewayTzLocation(t *testing.T) {
- // tzOffset -> location
- values := map[int]string{
- -12: "c",
- -10: "a",
- -5: "a",
- -3: "a",
- -1: "b",
- 0: "b",
- 2: "b",
- 5: "c",
- 8: "c",
- 12: "c",
- }
-
- for tzOffset, location := range values {
- b := Bonafide{
- client: client{eipPath},
- tzOffsetHours: tzOffset,
- }
- gateways, err := b.GetGateways("openvpn")
- if err != nil {
- t.Errorf("getGateways returned an error: %v", err)
- continue
- }
- if len(gateways) < 4 {
- t.Errorf("Wrong number of gateways: %d", len(gateways))
- continue
-
- }
- if gateways[0].Location != location {
- t.Errorf("Wrong location for tz %d: %s, expected: %s", tzOffset, gateways[0].Location, location)
- }
- }
-}
-
-func TestOpenvpnGateways(t *testing.T) {
- b := Bonafide{
- client: client{eipPath},
- }
- gateways, err := b.GetGateways("openvpn")
- if err != nil {
- t.Fatalf("getGateways returned an error: %v", err)
- }
- if len(gateways) == 0 {
- t.Fatalf("No obfs4 gateways found")
- }
-
- present := make([]bool, 6)
- for _, g := range gateways {
- i, err := strconv.Atoi(g.Host[0:1])
- if err != nil {
- t.Fatalf("unkonwn host %s: %v", g.Host, err)
- }
- present[i] = true
- }
- for i, p := range present {
- switch i {
- case 0:
- continue
- case 5:
- if p {
- t.Errorf("Host %d should not have obfs4 transport", i)
- }
- default:
- if !p {
- t.Errorf("Host %d should have obfs4 transport", i)
- }
- }
- }
-}
-
-func TestObfs4Gateways(t *testing.T) {
- b := Bonafide{
- client: client{eipPath},
- }
- gateways, err := b.GetGateways("obfs4")
- if err != nil {
- t.Fatalf("getGateways returned an error: %v", err)
- }
- if len(gateways) == 0 {
- t.Fatalf("No obfs4 gateways found")
- }
-
- present := make([]bool, 6)
- for _, g := range gateways {
- i, err := strconv.Atoi(g.Host[0:1])
- if err != nil {
- t.Fatalf("unkonwn host %s: %v", g.Host, err)
- }
- present[i] = true
-
- cert, ok := g.Options["cert"]
- if !ok {
- t.Fatalf("No cert in options (%s): %v", g.Host, g.Options)
- }
- if cert != "obfs-cert" {
- t.Errorf("No valid options given (%s): %v", g.Host, g.Options)
- }
- }
- for i, p := range present {
- switch i {
- case 0:
- continue
- case 2, 4:
- if p {
- t.Errorf("Host %d should not have obfs4 transport", i)
- }
- default:
- if !p {
- t.Errorf("Host %d should have obfs4 transport", i)
- }
- }
- }
-}
-
-type fallClient struct {
- path string
-}
-
-func (c fallClient) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) {
- statusCode := 200
- if strings.Contains(url, "3/config/eip-service.json") {
- statusCode = 404
- }
- f, err := os.Open(c.path)
- return &http.Response{
- Body: f,
- StatusCode: statusCode,
- }, err
-}
-
-func TestEipServiceV1Fallback(t *testing.T) {
- b := Bonafide{
- client: fallClient{eip1Path},
- }
- gateways, err := b.GetGateways("obfs4")
- if err != nil {
- t.Fatalf("getGateways obfs4 returned an error: %v", err)
- }
- if len(gateways) != 0 {
- t.Fatalf("It found some obfs4 gateways: %v", gateways)
- }
-
- gateways, err = b.GetGateways("openvpn")
- if err != nil {
- t.Fatalf("getGateways openvpn returned an error: %v", err)
- }
- if len(gateways) != 4 {
- t.Fatalf("It not right number of gateways: %v", gateways)
- }
-}
diff --git a/pkg/standalone/bonafide/eip_service.go b/pkg/standalone/bonafide/eip_service.go
deleted file mode 100644
index c097e8a..0000000
--- a/pkg/standalone/bonafide/eip_service.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package bonafide
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "log"
- "math/rand"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "0xacab.org/leap/bitmask-vpn/pkg/config"
-)
-
-const (
- eip1API = config.APIURL + "1/config/eip-service.json"
- eip3API = config.APIURL + "3/config/eip-service.json"
-)
-
-type eipService struct {
- Gateways []gatewayV3
- Locations map[string]location
- OpenvpnConfiguration openvpnConfig `json:"openvpn_configuration"`
- defaultGateway string
-}
-
-type eipServiceV1 struct {
- Gateways []gatewayV1
- Locations map[string]location
- OpenvpnConfiguration openvpnConfig `json:"openvpn_configuration"`
-}
-
-type location struct {
- CountryCode string
- Hemisphere string
- Name string
- Timezone string
-}
-
-type gatewayV1 struct {
- Capabilities struct {
- Ports []string
- Protocols []string
- }
- Host string
- IPAddress string `json:"ip_address"`
- Location string
-}
-
-type gatewayV3 struct {
- Capabilities struct {
- Transport []transportV3
- }
- Host string
- IPAddress string `json:"ip_address"`
- Location string
-}
-
-type transportV3 struct {
- Type string
- Protocols []string
- Ports []string
- Options map[string]string
-}
-
-func (b *Bonafide) fetchEipJSON() error {
- resp, err := b.client.Post(eip3API, "", nil)
- for err != nil {
- log.Printf("Error fetching eip v3 json: %v", err)
- time.Sleep(retryFetchJSONSeconds * time.Second)
- resp, err = b.client.Post(eip3API, "", nil)
- }
- defer resp.Body.Close()
-
- switch resp.StatusCode {
- case 200:
- b.eip, err = decodeEIP3(resp.Body)
- case 404:
- buf := make([]byte, 128)
- resp.Body.Read(buf)
- log.Printf("Error fetching eip v3 json: %s", buf)
- resp, err = b.client.Post(eip1API, "", nil)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- return fmt.Errorf("get eip json has failed with status: %s", resp.Status)
- }
-
- b.eip, err = decodeEIP1(resp.Body)
- default:
- return fmt.Errorf("get eip json has failed with status: %s", resp.Status)
- }
- if err != nil {
- return err
- }
-
- b.sortGateways()
- return nil
-}
-
-func decodeEIP3(body io.Reader) (*eipService, error) {
- var eip eipService
- decoder := json.NewDecoder(body)
- err := decoder.Decode(&eip)
- return &eip, err
-}
-
-func decodeEIP1(body io.Reader) (*eipService, error) {
- var eip1 eipServiceV1
- decoder := json.NewDecoder(body)
- err := decoder.Decode(&eip1)
- if err != nil {
- log.Printf("Error fetching eip v1 json: %v", err)
- return nil, err
- }
-
- eip3 := eipService{
- Gateways: make([]gatewayV3, len(eip1.Gateways)),
- Locations: eip1.Locations,
- OpenvpnConfiguration: eip1.OpenvpnConfiguration,
- }
- for _, g := range eip1.Gateways {
- gateway := gatewayV3{
- Host: g.Host,
- IPAddress: g.IPAddress,
- Location: g.Location,
- }
- gateway.Capabilities.Transport = []transportV3{
- transportV3{
- Type: "openvpn",
- Ports: g.Capabilities.Ports,
- Protocols: g.Capabilities.Protocols,
- },
- }
- eip3.Gateways = append(eip3.Gateways, gateway)
- }
- return &eip3, nil
-}
-
-func (eip eipService) getGateways(transport string) []Gateway {
- gws := []Gateway{}
- for _, g := range eip.Gateways {
- for _, t := range g.Capabilities.Transport {
- if t.Type != transport {
- continue
- }
-
- gateway := Gateway{
- Host: g.Host,
- IPAddress: g.IPAddress,
- Location: g.Location,
- Ports: t.Ports,
- Protocols: t.Protocols,
- Options: t.Options,
- }
- gws = append(gws, gateway)
- }
- }
- return gws
-}
-
-func (eip *eipService) setDefaultGateway(name string) {
- eip.defaultGateway = name
-}
-
-func (eip eipService) getOpenvpnArgs() []string {
- args := []string{}
- for arg, value := range eip.OpenvpnConfiguration {
- switch v := value.(type) {
- case string:
- args = append(args, "--"+arg)
- args = append(args, strings.Split(v, " ")...)
- case bool:
- if v {
- args = append(args, "--"+arg)
- }
- default:
- log.Printf("Unknown openvpn argument type: %s - %v", arg, value)
- }
- }
- return args
-}
-
-func (eip *eipService) sortGatewaysByGeolocation(geolocatedGateways []string) {
- gws := make([]gatewayV3, len(eip.Gateways))
-
- if eip.defaultGateway != "" {
- for _, gw := range eip.Gateways {
- if gw.Location == eip.defaultGateway {
- gws = append(gws, gw)
- break
- }
- }
- }
- for _, host := range geolocatedGateways {
- for _, gw := range eip.Gateways {
- if gw.Host == host {
- gws = append(gws, gw)
- }
- }
- }
- eip.Gateways = gws
-}
-
-type gatewayDistance struct {
- gateway gatewayV3
- distance int
-}
-
-func (eip *eipService) sortGatewaysByTimezone(tzOffsetHours int) {
- gws := []gatewayDistance{}
-
- for _, gw := range eip.Gateways {
- distance := 13
- if gw.Location == eip.defaultGateway {
- distance = -1
- } else {
- gwOffset, err := strconv.Atoi(eip.Locations[gw.Location].Timezone)
- if err != nil {
- log.Printf("Error sorting gateways: %v", err)
- } else {
- distance = tzDistance(tzOffsetHours, gwOffset)
- }
- }
- gws = append(gws, gatewayDistance{gw, distance})
- }
- rand.Seed(time.Now().UnixNano())
- cmp := func(i, j int) bool {
- if gws[i].distance == gws[j].distance {
- return rand.Intn(2) == 1
- }
- return gws[i].distance < gws[j].distance
- }
- sort.Slice(gws, cmp)
-
- for i, gw := range gws {
- eip.Gateways[i] = gw.gateway
- }
-}
-
-func tzDistance(offset1, offset2 int) int {
- abs := func(x int) int {
- if x < 0 {
- return -x
- }
- return x
- }
- distance := abs(offset1 - offset2)
- if distance > 12 {
- distance = 24 - distance
- }
- return distance
-}
diff --git a/pkg/standalone/bonafide/testdata/cert b/pkg/standalone/bonafide/testdata/cert
deleted file mode 100644
index 4968b3f..0000000
--- a/pkg/standalone/bonafide/testdata/cert
+++ /dev/null
@@ -1,54 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEA3TQAmZs9U6e1xqQqVWkb132AGXdaO97bsXPOrrKUp63hKeXD
-2OQbmG96H3COi0uubVFQT1cAmpuym2COtgahQlnv42p0u2CYsBqfrCHw3iSK7nf6
-Q8RaG2oUIvlQj5m4DUk1wfRBgG5z0pN2HwFWmgheoT0RnOelTO3vcLCaSJA6PF4M
-Wehg5ScXi9wr0vibKsANpqab3oUxcHEYcNcKfJKRnXryJx6ctLrRp1WPv3JAXLnn
-oUtQ00S0dSHrLED5yPwGFV08q4bkv54qFai2cPO8ITReC6BpvrilBzOjT6fjCmzm
-6MCwBot7aRHYcWJgfp7H2b2S7T2qhnC4c2u6mwIDAQABAoIBAFue83SsOS2SNJdv
-Xd18qLyLzeg+aFCOET8h8YSokSwWuEGLWqBWcxujaNjm3RPTKA89c9848RYY0VTM
-HLBGdLqv183BRVJrQzMGBAbfFA5e4nC9nxo8lPnv6SFHVNf12qceILcSPaM9nJmm
-3HEhM8afGtr8GXR8+hmwH9H0RCMzXIjO1//WrY3nfOP8LRuQpSnnhsfZRyngWhot
-xsJlDP5plFNw7J/PDLtbjnbOXOktv0fhhq7aWR+A+0s0627r7Tidk1YoNwusYJeB
-uKrzNW1+c7Z9xl2yvMQ6+0Wry7A5YUVYP/BakYb/f/skB4ox/zz8vcWeQ4ShZ7m6
-LwPN0ckCgYEA+9wjSBbOlksath3QrJywikD1sQYFOdNrINTBFQnuipKOYKLJNhQM
-OzKHY1OiO7G6FcEvz9gKYMpMyMOs8TsISyKPNOXLpnwpgIUx6WRo6qxgEuyWLpBb
-Q3Kodl1a/q51dw56pPDEATKjSB1CjXXzm717m5FimH5csPKj9SzrGecCgYEA4Nbb
-QML1Jh9cu7TvlK3WqbAFJa4Mx/0+OQ+5xlhbs/ygn3/AZiSsPWdNK11XJ25jgGJw
-AucXr/kHgwJX23kFpCYB3zZE0Vh/hOqk/KlUFmptuADIDOAVst0v8MqBLZpZessN
-TXph5VBT6P51Oz/ZLC67uno02R1vUhDMB5VCyy0CgYEAoriZuuuxUXz4pw0gU0Vw
-8gICOvsuySuFHVMX5GXkTnddsaW65kuRk3WT72KLgJHVLlUAdQKZwesyLMvvonOH
-ajPL3ltRdiDmF3j2xFnxRx1TfSaJ6U+vBya/HKo4Li+9CMy8BHDh0fxLbj4pT4gT
-el2zzNDjqK6LaG976t24j6UCgYEAyTD5uRW7cIWX4Y+i4xQ7hlQwBuucHEkMKNtd
-jZL7XC+vO4qBi+U9CyUo9KjtmCc7emKbgL1xgNICWsT6ATZmSeCIxEg3hG0Ajtu5
-Dy4mRHiv/XsViA/s2sT6ZSmQNlJrx2lzWeUtPJmIvHEWThJwLw0Sh2dbavzf5DuL
-ly2FO3ECgYEA5AKnPQo45I+abEA/zKHsKHCqBPEbIaZpJJTaiInrsLiGJf+WzN4N
-zr/VAzvY+v0X5RgZmROY5ZLPVf2fTeVNzU5WzoB78hHOI67YI2Sbq7jZlatOgX4z
-Ur2BQdT0bW6VINYpDLUvS4goW5p0nQbGItdk69yyef1v3NDbCJ/Sg+Q=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIEnDCCAoSgAwIBAgIRAJzr5xxPLgDD+drzU+5p8cgwDQYJKoZIhvcNAQELBQAw
-dTEYMBYGA1UECgwPUmlzZXVwIE5ldHdvcmtzMRswGQYDVQQLDBJodHRwczovL3Jp
-c2V1cC5uZXQxPDA6BgNVBAMMM1Jpc2V1cCBOZXR3b3JrcyBSb290IENBIChjbGll
-bnQgY2VydGlmaWNhdGVzIG9ubHkhKTAeFw0xODEwMjMwMDAwMDBaFw0xOTAxMjMw
-MDAwMDBaMC0xKzApBgNVBAMMIlVOTElNSVRFRDVmbzdsMmxiY3g0OWR5ZzR5MWY4
-YXN3YXcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdNACZmz1Tp7XG
-pCpVaRvXfYAZd1o73tuxc86uspSnreEp5cPY5BuYb3ofcI6LS65tUVBPVwCam7Kb
-YI62BqFCWe/janS7YJiwGp+sIfDeJIrud/pDxFobahQi+VCPmbgNSTXB9EGAbnPS
-k3YfAVaaCF6hPRGc56VM7e9wsJpIkDo8XgxZ6GDlJxeL3CvS+JsqwA2mppvehTFw
-cRhw1wp8kpGdevInHpy0utGnVY+/ckBcueehS1DTRLR1IessQPnI/AYVXTyrhuS/
-nioVqLZw87whNF4LoGm+uKUHM6NPp+MKbObowLAGi3tpEdhxYmB+nsfZvZLtPaqG
-cLhza7qbAgMBAAGjbzBtMB0GA1UdDgQWBBRwXpI96PjilFPrkK+CHUPia++ISTAL
-BgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCQYDVR0TBAIwADAfBgNV
-HSMEGDAWgBQX9BvV5SoBAU1rol02CikJlmWARjANBgkqhkiG9w0BAQsFAAOCAgEA
-ryNFLixuicVRepocY2lTSY0cpG0eRmLuYJGupk9KeiLA5YEFzl4ZfXJLi+9UHoUR
-Bgfe6QYLBb77nO24CoeiMJQw6s593ctMLiMU++fjew31gNp6aA9DmvbLd+fNuLyO
-XObRtGw99M37cyf3ZS2SEbTBr4NBp/r3OCyUYsxPYKOzEkr9kNYa8ZZSI960i7/R
-/aiq2qemQaOQHTlmrhcBuARJoRVVlLnn2zgLSVm6ptbFLNtAk0lWriUT/WlRmn8j
-Cyn/JOuo/1wtrK1dHkaXr8bkEq1oFQzcwMN85hrZKWU0BCehELZtiUg8grqaX/sf
-/jaXD61FEqWjIXeGqY/K6ruosZCw2R8sQYzTuQNHMjxmx+J3pch7dMmJPbmA3HW2
-nA7yVp51SX8iZ26zb40S7GG6RNesU+BZxz05XVLt1GwyLx/uNxS4rFpKAT/+ifWG
-3Y1j1lMqBxx6RbuqiM1TWqU7Xtzu3hf8ytP5qP7kudXn1TyNtpZCIrzbTXbLnYiD
-nH4ZQEWGyAKBOz41eOcG6EXn0TznSGE593ueXBeFnsym7i9MjoOWNGaJ7UbkipfX
-FzxirlY5IRkWnmHCL0wGUg6YGnZ1OQ8VBBGb/dBPRMDwA7zWvoM7+3yDLR3aRaLH
-mTQzNzu3jy6CRdlpIUcPRcgbniySip1jJrHRYBui+9w=
------END CERTIFICATE-----
diff --git a/pkg/standalone/bonafide/testdata/eip-service.json b/pkg/standalone/bonafide/testdata/eip-service.json
deleted file mode 100644
index d5f2413..0000000
--- a/pkg/standalone/bonafide/testdata/eip-service.json
+++ /dev/null
@@ -1,113 +0,0 @@
-{
- "gateways": [
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ],
- "transport": [
- "openvpn"
- ],
- "user_ips": false
- },
- "host": "1.example.com",
- "ip_address": "1.1.1.1",
- "location": "a"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ],
- "transport": [
- "openvpn"
- ],
- "user_ips": false
- },
- "host": "2.example.com",
- "ip_address": "2.2.2.2",
- "location": "b"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ],
- "transport": [
- "openvpn"
- ],
- "user_ips": false
- },
- "host": "3.example.com",
- "ip_address": "3.3.3.3",
- "location": "b"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ],
- "transport": [
- "openvpn"
- ],
- "user_ips": false
- },
- "host": "4.example.com",
- "ip_address": "4.4.4.4",
- "location": "c"
- }
- ],
- "locations": {
- "a": {
- "country_code": "AA",
- "hemisphere": "N",
- "name": "a",
- "timezone": "-5"
- },
- "b": {
- "country_code": "BB",
- "hemisphere": "S",
- "name": "b",
- "timezone": "+1"
- },
- "c": {
- "country_code": "CC",
- "hemisphere": "N",
- "name": "c",
- "timezone": "+8"
- }
- },
- "openvpn_configuration": {
- "auth": "SHA1",
- "cipher": "AES-128-CBC",
- "keepalive": "10 30",
- "tls-cipher": "DHE-RSA-AES128-SHA",
- "tun-ipv6": true
- },
- "serial": 1,
- "version": 1
-}
diff --git a/pkg/standalone/bonafide/testdata/eip-service3.json b/pkg/standalone/bonafide/testdata/eip-service3.json
deleted file mode 100644
index cefd6c0..0000000
--- a/pkg/standalone/bonafide/testdata/eip-service3.json
+++ /dev/null
@@ -1,173 +0,0 @@
-{
- "gateways": [
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "transport": [
- {
- "type": "openvpn",
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ]
- },
- {
- "type": "obfs4",
- "ports": [
- "2345"
- ],
- "protocols": [
- "tcp"
- ],
- "options": {
- "cert": "obfs-cert",
- "iat-mode": "0"
- }
- }
- ],
- "user_ips": false
- },
- "host": "1.example.com",
- "ip_address": "1.1.1.1",
- "location": "a"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "transport": [
- {
- "type": "openvpn",
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ]
- }
- ],
- "user_ips": false
- },
- "host": "2.example.com",
- "ip_address": "2.2.2.2",
- "location": "b"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "transport": [
- {
- "type": "openvpn",
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ]
- },
- {
- "type": "obfs4",
- "ports": [
- "2345"
- ],
- "protocols": [
- "tcp"
- ],
- "options": {
- "cert": "obfs-cert",
- "iat-mode": "0"
- }
- }
- ],
- "user_ips": false
- },
- "host": "3.example.com",
- "ip_address": "3.3.3.3",
- "location": "b"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "transport": [
- {
- "type": "openvpn",
- "ports": [
- "443"
- ],
- "protocols": [
- "tcp"
- ]
- }
- ],
- "user_ips": false
- },
- "host": "4.example.com",
- "ip_address": "4.4.4.4",
- "location": "c"
- },
- {
- "capabilities": {
- "adblock": false,
- "filter_dns": false,
- "limited": false,
- "transport": [
- {
- "type": "obfs4",
- "ports": [
- "2345"
- ],
- "protocols": [
- "tcp"
- ],
- "options": {
- "cert": "obfs-cert",
- "iat-mode": "0"
- }
- }
- ],
- "user_ips": false
- },
- "host": "5.example.com",
- "ip_address": "5.5.5.5",
- "location": "c"
- }
- ],
- "locations": {
- "a": {
- "country_code": "AA",
- "hemisphere": "N",
- "name": "a",
- "timezone": "-5"
- },
- "b": {
- "country_code": "BB",
- "hemisphere": "S",
- "name": "b",
- "timezone": "+1"
- },
- "c": {
- "country_code": "CC",
- "hemisphere": "N",
- "name": "c",
- "timezone": "+8"
- }
- },
- "openvpn_configuration": {
- "auth": "SHA1",
- "cipher": "AES-128-CBC",
- "keepalive": "10 30",
- "tls-cipher": "DHE-RSA-AES128-SHA",
- "tun-ipv6": true
- },
- "serial": 1,
- "version": 3
-}
diff --git a/pkg/standalone/launcher.go b/pkg/standalone/launcher.go
deleted file mode 100644
index 621ba4c..0000000
--- a/pkg/standalone/launcher.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// +build !linux
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package standalone
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "strconv"
- "strings"
- "time"
-
- "0xacab.org/leap/bitmask-vpn/pkg/config"
- "0xacab.org/leap/bitmask-vpn/pkg/standalone/bonafide"
-)
-
-type launcher struct {
- helperAddr string
-}
-
-const initialHelperPort = 7171
-
-func probeHelperPort(port int) int {
- // this should be enough for a local reply
- timeout := time.Duration(500 * time.Millisecond)
- c := http.Client{Timeout: timeout}
- for {
- if smellsLikeOurHelperSpirit(port, &c) {
- return port
- }
- port++
- if port > 65535 {
- break
- }
- }
- return 0
-}
-
-func smellsLikeOurHelperSpirit(port int, c *http.Client) bool {
- uri := "http://localhost:" + strconv.Itoa(port) + "/version"
- log.Println("probing for helper at", uri)
- resp, err := c.Get(uri)
- if err != nil {
- return false
- }
- if resp.StatusCode == 200 {
- ver, err := ioutil.ReadAll(resp.Body)
- defer resp.Body.Close()
- if err != nil {
- return false
- }
- if strings.Contains(string(ver), config.ApplicationName) {
- return true
- } else {
- log.Println("Another helper replied to our version request:", string(ver))
- }
- }
- return false
-}
-
-func newLauncher() (*launcher, error) {
- helperPort := probeHelperPort(initialHelperPort)
- helperAddr := "http://localhost:" + strconv.Itoa(helperPort)
- return &launcher{helperAddr}, nil
-}
-
-func (l *launcher) close() error {
- return nil
-}
-
-func (l *launcher) check() (helpers bool, priviledge bool, err error) {
- return true, true, nil
-}
-
-func (l *launcher) openvpnStart(flags ...string) error {
- byteFlags, err := json.Marshal(flags)
- if err != nil {
- return err
- }
- return l.send("/openvpn/start", byteFlags)
-}
-
-func (l *launcher) openvpnStop() error {
- return l.send("/openvpn/stop", nil)
-}
-
-func (l *launcher) firewallStart(gateways []bonafide.Gateway) error {
- ipList := make([]string, len(gateways))
- for i, gw := range gateways {
- ipList[i] = gw.IPAddress
- }
- byteIPs, err := json.Marshal(ipList)
- if err != nil {
- return err
- }
- return l.send("/firewall/start", byteIPs)
-}
-
-func (l *launcher) firewallStop() error {
- return l.send("/firewall/stop", nil)
-}
-
-func (l *launcher) firewallIsUp() bool {
- var isup bool = false
- res, err := http.Post(l.helperAddr+"/firewall/isup", "", nil)
- if err != nil {
- return false
- }
- defer res.Body.Close()
-
- if res.StatusCode != http.StatusOK {
- fmt.Printf("Got an error status code for firewall/isup: %v\n", res.StatusCode)
- isup = false
- } else {
- upStr, err := ioutil.ReadAll(res.Body)
- if err != nil {
- fmt.Errorf("Error getting body for firewall/isup: %q", err)
- return false
- }
- isup, err = strconv.ParseBool(string(upStr))
- if err != nil {
- fmt.Errorf("Error parsing body for firewall/isup: %q", err)
- return false
- }
- }
- return isup
-}
-
-func (l *launcher) send(path string, body []byte) error {
- var reader io.Reader
- if body != nil {
- reader = bytes.NewReader(body)
- }
- res, err := http.Post(l.helperAddr+path, "", reader)
- if err != nil {
- return err
- }
- defer res.Body.Close()
-
- resErr, err := ioutil.ReadAll(res.Body)
- if len(resErr) > 0 {
- return fmt.Errorf("Helper returned an error: %q", resErr)
- }
- return err
-}
diff --git a/pkg/standalone/launcher_linux.go b/pkg/standalone/launcher_linux.go
deleted file mode 100644
index 5b66415..0000000
--- a/pkg/standalone/launcher_linux.go
+++ /dev/null
@@ -1,224 +0,0 @@
-// +build linux
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package standalone
-
-import (
- "errors"
- "log"
- "os"
- "os/exec"
- "strings"
-
- "0xacab.org/leap/bitmask-vpn/pkg/config"
- "0xacab.org/leap/bitmask-vpn/pkg/standalone/bonafide"
- "github.com/keybase/go-ps"
-)
-
-const (
- systemOpenvpnPath = "/usr/sbin/openvpn"
- snapOpenvpnPath = "/snap/bin/" + config.BinaryName + ".openvpn"
- snapBitmaskRootPath = "/snap/bin/" + config.BinaryName + ".bitmask-root"
-)
-
-var bitmaskRootPaths = []string{
- "/usr/sbin/bitmask-root",
- "/usr/local/sbin/bitmask-root",
-}
-
-type launcher struct {
- openvpnCh chan []string
-}
-
-func newLauncher() (*launcher, error) {
- l := launcher{make(chan []string, 1)}
- go l.openvpnRunner()
- return &l, nil
-}
-
-func (l *launcher) close() error {
- return nil
-}
-
-func (l *launcher) check() (helpers bool, priviledge bool, err error) {
-
- /*
- isRunning, err := isPolkitRunning()
- if err != nil {
- return
- }
- if !isRunning {
- polkitPath := getPolkitPath()
- if polkitPath == "" {
- return true, false, nil
- }
- cmd := exec.Command("setsid", polkitPath)
- err = cmd.Start()
- if err != nil {
- return
- }
- isRunning, err = isPolkitRunning()
- return true, isRunning, err
- }
- */
-
- return true, true, nil
-}
-
-func isPolkitRunning() (bool, error) {
- var polkitProcNames = [...]string{
- "polkit-gnome-authentication-agent-1",
- "polkit-kde-authentication-agent-1",
- "polkit-mate-authentication-agent-1",
- "lxpolkit",
- "lxsession",
- "gnome-shell",
- "gnome-flashback",
- "fingerprint-polkit-agent",
- "xfce-polkit",
- }
-
- processes, err := ps.Processes()
- if err != nil {
- return false, err
- }
-
- for _, proc := range processes {
- executable := proc.Executable()
- for _, name := range polkitProcNames {
- if strings.Contains(executable, name) {
- return true, nil
- }
- }
- }
- return false, nil
-}
-
-func getPolkitPath() string {
- var polkitPaths = [...]string{
- "/usr/bin/lxpolkit",
- "/usr/bin/lxqt-policykit-agent",
- "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1",
- "/usr/lib/x86_64-linux-gnu/polkit-mate/polkit-mate-authentication-agent-1",
- "/usr/lib/mate-polkit/polkit-mate-authentication-agent-1",
- "/usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1",
- "/usr/lib/kde4/libexec/polkit-kde-authentication-agent-1",
- // now we get weird
- "/usr/libexec/policykit-1-pantheon/pantheon-agent-polkit",
- "/usr/lib/polkit-1-dde/dde-polkit-agent",
- // do you know some we"re still missing? :)
- }
-
- for _, polkit := range polkitPaths {
- _, err := os.Stat(polkit)
- if err == nil {
- return polkit
- }
- }
- return ""
-}
-
-func (l *launcher) openvpnStart(flags ...string) error {
- log.Println("openvpn start: ", flags)
- arg := []string{"openvpn", "start", getOpenvpnPath()}
- arg = append(arg, flags...)
- l.openvpnCh <- arg
- return nil
-}
-
-func (l *launcher) openvpnStop() error {
- l.openvpnCh <- nil
- log.Println("openvpn stop")
- return runBitmaskRoot("openvpn", "stop")
-}
-
-func (l *launcher) firewallStart(gateways []bonafide.Gateway) error {
- log.Println("firewall start")
- arg := []string{"firewall", "start"}
- for _, gw := range gateways {
- arg = append(arg, gw.IPAddress)
- }
- return runBitmaskRoot(arg...)
-}
-
-func (l *launcher) firewallStop() error {
- log.Println("firewall stop")
- return runBitmaskRoot("firewall", "stop")
-}
-
-func (l *launcher) firewallIsUp() bool {
- err := runBitmaskRoot("firewall", "isup")
- return err == nil
-}
-
-func (l *launcher) openvpnRunner(arg ...string) {
- running := false
- runOpenvpn := func(arg []string) {
- for running {
- err := runBitmaskRoot(arg...)
- if err != nil {
- log.Printf("An error ocurred running openvpn: %v", err)
- }
- }
- }
-
- for arg := range l.openvpnCh {
- if arg == nil {
- running = false
- } else {
- running = true
- go runOpenvpn(arg)
- }
- }
-}
-
-func runBitmaskRoot(arg ...string) error {
- bitmaskRoot, err := bitmaskRootPath()
- if err != nil {
- return err
- }
- arg = append([]string{bitmaskRoot}, arg...)
-
- out, err := exec.Command("pkexec", arg...).Output()
- if err != nil && arg[2] != "isup" {
- log.Println("Error while running bitmask-root:")
- log.Println("args: ", arg)
- log.Println("output: ", string(out))
- }
- return err
-}
-
-func bitmaskRootPath() (string, error) {
- if os.Getenv("SNAP") != "" {
- path := snapBitmaskRootPath
- if _, err := os.Stat(path); !os.IsNotExist(err) {
- return path, nil
- }
- }
- for _, path := range bitmaskRootPaths {
- if _, err := os.Stat(path); !os.IsNotExist(err) {
- return path, nil
- }
- }
- return "", errors.New("No bitmask-root found")
-}
-
-func getOpenvpnPath() string {
- if os.Getenv("SNAP") != "" {
- return snapOpenvpnPath
- }
- return systemOpenvpnPath
-}
diff --git a/pkg/standalone/main.go b/pkg/standalone/main.go
deleted file mode 100644
index 4ac5776..0000000
--- a/pkg/standalone/main.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package standalone
-
-import (
- "io/ioutil"
- "log"
- "os"
-
- "0xacab.org/leap/bitmask-vpn/pkg/config"
- "0xacab.org/leap/bitmask-vpn/pkg/standalone/bonafide"
- "0xacab.org/leap/shapeshifter"
- "github.com/apparentlymart/go-openvpn-mgmt/openvpn"
-)
-
-// Bitmask holds the bitmask client data
-type Bitmask struct {
- tempdir string
- statusCh chan string
- managementClient *openvpn.MgmtClient
- bonafide *bonafide.Bonafide
- launch *launcher
- transport string
- shapes *shapeshifter.ShapeShifter
-}
-
-// Init the connection to bitmask
-func Init() (*Bitmask, error) {
- statusCh := make(chan string, 10)
- tempdir, err := ioutil.TempDir("", "leap-")
- if err != nil {
- return nil, err
- }
- bonafide := bonafide.New()
- launch, err := newLauncher()
- if err != nil {
- return nil, err
- }
- b := Bitmask{tempdir, statusCh, nil, bonafide, launch, "", nil}
-
- err = b.StopVPN()
- if err != nil {
- return nil, err
- }
- err = ioutil.WriteFile(b.getCaCertPath(), config.CaCert, 0600)
-
- go b.openvpnManagement()
- return &b, err
-}
-
-// GetStatusCh returns a channel that will recieve VPN status changes
-func (b *Bitmask) GetStatusCh() <-chan string {
- return b.statusCh
-}
-
-// Close the connection to bitmask
-func (b *Bitmask) Close() {
- log.Printf("Close: cleanup and vpn shutdown...")
- b.StopVPN()
- err := b.launch.close()
- if err != nil {
- log.Printf("There was an error closing the launcher: %v", err)
- }
- err = os.RemoveAll(b.tempdir)
- if err != nil {
- log.Printf("There was an error removing temp dir: %v", err)
- }
-}
-
-// Version gets the bitmask version string
-func (b *Bitmask) Version() (string, error) {
- return "", nil
-}
diff --git a/pkg/standalone/status.go b/pkg/standalone/status.go
deleted file mode 100644
index 96177e1..0000000
--- a/pkg/standalone/status.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package standalone
-
-import (
- "fmt"
- "log"
-
- "github.com/apparentlymart/go-openvpn-mgmt/openvpn"
-)
-
-const (
- On = "on"
- Off = "off"
- Starting = "starting"
- Stopping = "stopping"
- Failed = "failed"
-)
-
-var statusNames = map[string]string{
- "CONNECTING": Starting,
- "WAIT": Starting,
- "AUTH": Starting,
- "GET_CONFIG": Starting,
- "ASSIGN_IP": Starting,
- "ADD_ROUTES": Starting,
- "CONNECTED": On,
- "RECONNECTING": Starting,
- "EXITING": Stopping,
- "OFF": Off,
- "FAILED": Off,
-}
-
-func (b *Bitmask) openvpnManagement() {
- // TODO: we should warn the user on ListenAndServe errors
- newConnection := func(conn openvpn.IncomingConn) {
- eventCh := make(chan openvpn.Event, 10)
- log.Println("New connection into the management")
- b.managementClient = conn.Open(eventCh)
- b.managementClient.SetStateEvents(true)
- b.eventHandler(eventCh)
- }
- log.Fatal(openvpn.ListenAndServe(
- fmt.Sprintf("%s:%s", openvpnManagementAddr, openvpnManagementPort),
- openvpn.IncomingConnHandlerFunc(newConnection),
- ))
-}
-
-func (b *Bitmask) eventHandler(eventCh <-chan openvpn.Event) {
- for event := range eventCh {
- log.Printf("Event: %v", event)
- stateEvent, ok := event.(*openvpn.StateEvent)
- if !ok {
- continue
- }
- status, ok := statusNames[stateEvent.NewState()]
- if ok {
- b.statusCh <- status
- }
- }
- b.statusCh <- Off
-}
-
-func (b *Bitmask) getOpenvpnState() (string, error) {
- if b.managementClient == nil {
- return "", fmt.Errorf("No management connected")
- }
- stateEvent, err := b.managementClient.LatestState()
- if err != nil {
- return "", err
- }
- status, ok := statusNames[stateEvent.NewState()]
- if !ok {
- return "", fmt.Errorf("Unkonw status")
- }
- return status, nil
-}
diff --git a/pkg/standalone/vpn.go b/pkg/standalone/vpn.go
deleted file mode 100644
index 4682a47..0000000
--- a/pkg/standalone/vpn.go
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright (C) 2018 LEAP
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package standalone
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "path"
- "strconv"
- "strings"
-
- "0xacab.org/leap/shapeshifter"
-)
-
-const (
- openvpnManagementAddr = "127.0.0.1"
- openvpnManagementPort = "6061"
-)
-
-// StartVPN for provider
-func (b *Bitmask) StartVPN(provider string) error {
- var proxy string
- if b.transport != "" {
- var err error
- proxy, err = b.startTransport()
- if err != nil {
- return err
- }
- }
-
- return b.startOpenVPN(proxy)
-}
-
-func (b *Bitmask) startTransport() (proxy string, err error) {
- proxy = "127.0.0.1:4430"
- if b.shapes != nil {
- return proxy, nil
- }
-
- gateways, err := b.bonafide.GetGateways(b.transport)
- if err != nil {
- return "", err
- }
- if len(gateways) == 0 {
- log.Printf("No gateway for transport %s in provider", b.transport)
- return "", nil
- }
-
- for _, gw := range gateways {
- if _, ok := gw.Options["cert"]; !ok {
- continue
- }
- b.shapes = &shapeshifter.ShapeShifter{
- Cert: gw.Options["cert"],
- Target: gw.IPAddress + ":" + gw.Ports[0],
- SocksAddr: proxy,
- }
- go b.listenShapeErr()
- if iatMode, ok := gw.Options["iat-mode"]; ok {
- b.shapes.IatMode, err = strconv.Atoi(iatMode)
- if err != nil {
- b.shapes.IatMode = 0
- }
- }
- err = b.shapes.Open()
- if err != nil {
- log.Printf("Can't connect to transport %s: %v", b.transport, err)
- continue
- }
- return proxy, nil
- }
- return "", fmt.Errorf("No working gateway for transport %s: %v", b.transport, err)
-}
-
-func (b *Bitmask) listenShapeErr() {
- ch := b.shapes.GetErrorChannel()
- for {
- err, more := <-ch
- if !more {
- return
- }
- log.Printf("Error from shappeshifter: %v", err)
- }
-}
-
-func (b *Bitmask) startOpenVPN(proxy string) error {
- certPemPath, err := b.getCert()
- if err != nil {
- return err
- }
- arg, err := b.bonafide.GetOpenvpnArgs()
- if err != nil {
- return err
- }
-
- if proxy == "" {
- gateways, err := b.bonafide.GetGateways("openvpn")
- if err != nil {
- return err
- }
- err = b.launch.firewallStart(gateways)
- if err != nil {
- return err
- }
-
- for _, gw := range gateways {
- for _, port := range gw.Ports {
- arg = append(arg, "--remote", gw.IPAddress, port, "tcp4")
- }
- }
- } else {
- gateways, err := b.bonafide.GetGateways(b.transport)
- if err != nil {
- return err
- }
- err = b.launch.firewallStart(gateways)
- if err != nil {
- return err
- }
-
- proxyArgs := strings.Split(proxy, ":")
- arg = append(arg, "--remote", proxyArgs[0], proxyArgs[1], "tcp4")
- }
- arg = append(arg,
- "--verb", "1",
- "--management-client",
- "--management", openvpnManagementAddr, openvpnManagementPort,
- "--ca", b.getCaCertPath(),
- "--cert", certPemPath,
- "--key", certPemPath)
- return b.launch.openvpnStart(arg...)
-}
-
-func (b *Bitmask) getCert() (certPath string, err error) {
- certPath = b.getCertPemPath()
-
- if _, err := os.Stat(certPath); os.IsNotExist(err) {
- cert, err := b.bonafide.GetCertPem()
- if err != nil {
- return "", err
- }
- err = ioutil.WriteFile(certPath, cert, 0600)
- }
-
- return certPath, err
-}
-
-// StopVPN or cancel
-func (b *Bitmask) StopVPN() error {
- err := b.launch.firewallStop()
- if err != nil {
- return err
- }
- if b.shapes != nil {
- b.shapes.Close()
- b.shapes = nil
- }
- return b.launch.openvpnStop()
-}
-
-// ReloadFirewall restarts the firewall
-func (b *Bitmask) ReloadFirewall() error {
- err := b.launch.firewallStop()
- if err != nil {
- return err
- }
-
- status, err := b.GetStatus()
- if err != nil {
- return err
- }
-
- if status != Off {
- gateways, err := b.bonafide.GetGateways("openvpn")
- if err != nil {
- return err
- }
- return b.launch.firewallStart(gateways)
- }
- return nil
-}
-
-// GetStatus returns the VPN status
-func (b *Bitmask) GetStatus() (string, error) {
- status, err := b.getOpenvpnState()
- if err != nil {
- status = Off
- }
- if status == Off && b.launch.firewallIsUp() {
- return Failed, nil
- }
- return status, nil
-}
-
-// InstallHelpers into the system
-func (b *Bitmask) InstallHelpers() error {
- // TODO
- return nil
-}
-
-// VPNCheck returns if the helpers are installed and up to date and if polkit is running
-func (b *Bitmask) VPNCheck() (helpers bool, priviledge bool, err error) {
- return b.launch.check()
-}
-
-// ListGateways return the names of the gateways
-func (b *Bitmask) ListGateways(provider string) ([]string, error) {
- gateways, err := b.bonafide.GetGateways("openvpn")
- if err != nil {
- return nil, err
- }
- gatewayNames := make([]string, len(gateways))
- for i, gw := range gateways {
- gatewayNames[i] = gw.Location
- }
- return gatewayNames, nil
-}
-
-// UseGateway selects name as the default gateway
-func (b *Bitmask) UseGateway(name string) error {
- b.bonafide.SetDefaultGateway(name)
- return nil
-}
-
-// UseTransport selects an obfuscation transport to use
-func (b *Bitmask) UseTransport(transport string) error {
- if transport != "obfs4" {
- return fmt.Errorf("Transport %s not implemented", transport)
- }
- b.transport = transport
- return nil
-}
-
-func (b *Bitmask) getCertPemPath() string {
- return path.Join(b.tempdir, "openvpn.pem")
-}
-
-func (b *Bitmask) getCaCertPath() string {
- return path.Join(b.tempdir, "cacert.pem")
-}