summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2018-06-13 20:48:27 +0200
committerRuben Pollan <meskio@sindominio.net>2018-06-20 12:18:17 +0200
commit37413f5eb2b8d4719c959db03874cc9bcc362ddc (patch)
treebd14bf1489da7b0da030015d2d9ff112c1b2b833
parentd4f013fee611299aea7f8cfff0377ba8646ba17d (diff)
[feat] get openvpn args/gateways from the eip-service.json
-rw-r--r--bitmask_go/bonafide.go94
-rw-r--r--bitmask_go/bonafide_test.go22
-rw-r--r--bitmask_go/launcher_linux.go6
-rw-r--r--bitmask_go/main.go6
-rw-r--r--bitmask_go/vpn.go22
5 files changed, 130 insertions, 20 deletions
diff --git a/bitmask_go/bonafide.go b/bitmask_go/bonafide.go
index 25fa302..cc94b25 100644
--- a/bitmask_go/bonafide.go
+++ b/bitmask_go/bonafide.go
@@ -18,13 +18,16 @@ package bitmask
import (
"crypto/tls"
"crypto/x509"
+ "encoding/json"
"fmt"
"io/ioutil"
+ "log"
"net/http"
)
const (
certAPI = "https://api.black.riseup.net/1/cert"
+ eipAPI = "https://api.black.riseup.net/1/config/eip-service.json"
)
var (
@@ -62,7 +65,33 @@ UN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp
-----END CERTIFICATE-----`)
)
-func getCertPem() ([]byte, error) {
+type bonafide struct {
+ client *http.Client
+ eip *eipService
+}
+
+type eipService struct {
+ Gateways []gateway
+ Locations map[string]struct {
+ CountryCode string
+ Hemisphere string
+ Name string
+ Timezone string
+ }
+ OpenvpnConfiguration map[string]interface{} `json:"openvpn_configuration"`
+}
+
+type gateway struct {
+ Capabilities struct {
+ Ports []string
+ Protocols []string
+ }
+ Host string
+ IPAddress string `json:"ip_address"`
+ Location string
+}
+
+func newBonafide() *bonafide {
certs := x509.NewCertPool()
certs.AppendCertsFromPEM(caCert)
client := &http.Client{
@@ -73,15 +102,74 @@ func getCertPem() ([]byte, error) {
},
}
- resp, err := client.Post(certAPI, "", nil)
+ return &bonafide{client, nil}
+}
+
+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 != 200 {
return nil, fmt.Errorf("get vpn cert has failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
+
+func (b *bonafide) getGateways() ([]gateway, error) {
+ if b.eip == nil {
+ err := b.fetchEipJSON()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return b.eip.Gateways, nil
+}
+
+func (b *bonafide) getOpenvpnArgs() ([]string, error) {
+ if b.eip == nil {
+ err := b.fetchEipJSON()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ args := []string{}
+ for arg, value := range b.eip.OpenvpnConfiguration {
+ switch v := value.(type) {
+ case string:
+ args = append(args, "--"+arg, v)
+ case bool:
+ if v {
+ args = append(args, "--"+arg)
+ }
+ default:
+ log.Printf("Uknwon openvpn argument type: %s - %v", arg, value)
+ }
+ }
+ return args, nil
+}
+
+func (b *bonafide) fetchEipJSON() error {
+ resp, err := b.client.Post(eipAPI, "", nil)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != 200 {
+ return fmt.Errorf("get vpn cert has failed with status: %s", resp.Status)
+ }
+
+ var eip eipService
+ decoder := json.NewDecoder(resp.Body)
+ err = decoder.Decode(&eip)
+ if err != nil {
+ return err
+ }
+
+ b.eip = &eip
+ return nil
+}
diff --git a/bitmask_go/bonafide_test.go b/bitmask_go/bonafide_test.go
index c40c98d..152b108 100644
--- a/bitmask_go/bonafide_test.go
+++ b/bitmask_go/bonafide_test.go
@@ -11,16 +11,32 @@ var (
)
func TestGetCert(t *testing.T) {
- cert, err := getCertPem()
+ b := newBonafide()
+ cert, err := b.getCertPem()
if err != nil {
- t.Fatal("get_cert returned an error: ", err)
+ t.Fatal("getCert returned an error: ", err)
}
if !bytes.Contains(cert, privateKeyHeader) {
t.Errorf("No private key present: \n%q", cert)
}
- if !bytes.Equal(cert, certHeader) {
+ if !bytes.Contains(cert, certHeader) {
t.Errorf("No cert present: \n%q", cert)
}
}
+
+func TestGetGateways(t *testing.T) {
+ b := newBonafide()
+ gateways, err := b.getGateways()
+ if err != nil {
+ t.Fatal("getGateways returned an error: ", err)
+ }
+
+ for _, gw := range gateways {
+ if gw.IPAddress == "5.79.86.180" {
+ return
+ }
+ }
+ t.Errorf("5.79.86.180 not in the list")
+}
diff --git a/bitmask_go/launcher_linux.go b/bitmask_go/launcher_linux.go
index 6a1407c..12bd1cb 100644
--- a/bitmask_go/launcher_linux.go
+++ b/bitmask_go/launcher_linux.go
@@ -58,10 +58,12 @@ func (l *launcher) openvpnStop() error {
return runBitmaskRoot("openvpn", "stop")
}
-func (l *launcher) firewallStart(gateways []string) error {
+func (l *launcher) firewallStart(gateways []gateway) error {
log.Println("firewall start")
arg := []string{"firewall", "start"}
- arg = append(arg, gateways...)
+ for _, gw := range gateways {
+ arg = append(arg, gw.IPAddress)
+ }
return runBitmaskRoot(arg...)
}
diff --git a/bitmask_go/main.go b/bitmask_go/main.go
index 6b60d43..fee4a42 100644
--- a/bitmask_go/main.go
+++ b/bitmask_go/main.go
@@ -28,6 +28,7 @@ type Bitmask struct {
tempdir string
statusCh chan string
managementClient *openvpn.MgmtClient
+ bonafide *bonafide
launch *launcher
}
@@ -38,15 +39,16 @@ func Init() (*Bitmask, error) {
if err != nil {
return nil, err
}
+ bonafide := newBonafide()
launch := newLauncher()
- b := Bitmask{tempdir, statusCh, nil, launch}
+ b := Bitmask{tempdir, statusCh, nil, bonafide, launch}
err = b.StopVPN()
if err != nil {
return nil, err
}
- cert, err := getCertPem()
+ cert, err := b.bonafide.getCertPem()
if err != nil {
return nil, err
}
diff --git a/bitmask_go/vpn.go b/bitmask_go/vpn.go
index 2e69368..041a8e4 100644
--- a/bitmask_go/vpn.go
+++ b/bitmask_go/vpn.go
@@ -24,26 +24,28 @@ const (
openvpnManagementPort = "6061"
)
-var gateways = []string{
- "5.79.86.180",
- "199.58.81.145",
- "198.252.153.28",
-}
-
// StartVPN for provider
func (b *Bitmask) StartVPN(provider string) error {
- // TODO: openvpn args are hardcoded
- err := b.launch.firewallStart(gateways)
+ gateways, err := b.bonafide.getGateways()
+ if err != nil {
+ return err
+ }
+ err = b.launch.firewallStart(gateways)
if err != nil {
return err
}
arg := []string{"--nobind", "--verb", "1"}
+ bonafideArgs, err := b.bonafide.getOpenvpnArgs()
+ if err != nil {
+ return err
+ }
+ arg = append(arg, bonafideArgs...)
for _, gw := range gateways {
- arg = append(arg, "--remote", gw, "443", "tcp4")
+ arg = append(arg, "--remote", gw.IPAddress, "443", "tcp4")
}
certPemPath := b.getCertPemPath()
- arg = append(arg, "--client", "--tls-client", "--remote-cert-tls", "server", "--tls-cipher", "DHE-RSA-AES128-SHA", "--cipher", "AES-128-CBC", "--tun-ipv6", "--auth", "SHA1", "--keepalive", "10 30", "--management-client", "--management", openvpnManagementAddr+" "+openvpnManagementPort, "--ca", b.getCaCertPath(), "--cert", certPemPath, "--key", certPemPath)
+ arg = append(arg, "--client", "--tls-client", "--remote-cert-tls", "server", "--management-client", "--management", openvpnManagementAddr+" "+openvpnManagementPort, "--ca", b.getCaCertPath(), "--cert", certPemPath, "--key", certPemPath)
return b.launch.openvpnStart(arg...)
}