From 5518645dfdfd1250dcabd98bda5d71d18eb4edcc Mon Sep 17 00:00:00 2001
From: kali <kali@win>
Date: Fri, 25 Sep 2020 16:49:46 +0200
Subject: [PATCH] [pkg] windows helper and qtinstaller

---
 Makefile                                      | 16 ++--
 bitmask.pro                                   |  1 +
 branding/qtinstaller/config/config.xml        |  9 +++
 .../packages/root.win_x86_64/.gitignore       |  1 +
 .../root.win_x86_64/meta/installscript.js     | 75 +++++++++++++++++++
 .../packages/root.win_x86_64/meta/package.xml | 10 +++
 .../packages/root/meta/package.xml            |  7 ++
 cmd/bitmask-helper/main.go                    |  8 +-
 gui/backend.go                                |  4 +-
 gui/handlers.cpp                              |  2 +-
 gui/qml/main.qml                              | 12 ++-
 pkg/bitmask/autostart.go                      |  4 +-
 pkg/bitmask/init.go                           |  3 -
 pkg/helper/helper.go                          | 10 ++-
 pkg/helper/windows.go                         | 32 +++++---
 15 files changed, 163 insertions(+), 31 deletions(-)
 create mode 100644 branding/qtinstaller/config/config.xml
 create mode 100644 branding/qtinstaller/packages/root.win_x86_64/.gitignore
 create mode 100644 branding/qtinstaller/packages/root.win_x86_64/meta/installscript.js
 create mode 100644 branding/qtinstaller/packages/root.win_x86_64/meta/package.xml
 create mode 100644 branding/qtinstaller/packages/root/meta/package.xml

diff --git a/Makefile b/Makefile
index ce65db48..e1af715f 100644
--- a/Makefile
+++ b/Makefile
@@ -69,14 +69,9 @@ else
 	$(MAKE) _buildparts
 endif
 
-_buildparts: $(foreach path,$(wildcard cmd/*),build_$(patsubst cmd/%,%,$(path)))
 
-build_%:
-	@echo "PLATFORM: ${PLATFORM}"
-	@mkdir -p build/bin/${PLATFORM}
-	go build -tags $(TAGS) -ldflags "-s -w -X main.version=`git describe --tags` ${EXTRA_LDFLAGS}" -o build/bin/${PLATFORM}/$* ./cmd/$*
-	-@rm -rf build/${PROVIDER}/staging/${PLATFORM} && mkdir -p build/${PROVIDER}/staging/${PLATFORM}
-	-@ln -s ../../../bin/${PLATFORM}/$* build/${PROVIDER}/staging/${PLATFORM}/$*
+helper:
+	go build -ldflags "-X main.AppName=${PROVIDER}VPN -X main.Version=${VERSION}" cmd/bitmask-helper/main.go
 
 test:
 	@go test -tags "integration $(TAGS)" ./pkg/...
@@ -228,6 +223,13 @@ package_snap:
 package_deb:
 	@make -C build/${PROVIDER} pkg_deb
 
+installer_win:
+	cp qtbuild/release/bitmask.exe branding/qtinstaller/packages/root.win_x86_64/data/${PROVIDER}-vpn.exe
+	windeployqt --qmldir gui/qml branding/qtinstaller/packages/root.win_x86_64/data/${PROVIDER}-vpn.exe
+	"/c/Qt/QtIFW-3.2.2/bin/binarycreator.exe" -c ./branding/qtinstaller/config/config.xml -p ./branding/qtinstaller/packages build/${PROVIDER}-vpn-${VERSION}-installer.exe
+
+# FIXME --- old nsis installer. deprecate, but probably we need something similar to sign all the binaries (helper, main app, installer...)
+
 package_win_stage_1:
 	@make -C build/${PROVIDER} pkg_win_stage_1
 
diff --git a/bitmask.pro b/bitmask.pro
index db675ab1..7d4543a5 100644
--- a/bitmask.pro
+++ b/bitmask.pro
@@ -1,3 +1,4 @@
+#TARGET=bitmask
 #TARGET = $$BINARY_NAME
 
 CONFIG += qt staticlib
diff --git a/branding/qtinstaller/config/config.xml b/branding/qtinstaller/config/config.xml
new file mode 100644
index 00000000..4469d65a
--- /dev/null
+++ b/branding/qtinstaller/config/config.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+	<Name>DemoLibVPN</Name>
+	<Version>0.0.1</Version>
+	<Title>DemoLibVPN Installer</Title>
+	<Publisher>LEAP Encryption Access Project</Publisher>
+	<StartMenuDir>DemoLibVPN</StartMenuDir>
+	<TargetDir>@ApplicationsDir@/DemoLibVPN</TargetDir>
+</Installer>
diff --git a/branding/qtinstaller/packages/root.win_x86_64/.gitignore b/branding/qtinstaller/packages/root.win_x86_64/.gitignore
new file mode 100644
index 00000000..60baa9cb
--- /dev/null
+++ b/branding/qtinstaller/packages/root.win_x86_64/.gitignore
@@ -0,0 +1 @@
+data/*
diff --git a/branding/qtinstaller/packages/root.win_x86_64/meta/installscript.js b/branding/qtinstaller/packages/root.win_x86_64/meta/installscript.js
new file mode 100644
index 00000000..691d1a4c
--- /dev/null
+++ b/branding/qtinstaller/packages/root.win_x86_64/meta/installscript.js
@@ -0,0 +1,75 @@
+/*
+**
+** Copyright (C) 2020 LEAP Encryption Access Project.
+** 
+*/
+
+function cancelInstaller(message)
+{
+    installer.setDefaultPageVisible(QInstaller.Introduction, false);
+    installer.setDefaultPageVisible(QInstaller.TargetDirectory, false);
+    installer.setDefaultPageVisible(QInstaller.ComponentSelection, false);
+    installer.setDefaultPageVisible(QInstaller.ReadyForInstallation, false);
+    installer.setDefaultPageVisible(QInstaller.StartMenuSelection, false);
+    installer.setDefaultPageVisible(QInstaller.PerformInstallation, false);
+    installer.setDefaultPageVisible(QInstaller.LicenseCheck, false);
+
+    var abortText = "<font color='red'>" + message +"</font>";
+    installer.setValue("FinishedText", abortText);
+}
+function majorVersion(str)
+{
+    return parseInt(str.split(".", 1));
+}
+
+function Component()
+{
+    // Check whether OS is supported.
+    // start installer with -v to see debug output
+
+    console.log("OS: " + systemInfo.productType);
+    console.log("Kernel: " + systemInfo.kernelType + "/" + systemInfo.kernelVersion);
+
+    var validOs = false;
+
+    if (systemInfo.kernelType === "winnt") {
+        if (majorVersion(systemInfo.kernelVersion) >= 6)
+            validOs = true;
+    } else if (systemInfo.kernelType === "darwin") {
+        if (majorVersion(systemInfo.kernelVersion) >= 11)
+            validOs = true;
+    } else {
+        if (systemInfo.productType !== "ubuntu"
+                || systemInfo.productVersion !== "20.04") {
+            QMessageBox["warning"]("os.warning", "Installer",
+                                   "Note that the binaries are only tested on Ubuntu 20.04",
+                                   QMessageBox.Ok);
+        }
+        validOs = true;
+    }
+
+    if (!validOs) {
+        cancelInstaller("Installation on " + systemInfo.prettyProductName + " is not supported");
+        return;
+    }
+
+    console.log("CPU Architecture: " +  systemInfo.currentCpuArchitecture);
+
+    if ( systemInfo.kernelType === "winnt") {
+        installer.componentByName("root.win_x86_64").setValue("Default", "true");
+        installer.componentByName("root.win_x86_64").setValue("Virtual", "false");
+    }
+}
+
+Component.prototype.createOperations = function() 
+{
+	component.createOperations()
+	component.addElevatedOperation("Execute", "@TargetDir@/helper.exe", "install", "UNDOEXECUTE", "@TargetDir@/helper.exe", "remove");
+	component.addElevatedOperation("Execute", "@TargetDir@/helper.exe", "start", "UNDOEXECUTE", "@TargetDir@/helper.exe", "stop");
+        if (systemInfo.productType === "windows") {
+             console.log("Adding shortcut entries");
+             component.addElevatedOperation("Mkdir", "@StartMenuDir@");
+             component.addElevatedOperation("CreateShortcut", "@TargetDir@/demolib-vpn.exe", "@StartMenuDir@/DemoLibVPN.lnk", "workingDirectory=@TargetDir@", "iconPath=%SystemRoot%/system32/SHELL32.dll", "iconId=2", "description=Start DemoLibVPN");
+             component.addElevatedOperation("CreateShortcut", "@TargetDir@/maintenancetool.exe", "@StartMenuDir@/uninstall.lnk", "workingDirectory=@TargetDir@", "iconPath=%SystemRoot%/system32/SHELL32.dll", "iconId=2", "description=Uninstall application");
+        }
+}
diff --git a/branding/qtinstaller/packages/root.win_x86_64/meta/package.xml b/branding/qtinstaller/packages/root.win_x86_64/meta/package.xml
new file mode 100644
index 00000000..11d630f1
--- /dev/null
+++ b/branding/qtinstaller/packages/root.win_x86_64/meta/package.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Package>
+	<DisplayName>DemoLibVPN For Windows</DisplayName>
+	<Description>Install DemoLibVPN</Description>
+	<Version>0.0.1-1</Version>
+	<ReleaseDate>2020-09-15</ReleaseDate>
+	<Default>true</Default>
+	<RequiresAdminRights>true</RequiresAdminRights>
+	<Script>installscript.js</Script>
+</Package>
diff --git a/branding/qtinstaller/packages/root/meta/package.xml b/branding/qtinstaller/packages/root/meta/package.xml
new file mode 100644
index 00000000..b4ca25e2
--- /dev/null
+++ b/branding/qtinstaller/packages/root/meta/package.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Package>
+	<DisplayName>DemoLibVPN</DisplayName>
+	<Version>0.0.1-1</Version>
+	<ReleaseDate>2020-09-15</ReleaseDate>
+	<Default>script</Default>
+</Package>
diff --git a/cmd/bitmask-helper/main.go b/cmd/bitmask-helper/main.go
index 4a627d94..ec9868ef 100644
--- a/cmd/bitmask-helper/main.go
+++ b/cmd/bitmask-helper/main.go
@@ -28,7 +28,10 @@ const (
 	logFile       = "helper.log"
 )
 
-var version string
+var (
+	Version string
+	AppName string
+)
 
 func main() {
 	logger, err := config.ConfigureLogger(path.Join(helper.LogFolder, logFile))
@@ -37,7 +40,8 @@ func main() {
 	} else {
 		defer logger.Close()
 	}
-	config.Version = version
+	helper.Version = Version
+	helper.AppName = AppName
 
 	// StartHelper is the main entry point - it also handles cli args in windows, and starts the http server.
 	helper.StartHelper(preferredPort)
diff --git a/gui/backend.go b/gui/backend.go
index e353a22e..abacd852 100644
--- a/gui/backend.go
+++ b/gui/backend.go
@@ -10,8 +10,8 @@ import (
 	"0xacab.org/leap/bitmask-vpn/pkg/backend"
 )
 
-//export GetVersion
-func GetVersion() *C.char {
+//export GetBitmaskVersion
+func GetBitmaskVersion() *C.char {
 	return (*C.char)(backend.GetVersion())
 }
 
diff --git a/gui/handlers.cpp b/gui/handlers.cpp
index f4fe10b6..6cafab54 100644
--- a/gui/handlers.cpp
+++ b/gui/handlers.cpp
@@ -19,7 +19,7 @@ Backend::Backend(QObject *parent) : QObject(parent)
 
 QString Backend::getVersion()
 {
-    return QString(GetVersion());
+    return QString(GetBitmaskVersion());
 }
 
 void Backend::switchOn()
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
index 4bd87bac..adf11bd2 100644
--- a/gui/qml/main.qml
+++ b/gui/qml/main.qml
@@ -141,10 +141,20 @@ ApplicationWindow {
             // left and right click seem to be working fine, so let's ignore this for now.
             switch (reason) {
             case SystemTrayIcon.Unknown:
-                break
+	        console.debug("reason: unknown")
+                menu.open()
+		break
             case SystemTrayIcon.Context:
+	        console.debug("activated: context")
+		if (Qt.platform.os !== "linux") {
+			menu.open()
+		}
                 break
             case SystemTrayIcon.DoubleClick:
+	        console.debug("activated: double click")
+		if (Qt.platform.os !== "linux") {
+			menu.open()
+		}
                 break
             case SystemTrayIcon.Trigger:
                 break
diff --git a/pkg/bitmask/autostart.go b/pkg/bitmask/autostart.go
index f314dbc4..f8f0f19f 100644
--- a/pkg/bitmask/autostart.go
+++ b/pkg/bitmask/autostart.go
@@ -1,3 +1,5 @@
+// +build !windows
+
 // Copyright (C) 2018 LEAP
 //
 // This program is free software: you can redistribute it and/or modify
@@ -35,7 +37,7 @@ type Autostart interface {
 	Enable() error
 }
 
-// newAutostart creates a handler for the autostart of your platform
+// NewAutostart creates a handler for the autostart of your platform
 func NewAutostart(appName string, iconPath string) Autostart {
 	exec := os.Args
 	if os.Getenv("SNAP") != "" {
diff --git a/pkg/bitmask/init.go b/pkg/bitmask/init.go
index 00f145e8..3e040b4c 100644
--- a/pkg/bitmask/init.go
+++ b/pkg/bitmask/init.go
@@ -16,8 +16,6 @@
 package bitmask
 
 import (
-	"errors"
-	"fmt"
 	"log"
 	"os"
 	"path"
@@ -91,7 +89,6 @@ func initBitmask() (Bitmask, error) {
 	b, err := vpn.Init()
 	if err != nil {
 		log.Printf("An error ocurred starting bitmask: %v", err)
-		err = errors.New(fmt.Sprintf(errorMsg, err))
 	}
 	return b, err
 }
diff --git a/pkg/helper/helper.go b/pkg/helper/helper.go
index 4fa88b2a..9d0b3304 100644
--- a/pkg/helper/helper.go
+++ b/pkg/helper/helper.go
@@ -22,13 +22,18 @@
 package helper
 
 import (
-	"0xacab.org/leap/bitmask-vpn/pkg/config"
 	"encoding/json"
 	"log"
 	"net/http"
 	"os/exec"
 )
 
+var (
+	AppName = "DemoLibVPN"
+	BinaryName = "bitmask"
+	Version = "git"
+)
+
 type openvpnT struct {
 	cmd *exec.Cmd
 }
@@ -82,6 +87,7 @@ func (openvpn *openvpnT) run(args []string) error {
 			return err
 		}
 	}
+	log.Println("OPENVPN PATH:", getOpenvpnPath())
 
 	// TODO: if it dies we should restart it
 	openvpn.cmd = exec.Command(getOpenvpnPath(), args...)
@@ -151,7 +157,7 @@ func firewallIsUpHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func versionHandler(w http.ResponseWriter, r *http.Request) {
-	w.Write([]byte(config.ApplicationName + "/" + config.Version + "\n"))
+	w.Write([]byte(AppName + "/" + Version + "\n"))
 	w.WriteHeader(http.StatusOK)
 }
 
diff --git a/pkg/helper/windows.go b/pkg/helper/windows.go
index 5eef863c..ef4f2719 100644
--- a/pkg/helper/windows.go
+++ b/pkg/helper/windows.go
@@ -1,5 +1,5 @@
 // +build windows
-// Copyright (C) 2018 LEAP
+// Copyright (C) 2018-2020 LEAP
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -23,25 +23,20 @@ import (
 	"os/exec"
 	"strconv"
 	"strings"
+	"path"
 
-	"0xacab.org/leap/bitmask-vpn/pkg/config"
 	"golang.org/x/sys/windows"
 	"golang.org/x/sys/windows/svc"
 )
 
-const (
-	svcName          = config.BinaryName + `-helper-v2`
-	appPath          = `C:\Program Files\` + config.ApplicationName + `\`
-	LogFolder        = appPath
-	openvpnPath      = appPath + `openvpn.exe`
-	chocoOpenvpnPath = `C:\Program Files\OpenVPN\bin\openvpn.exe`
-)
 
-type httpConf struct {
-	BindAddr string
-}
 
 var (
+	svcName          = BinaryName + `-helper-v2`
+	appPath          = getExecDir()
+	LogFolder        = appPath
+	openvpnPath      = path.Join(appPath, "openvpn.exe")
+	chocoOpenvpnPath = `C:\Program Files\OpenVPN\bin\openvpn.exe`
 	platformOpenvpnFlags = []string{
 		"--script-security", "1",
 		"--block-outside-dns",
@@ -49,6 +44,19 @@ var (
 	httpServerConf = &httpConf{}
 )
 
+func getExecDir() string {
+	ex, err := os.Executable()
+	if err != nil {
+		log.Fatal("Cannot find executable path")
+	}
+	return path.Dir(ex)
+}
+
+type httpConf struct {
+	BindAddr string
+}
+
+
 // parseCliArgs allows the helper binary to install/uninstall itself. It requires admin privileges.
 // However, be warned: if you intend to use it from the command line, you will have to compile it with the Go compiler yourself.
 // the version we're shipping (ie, cross-compiled with the mingw compiler) apparently is not able to output to stdout/stderr properly.
-- 
GitLab