]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
macOS: Exclude private IPs
authorRoopesh Chander <roop@roopc.net>
Sat, 16 Feb 2019 12:55:17 +0000 (18:25 +0530)
committerRoopesh Chander <roop@roopc.net>
Sat, 16 Feb 2019 12:55:17 +0000 (18:25 +0530)
Signed-off-by: Roopesh Chander <roop@roopc.net>
WireGuard/WireGuard/UI/TunnelViewModel.swift
WireGuard/WireGuard/UI/macOS/View/ConfTextView.swift
WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift

index 1864cad66b07285634bb4a1138be59350d49feb6..8f95039de3b8df2c36b7ed8f9194ed4748003ef9 100644 (file)
@@ -547,6 +547,14 @@ class TunnelViewModel {
         }
     }
 
+    func asWgQuickConfig() -> String? {
+        let saveResult = save()
+        if case .saved(let tunnelConfiguration) = saveResult {
+            return tunnelConfiguration.asWgQuickConfig()
+        }
+        return nil
+    }
+
     @discardableResult
     func applyConfiguration(other: TunnelConfiguration) -> Changes {
         // Replaces current data with data from other TunnelConfiguration, ignoring any changes in peer ordering.
index bc019f823e5367048ec9fccc94d70f51e58f61e5..2ea8f843190449fb658342507372a91beb8cd678 100644 (file)
@@ -9,6 +9,7 @@ class ConfTextView: NSTextView {
 
     @objc dynamic var hasError: Bool = false
     @objc dynamic var privateKeyString: String?
+    @objc dynamic var singlePeerAllowedIPs: [String]?
 
     override var string: String {
         didSet {
@@ -52,6 +53,13 @@ class ConfTextView: NSTextView {
         }
     }
 
+    func setConfText(_ text: String) {
+        let fullTextRange = NSRange(location: 0, length: (string as NSString).length)
+        if shouldChangeText(in: fullTextRange, replacementString: text) {
+            replaceCharacters(in: fullTextRange, with: text)
+            didChangeText()
+        }
+    }
 }
 
 extension ConfTextView: NSTextViewDelegate {
@@ -64,6 +72,10 @@ extension ConfTextView: NSTextViewDelegate {
         if privateKeyString != confTextStorage.privateKeyString {
             privateKeyString = confTextStorage.privateKeyString
         }
+        let updatedSinglePeerAllowedIPs = confTextStorage.hasOnePeer && !confTextStorage.hasError ? confTextStorage.lastOnePeerAllowedIPs : nil
+        if singlePeerAllowedIPs != updatedSinglePeerAllowedIPs {
+            singlePeerAllowedIPs = updatedSinglePeerAllowedIPs
+        }
         needsDisplay = true
     }
 
index efb3fd74434531f7cdcc9a581ecd384814347ddf..772ee7f909196a667c8f20607bcdc87cb8552c31 100644 (file)
@@ -56,6 +56,14 @@ class TunnelEditViewController: NSViewController {
         return scrollView
     }()
 
+    let excludePrivateIPsCheckbox: NSButton = {
+        let checkbox = NSButton()
+        checkbox.title = tr("tunnelPeerExcludePrivateIPs")
+        checkbox.setButtonType(.switch)
+        checkbox.state = .off
+        return checkbox
+    }()
+
     let discardButton: NSButton = {
         let button = NSButton()
         button.title = tr("macEditDiscard")
@@ -86,6 +94,7 @@ class TunnelEditViewController: NSViewController {
 
     var privateKeyObservationToken: AnyObject?
     var hasErrorObservationToken: AnyObject?
+    var singlePeerAllowedIPsObservationToken: AnyObject?
 
     init(tunnelsManager: TunnelsManager, tunnel: TunnelContainer?) {
         self.tunnelsManager = tunnelsManager
@@ -111,6 +120,8 @@ class TunnelEditViewController: NSViewController {
             } else {
                 selectedActivateOnDemandOption = .none
             }
+            let singlePeer = tunnelConfiguration.peers.count == 1 ? tunnelConfiguration.peers.first : nil
+            updateExcludePrivateIPsVisibility(singlePeerAllowedIPs: singlePeer?.allowedIPs.map { $0.stringRepresentation })
         } else {
             // Creating a new tunnel
             let privateKey = Curve25519.generatePrivateKey()
@@ -133,6 +144,9 @@ class TunnelEditViewController: NSViewController {
         hasErrorObservationToken = textView.observe(\.hasError) { [weak saveButton] textView, _ in
             saveButton?.isEnabled = !textView.hasError
         }
+        singlePeerAllowedIPsObservationToken = textView.observe(\.singlePeerAllowedIPs) { [weak self] textView, _ in
+            self?.updateExcludePrivateIPsVisibility(singlePeerAllowedIPs: textView.singlePeerAllowedIPs)
+        }
 
         onDemandRow.valueOptions = activateOnDemandOptions.map { TunnelViewModel.activateOnDemandOptionText(for: $0) }
         onDemandRow.selectedOptionIndex = activateOnDemandOptions.firstIndex(of: selectedActivateOnDemandOption)!
@@ -149,6 +163,9 @@ class TunnelEditViewController: NSViewController {
         discardButton.target = self
         discardButton.action = #selector(handleDiscardAction)
 
+        excludePrivateIPsCheckbox.target = self
+        excludePrivateIPsCheckbox.action = #selector(excludePrivateIPsCheckboxToggled(sender:))
+
         let margin: CGFloat = 20
         let internalSpacing: CGFloat = 10
 
@@ -159,6 +176,7 @@ class TunnelEditViewController: NSViewController {
 
         let buttonRowStackView = NSStackView()
         buttonRowStackView.setViews([discardButton, saveButton], in: .trailing)
+        buttonRowStackView.addView(excludePrivateIPsCheckbox, in: .leading)
         buttonRowStackView.orientation = .horizontal
         buttonRowStackView.spacing = internalSpacing
 
@@ -237,4 +255,27 @@ class TunnelEditViewController: NSViewController {
         delegate?.tunnelEditingCancelled()
         dismiss(self)
     }
+
+    func updateExcludePrivateIPsVisibility(singlePeerAllowedIPs: [String]?) {
+        let shouldAllowExcludePrivateIPsControl: Bool
+        let excludePrivateIPsValue: Bool
+        if let singlePeerAllowedIPs = singlePeerAllowedIPs {
+            (shouldAllowExcludePrivateIPsControl, excludePrivateIPsValue) = TunnelViewModel.PeerData.excludePrivateIPsFieldStates(isSinglePeer: true, allowedIPs: Set<String>(singlePeerAllowedIPs))
+        } else {
+            (shouldAllowExcludePrivateIPsControl, excludePrivateIPsValue) = TunnelViewModel.PeerData.excludePrivateIPsFieldStates(isSinglePeer: false, allowedIPs: Set<String>())
+        }
+        excludePrivateIPsCheckbox.isHidden = !shouldAllowExcludePrivateIPsControl
+        excludePrivateIPsCheckbox.state = excludePrivateIPsValue ? .on : .off
+    }
+
+    @objc func excludePrivateIPsCheckboxToggled(sender: AnyObject?) {
+        guard let excludePrivateIPsCheckbox = sender as? NSButton else { return }
+        guard let tunnelConfiguration = try? TunnelConfiguration(fromWgQuickConfig: textView.string, called: nameRow.value) else { return }
+        let isOn = excludePrivateIPsCheckbox.state == .on
+        let tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnelConfiguration)
+        tunnelViewModel.peersData.first?.excludePrivateIPsValueChanged(isOn: isOn, dnsServers: tunnelViewModel.interfaceData[.dns])
+        if let modifiedConfig = tunnelViewModel.asWgQuickConfig() {
+            textView.setConfText(modifiedConfig)
+        }
+    }
 }