diff options
Diffstat (limited to 'pkg/standalone')
-rw-r--r-- | pkg/standalone/bonafide/bonafide.go | 8 | ||||
-rw-r--r-- | pkg/standalone/bonafide/eip_service.go | 7 | ||||
-rw-r--r-- | pkg/standalone/main.go | 5 | ||||
-rw-r--r-- | pkg/standalone/vpn.go | 106 |
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") } |