From 3fdbb895b8372caa080044cade00f2de6b00ce91 Mon Sep 17 00:00:00 2001
From: "kali kaneko (leap communications)" <kali@leap.se>
Date: Mon, 31 May 2021 02:34:21 +0200
Subject: [PATCH] [feat] obfs4 selectable from gui

---
 docs/circumvention.rst  |  3 +--
 gui/backend.go          |  6 +++---
 gui/handlers.cpp        |  4 ++--
 gui/handlers.h          |  2 +-
 gui/qml/BridgesItem.qml |  9 +++++++--
 gui/qml/main.qml        |  8 ++++++++
 pkg/backend/actions.go  |  5 ++---
 pkg/backend/api.go      |  4 ++--
 pkg/bitmask/bitmask.go  |  1 -
 pkg/bitmask/init.go     |  2 +-
 pkg/vpn/openvpn.go      | 29 +++++++++++++++--------------
 11 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/docs/circumvention.rst b/docs/circumvention.rst
index ee31e58a..d72497d6 100644
--- a/docs/circumvention.rst
+++ b/docs/circumvention.rst
@@ -19,8 +19,7 @@ Obfuscated bridges
 -----------------------------
 
 At the moment RiseupVPN offers obfs4 transport "bridges" (you can try them with
-the `--obfs4` command line argument, a way to enable them from the gui will be
-following soon).
+the `--obfs4` command line argument, or by checking the "use obfs4 bridges" checkbox on the preferences panel.
 
 If you know you need bridges but the current ones do not work for you, please
 get in contact. We're interested in learning what are the specific censorship
diff --git a/gui/backend.go b/gui/backend.go
index 38f40a84..04d1293a 100644
--- a/gui/backend.go
+++ b/gui/backend.go
@@ -43,9 +43,9 @@ func UseAutomaticGateway() {
 	backend.UseAutomaticGateway()
 }
 
-//export UseTransport
-func UseTransport(transport string) {
-	backend.UseTransport(transport)
+//export SetTransport
+func SetTransport(transport string) {
+	backend.SetTransport(string(transport))
 }
 
 //export GetTransport
diff --git a/gui/handlers.cpp b/gui/handlers.cpp
index cec43cab..29fecf1a 100644
--- a/gui/handlers.cpp
+++ b/gui/handlers.cpp
@@ -52,9 +52,9 @@ void Backend::useAutomaticGateway()
     UseAutomaticGateway();
 }
 
-void Backend::useTransport(QString transport)
+void Backend::setTransport(QString transport)
 {
-    UseTransport(toGoStr(transport));
+    SetTransport(toGoStr(transport));
 }
 
 QString Backend::getTransport()
diff --git a/gui/handlers.h b/gui/handlers.h
index 9c11b60a..a3812c5d 100644
--- a/gui/handlers.h
+++ b/gui/handlers.h
@@ -38,7 +38,7 @@ public slots:
     void donateSeen();
     void useLocation(QString username);
     void useAutomaticGateway();
-    void useTransport(QString transport);
+    void setTransport(QString transport);
     QString getTransport();
     void login(QString username, QString password);
     void resetError(QString errlabel);
diff --git a/gui/qml/BridgesItem.qml b/gui/qml/BridgesItem.qml
index 1cf152c0..1343403a 100644
--- a/gui/qml/BridgesItem.qml
+++ b/gui/qml/BridgesItem.qml
@@ -9,6 +9,8 @@ Item {
     anchors.centerIn: parent
     width: parent.width
     property alias displayReconnect: bridgeReconnect.visible
+    // TODO get obfs4Available from backend, in case provider doesn't have it
+    visible: true
 
     Column {
 
@@ -26,11 +28,13 @@ Item {
                 if (checked) {
                     Logic.setNeedsReconnect(true);
                     bridgeReconnect.visible = true;
+                    app.useBridges(true);
                 } else {
                     // This would also need a "needs reconnect" for de-selecting bridges the next time.
                     // better to wait and see the new connection widgets though
                     Logic.setNeedsReconnect(false);
                     bridgeReconnect.visible = false;
+                    app.useBridges(false);
                 }
             }
         }
@@ -42,6 +46,7 @@ Item {
             text: qsTr("Select a bridge only if you know that you need it to evade censorship in your country or local network.")
             anchors.horizontalCenter: parent.horizontalCenter
             wrapMode: Text.WordWrap 
+            visible: !bridgeReconnect.visible
         }
 
         Text {
@@ -49,10 +54,10 @@ Item {
             width: 250
             font.pixelSize: 12
             color: "red"
-            text: qsTr("We will attempt to connect to a bridge the next time you connect to the VPN.")
+            text: qsTr("An obfs4 bridge will be used the next time you connect to the VPN.")
             anchors.horizontalCenter: parent.horizontalCenter
             wrapMode: Text.WordWrap 
-            visible: false;
+            visible: false
         }
     }
 }
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
index f75a121a..cef33443 100644
--- a/gui/qml/main.qml
+++ b/gui/qml/main.qml
@@ -507,6 +507,14 @@ ApplicationWindow {
         return ctx.currentLocation + ", " + ctx.currentCountry
     }
 
+    function useBridges(value) {
+        if (value==true) {
+            backend.setTransport("obfs4")
+        } else {
+            backend.setTransport("openvpn")
+        }
+    }
+
     property alias brReconnect:bridgesTab.displayReconnect
 
 }
diff --git a/pkg/backend/actions.go b/pkg/backend/actions.go
index 1860b091..9e0941b6 100644
--- a/pkg/backend/actions.go
+++ b/pkg/backend/actions.go
@@ -24,9 +24,8 @@ func getGateway() string {
 	return ctx.bm.GetCurrentGateway()
 }
 
-// TODO return bool?
-func useTransport(transport string) {
-	err := ctx.bm.UseTransport(transport)
+func setTransport(t string) {
+	err := ctx.bm.SetTransport(t)
 	if err != nil {
 		log.Println(err)
 	}
diff --git a/pkg/backend/api.go b/pkg/backend/api.go
index e96c65b7..53800b35 100644
--- a/pkg/backend/api.go
+++ b/pkg/backend/api.go
@@ -79,8 +79,8 @@ func UseAutomaticGateway() {
 	}
 }
 
-func UseTransport(label string) {
-	ctx.bm.UseTransport(label)
+func SetTransport(label string) {
+	ctx.bm.SetTransport(label)
 }
 
 func GetTransport() *C.char {
diff --git a/pkg/bitmask/bitmask.go b/pkg/bitmask/bitmask.go
index b4308089..364312e7 100644
--- a/pkg/bitmask/bitmask.go
+++ b/pkg/bitmask/bitmask.go
@@ -36,7 +36,6 @@ type Bitmask interface {
 	GetCurrentLocation() string
 	GetCurrentCountry() string
 	IsManualLocation() bool
-	UseTransport(transport string) error
 	NeedsCredentials() bool
 	DoLogin(username, password string) (bool, error)
 }
diff --git a/pkg/bitmask/init.go b/pkg/bitmask/init.go
index b6b41b41..ab40fed8 100644
--- a/pkg/bitmask/init.go
+++ b/pkg/bitmask/init.go
@@ -109,7 +109,7 @@ func InitializeBitmask(conf *config.Config) (Bitmask, error) {
 func setTransport(b Bitmask, conf *config.Config) error {
 	if conf.Obfs4 {
 		log.Printf("Use transport Obfs4")
-		err := b.UseTransport("obfs4")
+		err := b.SetTransport("obfs4")
 		if err != nil {
 			log.Printf("Error setting transport: %v", err)
 			return err
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index d69f4e64..1a92d663 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -319,15 +319,25 @@ func (b *Bitmask) UseAutomaticGateway() {
 	b.bonafide.SetAutomaticGateway()
 }
 
-// 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)
+// SetTransport selects an obfuscation transport to use
+func (b *Bitmask) SetTransport(t string) error {
+	if t != "openvpn" && t != "obfs4" {
+		return fmt.Errorf("Transport %s not implemented", t)
+	}
+	log.Println("Setting transport to", t)
+	// compare and set string looks strange, but if assigning directly
+	// we're getting some kind of corruption with the transport string.
+	// I suspect something's
+	// not quite right with the c<->go char pointers handling.
+	if t == "obfs4" {
+		b.transport = "obfs4"
+	} else if t == "openvpn" {
+		b.transport = "openvpn"
 	}
-	b.transport = transport
 	return nil
 }
 
+// GetTransport gets the obfuscation transport to use. Only obfs4 available for now.
 func (b *Bitmask) GetTransport() string {
 	if b.transport == "obfs4" {
 		return "obfs4"
@@ -336,15 +346,6 @@ func (b *Bitmask) GetTransport() string {
 	}
 }
 
-func (b *Bitmask) SetTransport(t string) error {
-	if t != "openvpn" && t != "obfs4" {
-		return errors.New("Transport not supported: " + t)
-	}
-	log.Println("Setting transport to", t)
-	b.transport = t
-	return nil
-}
-
 func (b *Bitmask) getTempCertPemPath() string {
 	return path.Join(b.tempdir, "openvpn.pem")
 }
-- 
GitLab