aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2019-01-09 04:14:08 +0530
committerRoopesh Chander <roop@roopc.net>2019-01-14 14:52:36 +0530
commit13e8c6b1780eab5bd7257ba79020651e421f099c (patch)
tree0478cdfc35591b0785532d70aeeb66689ebdfb6d /WireGuard
parentmacOS: Quit menu item (diff)
downloadwireguard-apple-13e8c6b1780eab5bd7257ba79020651e421f099c.tar.xz
wireguard-apple-13e8c6b1780eab5bd7257ba79020651e421f099c.zip
macOS: Support for on-demand activation
Signed-off-by: Roopesh Chander <roop@roopc.net>
Diffstat (limited to 'WireGuard')
-rw-r--r--WireGuard/WireGuard.xcodeproj/project.pbxproj4
-rw-r--r--WireGuard/WireGuard/Base.lproj/Localizable.strings1
-rw-r--r--WireGuard/WireGuard/UI/macOS/View/PopupRow.swift75
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift11
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift36
5 files changed, 124 insertions, 3 deletions
diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj
index 0cc3579a..a5119b65 100644
--- a/WireGuard/WireGuard.xcodeproj/project.pbxproj
+++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj
@@ -59,6 +59,7 @@
6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */; };
6F919EDB218C65C50023B400 /* wireguard_doc_logo_64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED7218C65C50023B400 /* wireguard_doc_logo_64x64.png */; };
6F919EDC218C65C50023B400 /* wireguard_doc_logo_320x320.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED8218C65C50023B400 /* wireguard_doc_logo_320x320.png */; };
+ 6F9B582921E8D6D100544D02 /* PopupRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F9B582721E8CD4300544D02 /* PopupRow.swift */; };
6FB1017921C57DE600766195 /* MockTunnels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB1017821C57DE600766195 /* MockTunnels.swift */; };
6FB1BD6021D2607A00A991BF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB1BD5F21D2607A00A991BF /* AppDelegate.swift */; };
6FB1BD6221D2607E00A991BF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6FB1BD6121D2607E00A991BF /* Assets.xcassets */; };
@@ -267,6 +268,7 @@
6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_44x58.png; sourceTree = "<group>"; };
6F919ED7218C65C50023B400 /* wireguard_doc_logo_64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_64x64.png; sourceTree = "<group>"; };
6F919ED8218C65C50023B400 /* wireguard_doc_logo_320x320.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_320x320.png; sourceTree = "<group>"; };
+ 6F9B582721E8CD4300544D02 /* PopupRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupRow.swift; sourceTree = "<group>"; };
6FB1017821C57DE600766195 /* MockTunnels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTunnels.swift; sourceTree = "<group>"; };
6FB1BD5D21D2607A00A991BF /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
6FB1BD5F21D2607A00A991BF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -387,6 +389,7 @@
6F613D9A21DE33B8004B217A /* KeyValueRow.swift */,
5F52D0BA21E3781B00283CEA /* ConfTextView.swift */,
5F52D0BC21E3785C00283CEA /* ConfTextStorage.swift */,
+ 6F9B582721E8CD4300544D02 /* PopupRow.swift */,
);
path = View;
sourceTree = "<group>";
@@ -1103,6 +1106,7 @@
6FCD99B121E0EDA900BA4C82 /* TunnelEditViewController.swift in Sources */,
6FB1BDCA21D50F1700A991BF /* x25519.c in Sources */,
6FB1BDCB21D50F1700A991BF /* Curve25519.swift in Sources */,
+ 6F9B582921E8D6D100544D02 /* PopupRow.swift in Sources */,
6FB1BDBB21D50F0200A991BF /* Localizable.strings in Sources */,
6FB1BDBC21D50F0200A991BF /* ringlogger.c in Sources */,
6FB1BDBD21D50F0200A991BF /* ringlogger.h in Sources */,
diff --git a/WireGuard/WireGuard/Base.lproj/Localizable.strings b/WireGuard/WireGuard/Base.lproj/Localizable.strings
index 369cfccd..cf73bf30 100644
--- a/WireGuard/WireGuard/Base.lproj/Localizable.strings
+++ b/WireGuard/WireGuard/Base.lproj/Localizable.strings
@@ -255,6 +255,7 @@
// Mac detail/edit view fields
"macFieldKey (%@)" = "%@:";
+"macFieldOnDemand" = "On-Demand:";
// Mac status display
diff --git a/WireGuard/WireGuard/UI/macOS/View/PopupRow.swift b/WireGuard/WireGuard/UI/macOS/View/PopupRow.swift
new file mode 100644
index 00000000..2ef55f5e
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/View/PopupRow.swift
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018 WireGuard LLC. All Rights Reserved.
+
+import Cocoa
+
+class PopupRow: NSView {
+ let keyLabel: NSTextField = {
+ let keyLabel = NSTextField()
+ keyLabel.isEditable = false
+ keyLabel.isSelectable = false
+ keyLabel.isBordered = false
+ keyLabel.alignment = .right
+ keyLabel.maximumNumberOfLines = 1
+ keyLabel.lineBreakMode = .byTruncatingTail
+ keyLabel.backgroundColor = .clear
+ return keyLabel
+ }()
+
+ let valuePopup = NSPopUpButton()
+
+ var key: String {
+ get { return keyLabel.stringValue }
+ set(value) { keyLabel.stringValue = value }
+ }
+
+ var valueOptions: [String] {
+ get { return valuePopup.itemTitles }
+ set(value) {
+ valuePopup.removeAllItems()
+ valuePopup.addItems(withTitles: value)
+ }
+ }
+
+ var selectedOptionIndex: Int {
+ get { return valuePopup.indexOfSelectedItem }
+ set(value) { valuePopup.selectItem(at: value) }
+ }
+
+ override var intrinsicContentSize: NSSize {
+ let height = max(keyLabel.intrinsicContentSize.height, valuePopup.intrinsicContentSize.height)
+ return NSSize(width: NSView.noIntrinsicMetric, height: height)
+ }
+
+ init() {
+ super.init(frame: CGRect.zero)
+
+ addSubview(keyLabel)
+ addSubview(valuePopup)
+ keyLabel.translatesAutoresizingMaskIntoConstraints = false
+ valuePopup.translatesAutoresizingMaskIntoConstraints = false
+
+ NSLayoutConstraint.activate([
+ keyLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor),
+ keyLabel.firstBaselineAnchor.constraint(equalTo: valuePopup.firstBaselineAnchor),
+ self.leadingAnchor.constraint(equalTo: keyLabel.leadingAnchor),
+ keyLabel.trailingAnchor.constraint(equalTo: valuePopup.leadingAnchor, constant: -5)
+ ])
+
+ keyLabel.setContentCompressionResistancePriority(.defaultHigh + 2, for: .horizontal)
+ keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
+
+ let widthConstraint = keyLabel.widthAnchor.constraint(equalToConstant: 150)
+ widthConstraint.priority = .defaultHigh + 1
+ widthConstraint.isActive = true
+ }
+
+ required init?(coder decoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func prepareForReuse() {
+ key = ""
+ valueOptions = []
+ }
+}
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift
index 3c070606..5f6c891b 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift
@@ -8,12 +8,14 @@ class TunnelDetailTableViewController: NSViewController {
private enum TableViewModelRow {
case interfaceFieldRow(TunnelViewModel.InterfaceField)
case peerFieldRow(peer: TunnelViewModel.PeerData, field: TunnelViewModel.PeerField)
+ case onDemandRow
case spacerRow
func localizedSectionKeyString() -> String {
switch self {
case .interfaceFieldRow: return tr("tunnelSectionTitleInterface")
case .peerFieldRow: return tr("tunnelSectionTitlePeer")
+ case .onDemandRow: return ""
case .spacerRow: return ""
}
}
@@ -22,6 +24,7 @@ class TunnelDetailTableViewController: NSViewController {
switch self {
case .interfaceFieldRow(let field): return field == .name
case .peerFieldRow(_, let field): return field == .publicKey
+ case .onDemandRow: return true
case .spacerRow: return false
}
}
@@ -163,6 +166,8 @@ class TunnelDetailTableViewController: NSViewController {
tableViewModelRows.append(.peerFieldRow(peer: peerData, field: field))
}
}
+ tableViewModelRows.append(.spacerRow)
+ tableViewModelRows.append(.onDemandRow)
}
func updateStatus() {
@@ -232,6 +237,12 @@ extension TunnelDetailTableViewController: NSTableViewDelegate {
return cell
case .spacerRow:
return NSView()
+ case .onDemandRow:
+ let cell: KeyValueRow = tableView.dequeueReusableCell()
+ cell.key = tr("macFieldOnDemand")
+ cell.value = TunnelViewModel.activateOnDemandDetailText(for: tunnel.activateOnDemandSetting)
+ cell.isKeyInBold = true
+ return cell
}
}
}
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift
index ae95fba2..aecb3c91 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift
@@ -41,6 +41,12 @@ class TunnelEditViewController: NSViewController {
return textView
}()
+ let onDemandRow: PopupRow = {
+ let popupRow = PopupRow()
+ popupRow.key = tr("macFieldOnDemand")
+ return popupRow
+ }()
+
let scrollView: NSScrollView = {
let scrollView = NSScrollView()
scrollView.hasVerticalScroller = true
@@ -64,6 +70,13 @@ class TunnelEditViewController: NSViewController {
return button
}()
+ let activateOnDemandOptions: [ActivateOnDemandOption] = [
+ .none,
+ .useOnDemandOverWiFiOrEthernet,
+ .useOnDemandOverWiFiOnly,
+ .useOnDemandOverEthernetOnly
+ ]
+
let tunnelsManager: TunnelsManager
let tunnel: TunnelContainer?
@@ -82,6 +95,7 @@ class TunnelEditViewController: NSViewController {
}
func populateTextFields() {
+ let selectedActivateOnDemandOption: ActivateOnDemandOption
if let tunnel = tunnel {
// Editing an existing tunnel
let tunnelConfiguration = tunnel.tunnelConfiguration!
@@ -99,6 +113,11 @@ class TunnelEditViewController: NSViewController {
publicKeyRow?.value = ""
}
}
+ if tunnel.activateOnDemandSetting.isActivateOnDemandEnabled {
+ selectedActivateOnDemandOption = tunnel.activateOnDemandSetting.activateOnDemandOption
+ } else {
+ selectedActivateOnDemandOption = .none
+ }
} else {
// Creating a new tunnel
let privateKey = Curve25519.generatePrivateKey()
@@ -109,7 +128,13 @@ class TunnelEditViewController: NSViewController {
"""
publicKeyRow.value = publicKey.base64EncodedString()
textView.string = bootstrappingText
+ selectedActivateOnDemandOption = .none
}
+
+ onDemandRow.valueOptions = activateOnDemandOptions.map {
+ return TunnelViewModel.activateOnDemandOptionText(for: $0)
+ }
+ onDemandRow.selectedOptionIndex = activateOnDemandOptions.firstIndex(of: selectedActivateOnDemandOption)!
}
override func loadView() {
@@ -126,7 +151,7 @@ class TunnelEditViewController: NSViewController {
let margin: CGFloat = 20
let internalSpacing: CGFloat = 10
- let editorStackView = NSStackView(views: [nameRow, publicKeyRow, scrollView])
+ let editorStackView = NSStackView(views: [nameRow, publicKeyRow, onDemandRow, scrollView])
editorStackView.orientation = .vertical
editorStackView.setHuggingPriority(.defaultHigh, for: .horizontal)
editorStackView.spacing = internalSpacing
@@ -157,6 +182,13 @@ class TunnelEditViewController: NSViewController {
ErrorPresenter.showErrorAlert(title: tr("macAlertNameIsEmpty"), message: "", from: self)
return
}
+ let onDemandSetting: ActivateOnDemandSetting
+ let onDemandOption = activateOnDemandOptions[onDemandRow.selectedOptionIndex]
+ if onDemandOption == .none {
+ onDemandSetting = ActivateOnDemandSetting.defaultSetting
+ } else {
+ onDemandSetting = ActivateOnDemandSetting(isActivateOnDemandEnabled: true, activateOnDemandOption: onDemandOption)
+ }
if let tunnel = tunnel {
// We're modifying an existing tunnel
if name != tunnel.name && tunnelsManager.tunnel(named: name) != nil {
@@ -165,7 +197,6 @@ class TunnelEditViewController: NSViewController {
}
do {
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: textView.string, called: nameRow.value)
- let onDemandSetting = ActivateOnDemandSetting.defaultSetting
tunnelsManager.modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: onDemandSetting) { [weak self] error in
if let error = error {
ErrorPresenter.showErrorAlert(error: error, from: self)
@@ -187,7 +218,6 @@ class TunnelEditViewController: NSViewController {
}
do {
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: textView.string, called: nameRow.value)
- let onDemandSetting = ActivateOnDemandSetting.defaultSetting
tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: onDemandSetting) { [weak self] result in
if let error = result.error {
ErrorPresenter.showErrorAlert(error: error, from: self)