From ef892643df8970aec45dbc3f48eabb95a1ccbf22 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 30 Sep 2020 16:25:27 +0200 Subject: [pkg] osx helper and working qt installer --- Makefile | 108 ++++++++++++--------- bitmask.pro | 4 +- .../installer/osx/se.leap.bitmask-helper.plist | 26 ----- branding/installer/post-install.py | 96 ------------------ branding/scripts/gen-providers-json.py | 1 + branding/scripts/getparam | 36 +++++++ branding/templates/bitmaskvpn/config.go | 31 ------ branding/templates/qtinstaller/config/config.xml | 22 +++++ branding/templates/qtinstaller/installer.pro | 36 +++++++ branding/templates/qtinstaller/osx/post-install.py | 98 +++++++++++++++++++ .../qtinstaller/osx/se.leap.bitmask-helper.plist | 26 +++++ .../qtinstaller/packages/bitmaskvpn/.gitignore | 1 + .../packages/bitmaskvpn/meta/install.js | 53 ++++++++++ .../packages/bitmaskvpn/meta/package.xml | 11 +++ gui/build.sh | 39 ++++++-- installer/.gitignore | 4 - installer/bitmask-installer.pro | 38 -------- installer/config/config.xml | 14 --- installer/packages/riseupvpn/data/.gitignore | 3 - installer/packages/riseupvpn/data/README.txt | 3 - installer/packages/riseupvpn/data/post-install.py | 96 ------------------ .../riseupvpn/data/se.leap.bitmask-helper.plist | 26 ----- installer/packages/riseupvpn/meta/install.js | 53 ---------- installer/packages/riseupvpn/meta/package.xml | 11 --- pkg/helper/darwin.go | 24 +++-- pkg/vpn/launcher.go | 10 +- 26 files changed, 395 insertions(+), 475 deletions(-) delete mode 100644 branding/installer/osx/se.leap.bitmask-helper.plist delete mode 100755 branding/installer/post-install.py create mode 100755 branding/scripts/getparam delete mode 100644 branding/templates/bitmaskvpn/config.go create mode 100644 branding/templates/qtinstaller/config/config.xml create mode 100644 branding/templates/qtinstaller/installer.pro create mode 100755 branding/templates/qtinstaller/osx/post-install.py create mode 100644 branding/templates/qtinstaller/osx/se.leap.bitmask-helper.plist create mode 100644 branding/templates/qtinstaller/packages/bitmaskvpn/.gitignore create mode 100644 branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js create mode 100644 branding/templates/qtinstaller/packages/bitmaskvpn/meta/package.xml delete mode 100644 installer/.gitignore delete mode 100644 installer/bitmask-installer.pro delete mode 100644 installer/config/config.xml delete mode 100644 installer/packages/riseupvpn/data/.gitignore delete mode 100644 installer/packages/riseupvpn/data/README.txt delete mode 100755 installer/packages/riseupvpn/data/post-install.py delete mode 100644 installer/packages/riseupvpn/data/se.leap.bitmask-helper.plist delete mode 100644 installer/packages/riseupvpn/meta/install.js delete mode 100644 installer/packages/riseupvpn/meta/package.xml diff --git a/Makefile b/Makefile index 88793bd..440bb4c 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,8 @@ XBUILD ?= no SKIP_CACHECK ?= no PROVIDER ?= $(shell grep ^'provider =' branding/config/vendor.conf | cut -d '=' -f 2 | tr -d "[:space:]") -TARGET ?= bitmask +APPNAME ?= $(shell branding/scripts/getparam appname | tail -n 1) +TARGET ?= $(shell branding/scripts/getparam binname | tail -n 1) PROVIDER_CONFIG ?= branding/config/vendor.conf DEFAULT_PROVIDER = branding/assets/default/ VERSION ?= $(shell git describe) @@ -21,17 +22,22 @@ SOURCE_GOLIB=gui/backend.go # detect OS, we use it for dependencies UNAME = $(shell uname -s) PLATFORM ?= $(shell echo ${UNAME} | awk "{print tolower(\$$0)}") + +QTBUILD = build/qt WININST_DATA = branding/qtinstaller/packages/root.win_x86_64/data/ +OSX_DATA = build/installer/packages/bitmaskvpn/data/ +OSX_CERT="Developer ID Installer: LEAP Encryption Access Project" +MACDEPLOYQT_OPTS = -appstore-compliant -qmldir=gui/qml -always-overwrite +# XXX expired cert -codesign="${OSX_CERT}" + +# TODO converge both OSX/WINDOWS -TEMPLATES = branding/templates SCRIPTS = branding/scripts - -all: icon locales helper build +TEMPLATES = branding/templates HAS_QTIFW := $(shell PATH=$(PATH) which binarycreator) OPENVPN_BIN = "$(HOME)/openvpn_build/sbin/$(shell grep OPENVPN branding/thirdparty/openvpn/build_openvpn.sh | head -n 1 | cut -d = -f 2 | tr -d '"')" - ######################################################################### # go build ######################################################################### @@ -57,20 +63,23 @@ dependsDarwin: @brew install --default-names gnu-sed ifeq ($(PLATFORM), darwin) - EXTRA_FLAGS = MACOSX_DEPLOYMENT_TARGET=10.10 GOOS=darwin CC=clang +EXTRA_FLAGS = MACOSX_DEPLOYMENT_TARGET=10.10 GOOS=darwin CC=clang else - EXTRA_FLAGS = +EXTRA_FLAGS = endif + golib: - CGO_ENABLED=1 ${EXTRA_FLAGS} go build -buildmode=c-archive -o ${TARGET_GOLIB} ${SOURCE_GOLIB} + # TODO stop building golib in gui/build.sh, it's redundant. + # we should port the buildGoLib parts of the gui/build.sh script here + @echo "doing nothing" -build: build_helper build_openvpn - @XBUILD=no gui/build.sh +build: golib build_helper build_openvpn + @XBUILD=no TARGET=${TARGET} gui/build.sh build_helper: @echo "PLATFORM: ${PLATFORM}" @mkdir -p build/bin/${PLATFORM} - go build -o build/bin/${PLATFORM}/bitmask-helper -ldflags "-X main.AppName=${PROVIDER}VPN -X main.Version=${VERSION}" ./cmd/bitmask-helper/ + go build -o build/bin/${PLATFORM}/bitmask-helper -ldflags "-X main.AppName=${APPNAME} -X main.Version=${VERSION}" ./cmd/bitmask-helper/ build_old: ifeq (${XBUILD}, yes) @@ -91,13 +100,38 @@ build_openvpn: @[ -f $(OPENVPN_BIN) ] && echo "OpenVPN already built at" $(OPENVPN_BIN) || ./branding/thirdparty/openvpn/build_openvpn.sh build_installer: check_qtifw build - cp -r qtbuild/release/${PROVIDER}-vpn.app installer/packages/${PROVIDER}vpn/data/ - cp build/bin/${PLATFORM}/bitmask-helper installer/packages/${PROVIDER}vpn/data/ - cp $(OPENVPN_BIN) installer/packages/${PROVIDER}vpn/data/openvpn.leap - cp branding/templates/osx/bitmask.pf.conf installer/packages/${PROVIDER}vpn/data/helper/bitmask.pf.conf - cp branding/templates/osx/client.up.sh installer/packages/${PROVIDER}vpn/data/ - cp branding/templates/osx/client.down.sh installer/packages/${PROVIDER}vpn/data/ - cd installer && qmake && make + echo "mkdir osx data" + @mkdir -p ${OSX_DATA} + @cp -r ${TEMPLATES}/qtinstaller/config build/installer/ + @cp -r ${TEMPLATES}/qtinstaller/packages build/installer/ + @cp -r ${TEMPLATES}/qtinstaller/installer.pro build/installer/ +ifeq (${PLATFORM}, darwin) + @mkdir -p ${OSX_DATA}/helper + @cp "${TEMPLATES}/osx/bitmask.pf.conf" ${OSX_DATA}/helper/bitmask.pf.conf + @cp "${TEMPLATES}/osx/client.up.sh" ${OSX_DATA}/ + @cp "${TEMPLATES}/osx/client.down.sh" ${OSX_DATA}/ + @cp "${TEMPLATES}/qtinstaller/osx/post-install.py" ${OSX_DATA}/ + @cp "${TEMPLATES}/qtinstaller/osx/se.leap.bitmask-helper.plist" ${OSX_DATA}/ + @cp build/bin/${PLATFORM}/bitmask-helper ${OSX_DATA}/ + # FIXME our static openvpn build fails with an "Assertion failed at crypto.c". Needs to be fixed!!! - kali + #@cp $(OPENVPN_BIN) ${OSX_DATA}/openvpn.leap + @echo "WARNING: workaround for broken static build. Shipping homebrew dynamically linked instead" + @rm -f ${OSX_DATA}openvpn.leap && cp /usr/local/bin/openvpn ${OSX_DATA}openvpn.leap + @echo "[+] Running macdeployqt" + @macdeployqt ${QTBUILD}/release/${PROVIDER}-vpn.app ${MACDEPLOYQT_OPTS} + @cp -r "${QTBUILD}/release/${TARGET}.app"/ ${OSX_DATA}/ +endif + @echo "[+] All templates, binaries and libraries copied to build/installer." + @echo "[+] Now building the installer." + @cd build/installer && qmake INSTALLER=${APPNAME}-installer-${VERSION} && make + +installer_win: + # XXX refactor with build_installer + cp helper.exe ${WININST_DATA} + cp ${QTBUILD}/release/${TARGET}.exe ${WININST_DATA}${TARGET}.exe + # XXX add sign step here + windeployqt --qmldir gui/qml ${WININST_DATA}${TARGET}.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 check_qtifw: ifdef HAS_QTIFW @@ -134,11 +168,8 @@ _build_xbuild_done: # --------- FIXME ----------------------------------------------------------------------- clean: - @rm -rf installer/*.app - @rm -rf installer/packages/${PROVIDER}vpn/data/*.app - @rm -rf installer/packages/${PROVIDER}vpn/data/bitmask-helper @rm -rf build/ - @unlink branding/assets/default + @unlink branding/assets/default || true ######################################################################### # build them all @@ -208,6 +239,7 @@ tgz: @cd build/ && tar czf bitmask-vpn_$(VERSION).tgz ${TGZ_NAME} @rm -rf $(TGZ_PATH) +# XXX port/deprecate ----------------------------------------------- gen_pkg_win: @mkdir -p build/${PROVIDER}/windows/ @cp -r ${TEMPLATES}/windows build/${PROVIDER} @@ -230,6 +262,13 @@ endif @cd build/${PROVIDER}/osx && python3 generate.py @cd build/${PROVIDER}/osx/scripts && chmod +x preinstall postinstall +gen_pkg_deb: + @cp -r ${TEMPLATES}/debian build/${PROVIDER} + @VERSION=${VERSION} PROVIDER_CONFIG=${PROVIDER_CONFIG} ${SCRIPTS}/generate-debian.py build/${PROVIDER}/debian/data.json + @mkdir -p build/${PROVIDER}/debian/icons/scalable && cp branding/assets/default/icon.svg build/${PROVIDER}/debian/icons/scalable/icon.svg + @cd build/${PROVIDER}/debian && python3 generate.py + @cd build/${PROVIDER}/debian && rm app.desktop-template changelog-template rules-template control-template generate.py data.json && chmod +x rules + gen_pkg_snap: @cp -r ${TEMPLATES}/snap build/${PROVIDER} @VERSION=${VERSION} PROVIDER_CONFIG=${PROVIDER_CONFIG} ${SCRIPTS}/generate-snap.py build/${PROVIDER}/snap/data.json @@ -241,13 +280,6 @@ gen_pkg_snap: @cp branding/assets/default/icon.png build/${PROVIDER}/snap/gui/${PROVIDER}-vpn.png rm build/${PROVIDER}/snap/generate.py -gen_pkg_deb: - @cp -r ${TEMPLATES}/debian build/${PROVIDER} - @VERSION=${VERSION} PROVIDER_CONFIG=${PROVIDER_CONFIG} ${SCRIPTS}/generate-debian.py build/${PROVIDER}/debian/data.json - @mkdir -p build/${PROVIDER}/debian/icons/scalable && cp branding/assets/default/icon.svg build/${PROVIDER}/debian/icons/scalable/icon.svg - @cd build/${PROVIDER}/debian && python3 generate.py - @cd build/${PROVIDER}/debian && rm app.desktop-template changelog-template rules-template control-template generate.py data.json && chmod +x rules - prepare_done: @echo @echo 'Done. You can do "make build" now.' @@ -275,24 +307,8 @@ package_snap: package_deb: @make -C build/${PROVIDER} pkg_deb -installer_win: - # XXX refactor with build_installer - cp helper.exe ${WININST_DATA} - cp qtbuild/release/${TARGET}.exe ${WININST_DATA}${PROVIDER}-vpn.exe - windeployqt --qmldir gui/qml ${WININST_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 - -package_win_stage_2: - @make -C build/${PROVIDER} pkg_win_stage_2 - package_osx: - @make -C build/${PROVIDER} pkg_osx - + @echo "tbd" ######################################################################### diff --git a/bitmask.pro b/bitmask.pro index 7acf7a9..4099301 100644 --- a/bitmask.pro +++ b/bitmask.pro @@ -1,4 +1,3 @@ -#TARGET=bitmask #TARGET = $$BINARY_NAME CONFIG += qt staticlib @@ -25,7 +24,8 @@ HEADERS += \ gui/qjsonmodel.h \ lib/libgoshim.h -LIBS += -L../lib -lgoshim -lpthread +# we build from build/qt +LIBS += -L../../lib -lgoshim -lpthread RESOURCES += gui/gui.qrc diff --git a/branding/installer/osx/se.leap.bitmask-helper.plist b/branding/installer/osx/se.leap.bitmask-helper.plist deleted file mode 100644 index c9d9687..0000000 --- a/branding/installer/osx/se.leap.bitmask-helper.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - WorkingDirectory - /tmp - StandardOutPath - bitmask-helper.log - StandardErrorPath - bitmask-helper-err.log - GroupName - daemon - RunAtLoad - - SessionCreate - - KeepAlive - - ThrottleInterval - 5 - Label - se.leap.BitmaskHelper - Program - PATH/bitmask-helper - - diff --git a/branding/installer/post-install.py b/branding/installer/post-install.py deleted file mode 100755 index 02da859..0000000 --- a/branding/installer/post-install.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -import os -import shutil -import sys -import subprocess - -HELPER = "bitmask-helper" -HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist" -_dir = os.path.dirname(os.path.realpath(__file__)) - -def main(): - log = open(os.path.join(_dir, 'post-install.log'), 'w') - log.write('Checking for admin privileges...\n') - - _id = os.getuid() - if _id != 0: - err = "error: need to run as root. UID: %s\n" % str(_id) - logErr(log, err) - - # failure: sys.exit(1) - - if isHelperRunning(): - log.write("Trying to stop bitmask-helper...\n") - # if this fail, we can check if the HELPER_PLIST is there - ok = unloadHelper() - log.write("success: %s \n" % str(ok)) - - ok = fixHelperOwner(log) - log.write("chown helper: %s \n" % str(ok)) - - log.write("Copy launch daemon...\n") - copyLaunchDaemon() - - out = launchHelper() - log.write("Copy plist: %s \n" % str(ok)) - - grantPermissionsOnLogFolder() - - # all done - log.write('post-install script: done\n') - sys.exit(0) - - -def logErr(log, msg): - log.write(msg) - sys.exit(1) - -def isHelperRunning(): - ps = _getProcessList() - return HELPER in ps - -def unloadHelper(): - out = subprocess.call(["launchctl", "unload", HELPER_PLIST]) - return out == 0 - -def fixHelperOwner(log): - path = os.path.join(_dir, HELPER) - try: - os.chown(path, 0, 0) - except OSError as exc: - log.write(str(exc)) - return False - return True - -def copyLaunchDaemon(): - plist = "se.leap.bitmask-helper.plist" - path = os.path.join(_dir, plist) - dest = os.path.join('/Library/LaunchDaemons', plist) - _p = _dir.replace("/", "\/") - subprocess.call(["sed", "-i.back", "s/PATH/%s/" % _p, path]) - shutil.copy(path, dest) - -def launchHelper(): - out = subprocess.call(["launchctl", "load", "/Library/LaunchDaemons/se.leap.bitmask-helper.plist"]) - return out == 0 - -def grantPermissionsOnLogFolder(): - helperDir = os.path.join(_dir, 'helper') - try: - os.makedirs(helperDir) - except Exception: - pass - os.chown(helperDir, 0, 0) - -def _getProcessList(): - _out = [] - output = subprocess.Popen(["ps", "-ceA"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout, stderr = output.communicate() - for line in stdout.split('\n'): - cmd = line.split(' ')[-1] - _out.append(cmd.strip()) - return _out - -if __name__ == "__main__": - main() diff --git a/branding/scripts/gen-providers-json.py b/branding/scripts/gen-providers-json.py index beef3fe..c89217a 100644 --- a/branding/scripts/gen-providers-json.py +++ b/branding/scripts/gen-providers-json.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 + import configparser import json import os diff --git a/branding/scripts/getparam b/branding/scripts/getparam new file mode 100755 index 0000000..2b87e1e --- /dev/null +++ b/branding/scripts/getparam @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +# A short utility to get appname in compilation time. +# This is a convenience to build helpers while we move the branding mechanism to a separate repo. + +import configparser + +import os +import sys + +from provider import getDefaultProvider +from provider import getProviderData + +def getData(): + here = os.path.abspath(os.path.dirname(__file__)) + configPath = os.path.join(here, '../../branding/config/vendor.conf') + if not os.path.isfile(configPath): + print("ERROR: path does not exist", config) + os.exit(1) + config = configparser.ConfigParser() + config.read(configPath) + defaultProvider = getDefaultProvider(config) + return getProviderData(getDefaultProvider(config), config) + +if __name__ == "__main__": + param = sys.argv[1] + if param == "appname": + field = "applicationName" + elif param == "binname": + field = "binaryName" + else: + print("ERROR: unknown param") + sys.exit(1) + + data = getData() + print(data[field]) diff --git a/branding/templates/bitmaskvpn/config.go b/branding/templates/bitmaskvpn/config.go deleted file mode 100644 index e3d70cf..0000000 --- a/branding/templates/bitmaskvpn/config.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by vendorize.py -// At $timeStamp - -package config - -/* All these constants are defined in the vendor.conf file - */ -const ( - Provider = "$providerURL" - ApplicationName = "$applicationName" - BinaryName = "$binaryName" - Auth = "$auth" - DonateURL = "$donateURL" - AskForDonations = "$askForDonations" - HelpURL = "$helpURL" - TosURL = "$tosURL" - APIURL = "$apiURL" - GeolocationAPI = "$geolocationAPI" -) - -var Version string - -/* - -CaCert : a string containing a representation of the provider CA, used to - sign the webapp and openvpn certificates. should be placed in - config/[provider]-ca.crt - -*/ -var CaCert = []byte(`$caCertString`) diff --git a/branding/templates/qtinstaller/config/config.xml b/branding/templates/qtinstaller/config/config.xml new file mode 100644 index 0000000..936726d --- /dev/null +++ b/branding/templates/qtinstaller/config/config.xml @@ -0,0 +1,22 @@ + + + DemoLibVPN-0.0.1 + 0.0.1 + DemoLibVPN Installer + LEAP Encryption Access Project + @ApplicationsDir@/DemoLibVPN + @TargetDir@/demolib-vpn.app + + + DemoLibVPN + false + + Uninstall-DemoLibVPN + mac + diff --git a/branding/templates/qtinstaller/installer.pro b/branding/templates/qtinstaller/installer.pro new file mode 100644 index 0000000..ec800c1 --- /dev/null +++ b/branding/templates/qtinstaller/installer.pro @@ -0,0 +1,36 @@ +!defined(INSTALLER, var):INSTALLER= "BitmaskVPN-Installer-git" +TEMPLATE = aux +CONFIG -= debug_and_release + +INPUT = $$PWD/config/config.xml $$PWD/packages +inst.input = INPUT +inst.output = $$INSTALLER +inst.commands = binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT} +inst.CONFIG += target_predeps no_link combine + +QMAKE_EXTRA_COMPILERS += inst + +OTHER_FILES += \ +# watch out... it chokes with dashes in the path + packages/riseupvpn/meta/package.xml \ + packages/riseupvpn/meta/install.js \ + packages/riseupvpn/data/README.txt \ + +macx { + OTHER_FILES += "packages/riseupvpn/data/riseup-vpn.app" + OTHER_FILES += "packages/riseupvpn/data/bitmask-helper" + OTHER_FILES += "packages/riseupvpn/data/installer.py" + OTHER_FILES += "packages/riseupvpn/data/se.leap.bitmask-helper.plist" + OTHER_FILES += "packages/riseupvpn/data/openvpn.leap" + OTHER_FILES += "packages/riseupvpn/data/helper/bitmask.pf.conf" + OTHER_FILES += "packages/riseupvpn/data/client.up.sh" + OTHER_FILES += "packages/riseupvpn/data/client.down.sh" +} +linux { + OTHER_FILES += "packages/riseupvpn/data/riseup-vpn" + OTHER_FILES += "packages/riseupvpn/data/bitmask-helper" +} +win32{ + OTHER_FILES += "packages/riseupvpn/data/riseup-vpn.exe" + OTHER_FILES += "packages/riseupvpn/data/helper.exe" +} diff --git a/branding/templates/qtinstaller/osx/post-install.py b/branding/templates/qtinstaller/osx/post-install.py new file mode 100755 index 0000000..32b4780 --- /dev/null +++ b/branding/templates/qtinstaller/osx/post-install.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +import os +import shutil +import sys +import subprocess + +HELPER = "bitmask-helper" +HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist" +_dir = os.path.dirname(os.path.realpath(__file__)) + +def main(): + log = open(os.path.join(_dir, 'post-install.log'), 'w') + log.write('Checking for admin privileges...\n') + + _id = os.getuid() + if _id != 0: + err = "error: need to run as root. UID: %s\n" % str(_id) + logErr(log, err) + + # failure: sys.exit(1) + + if isHelperRunning(): + log.write("Trying to stop bitmask-helper...\n") + # if this fail, we can check if the HELPER_PLIST is there + ok = unloadHelper() + log.write("success: %s \n" % str(ok)) + + ok = fixHelperOwner(log) + log.write("chown helper: %s \n" % str(ok)) + + log.write("Copy launch daemon...\n") + copyLaunchDaemon() + + log.write("Trying to launch helper...\n") + out = launchHelper() + log.write("result: %s \n" % str(out)) + + grantPermissionsOnLogFolder() + + # all done + log.write('post-install script: done\n') + sys.exit(0) + + +def logErr(log, msg): + log.write(msg) + sys.exit(1) + +def isHelperRunning(): + ps = _getProcessList() + return HELPER in ps + +def unloadHelper(): + out = subprocess.call(["launchctl", "unload", HELPER_PLIST]) + out2 = subprocess.call(["pkill", "-9", "bitmask-helper"]) # just in case + return out == 0 + +def fixHelperOwner(log): + path = os.path.join(_dir, HELPER) + try: + os.chown(path, 0, 0) + except OSError as exc: + log.write(str(exc)) + return False + return True + +def copyLaunchDaemon(): + plist = "se.leap.bitmask-helper.plist" + path = os.path.join(_dir, plist) + dest = os.path.join('/Library/LaunchDaemons', plist) + _p = _dir.replace("/", "\/") + subprocess.call(["sed", "-i.back", "s/PATH/%s/" % _p, path]) + shutil.copy(path, dest) + +def launchHelper(): + out = subprocess.call(["launchctl", "load", "/Library/LaunchDaemons/se.leap.bitmask-helper.plist"]) + return out == 0 + +def grantPermissionsOnLogFolder(): + helperDir = os.path.join(_dir, 'helper') + try: + os.makedirs(helperDir) + except Exception: + pass + os.chown(helperDir, 0, 0) + +def _getProcessList(): + _out = [] + output = subprocess.Popen(["ps", "-ceA"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + stdout, stderr = output.communicate() + for line in stdout.split('\n'): + cmd = line.split(' ')[-1] + _out.append(cmd.strip()) + return _out + +if __name__ == "__main__": + main() diff --git a/branding/templates/qtinstaller/osx/se.leap.bitmask-helper.plist b/branding/templates/qtinstaller/osx/se.leap.bitmask-helper.plist new file mode 100644 index 0000000..c9d9687 --- /dev/null +++ b/branding/templates/qtinstaller/osx/se.leap.bitmask-helper.plist @@ -0,0 +1,26 @@ + + + + + WorkingDirectory + /tmp + StandardOutPath + bitmask-helper.log + StandardErrorPath + bitmask-helper-err.log + GroupName + daemon + RunAtLoad + + SessionCreate + + KeepAlive + + ThrottleInterval + 5 + Label + se.leap.BitmaskHelper + Program + PATH/bitmask-helper + + diff --git a/branding/templates/qtinstaller/packages/bitmaskvpn/.gitignore b/branding/templates/qtinstaller/packages/bitmaskvpn/.gitignore new file mode 100644 index 0000000..60baa9c --- /dev/null +++ b/branding/templates/qtinstaller/packages/bitmaskvpn/.gitignore @@ -0,0 +1 @@ +data/* diff --git a/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js b/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js new file mode 100644 index 0000000..f9c85f2 --- /dev/null +++ b/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 LEAP +** +****************************************************************************/ + +function Component() { +} + +Component.prototype.createOperations = function () +{ + // This will actually install the files + component.createOperations(); + + // And now our custom actions. + // See https://doc.qt.io/qtinstallerframework/operations.html for reference + // + // We can also use this to register different components (different architecture for instance) + // See https://doc.qt.io/qtinstallerframework/qt-installer-framework-systeminfo-packages-root-meta-installscript-qs.html + + if (systemInfo.productType === "windows") { + postInstallWindows(); + } else if (systemInfo.productType === "osx") { + postInstallOSX(); + } else { + postInstallLinux(); + } +} + +function postInstallWindows() { + component.addOperation( + "CreateShortcut", + "@TargetDir@/README.txt", + "@StartMenuDir@/README.lnk", + "workingDirectory=@TargetDir@", + "iconPath=%SystemRoot%/system32/SHELL32.dll", + "iconId=2"); +} + +function postInstallOSX() { + console.log("Post-installation for OSX"); + // TODO add UNDOEXECUTE for the uninstaller + component.addElevatedOperation( + "Execute", "{0}", + "@TargetDir@/post-install.py", + "errormessage=There was an error during the post-installation script, things might be broken. Please report this error and attach the post-install.log file."); +} + +function postInstallLinux() { + console.log("Post-installation for GNU/Linux"); + console.log("Maybe you want to use your package manager instead?"); + component.addOperation("AppendFile", "/tmp/riseupvpn.log", "this is a test - written from the installer"); +} diff --git a/branding/templates/qtinstaller/packages/bitmaskvpn/meta/package.xml b/branding/templates/qtinstaller/packages/bitmaskvpn/meta/package.xml new file mode 100644 index 0000000..b910e7f --- /dev/null +++ b/branding/templates/qtinstaller/packages/bitmaskvpn/meta/package.xml @@ -0,0 +1,11 @@ + + + DemoLibVPN + DemoLibVPN + 0.20.9-1 + 2020-10-01 + false + true + + true + diff --git a/gui/build.sh b/gui/build.sh index 9c10341..a6c0a22 100755 --- a/gui/build.sh +++ b/gui/build.sh @@ -10,7 +10,10 @@ PROJECT=bitmask.pro TARGET_GOLIB=lib/libgoshim.a SOURCE_GOLIB=gui/backend.go -RELEASE=qtbuild/release +QTBUILD=build/qt +RELEASE=$QTBUILD/release + +PLATFORM=$(uname -s) if [ "$TARGET" == "" ] then @@ -36,6 +39,7 @@ function init { mkdir -p lib } +# TODO this should be moved to the makefile function buildGoLib { echo "[+] Using go in" $GO "[`go version`]" $GO generate ./pkg/config/version/genver/gen.go @@ -63,19 +67,36 @@ function buildGoLib { function buildQmake { echo "[+] Now building Qml app with Qt qmake" echo "[+] Using qmake in:" $QMAKE - mkdir -p qtbuild - $QMAKE -o qtbuild/Makefile "CONFIG-=debug CONFIG+=release" $PROJECT + mkdir -p $QTBUILD + $QMAKE -o $QTBUILD/Makefile "CONFIG-=debug CONFIG+=release" $PROJECT +} + +function renameOutput { + # i would expect that passing QMAKE_TARGET would produce the right output, but nope. + if [ "$PLATFORM" == "Linux" ] + then + mv $RELEASE/bitmask $RELEASE/$TARGET + strip $RELEASE/$TARGET + echo "[+] Binary is in" $RELEASE/$TARGET + fi + if [ "$PLATFORM" == "Darwin" ] + then + rm -rf $RELEASE/$TARGET.app + mv $RELEASE/bitmask.app/ $RELEASE/$TARGET.app/ + echo "[+] App is in" $RELEASE/$TARGET + fi } echo "[+] Building BitmaskVPN" lrelease bitmask.pro + +# FIXME move buildGoLib to the main makefile, to avoid redundant builds if possible buildGoLib buildQmake -make -C qtbuild clean -make -C qtbuild -j4 all -# i would expect that passing QMAKE_TARGET would produce the right output, but nope. -mv qtbuild/release/bitmask $RELEASE/$TARGET -strip $RELEASE/$TARGET -echo "[+] Binary is in" $RELEASE/$TARGET +make -C $QTBUILD clean +make -C $QTBUILD -j4 all + +renameOutput +echo "[+] Done." diff --git a/installer/.gitignore b/installer/.gitignore deleted file mode 100644 index 2fdd01e..0000000 --- a/installer/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.qmake.stash -Makefile -packages/riseupvpn/data/riseup-vpn -RiseupVPN-Installer diff --git a/installer/bitmask-installer.pro b/installer/bitmask-installer.pro deleted file mode 100644 index 49179c4..0000000 --- a/installer/bitmask-installer.pro +++ /dev/null @@ -1,38 +0,0 @@ -TEMPLATE = aux - -CONFIG -= debug_and_release - -INSTALLER = RiseupVPN-Installer - -INPUT = $$PWD/config/config.xml $$PWD/packages -inst.input = INPUT -inst.output = $$INSTALLER -inst.commands = binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT} -inst.CONFIG += target_predeps no_link combine - -QMAKE_EXTRA_COMPILERS += inst - -OTHER_FILES += \ -# watch out... it chokes with dashes in the path - packages/riseupvpn/meta/package.xml \ - packages/riseupvpn/meta/install.js \ - packages/riseupvpn/data/README.txt \ - -macx { - OTHER_FILES += "packages/riseupvpn/data/riseup-vpn.app" - OTHER_FILES += "packages/riseupvpn/data/bitmask-helper" - OTHER_FILES += "packages/riseupvpn/data/installer.py" - OTHER_FILES += "packages/riseupvpn/data/se.leap.bitmask-helper.plist" - OTHER_FILES += "packages/riseupvpn/data/openvpn.leap" - OTHER_FILES += "packages/riseupvpn/data/helper/bitmask.pf.conf" - OTHER_FILES += "packages/riseupvpn/data/client.up.sh" - OTHER_FILES += "packages/riseupvpn/data/client.down.sh" -} -linux { - OTHER_FILES += "packages/riseupvpn/data/riseup-vpn" - OTHER_FILES += "packages/riseupvpn/data/bitmask-helper" -} -win32{ - OTHER_FILES += "packages/riseupvpn/data/riseup-vpn.exe" - OTHER_FILES += "packages/riseupvpn/data/helper.exe" -} diff --git a/installer/config/config.xml b/installer/config/config.xml deleted file mode 100644 index 492e76f..0000000 --- a/installer/config/config.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - RiseupVPN Installer 1.0 - LEAP Encryption Access Project - RiseupVPN Installer - 1.0.0 - @ApplicationsDir@/RiseupVPN - - - http://localhost/repository/ - - - mac - diff --git a/installer/packages/riseupvpn/data/.gitignore b/installer/packages/riseupvpn/data/.gitignore deleted file mode 100644 index 63c86a1..0000000 --- a/installer/packages/riseupvpn/data/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -openvpn.leap -bitmask-helper -riseup-vpn.app diff --git a/installer/packages/riseupvpn/data/README.txt b/installer/packages/riseupvpn/data/README.txt deleted file mode 100644 index c71984f..0000000 --- a/installer/packages/riseupvpn/data/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This is the RiseupVPN README. -It should be replaced with something more meaningful -(give links to issue tracker, repos, uninstaller etc). diff --git a/installer/packages/riseupvpn/data/post-install.py b/installer/packages/riseupvpn/data/post-install.py deleted file mode 100755 index 02da859..0000000 --- a/installer/packages/riseupvpn/data/post-install.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -import os -import shutil -import sys -import subprocess - -HELPER = "bitmask-helper" -HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist" -_dir = os.path.dirname(os.path.realpath(__file__)) - -def main(): - log = open(os.path.join(_dir, 'post-install.log'), 'w') - log.write('Checking for admin privileges...\n') - - _id = os.getuid() - if _id != 0: - err = "error: need to run as root. UID: %s\n" % str(_id) - logErr(log, err) - - # failure: sys.exit(1) - - if isHelperRunning(): - log.write("Trying to stop bitmask-helper...\n") - # if this fail, we can check if the HELPER_PLIST is there - ok = unloadHelper() - log.write("success: %s \n" % str(ok)) - - ok = fixHelperOwner(log) - log.write("chown helper: %s \n" % str(ok)) - - log.write("Copy launch daemon...\n") - copyLaunchDaemon() - - out = launchHelper() - log.write("Copy plist: %s \n" % str(ok)) - - grantPermissionsOnLogFolder() - - # all done - log.write('post-install script: done\n') - sys.exit(0) - - -def logErr(log, msg): - log.write(msg) - sys.exit(1) - -def isHelperRunning(): - ps = _getProcessList() - return HELPER in ps - -def unloadHelper(): - out = subprocess.call(["launchctl", "unload", HELPER_PLIST]) - return out == 0 - -def fixHelperOwner(log): - path = os.path.join(_dir, HELPER) - try: - os.chown(path, 0, 0) - except OSError as exc: - log.write(str(exc)) - return False - return True - -def copyLaunchDaemon(): - plist = "se.leap.bitmask-helper.plist" - path = os.path.join(_dir, plist) - dest = os.path.join('/Library/LaunchDaemons', plist) - _p = _dir.replace("/", "\/") - subprocess.call(["sed", "-i.back", "s/PATH/%s/" % _p, path]) - shutil.copy(path, dest) - -def launchHelper(): - out = subprocess.call(["launchctl", "load", "/Library/LaunchDaemons/se.leap.bitmask-helper.plist"]) - return out == 0 - -def grantPermissionsOnLogFolder(): - helperDir = os.path.join(_dir, 'helper') - try: - os.makedirs(helperDir) - except Exception: - pass - os.chown(helperDir, 0, 0) - -def _getProcessList(): - _out = [] - output = subprocess.Popen(["ps", "-ceA"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout, stderr = output.communicate() - for line in stdout.split('\n'): - cmd = line.split(' ')[-1] - _out.append(cmd.strip()) - return _out - -if __name__ == "__main__": - main() diff --git a/installer/packages/riseupvpn/data/se.leap.bitmask-helper.plist b/installer/packages/riseupvpn/data/se.leap.bitmask-helper.plist deleted file mode 100644 index c9d9687..0000000 --- a/installer/packages/riseupvpn/data/se.leap.bitmask-helper.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - WorkingDirectory - /tmp - StandardOutPath - bitmask-helper.log - StandardErrorPath - bitmask-helper-err.log - GroupName - daemon - RunAtLoad - - SessionCreate - - KeepAlive - - ThrottleInterval - 5 - Label - se.leap.BitmaskHelper - Program - PATH/bitmask-helper - - diff --git a/installer/packages/riseupvpn/meta/install.js b/installer/packages/riseupvpn/meta/install.js deleted file mode 100644 index f9c85f2..0000000 --- a/installer/packages/riseupvpn/meta/install.js +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 LEAP -** -****************************************************************************/ - -function Component() { -} - -Component.prototype.createOperations = function () -{ - // This will actually install the files - component.createOperations(); - - // And now our custom actions. - // See https://doc.qt.io/qtinstallerframework/operations.html for reference - // - // We can also use this to register different components (different architecture for instance) - // See https://doc.qt.io/qtinstallerframework/qt-installer-framework-systeminfo-packages-root-meta-installscript-qs.html - - if (systemInfo.productType === "windows") { - postInstallWindows(); - } else if (systemInfo.productType === "osx") { - postInstallOSX(); - } else { - postInstallLinux(); - } -} - -function postInstallWindows() { - component.addOperation( - "CreateShortcut", - "@TargetDir@/README.txt", - "@StartMenuDir@/README.lnk", - "workingDirectory=@TargetDir@", - "iconPath=%SystemRoot%/system32/SHELL32.dll", - "iconId=2"); -} - -function postInstallOSX() { - console.log("Post-installation for OSX"); - // TODO add UNDOEXECUTE for the uninstaller - component.addElevatedOperation( - "Execute", "{0}", - "@TargetDir@/post-install.py", - "errormessage=There was an error during the post-installation script, things might be broken. Please report this error and attach the post-install.log file."); -} - -function postInstallLinux() { - console.log("Post-installation for GNU/Linux"); - console.log("Maybe you want to use your package manager instead?"); - component.addOperation("AppendFile", "/tmp/riseupvpn.log", "this is a test - written from the installer"); -} diff --git a/installer/packages/riseupvpn/meta/package.xml b/installer/packages/riseupvpn/meta/package.xml deleted file mode 100644 index 4dd7ae9..0000000 --- a/installer/packages/riseupvpn/meta/package.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - RiseupVPN - RiseupVPN - 0.20.6-1 - 2020-07-01 - false - true - - true - diff --git a/pkg/helper/darwin.go b/pkg/helper/darwin.go index ae42646..2210da3 100644 --- a/pkg/helper/darwin.go +++ b/pkg/helper/darwin.go @@ -50,24 +50,23 @@ const ( func _getExecPath() string { ex, err := os.Executable() if err != nil { - log.Print("error while getting executable path!") + log.Print("ERROR: cannot find executable path") } return filepath.Dir(ex) } -func getHelperPath() string { - execPath := _getExecPath() - hp := filepath.Join(execPath, "../../../", "bitmask-helper") - log.Println(">>> DEBUG: helper", hp) - return hp +func getHelperDir() string { + d := _getExecPath() + log.Println(">>> DEBUG: helper dir", d) + return d } func getPlatformOpenvpnFlags() []string { - helperPath := getHelperPath() + helperDir := getHelperDir() return []string{ "--script-security", "2", - "--up", helperPath + "client.up.sh", - "--down", helperPath + "client.down.sh", + "--up", filepath.Join(helperDir, "client.up.sh"), + "--down", filepath.Join(helperDir, "client.down.sh"), } } @@ -83,7 +82,7 @@ func daemonize() { PidFilePerm: 0644, LogFileName: "bitmask-helper.log", LogFilePerm: 0640, - WorkDir: "./", + WorkDir: filepath.Join(getHelperDir(), "helper"), Umask: 027, Args: []string{"[bitmask-helper]"}, } @@ -107,8 +106,7 @@ func runServer(preferredPort int) { } func getOpenvpnPath() string { - execPath := _getExecPath() - openvpnPath := filepath.Join(execPath, "../../../", "openvpn.leap") + openvpnPath := filepath.Join(getHelperDir(), "openvpn.leap") log.Println(">>> DEBUG: openvpn", openvpnPath) return openvpnPath } @@ -203,7 +201,7 @@ func loadBitmaskAnchor() error { } func getRulefilePath() (string, error) { - rulefilePath := filepath.Join(getHelperPath(), "helper", "bitmask.pf.conf") + rulefilePath := filepath.Join(getHelperDir(), "helper", "bitmask.pf.conf") log.Println("DEBUG: rule file path", rulefilePath) if _, err := os.Stat(rulefilePath); !os.IsNotExist(err) { diff --git a/pkg/vpn/launcher.go b/pkg/vpn/launcher.go index e18fdc6..234a89c 100644 --- a/pkg/vpn/launcher.go +++ b/pkg/vpn/launcher.go @@ -1,5 +1,5 @@ // +build !linux -// 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 @@ -51,12 +51,12 @@ func probeHelperPort(port int) int { break } } + log.Println("WARN: Cannot find working helper") return 0 } func smellsLikeOurHelperSpirit(port int, c *http.Client) bool { uri := "http://localhost:" + strconv.Itoa(port) + "/version" - log.Println("probing for helper at", uri) resp, err := c.Get(uri) if err != nil { return false @@ -68,9 +68,10 @@ func smellsLikeOurHelperSpirit(port int, c *http.Client) bool { return false } if strings.Contains(string(ver), config.ApplicationName) { + log.Println("DEBUG: Successfully probed for matching helper at", uri) return true } else { - log.Println("Another helper replied to our version request:", string(ver)) + log.Println("DEBUG: Another helper seems to be running:", string(ver)) } } return false @@ -157,7 +158,8 @@ func (l *launcher) send(path string, body []byte) error { resErr, err := ioutil.ReadAll(res.Body) if len(resErr) > 0 { - return fmt.Errorf("Helper returned an error: %q", resErr) + /* FIXME why do we trigger a fatal with this error? */ + return fmt.Errorf("FATAL: Helper returned an error: %q", resErr) } return err } -- cgit v1.2.3