summaryrefslogtreecommitdiff
path: root/pkg/standalone
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/standalone')
-rw-r--r--pkg/standalone/bonafide/bonafide.go8
-rw-r--r--pkg/standalone/bonafide/eip_service.go7
-rw-r--r--pkg/standalone/main.go5
-rw-r--r--pkg/standalone/vpn.go106
4 files changed, 116 insertions, 10 deletions
diff --git a/pkg/standalone/bonafide/bonafide.go b/pkg/standalone/bonafide/bonafide.go
index bdf6fff..fd32f2a 100644
--- a/pkg/standalone/bonafide/bonafide.go
+++ b/pkg/standalone/bonafide/bonafide.go
@@ -31,6 +31,7 @@ import (
const (
certAPI = config.APIURL + "1/cert"
+ certAPI3 = config.APIURL + "3/cert"
secondsPerHour = 60 * 60
retryFetchJSONSeconds = 15
)
@@ -91,6 +92,13 @@ func (b *Bonafide) GetCertPem() ([]byte, error) {
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)
}
diff --git a/pkg/standalone/bonafide/eip_service.go b/pkg/standalone/bonafide/eip_service.go
index 94e303d..c097e8a 100644
--- a/pkg/standalone/bonafide/eip_service.go
+++ b/pkg/standalone/bonafide/eip_service.go
@@ -78,11 +78,17 @@ func (b *Bonafide) fetchEipJSON() error {
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:
@@ -108,6 +114,7 @@ func decodeEIP1(body io.Reader) (*eipService, error) {
decoder := json.NewDecoder(body)
err := decoder.Decode(&eip1)
if err != nil {
+ log.Printf("Error fetching eip v1 json: %v", err)
return nil, err
}
diff --git a/pkg/standalone/main.go b/pkg/standalone/main.go
index e19634c..6c267d6 100644
--- a/pkg/standalone/main.go
+++ b/pkg/standalone/main.go
@@ -22,6 +22,7 @@ import (
"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"
)
@@ -32,6 +33,8 @@ type Bitmask struct {
managementClient *openvpn.MgmtClient
bonafide *bonafide.Bonafide
launch *launcher
+ transport string
+ shapes *shapeshifter.ShapeShifter
}
// Init the connection to bitmask
@@ -46,7 +49,7 @@ func Init() (*Bitmask, error) {
if err != nil {
return nil, err
}
- b := Bitmask{tempdir, statusCh, nil, bonafide, launch}
+ b := Bitmask{tempdir, statusCh, nil, bonafide, launch, "", nil}
err = b.StopVPN()
if err != nil {
diff --git a/pkg/standalone/vpn.go b/pkg/standalone/vpn.go
index 260eec1..e593f59 100644
--- a/pkg/standalone/vpn.go
+++ b/pkg/standalone/vpn.go
@@ -16,9 +16,15 @@
package standalone
import (
+ "fmt"
"io/ioutil"
+ "log"
"os"
"path"
+ "strconv"
+ "strings"
+
+ "0xacab.org/leap/shapeshifter"
)
const (
@@ -28,26 +34,95 @@ const (
// StartVPN for provider
func (b *Bitmask) StartVPN(provider string) error {
- gateways, err := b.bonafide.GetGateways("openvpn")
- if err != nil {
- return err
+ var proxy string
+ if b.transport != "" {
+ var err error
+ proxy, err = b.startTransport()
+ if err != nil {
+ return err
+ }
}
- certPemPath, err := b.getCert()
+
+ 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
+ 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,
+ }
+ 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)
+}
- err = b.launch.firewallStart(gateways)
+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
}
- for _, gw := range gateways {
- arg = append(arg, "--remote", gw.IPAddress, "443", "tcp4")
+
+ 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",
@@ -79,6 +154,10 @@ func (b *Bitmask) StopVPN() error {
if err != nil {
return err
}
+ if b.shapes != nil {
+ b.shapes.Close()
+ b.shapes = nil
+ }
return b.launch.openvpnStop()
}
@@ -146,6 +225,15 @@ func (b *Bitmask) UseGateway(name string) error {
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")
}