summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2021-11-25 13:45:54 +0100
committerkali kaneko (leap communications) <kali@leap.se>2021-11-29 18:14:05 +0100
commitb7b19b7195366dbacc4078b5b7a3fc6a3ad7889b (patch)
tree2b97e0167d507ddd9c1b5b0d5f0d3efbc4e6829c
parenta81bf938fe2b9409d1fa0175cc5f20635bb16127 (diff)
[feat] expose snowflake in preferences
it will be disabled if Tor not present, for now
-rw-r--r--gui/api.md6
-rw-r--r--gui/backend.go5
-rw-r--r--gui/components/Preferences.qml63
-rw-r--r--gui/gui.qrc1
-rw-r--r--gui/handlers.cpp5
-rw-r--r--gui/handlers.h1
-rw-r--r--pkg/backend/api.go9
-rw-r--r--pkg/backend/status.go7
-rw-r--r--pkg/bitmask/bitmask.go1
-rw-r--r--pkg/config/gui.go10
-rw-r--r--pkg/snowflake/tor.go15
-rw-r--r--pkg/vpn/main.go8
12 files changed, 113 insertions, 18 deletions
diff --git a/gui/api.md b/gui/api.md
new file mode 100644
index 0000000..eb11ec6
--- /dev/null
+++ b/gui/api.md
@@ -0,0 +1,6 @@
+# how to add an action to the api
+
+1. declare it in `handlers.h`
+2. define it in `handlers.cpp`
+3. export it in `backend.go`
+4. move to `pkg/backend/api.go` and implement what's needed from there
diff --git a/gui/backend.go b/gui/backend.go
index 5c07cda..516ef4a 100644
--- a/gui/backend.go
+++ b/gui/backend.go
@@ -58,6 +58,11 @@ func SetUDP(udp bool) {
backend.SetUDP(udp)
}
+//export SetSnowflake
+func SetSnowflake(snowflake bool) {
+ backend.SetSnowflake(snowflake)
+}
+
//export Quit
func Quit() {
backend.Quit()
diff --git a/gui/components/Preferences.qml b/gui/components/Preferences.qml
index f205358..fcd742f 100644
--- a/gui/components/Preferences.qml
+++ b/gui/components/Preferences.qml
@@ -91,10 +91,23 @@ ThemedPage {
}
}
+ Label {
+ text: qsTr("Traffic is obfuscated to bypass blocks.")
+ font.family: "Monospace"
+ color: "gray"
+ visible: true
+ wrapMode: Text.Wrap
+ font.pixelSize: Theme.fontSize - 4
+ Layout.leftMargin: 35
+ Layout.rightMargin: 15
+ Layout.bottomMargin: 5
+ Layout.preferredWidth: 240
+ }
+
MaterialCheckBox {
id: useSnowflake
- //wrapMode: Label.Wrap
- text: qsTr("Use Snowflake (experimental)")
+ //wrapMode: Text.Wrap
+ text: qsTr("Use Snowflake bootstrap")
enabled: false
checked: false
HoverHandler {
@@ -102,6 +115,23 @@ ThemedPage {
}
Layout.leftMargin: 10
Layout.rightMargin: 10
+ Layout.preferredWidth: 240
+ onClicked: {
+ doUseSnowflake(checked)
+ }
+ }
+
+ Label {
+ text: qsTr("Snowflake needs Tor installed in your system.")
+ font.family: "Monospace"
+ color: "gray"
+ visible: true
+ wrapMode: Text.Wrap
+ font.pixelSize: Theme.fontSize - 4
+ Layout.leftMargin: 35
+ Layout.rightMargin: 15
+ Layout.bottomMargin: 5
+ Layout.preferredWidth: 240
}
Label {
@@ -109,10 +139,11 @@ ThemedPage {
font.bold: true
Layout.leftMargin: 10
Layout.rightMargin: 10
+ Layout.topMargin: 8
}
Label {
- text: qsTr("UDP can make the VPN faster, but it might be blocked on certain networks")
+ text: qsTr("UDP can make the VPN faster. It might be blocked on certain networks.")
width: parent.width
color: "gray"
visible: true
@@ -200,22 +231,18 @@ ThemedPage {
function useBridges(value) {
if (value == true) {
- console.debug("use obfs4")
backend.setTransport("obfs4")
} else {
- console.debug("use regular")
backend.setTransport("openvpn")
}
}
function doUseUDP(value) {
- if (value == true) {
- console.debug("use udp")
- backend.setUDP(true)
- } else {
- console.debug("use tcp")
- backend.setUDP(false)
- }
+ backend.setUDP(value)
+ }
+
+ function doUseSnowflake(value) {
+ backend.setSnowflake(value)
}
function getBoxHeight() {
@@ -226,11 +253,17 @@ ThemedPage {
if (ctx && ctx.transport == "obfs4") {
useBridgesCheckBox.checked = true
}
- if (ctx && ctx.udp == "true") {
- useUDP.checked = true
- }
if (ctx && ctx.offersUdp == "false") {
useUDP.enabled = false
}
+ if (ctx && ctx.offersUdp && ctx.udp == "true") {
+ useUDP.checked = true
+ }
+ if (ctx && ctx.hasTor == "true") {
+ useSnowflake.enabled = true
+ }
+ if (ctx && ctx.hasTor && ctx.snowflake == "true") {
+ useSnowflake.checked = true
+ }
}
}
diff --git a/gui/gui.qrc b/gui/gui.qrc
index b32c708..c36f5c5 100644
--- a/gui/gui.qrc
+++ b/gui/gui.qrc
@@ -34,6 +34,7 @@
<file>components/VPNState.qml</file>
<file>components/InitErrors.qml</file>
<file>components/ErrorBox.qml</file>
+ <file>components/MotdBox.qml</file>
<!-- resources, assets -->
<file>resources/icon-noshield.svg</file>
diff --git a/gui/handlers.cpp b/gui/handlers.cpp
index b1d060b..4f855ef 100644
--- a/gui/handlers.cpp
+++ b/gui/handlers.cpp
@@ -62,6 +62,11 @@ void Backend::setUDP(bool udp)
SetUDP(udp);
}
+void Backend::setSnowflake(bool snowflake)
+{
+ SetSnowflake(snowflake);
+}
+
QString Backend::getTransport()
{
return QString(GetTransport());
diff --git a/gui/handlers.h b/gui/handlers.h
index 55dd32d..82678c0 100644
--- a/gui/handlers.h
+++ b/gui/handlers.h
@@ -40,6 +40,7 @@ public slots:
void useAutomaticGateway();
void setTransport(QString transport);
void setUDP(bool udp);
+ void setSnowflake(bool snowflake);
QString getTransport();
void login(QString username, QString password);
void resetError(QString errlabel);
diff --git a/pkg/backend/api.go b/pkg/backend/api.go
index d7dcbb3..6d5ceee 100644
--- a/pkg/backend/api.go
+++ b/pkg/backend/api.go
@@ -94,12 +94,19 @@ func SetTransport(label string) {
}
func SetUDP(udp bool) {
- log.Println("DEBUG setting UDP")
+ log.Printf("DEBUG udp:%v\n", udp)
ctx.cfg.SetUseUDP(udp)
ctx.bm.UseUDP(udp)
go trigger(OnStatusChanged)
}
+func SetSnowflake(snowflake bool) {
+ log.Printf("DEBUG snowflake:%v\n", snowflake)
+ ctx.cfg.SetUseSnowflake(snowflake)
+ ctx.bm.UseSnowflake(snowflake)
+ go trigger(OnStatusChanged)
+}
+
func GetTransport() *C.char {
return C.CString(ctx.bm.GetTransport())
}
diff --git a/pkg/backend/status.go b/pkg/backend/status.go
index 2ed5cfd..de6364f 100644
--- a/pkg/backend/status.go
+++ b/pkg/backend/status.go
@@ -8,6 +8,7 @@ import (
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
"0xacab.org/leap/bitmask-vpn/pkg/config"
+ "0xacab.org/leap/bitmask-vpn/pkg/snowflake"
)
const (
@@ -57,6 +58,8 @@ type connectionCtx struct {
IsReady bool `json:"isReady"`
CanUpgrade bool `json:"canUpgrade"`
Motd string `json:"motd"`
+ HasTor bool `json:"hasTor"`
+ UseSnowflake bool `json:"snowflake"`
bm bitmask.Bitmask
autostart bitmask.Autostart
cfg *config.Config
@@ -73,11 +76,13 @@ func (c *connectionCtx) toJson() ([]byte, error) {
c.CurrentCountry = c.bm.GetCurrentCountry()
c.BestLocation = c.bm.GetBestLocation(transport)
c.Transport = transport
- c.UseUDP = c.cfg.UDP // TODO initialize bitmask too
+ c.UseUDP = c.cfg.UDP // TODO initialize bitmask param?
c.OffersUDP = c.bm.OffersUDP()
+ c.UseSnowflake = c.cfg.Snowflake // TODO initialize bitmask param?
c.ManualLocation = c.bm.IsManualLocation()
c.CanUpgrade = c.bm.CanUpgrade()
c.Motd = c.bm.GetMotd()
+ c.HasTor = snowflake.HasTor()
}
defer statusMutex.Unlock()
b, err := json.Marshal(c)
diff --git a/pkg/bitmask/bitmask.go b/pkg/bitmask/bitmask.go
index 80b502e..0c2a344 100644
--- a/pkg/bitmask/bitmask.go
+++ b/pkg/bitmask/bitmask.go
@@ -36,6 +36,7 @@ type Bitmask interface {
GetTransport() string
SetTransport(string) error
UseUDP(bool) error
+ UseSnowflake(bool) error
OffersUDP() bool
GetCurrentGateway() string
GetCurrentLocation() string
diff --git a/pkg/config/gui.go b/pkg/config/gui.go
index 6004d20..1d23018 100644
--- a/pkg/config/gui.go
+++ b/pkg/config/gui.go
@@ -42,12 +42,14 @@ type Config struct {
UserStoppedVPN bool
DisableAutostart bool
UDP bool
+ Snowflake bool
}
SkipLaunch bool
Obfs4 bool
DisableAutostart bool
StartVPN bool
UDP bool
+ Snowflake bool
}
// ParseConfig reads the configuration from the configuration file
@@ -66,6 +68,8 @@ func ParseConfig() *Config {
conf.Obfs4 = conf.file.Obfs4
conf.DisableAutostart = conf.file.DisableAutostart
conf.StartVPN = !conf.file.UserStoppedVPN
+ conf.UDP = conf.file.UDP
+ conf.Snowflake = conf.file.Snowflake
return &conf
}
@@ -104,6 +108,12 @@ func (c *Config) SetUseUDP(val bool) error {
return c.save()
}
+func (c *Config) SetUseSnowflake(val bool) error {
+ c.Snowflake = val
+ c.file.Snowflake = val
+ return c.save()
+}
+
func (c *Config) save() error {
f, err := os.Create(configPath)
if err != nil {
diff --git a/pkg/snowflake/tor.go b/pkg/snowflake/tor.go
new file mode 100644
index 0000000..4f4c4e4
--- /dev/null
+++ b/pkg/snowflake/tor.go
@@ -0,0 +1,15 @@
+package snowflake
+
+import (
+ "errors"
+ "os"
+)
+
+func exists(path string) bool {
+ _, err := os.Stat(path)
+ return !errors.Is(err, os.ErrNotExist)
+}
+
+func HasTor() bool {
+ return exists("/usr/sbin/tor")
+}
diff --git a/pkg/vpn/main.go b/pkg/vpn/main.go
index 176c86f..da6caf1 100644
--- a/pkg/vpn/main.go
+++ b/pkg/vpn/main.go
@@ -43,6 +43,7 @@ type Bitmask struct {
certPemPath string
openvpnArgs []string
udp bool
+ snowflake bool
offersUdp bool
failed bool
canUpgrade bool
@@ -68,7 +69,7 @@ func Init() (*Bitmask, error) {
bonafide.Gateway{},
bonafide.Gateway{}, statusCh, nil, bf, launch,
"", nil, "", []string{},
- false, false, false, false,
+ false, false, false, false, false,
[]motd.Message{}, ""}
// FIXME multiprovider: need to pass provider name early on
// XXX we want to block on these, but they can timeout if we're blocked.
@@ -151,6 +152,11 @@ func (b *Bitmask) UseUDP(udp bool) error {
return nil
}
+func (b *Bitmask) UseSnowflake(s bool) error {
+ b.snowflake = s
+ return nil
+}
+
func (b *Bitmask) OffersUDP() bool {
return b.bonafide.IsUDPAvailable()
}