Skip to content

Commit

Permalink
Move WireGuard installed validation to Helper, simplify Helper prefer…
Browse files Browse the repository at this point in the history
…ences.
  • Loading branch information
Johan Bloemberg committed Jan 9, 2019
1 parent dd211c9 commit 24cfc8a
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 39 deletions.
29 changes: 21 additions & 8 deletions Shared/Const.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,36 @@

import Foundation

let defaultBrewPrefix = "/usr/local"
let runPath = "/var/run/wireguard"

let wireguardBinPath = "\(defaultBrewPrefix)/bin/wg"

let installInstructions = """
Currently this Application does not come with WireGuard binaries. \
Currently this application does not come with WireGuard binaries. \
It is required to manually install these using Homebrew.
Please follow the instructions on:
https://www.wireguard.com/install/
and restart this Application afterwards.
and restart this application afterwards.
"""

let defaultSettings = [
"showAllTunnelDetails": false,
"showConnectedTunnelDetails": true,
let defaultBrewPrefix = "/usr/local"

struct DefaultSettings {
static let App = [
"showAllTunnelDetails": false,
"showConnectedTunnelDetails": true,
]
static let Helper = [
// Prefix path for etc/wireguard, bin/wg, bin/wireguard-go and bin/bash (bash 4),
// can be overridden by the user via root defaults to allow custom location for Homebrew.
"brewPrefix": defaultBrewPrefix,
"wgquickBinPath": "",
]
}

// locations where wg-quick searches for configuration files
let configPaths = [
"/etc/wireguard",
"\(defaultBrewPrefix)/etc/wireguard",
]
1 change: 1 addition & 0 deletions Shared/HelperProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ protocol HelperProtocol {
func getTunnels(reply: @escaping (TunnelInfo) -> Void)
func setTunnel(tunnelName: String, enable: Bool, reply: @escaping (NSNumber) -> Void)
func getVersion(_ reply: @escaping (String) -> Void)
func wireguardInstalled(_ reply: @escaping (Bool) -> Void)
}
8 changes: 5 additions & 3 deletions WireGuardStatusbar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1010;
LastUpgradeCheck = 0940;
LastUpgradeCheck = 1010;
ORGANIZATIONNAME = "Johan Bloemberg";
TargetAttributes = {
0444B85E211F5CD700CA6ECA = {
Expand Down Expand Up @@ -573,6 +573,7 @@
__launchd_plist,
"\"$(SRCROOT)/WireGuardStatusbarHelper/Launchd.plist\"",
);
PRODUCT_BUNDLE_IDENTIFIER = WireGuardStatusbarHelper;
};
name = Debug;
};
Expand All @@ -589,6 +590,7 @@
__launchd_plist,
"\"$(SRCROOT)/WireGuardStatusbarHelper/Launchd.plist\"",
);
PRODUCT_BUNDLE_IDENTIFIER = WireGuardStatusbarHelper;
};
name = Release;
};
Expand Down Expand Up @@ -707,7 +709,6 @@
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = $TARGET_NAME;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
Expand Down Expand Up @@ -766,7 +767,6 @@
INFOPLIST_FILE = "$(SRCROOT)/$(TARGET_NAME)/Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = $TARGET_NAME;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
Expand All @@ -783,6 +783,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = WireGuardStatusbar;
};
name = Debug;
};
Expand All @@ -794,6 +795,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = WireGuardStatusbar;
};
name = Release;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
23 changes: 19 additions & 4 deletions WireGuardStatusbar/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, AppProtocol
// keep the existence and state of all tunnel(configuration)s
var tunnels = Tunnels()

// To check wg binary is enough to also guarentee wg-quick and wireguard-go when installed with Homebrew
@objc dynamic let wireguardInstalled = FileManager.default.fileExists(atPath: wireguardBinPath)
@objc dynamic var wireguardInstalled = false

let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
@IBOutlet var menu: NSMenu!
Expand All @@ -34,7 +33,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, AppProtocol

func applicationDidFinishLaunching(_: Notification) {
// set default preferences
defaults.register(defaults: defaultSettings)
defaults.register(defaults: DefaultSettings.App)

#if DEBUG
// reset preferences to defaults for development/(ui)testing
Expand All @@ -57,7 +56,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, AppProtocol
// if installation failed alert user
onFailure: alertHelperFailure,
// if helper is up to date, installed or updated, get initial tunnel state
onSuccess: updateState
onSuccess: connectedToHelper
)
}

Expand Down Expand Up @@ -92,6 +91,22 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, AppProtocol
}
}

// Perform initialization after first connection with helper
func connectedToHelper() {
validateHelper()
updateState()
}

// Query the Helper to ensure it is properly initialized (eg: wg-quick is available)
func validateHelper() {
let xpcService = privilegedHelper?.helperConnection()?.remoteObjectProxyWithErrorHandler { error -> Void in
NSLog("XPCService error: \(error)")
return
} as? HelperProtocol

xpcService?.wireguardInstalled { self.wireguardInstalled = $0 }
}

// query the Helper for all current tunnels configuration and runtime state, update menu icon
func updateState() {
NSLog("Updating tunnel configuration and runtime state.")
Expand Down
49 changes: 27 additions & 22 deletions WireGuardStatusbarHelper/Helper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,36 @@ class Helper: NSObject, HelperProtocol, SKQueueDelegate {

private var queue: SKQueue?

// prefix path for etc/wireguard, bin/wg, bin/wireguard-go and bin/bash (bash 4)
// can be overridden by the user via root defaults to allow custom location for Homebrew
// Prefix path for etc/wireguard, bin/wg, bin/wireguard-go and bin/bash (bash 4),
// can be overridden by the user via root defaults to allow custom location for Homebrew.
private var brewPrefix: String
// path to wg-quick, can be overriden by the user via root defaults
private var wgquickBinPath: String
// Path to wg-quick, can be overriden by the user via root defaults.
// NOTICE: the root defaults override feature is a half implemented feature
// the GUI App will not be aware of these settings and might falsely warn that WireGuard
// is not installed. This warning can be ignored.
// Example, to set defaults as root for wgquickBinPath run:
// sudo defaults write WireGuardStatusbarHelper wgquickBinPath /opt/local/bin/wg-quick
private var wgquickBinPath: String
// Path use to determine if WireGuard Homebrew package is installed.
// To check wg binary is enough to also guarentee wg-quick and wireguard-go when installed with Homebrew.
private var wireguardBinPath: String

// paths to search for tunnel configurations, ordered by wg-quick's preferences
private var configPaths: [String]
let defaults = UserDefaults.standard

// read preferences set via root defaults
// Read preferences set via root defaults.
override init() {
if let brewPrefix = CFPreferencesCopyAppValue("brewPrefix" as CFString,
HelperConstants.machServiceName as CFString) as? String {
defaults.register(defaults: DefaultSettings.Helper)

brewPrefix = defaults.string(forKey: "brewPrefix")!
if brewPrefix != DefaultSettings.Helper["brewPrefix"] {
NSLog("Overriding 'brewPrefix' with: \(brewPrefix)")
self.brewPrefix = brewPrefix
} else {
brewPrefix = defaultBrewPrefix
}
configPaths = [
"/etc/wireguard",
"\(brewPrefix)/etc/wireguard",
]
wireguardBinPath = "\(brewPrefix)/bin/wg"

if let wgquickBinPath = CFPreferencesCopyAppValue("wgquickBinPath" as CFString,
HelperConstants.machServiceName as CFString) as? String {
wgquickBinPath = "\(brewPrefix)/bin/wg-quick"
if let wgquickBinPath = defaults.string(forKey: "wgquickBinPath"), wgquickBinPath != "" {
NSLog("Overriding 'wgquickBinPath' with: \(wgquickBinPath)")
self.wgquickBinPath = wgquickBinPath
} else {
wgquickBinPath = "\(brewPrefix)/bin/wg-quick"
}
}

Expand Down Expand Up @@ -180,16 +176,25 @@ class Helper: NSObject, HelperProtocol, SKQueueDelegate {
}
}

func wireguardInstalled(_ reply: (Bool) -> Void) {
let wireguardInstalled = FileManager.default.fileExists(atPath: wireguardBinPath)
let wgquickInstalled = FileManager.default.fileExists(atPath: wgquickBinPath)
reply(wgquickInstalled && wireguardInstalled)
}

// Launchd throttles services that restart to soon (<10 seconds), provide a mechanism to prevent this.
// set the time in the future when it is safe to shutdown the helper without launchd penalty
let launchdMinimaltimeExpired = DispatchTime.now() + DispatchTimeInterval.seconds(10)
var shutdownTask: DispatchWorkItem?

func shutdown() {
NSLog("Shutting down")
NSLog("Going to shut down")
// Dispatch the shutdown of the runloop to at least 10 seconds after starting the application.
// This will shutdown immidiately if the deadline already passed.
shutdownTask = DispatchWorkItem { CFRunLoopStop(CFRunLoopGetCurrent()) }
shutdownTask = DispatchWorkItem {
CFRunLoopStop(CFRunLoopGetCurrent())
NSLog("Shutting down")
}
// Dispatch to main queue since that is the thread where the runloop is
DispatchQueue.main.asyncAfter(deadline: launchdMinimaltimeExpired, execute: shutdownTask!)
}
Expand Down
2 changes: 1 addition & 1 deletion WireGuardStatusbarHelper/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<key>CFBundleShortVersionString</key>
<string>1.17</string>
<key>CFBundleVersion</key>
<string>1.0.16</string>
<string>1.0.17</string>
<key>SMAuthorizedClients</key>
<array>
<string>anchor apple generic and identifier &quot;WireGuardStatusbar&quot;</string>
Expand Down

0 comments on commit 24cfc8a

Please sign in to comment.