Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ed5893fc6 | ||
|
|
e70c397e54 | ||
|
|
6a6be9edde | ||
|
|
37f8500fe6 | ||
|
|
207f82dd9d | ||
|
|
de8fedf87a | ||
|
|
98d306da5b | ||
|
|
c7b7b1247b | ||
|
|
a66f13eb01 |
@@ -1,12 +1,14 @@
|
|||||||
# [WireGuard](https://www.wireguard.com/) for iOS and macOS
|
# [WireGuard](https://www.wireguard.com/) for iOS and macOS
|
||||||
|
|
||||||
|
This project contains an application for iOS and for macOS, as well as many components shared between the two of them. You may toggle between the two platforms by selecting the target from within Xcode.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
- Clone this repo recursively:
|
- Clone this repo:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone --recursive https://git.zx2c4.com/wireguard-ios
|
$ git clone https://git.zx2c4.com/wireguard-apple
|
||||||
$ cd wireguard-ios
|
$ cd wireguard-apple
|
||||||
```
|
```
|
||||||
|
|
||||||
- Rename and populate developer team ID file:
|
- Rename and populate developer team ID file:
|
||||||
|
|||||||
@@ -413,8 +413,6 @@
|
|||||||
|
|
||||||
"macAppExitingWithActiveTunnelMessage" = "WireGuard is exiting with an active tunnel";
|
"macAppExitingWithActiveTunnelMessage" = "WireGuard is exiting with an active tunnel";
|
||||||
"macAppExitingWithActiveTunnelInfo" = "The tunnel will remain active after exiting. You may disable it by reopening this application or through the Network panel in System Preferences.";
|
"macAppExitingWithActiveTunnelInfo" = "The tunnel will remain active after exiting. You may disable it by reopening this application or through the Network panel in System Preferences.";
|
||||||
"macPrivacyNoticeMessage" = "Privacy notice: be sure you trust this configuration file";
|
|
||||||
"macPrivacyNoticeInfo" = "You will be prompted by the system to allow or disallow adding a VPN configuration. While this application does not send any information to the WireGuard project, information is by design sent to the servers specified inside of the configuration file you have just added, which configures your computer to use those servers as a VPN. Be certain that you trust this configuration before clicking “Allow” in the following dialog.";
|
|
||||||
|
|
||||||
// Mac tooltip
|
// Mac tooltip
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
VERSION_NAME = 0.0.20190531
|
VERSION_NAME = 0.0.20190610
|
||||||
VERSION_ID = 10
|
VERSION_ID = 12
|
||||||
|
|||||||
@@ -46,46 +46,59 @@ extension ActivateOnDemandOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(from tunnelProviderManager: NETunnelProviderManager) {
|
init(from tunnelProviderManager: NETunnelProviderManager) {
|
||||||
let rules = tunnelProviderManager.onDemandRules ?? []
|
if tunnelProviderManager.isOnDemandEnabled, let onDemandRules = tunnelProviderManager.onDemandRules {
|
||||||
let activateOnDemandOption: ActivateOnDemandOption
|
self = ActivateOnDemandOption.create(from: onDemandRules)
|
||||||
|
} else {
|
||||||
|
self = .off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func create(from rules: [NEOnDemandRule]) -> ActivateOnDemandOption {
|
||||||
switch rules.count {
|
switch rules.count {
|
||||||
case 0:
|
case 0:
|
||||||
activateOnDemandOption = .off
|
return .off
|
||||||
case 1:
|
case 1:
|
||||||
let rule = rules[0]
|
let rule = rules[0]
|
||||||
precondition(rule.action == .connect)
|
guard rule.action == .connect else { return .off }
|
||||||
activateOnDemandOption = .anyInterface(.anySSID)
|
return .anyInterface(.anySSID)
|
||||||
case 2:
|
case 2:
|
||||||
let connectRule = rules.first(where: { $0.action == .connect })!
|
guard let connectRule = rules.first(where: { $0.action == .connect }) else {
|
||||||
let disconnectRule = rules.first(where: { $0.action == .disconnect })!
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found but no connect rule.")
|
||||||
|
return .off
|
||||||
|
}
|
||||||
|
guard let disconnectRule = rules.first(where: { $0.action == .disconnect }) else {
|
||||||
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found but no disconnect rule.")
|
||||||
|
return .off
|
||||||
|
}
|
||||||
if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == nonWiFiInterfaceType {
|
if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == nonWiFiInterfaceType {
|
||||||
activateOnDemandOption = .wiFiInterfaceOnly(.anySSID)
|
return .wiFiInterfaceOnly(.anySSID)
|
||||||
} else if connectRule.interfaceTypeMatch == nonWiFiInterfaceType && disconnectRule.interfaceTypeMatch == .wiFi {
|
} else if connectRule.interfaceTypeMatch == nonWiFiInterfaceType && disconnectRule.interfaceTypeMatch == .wiFi {
|
||||||
activateOnDemandOption = .nonWiFiInterfaceOnly
|
return .nonWiFiInterfaceOnly
|
||||||
} else {
|
} else {
|
||||||
fatalError("Unexpected onDemandRules set on tunnel provider manager")
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found but interface types are inconsistent.")
|
||||||
|
return .off
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
let ssidRule = rules.first(where: { $0.interfaceTypeMatch == .wiFi && $0.ssidMatch != nil })!
|
guard let ssidRule = rules.first(where: { $0.interfaceTypeMatch == .wiFi && $0.ssidMatch != nil }) else { return .off }
|
||||||
let nonWiFiRule = rules.first(where: { $0.interfaceTypeMatch == nonWiFiInterfaceType })!
|
guard let nonWiFiRule = rules.first(where: { $0.interfaceTypeMatch == nonWiFiInterfaceType }) else { return .off }
|
||||||
let ssids = ssidRule.ssidMatch!
|
let ssids = ssidRule.ssidMatch!
|
||||||
switch (ssidRule.action, nonWiFiRule.action) {
|
switch (ssidRule.action, nonWiFiRule.action) {
|
||||||
case (.connect, .connect):
|
case (.connect, .connect):
|
||||||
activateOnDemandOption = .anyInterface(.onlySpecificSSIDs(ssids))
|
return .anyInterface(.onlySpecificSSIDs(ssids))
|
||||||
case (.connect, .disconnect):
|
case (.connect, .disconnect):
|
||||||
activateOnDemandOption = .wiFiInterfaceOnly(.onlySpecificSSIDs(ssids))
|
return .wiFiInterfaceOnly(.onlySpecificSSIDs(ssids))
|
||||||
case (.disconnect, .connect):
|
case (.disconnect, .connect):
|
||||||
activateOnDemandOption = .anyInterface(.exceptSpecificSSIDs(ssids))
|
return .anyInterface(.exceptSpecificSSIDs(ssids))
|
||||||
case (.disconnect, .disconnect):
|
case (.disconnect, .disconnect):
|
||||||
activateOnDemandOption = .wiFiInterfaceOnly(.exceptSpecificSSIDs(ssids))
|
return .wiFiInterfaceOnly(.exceptSpecificSSIDs(ssids))
|
||||||
default:
|
default:
|
||||||
fatalError("Unexpected SSID onDemandRules set on tunnel provider manager")
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found")
|
||||||
|
return .off
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fatalError("Unexpected number of onDemandRules set on tunnel provider manager")
|
wg_log(.error, message: "Unexpected number of onDemandRules set on tunnel provider manager: \(rules.count) rules found")
|
||||||
|
return .off
|
||||||
}
|
}
|
||||||
|
|
||||||
self = activateOnDemandOption
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,10 @@ extension SSIDOptionEditTableViewController {
|
|||||||
case .ssidOption:
|
case .ssidOption:
|
||||||
let previousOption = selectedOption
|
let previousOption = selectedOption
|
||||||
selectedOption = ssidOptionFields[indexPath.row]
|
selectedOption = ssidOptionFields[indexPath.row]
|
||||||
|
guard previousOption != selectedOption else {
|
||||||
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
|
return
|
||||||
|
}
|
||||||
loadSections()
|
loadSections()
|
||||||
if previousOption == .anySSID {
|
if previousOption == .anySSID {
|
||||||
let indexSet = IndexSet(1 ... 2)
|
let indexSet = IndexSet(1 ... 2)
|
||||||
|
|||||||
@@ -132,10 +132,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
||||||
if UserDefaults.standard.bool(forKey: "shouldSuppressAppStoreUpdateDetection") {
|
|
||||||
wg_log(.debug, staticMessage: "App Store update detection is suppressed")
|
|
||||||
return .terminateNow
|
|
||||||
}
|
|
||||||
guard let currentTunnel = tunnelsTracker?.currentTunnel, currentTunnel.status == .active || currentTunnel.status == .activating else {
|
guard let currentTunnel = tunnelsTracker?.currentTunnel, currentTunnel.status == .active || currentTunnel.status == .activating else {
|
||||||
return .terminateNow
|
return .terminateNow
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||||||
private var handle: Int32?
|
private var handle: Int32?
|
||||||
private var networkMonitor: NWPathMonitor?
|
private var networkMonitor: NWPathMonitor?
|
||||||
private var ifname: String?
|
private var ifname: String?
|
||||||
private var lastSeenInterfaces: [String] = []
|
|
||||||
private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator?
|
private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator?
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@@ -143,20 +142,14 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||||||
|
|
||||||
private func pathUpdate(path: Network.NWPath) {
|
private func pathUpdate(path: Network.NWPath) {
|
||||||
guard let handle = handle else { return }
|
guard let handle = handle else { return }
|
||||||
guard let ifname = ifname else { return }
|
|
||||||
wg_log(.debug, message: "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)")
|
wg_log(.debug, message: "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)")
|
||||||
guard path.status == .satisfied else { return }
|
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
if let packetTunnelSettingsGenerator = packetTunnelSettingsGenerator {
|
if let packetTunnelSettingsGenerator = packetTunnelSettingsGenerator {
|
||||||
_ = packetTunnelSettingsGenerator.endpointUapiConfiguration().withGoString { return wgSetConfig(handle, $0) }
|
_ = packetTunnelSettingsGenerator.endpointUapiConfiguration().withGoString { return wgSetConfig(handle, $0) }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
let interfaces = path.availableInterfaces.filter { $0.name != ifname }.compactMap { $0.name }
|
wgBumpSockets(handle)
|
||||||
if !interfaces.elementsEqual(lastSeenInterfaces) {
|
|
||||||
lastSeenInterfaces = interfaces
|
|
||||||
wgBumpSockets(handle)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user