Add switch to info view controller.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jeroen Leenarts
2018-09-29 22:29:34 +02:00
parent cc6c8e36e0
commit dd02986a78
6 changed files with 208 additions and 88 deletions
@@ -3,8 +3,22 @@
//
import Foundation
import NetworkExtension
extension AppCoordinator: TunnelInfoTableViewControllerDelegate {
func connect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
connect(tunnel: tunnel)
}
func disconnect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
disconnect(tunnel: tunnel)
}
func status(for tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) -> NEVPNStatus {
let session = self.providerManager(for: tunnel)?.connection as? NETunnelProviderSession
return session?.status ?? .invalid
}
func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
print("configure tunnel \(tunnel)")
let editContext = persistentContainer.newBackgroundContext()
@@ -55,77 +55,11 @@ extension AppCoordinator: TunnelsTableViewControllerDelegate {
}
func connect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
_ = refreshProviderManagers().then { () -> Promise<Void> in
let manager = self.providerManager(for: tunnel)!
let block = {
switch manager.connection.status {
case .invalid, .disconnected:
self.connect(tunnel: tunnel)
default:
break
}
}
if manager.connection.status == .invalid {
manager.loadFromPreferences { (_) in
block()
}
} else {
block()
}
return Promise.value(())
}
connect(tunnel: tunnel)
}
func disconnect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
_ = refreshProviderManagers().then { () -> Promise<Void> in
let manager = self.providerManager(for: tunnel)!
let block = {
switch manager.connection.status {
case .connected, .connecting:
self.disconnect(tunnel: tunnel)
default:
break
}
}
if manager.connection.status == .invalid {
manager.loadFromPreferences { (_) in
block()
}
} else {
block()
}
return Promise.value(())
}
}
private func connect(tunnel: Tunnel) {
os_log("connect tunnel: %{public}@", log: Log.general, type: .info, tunnel.description)
// Should the manager be enabled?
let manager = providerManager(for: tunnel)
manager?.isEnabled = true
manager?.saveToPreferences { (error) in
if let error = error {
os_log("error saving preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
return
}
os_log("saved preferences", log: Log.general, type: .info)
let session = manager?.connection as! NETunnelProviderSession //swiftlint:disable:this force_cast
do {
try session.startTunnel()
} catch let error {
os_log("error starting tunnel: %{public}@", log: Log.general, type: .error, error.localizedDescription)
}
}
}
func disconnect(tunnel: Tunnel) {
let manager = providerManager(for: tunnel)
manager?.connection.stopVPNTunnel()
disconnect(tunnel: tunnel)
}
func info(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
@@ -154,18 +88,6 @@ extension AppCoordinator: TunnelsTableViewControllerDelegate {
}
}
private func providerManager(for tunnel: Tunnel) -> NETunnelProviderManager? {
return self.providerManagers?.first {
guard let prot = $0.protocolConfiguration as? NETunnelProviderProtocol else {
return false
}
guard let tunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
return false
}
return tunnelIdentifier == tunnel.tunnelIdentifier
}
}
func saveTunnel(_ tunnel: Tunnel) {
let manager = providerManager(for: tunnel) ?? NETunnelProviderManager()
manager.localizedDescription = tunnel.title
@@ -291,6 +291,73 @@ class AppCoordinator: RootViewCoordinator {
showAlert(title: NSLocalizedString("Error", comment: "Error alert title"), message: error.localizedDescription)
}
func connect(tunnel: Tunnel) {
_ = refreshProviderManagers().then { () -> Promise<Void> in
let manager = self.providerManager(for: tunnel)!
let block = {
switch manager.connection.status {
case .invalid, .disconnected:
os_log("connect tunnel: %{public}@", log: Log.general, type: .info, tunnel.description)
// Should the manager be enabled?
let manager = self.providerManager(for: tunnel)
manager?.isEnabled = true
manager?.saveToPreferences { (error) in
if let error = error {
os_log("error saving preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
return
}
os_log("saved preferences", log: Log.general, type: .info)
let session = manager?.connection as! NETunnelProviderSession //swiftlint:disable:this force_cast
do {
try session.startTunnel()
} catch let error {
os_log("error starting tunnel: %{public}@", log: Log.general, type: .error, error.localizedDescription)
}
}
default:
break
}
}
if manager.connection.status == .invalid {
manager.loadFromPreferences { (_) in
block()
}
} else {
block()
}
return Promise.value(())
}
}
func disconnect(tunnel: Tunnel) {
_ = refreshProviderManagers().then { () -> Promise<Void> in
let manager = self.providerManager(for: tunnel)!
let block = {
switch manager.connection.status {
case .connected, .connecting:
let manager = self.providerManager(for: tunnel)
manager?.connection.stopVPNTunnel()
default:
break
}
}
if manager.connection.status == .invalid {
manager.loadFromPreferences { (_) in
block()
}
} else {
block()
}
return Promise.value(())
}
}
private func showAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default))
@@ -313,6 +380,18 @@ class AppCoordinator: RootViewCoordinator {
return "Reasserting"
}
}
func providerManager(for tunnel: Tunnel) -> NETunnelProviderManager? {
return self.providerManagers?.first {
guard let prot = $0.protocolConfiguration as? NETunnelProviderProtocol else {
return false
}
guard let tunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
return false
}
return tunnelIdentifier == tunnel.tunnelIdentifier
}
}
}
class AppDocumentPickerDelegate: NSObject, UIDocumentPickerDelegate {