aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-06-11 02:03:11 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-06-11 02:18:42 +0200
commit377f2f0496e88713fe576d9b47378150d4005655 (patch)
tree42d7718eef7ac63b98ee338316336d7c7ee7bb0a /WireGuard
parentVersion bump (diff)
downloadwireguard-apple-377f2f0496e88713fe576d9b47378150d4005655.tar.xz
wireguard-apple-377f2f0496e88713fe576d9b47378150d4005655.zip
TunnelsManager: store UID on macOS for keychain availability
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'WireGuard')
-rw-r--r--WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift29
-rw-r--r--WireGuard/WireGuard/Tunnel/TunnelsManager.swift46
-rw-r--r--WireGuard/WireGuard/UI/macOS/StatusMenu.swift2
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift2
4 files changed, 45 insertions, 34 deletions
diff --git a/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift b/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift
index 856df1f..7828d81 100644
--- a/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift
+++ b/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift
@@ -22,6 +22,9 @@ extension NETunnelProviderProtocol {
if passwordReference == nil {
return nil
}
+ #if os(macOS)
+ providerConfiguration = ["UID": getuid()]
+ #endif
let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint }
if endpoints.count == 1 {
@@ -60,11 +63,25 @@ extension NETunnelProviderProtocol {
* in the keychain. But it's still useful to keep the migration
* around so that .mobileconfig files are easier.
*/
- guard let oldConfig = providerConfiguration?["WgQuickConfig"] as? String else { return false }
- providerConfiguration = nil
- guard passwordReference == nil else { return true }
- wg_log(.debug, message: "Migrating tunnel configuration '\(name)'")
- passwordReference = Keychain.makeReference(containing: oldConfig, called: name)
- return true
+ if let oldConfig = providerConfiguration?["WgQuickConfig"] as? String {
+ #if os(macOS)
+ providerConfiguration = ["UID": getuid()]
+ #elseif os(iOS)
+ providerConfiguration = nil
+ #else
+ #error("Unimplemented")
+ #endif
+ guard passwordReference == nil else { return true }
+ wg_log(.debug, message: "Migrating tunnel configuration '\(name)'")
+ passwordReference = Keychain.makeReference(containing: oldConfig, called: name)
+ return true
+ }
+ #if os(macOS)
+ if passwordReference != nil && providerConfiguration?["UID"] == nil && verifyConfigurationReference() {
+ providerConfiguration = ["UID": getuid()]
+ return true
+ }
+ #endif
+ return false
}
}
diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
index c43fa50..ec1ea74 100644
--- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
+++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
@@ -58,7 +58,12 @@ class TunnelsManager {
#if os(iOS)
let passwordRef = proto.verifyConfigurationReference() ? proto.passwordReference : nil
#elseif os(macOS)
- let passwordRef = proto.passwordReference // To handle multiple users in macOS, we skip verifying
+ let passwordRef: Data?
+ if proto.providerConfiguration?["UID"] as? uid_t == getuid() {
+ passwordRef = proto.verifyConfigurationReference() ? proto.passwordReference : nil
+ } else {
+ passwordRef = proto.passwordReference // To handle multiple users in macOS, we skip verifying
+ }
#else
#error("Unimplemented")
#endif
@@ -262,10 +267,15 @@ class TunnelsManager {
func remove(tunnel: TunnelContainer, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
let tunnelProviderManager = tunnel.tunnelProvider
- if tunnel.isTunnelConfigurationAvailableInKeychain {
+ #if os(macOS)
+ if tunnel.isTunnelAvailableToUser {
(tunnelProviderManager.protocolConfiguration as? NETunnelProviderProtocol)?.destroyConfigurationReference()
}
-
+ #elseif os(iOS)
+ (tunnelProviderManager.protocolConfiguration as? NETunnelProviderProtocol)?.destroyConfigurationReference()
+ #else
+ #error("Unimplemented")
+ #endif
tunnelProviderManager.removeFromPreferences { [weak self] error in
guard error == nil else {
wg_log(.error, message: "Remove: Saving configuration failed: \(error!)")
@@ -493,14 +503,16 @@ class TunnelContainer: NSObject {
return tunnelProvider.tunnelConfiguration
}
- var isTunnelConfigurationAvailableInKeychain: Bool {
- return tunnelProvider.isTunnelConfigurationAvailableInKeychain
- }
-
var onDemandOption: ActivateOnDemandOption {
return ActivateOnDemandOption(from: tunnelProvider)
}
+ #if os(macOS)
+ var isTunnelAvailableToUser: Bool {
+ return (tunnelProvider.protocolConfiguration as? NETunnelProviderProtocol)?.providerConfiguration?["UID"] as? uid_t == getuid()
+ }
+ #endif
+
init(tunnel: NETunnelProviderManager) {
name = tunnel.localizedDescription ?? "Unnamed"
let status = TunnelStatus(from: tunnel.connection.status)
@@ -609,18 +621,8 @@ class TunnelContainer: NSObject {
}
extension NETunnelProviderManager {
- private static var cachedIsConfigAvailableInKeychainKey: UInt8 = 0
private static var cachedConfigKey: UInt8 = 0
- var isTunnelConfigurationAvailableInKeychain: Bool {
- if let cachedNumber = objc_getAssociatedObject(self, &NETunnelProviderManager.cachedIsConfigAvailableInKeychainKey) as? NSNumber {
- return cachedNumber.boolValue
- }
- let isAvailable = (protocolConfiguration as? NETunnelProviderProtocol)?.verifyConfigurationReference() ?? false
- objc_setAssociatedObject(self, &NETunnelProviderManager.cachedIsConfigAvailableInKeychainKey, NSNumber(value: isAvailable), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
- return isAvailable
- }
-
var tunnelConfiguration: TunnelConfiguration? {
if let cached = objc_getAssociatedObject(self, &NETunnelProviderManager.cachedConfigKey) as? TunnelConfiguration {
return cached
@@ -636,17 +638,9 @@ extension NETunnelProviderManager {
protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration, previouslyFrom: protocolConfiguration)
localizedDescription = tunnelConfiguration.name
objc_setAssociatedObject(self, &NETunnelProviderManager.cachedConfigKey, tunnelConfiguration, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
- objc_setAssociatedObject(self, &NETunnelProviderManager.cachedIsConfigAvailableInKeychainKey, NSNumber(value: true), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func isEquivalentTo(_ tunnel: TunnelContainer) -> Bool {
- switch (isTunnelConfigurationAvailableInKeychain, tunnel.isTunnelConfigurationAvailableInKeychain) {
- case (true, true):
- return tunnelConfiguration == tunnel.tunnelConfiguration
- case (false, false):
- return localizedDescription == tunnel.name
- default:
- return false
- }
+ return localizedDescription == tunnel.name && tunnelConfiguration == tunnel.tunnelConfiguration
}
}
diff --git a/WireGuard/WireGuard/UI/macOS/StatusMenu.swift b/WireGuard/WireGuard/UI/macOS/StatusMenu.swift
index f4f999d..ec9ffe8 100644
--- a/WireGuard/WireGuard/UI/macOS/StatusMenu.swift
+++ b/WireGuard/WireGuard/UI/macOS/StatusMenu.swift
@@ -168,7 +168,7 @@ extension StatusMenu {
func insertTunnelMenuItem(for tunnel: TunnelContainer, at tunnelIndex: Int) {
let menuItem = TunnelMenuItem(tunnel: tunnel, action: #selector(tunnelClicked(sender:)))
menuItem.target = self
- menuItem.isHidden = !tunnel.isTunnelConfigurationAvailableInKeychain
+ menuItem.isHidden = !tunnel.isTunnelAvailableToUser
insertItem(menuItem, at: firstTunnelMenuItemIndex + tunnelIndex)
if numberOfTunnelMenuItems == 0 {
insertItem(NSMenuItem.separator(), at: firstTunnelMenuItemIndex + tunnelIndex + 1)
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift
index 179387f..0ad0805 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift
@@ -81,7 +81,7 @@ extension ManageTunnelsRootViewController: TunnelsListTableViewControllerDelegat
assert(!tunnelIndices.isEmpty)
if tunnelIndices.count == 1 {
let tunnel = tunnelsManager.tunnel(at: tunnelIndices.first!)
- if tunnel.isTunnelConfigurationAvailableInKeychain {
+ if tunnel.isTunnelAvailableToUser {
let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
setTunnelDetailContentVC(tunnelDetailVC)
self.tunnelDetailVC = tunnelDetailVC