mirror of https://0xacab.org/leap/bitmask-vpn
parent
048e2914a7
commit
d1252ef5b9
23
Makefile
23
Makefile
|
@ -43,7 +43,7 @@ endif
|
|||
SCRIPTS = branding/scripts
|
||||
TEMPLATES = branding/templates
|
||||
|
||||
TAP_WINDOWS = https://build.openvpn.net/downloads/releases/tap-windows-9.24.2-I601-Win10.exe
|
||||
OPENVPN_WINDOWS_INSTALLER = https://build.openvpn.net/downloads/releases/OpenVPN-2.5.1-I601-amd64.msi
|
||||
|
||||
HAS_QTIFW != which binarycreator.exe 2>/dev/null || PATH=$(PATH) which binarycreator
|
||||
OPENVPN_BIN != echo -n "$(HOME)/openvpn_build/sbin/$$(grep OPENVPN branding/thirdparty/openvpn/build_openvpn.sh | head -n 1 | cut -d = -f 2 | tr -d '"')"
|
||||
|
@ -160,21 +160,11 @@ ifeq (${PLATFORM}, windows)
|
|||
"c:\windows\system32\rcedit.exe" ${QTBUILD}/release/${TARGET}.exe --set-version-string CompanyName "LEAP Encryption Access Project"
|
||||
"c:\windows\system32\rcedit.exe" ${QTBUILD}/release/${TARGET}.exe --set-version-string FileDescription "${APPNAME}"
|
||||
"c:\windows\system32\signtool.exe" sign -debug -f "z:\leap\LEAP.pfx" -p ${WINCERTPASS} ${QTBUILD}/release/${TARGET}.exe
|
||||
# XXX need to deprecate helper and embrace interactive service
|
||||
cp build/bin/${PLATFORM}/bitmask-helper build/bin/${PLATFORM}/bitmask-helper.exe
|
||||
"c:\windows\system32\rcedit.exe" build/bin/${PLATFORM}/bitmask-helper.exe --set-file-version ${VERSION}
|
||||
"c:\windows\system32\rcedit.exe" build/bin/${PLATFORM}/bitmask-helper.exe --set-product-version ${VERSION}
|
||||
"c:\windows\system32\rcedit.exe" build/bin/${PLATFORM}/bitmask-helper.exe --set-version-string ProductName "bitmask-helper-v2"
|
||||
"c:\windows\system32\rcedit.exe" build/bin/${PLATFORM}/bitmask-helper.exe --set-version-string CompanyName "LEAP Encryption Access Project"
|
||||
"c:\windows\system32\rcedit.exe" build/bin/${PLATFORM}/bitmask-helper.exe --set-version-string FileDescription "Administrative helper for ${APPNAME}"
|
||||
"c:\windows\system32\signtool.exe" sign -debug -f "z:\leap\LEAP.pfx" -p ${WINCERTPASS} build/bin/${PLATFORM}/bitmask-helper.exe
|
||||
endif
|
||||
|
||||
checksign:
|
||||
ifeq (${PLATFORM}, windows)
|
||||
@"c:\windows\system32\sigcheck.exe" ${QTBUILD}/release/${TARGET}.exe
|
||||
@"c:\windows\system32\sigcheck.exe" build/bin/${PLATFORM}/bitmask-helper.exe
|
||||
@"c:\windows\system32\sigcheck.exe" "/c/Program Files/OpenVPN/bin/openvpn.exe"
|
||||
endif
|
||||
|
||||
installer: check_qtifw checksign
|
||||
|
@ -207,29 +197,24 @@ endif
|
|||
endif
|
||||
ifeq (${PLATFORM}, windows)
|
||||
@VERSION=${VERSION} VENDOR_PATH=${VENDOR_PATH} ${SCRIPTS}/gen-qtinstaller windows ${INSTALLER}
|
||||
@cp build/bin/${PLATFORM}/bitmask-helper.exe ${INST_DATA}helper.exe
|
||||
ifeq (${VENDOR_PATH}, providers)
|
||||
@cp ${VENDOR_PATH}/${PROVIDER}/assets/icon.ico ${INST_DATA}/icon.ico
|
||||
else
|
||||
@cp ${VENDOR_PATH}/assets/icon.ico ${INST_DATA}/icon.ico
|
||||
endif
|
||||
@cp ${QTBUILD}/release/${TARGET}.exe ${INST_DATA}${TARGET}.exe
|
||||
@cp "/c/Program Files/OpenVPN/bin/openvpn.exe" ${INST_DATA}
|
||||
@cp "/c/Program Files/OpenVPN/bin/"*.dll ${INST_DATA}
|
||||
ifeq (${RELEASE}, yes)
|
||||
#@windeployqt --release --qmldir gui/components ${INST_DATA}${TARGET}.exe
|
||||
#FIXME -- cannot find platform plugin
|
||||
@windeployqt --qmldir gui/components ${INST_DATA}${TARGET}.exe
|
||||
@windeployqt --qmldir gui/qml ${INST_DATA}${TARGET}.exe # FIXME --release flag cannot find platform plugin
|
||||
else
|
||||
@windeployqt --qmldir gui/components ${INST_DATA}${TARGET}.exe
|
||||
endif
|
||||
# TODO stage it to shave some time
|
||||
@wget ${TAP_WINDOWS} -O ${INST_DATA}/tap-windows.exe
|
||||
# XXX this is a workaround for missing libs after windeployqt ---
|
||||
@cp /c/Qt/5.15.2/mingw81_64/bin/libgcc_s_seh-1.dll ${INST_DATA}
|
||||
@cp /c/Qt/5.15.2/mingw81_64/bin/libstdc++-6.dll ${INST_DATA}
|
||||
@cp /c/Qt/5.15.2/mingw81_64/bin/libwinpthread-1.dll ${INST_DATA}
|
||||
@cp -r /c/Qt/5.15.2/mingw81_64/qml ${INST_DATA}
|
||||
# TODO stage it
|
||||
@wget ${OPENVPN_WINDOWS_INSTALLER} -O ${INST_DATA}openvpn-installer.msi
|
||||
endif
|
||||
ifeq (${PLATFORM}, linux)
|
||||
@VERSION=${VERSION} ${SCRIPTS}/gen-qtinstaller linux ${INSTALLER}
|
||||
|
|
|
@ -99,24 +99,18 @@ function preInstallWindows() {
|
|||
}
|
||||
|
||||
function postInstallWindows() {
|
||||
// TODO - check if we're on Windows10 or older, and use the needed tap-windows installer accordingly.
|
||||
console.log("Installing OpenVPN tap driver");
|
||||
component.addElevatedOperation("Execute", "@TargetDir@/tap-windows.exe", "/S", "/SELECT_UTILITIES=1"); /* TODO uninstall */
|
||||
/* remove an existing service, if it is stopped. Remove-Service is only in PS>6, and sc.exe delete leaves some garbage on the registry, so let's use the binary itself */
|
||||
console.log("Removing any previously installer helper...");
|
||||
component.addElevatedOperation("Execute", "{0,1}", "@TargetDir@/helper.exe", "remove");
|
||||
console.log("Now trying to install latest helper");
|
||||
component.addElevatedOperation("Execute", "@TargetDir@/helper.exe", "install", "UNDOEXECUTE", "@TargetDir@/helper.exe", "remove");
|
||||
component.addElevatedOperation("Execute", "@TargetDir@/helper.exe", "start", "UNDOEXECUTE", "@TargetDir@/helper.exe", "stop");
|
||||
console.log("Adding shortcut entries/...");
|
||||
// TODO - we probably need to package different flavors of the installer for windows 8, arm, i386 etc, and change the installer we ship too.
|
||||
console.log("Installing OpenVPN binaries and service");
|
||||
component.addElevatedOperation("Execute", "{0}", "msiexec", "/i", "@TargetDir@\\openvpn-installer.msi", "ADDLOCAL=OpenVPN.Service,OpenVPN,Drivers,Drivers.TAPWindows6,Drivers.Wintun", "/passive")
|
||||
console.log("Adding shortcut entries...");
|
||||
component.addElevatedOperation("Mkdir", "@StartMenuDir@");
|
||||
component.addElevatedOperation("CreateShortcut", "@TargetDir@/$BINNAME.exe", "@StartMenuDir@/$APPNAME.lnk", "workingDirectory=@TargetDir@", "iconPath=@TargetDir@/icon.ico", "description=Start $APPNAME");
|
||||
component.addElevatedOperation("CreateShortcut", "@TargetDir@\\$BINNAME.exe", "@StartMenuDir@\\$APPNAME.lnk", "workingDirectory=@TargetDir@", "iconPath=@TargetDir@\\icon.ico", "description=Start $APPNAME");
|
||||
|
||||
// TODO I think this one is not being created because the path doesn't exist yet. We might want to do this by hooking on the installation finished signal instead.
|
||||
component.addElevatedOperation(
|
||||
"CreateShortcut",
|
||||
"@TargetDir@/Uninstall-$APPNAME.exe",
|
||||
"@StartMenuDir@/Uninstall.lnk"
|
||||
"@TargetDir@\\Uninstall-$APPNAME.exe",
|
||||
"@StartMenuDir@\\Uninstall.lnk"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,8 +42,9 @@ var (
|
|||
|
||||
func getPlatformOpenvpnFlags() []string {
|
||||
return []string{
|
||||
"--script-security", "1",
|
||||
"--script-security", "0",
|
||||
"--block-outside-dns",
|
||||
"--redirect-gateway",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ var bitmaskRootPaths = []string{
|
|||
type launcher struct {
|
||||
openvpnCh chan []string
|
||||
failed bool
|
||||
mngPass string
|
||||
}
|
||||
|
||||
func newLauncher() (*launcher, error) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// +build !linux
|
||||
// Copyright (C) 2018-2020 LEAP
|
||||
// +build osx
|
||||
// Copyright (C) 2018-2021 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
|
||||
|
@ -36,6 +36,7 @@ import (
|
|||
type launcher struct {
|
||||
helperAddr string
|
||||
failed bool
|
||||
mngPass string
|
||||
}
|
||||
|
||||
const initialHelperPort = 7171
|
|
@ -0,0 +1,158 @@
|
|||
// +build windows
|
||||
// Copyright (C) 2018-2021 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
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package vpn
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"unicode/utf16"
|
||||
"bytes"
|
||||
"time"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/natefinch/npipe"
|
||||
"0xacab.org/leap/bitmask-vpn/pkg/vpn/bonafide"
|
||||
)
|
||||
|
||||
const pipeName = `\\.\pipe\openvpn\service`
|
||||
|
||||
type launcher struct {
|
||||
mngPass string
|
||||
}
|
||||
|
||||
func newLauncher() (*launcher, error) {
|
||||
l := launcher{}
|
||||
return &l, nil
|
||||
}
|
||||
|
||||
func (l *launcher) close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *launcher) check() (helpers bool, privilege bool, err error) {
|
||||
// TODO check if the named pipe exists
|
||||
return true, true, nil
|
||||
}
|
||||
|
||||
func (l *launcher) openvpnStart(flags ...string) error {
|
||||
var b bytes.Buffer
|
||||
var filtered []string
|
||||
for _, v := range flags {
|
||||
if v != "--tun-ipv6" {
|
||||
filtered = append(filtered, v)
|
||||
}
|
||||
}
|
||||
|
||||
cwd, _ := os.Getwd()
|
||||
opts := `--client --dev tun --block-outside-dns --redirect-gateway --script-security 0 ` + strings.Join(filtered, " ")
|
||||
log.Println("openvpn start: ", opts)
|
||||
|
||||
timeout := 3 * time.Second
|
||||
conn, err := npipe.DialTimeout(pipeName, timeout)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR opening pipe")
|
||||
return errors.New("cannot open openvpn pipe")
|
||||
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
writeUTF16Bytes(&b, cwd)
|
||||
writeUTF16Bytes(&b, opts)
|
||||
writeUTF16Bytes(&b, `\n`)
|
||||
encoded := b.Bytes()
|
||||
|
||||
rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
|
||||
|
||||
_, err = rw.Write(encoded)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR writing to pipe")
|
||||
return errors.New("cannot write to openvpn pipe")
|
||||
}
|
||||
rw.Flush()
|
||||
pid, err := getCommandResponse(rw)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR getting pid")
|
||||
}
|
||||
fmt.Println("OpenVPN PID:", pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *launcher) openvpnStop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO we will have to bring our helper back to do firewall
|
||||
|
||||
func (l *launcher) firewallStart(gateways []bonafide.Gateway) error {
|
||||
log.Println("NO firewall in windows")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *launcher) firewallStop() error {
|
||||
log.Println("NO firewall in windows")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *launcher) firewallIsUp() bool {
|
||||
log.Println("NO firewall in windows")
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func writeUTF16Bytes(b *bytes.Buffer, in string) {
|
||||
var u16 []uint16 = utf16.Encode([]rune(in + "\x00"))
|
||||
binary.Write(b, binary.LittleEndian, u16)
|
||||
}
|
||||
|
||||
func decodeUTF16String(s string) int {
|
||||
var code int
|
||||
var dec []byte
|
||||
for _, v := range []byte(s) {
|
||||
if byte(v) != byte(0) {
|
||||
dec = append(dec, v)
|
||||
}
|
||||
}
|
||||
_, err := fmt.Sscanf(string(dec), "%v", &code)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR decoding")
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
func getCommandResponse(rw *bufio.ReadWriter) (int, error) {
|
||||
msg, err := rw.ReadString('\n')
|
||||
if err != nil {
|
||||
fmt.Println("ERROR reading")
|
||||
}
|
||||
ok := decodeUTF16String(msg)
|
||||
if ok != 0 {
|
||||
return -1, errors.New("command failed")
|
||||
}
|
||||
msg, err = rw.ReadString('\n')
|
||||
if err != nil {
|
||||
fmt.Println("ERROR reading")
|
||||
}
|
||||
pid := decodeUTF16String(msg)
|
||||
if pid == 0 {
|
||||
return -1, errors.New("command failed")
|
||||
}
|
||||
return pid, nil
|
||||
}
|
|
@ -265,7 +265,17 @@ func (b *Bitmask) StopVPN() error {
|
|||
b.obfsvpnProxy.Stop()
|
||||
b.obfsvpnProxy = nil
|
||||
}
|
||||
return b.launch.openvpnStop()
|
||||
b.stopFromManagement()
|
||||
b.launch.openvpnStop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bitmask) stopFromManagement() error {
|
||||
if b.managementClient == nil {
|
||||
return fmt.Errorf("No management connected")
|
||||
}
|
||||
b.managementClient.SendSignal("SIGTERM")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reconnect to the VPN
|
||||
|
|
Loading…
Reference in New Issue