Compare commits

...

9 Commits

Author SHA1 Message Date
Jason A. Donenfeld de8fedf87a Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-09 11:39:06 +02:00
Jason A. Donenfeld 98d306da5b macOS: remove store update escape hatch
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-09 11:39:06 +02:00
Jason A. Donenfeld c7b7b1247b TunnelProvider: store the entire NWPath
Otherwise [utun0, en0] == [en0, utun0] before WiFi has connected, and we
wind up not rebinding after WiFi does successfully connect, which means
people have trouble when resuming from sleep.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-09 11:39:06 +02:00
Jason A. Donenfeld a66f13eb01 README: update repo location
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-09 11:39:06 +02:00
Jason A. Donenfeld f50e7ae686 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-06 10:27:39 +02:00
Roopesh Chander 4d6692548c macOS: App menu > Quit shall show a prompt to quit or close window
Signed-off-by: Roopesh Chander <roop@roopc.net>
2019-06-06 10:27:11 +02:00
Roopesh Chander 1dccd39818 macOS: Save/restore the log window's size
Signed-off-by: Roopesh Chander <roop@roopc.net>
2019-06-04 20:34:37 +05:30
Roopesh Chander 4cb775c72f macOS: Log view: Allow resizing horizontally
Signed-off-by: Roopesh Chander <roop@roopc.net>
2019-06-04 15:48:42 +05:30
Jason A. Donenfeld 4cb783c447 go-bridge: bump version
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-05-31 19:20:51 +02:00
9 changed files with 84 additions and 39 deletions
+5 -3
View File
@@ -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:
@@ -308,7 +308,6 @@
"macMenuHideApp" = "Hide WireGuard"; "macMenuHideApp" = "Hide WireGuard";
"macMenuHideOtherApps" = "Hide Others"; "macMenuHideOtherApps" = "Hide Others";
"macMenuShowAllApps" = "Show All"; "macMenuShowAllApps" = "Show All";
"macMenuQuitManagingTunnels" = "Quit Tunnel Manager";
"macMenuFile" = "File"; "macMenuFile" = "File";
"macMenuCloseWindow" = "Close Window"; "macMenuCloseWindow" = "Close Window";
@@ -406,6 +405,12 @@
// Mac alert // Mac alert
"macConfirmAndQuitAlertMessage" = "Do you want to close the tunnels manager or quit WireGuard entirely?";
"macConfirmAndQuitAlertInfo" = "If you close the tunnels manager, WireGuard will continue to be available from the menu bar icon.";
"macConfirmAndQuitInfoWithActiveTunnel (%@)" = "If you close the tunnels manager, WireGuard will continue to be available from the menu bar icon.\n\nNote that if you quit WireGuard entirely the currently active tunnel ('%@') will still remain active until you deactivate it from this application or through the Network panel in System Preferences.";
"macConfirmAndQuitAlertQuitWireGuard" = "Quit WireGuard";
"macConfirmAndQuitAlertCloseWindow" = "Close Tunnels Manager";
"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"; "macPrivacyNoticeMessage" = "Privacy notice: be sure you trust this configuration file";
+2 -2
View File
@@ -1,2 +1,2 @@
VERSION_NAME = 0.0.20190531 VERSION_NAME = 0.0.20190609
VERSION_ID = 9 VERSION_ID = 11
+27 -4
View File
@@ -78,6 +78,33 @@ class AppDelegate: NSObject, NSApplicationDelegate {
return false return false
} }
@objc func confirmAndQuit() {
let alert = NSAlert()
alert.messageText = tr("macConfirmAndQuitAlertMessage")
if let currentTunnel = tunnelsTracker?.currentTunnel, currentTunnel.status == .active || currentTunnel.status == .activating {
alert.informativeText = tr(format: "macConfirmAndQuitInfoWithActiveTunnel (%@)", currentTunnel.name)
} else {
alert.informativeText = tr("macConfirmAndQuitAlertInfo")
}
alert.addButton(withTitle: tr("macConfirmAndQuitAlertCloseWindow"))
alert.addButton(withTitle: tr("macConfirmAndQuitAlertQuitWireGuard"))
NSApp.activate(ignoringOtherApps: true)
if let manageWindow = manageTunnelsWindowObject {
manageWindow.orderFront(self)
alert.beginSheetModal(for: manageWindow) { response in
switch response {
case .alertFirstButtonReturn:
manageWindow.close()
case .alertSecondButtonReturn:
NSApp.terminate(nil)
default:
break
}
}
}
}
@objc func quit() { @objc func quit() {
if let manageWindow = manageTunnelsWindowObject, manageWindow.attachedSheet != nil { if let manageWindow = manageTunnelsWindowObject, manageWindow.attachedSheet != nil {
NSApp.activate(ignoringOtherApps: true) NSApp.activate(ignoringOtherApps: true)
@@ -105,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
} }
+2 -2
View File
@@ -51,8 +51,8 @@ class MainMenu: NSMenu {
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
menu.addItem(withTitle: tr("macMenuQuitManagingTunnels"), menu.addItem(withTitle: tr("macMenuQuit"),
action: #selector(NSWindow.performClose(_:)), keyEquivalent: "q") action: #selector(AppDelegate.confirmAndQuit), keyEquivalent: "q")
return menu return menu
} }
@@ -3,13 +3,25 @@
import Cocoa import Cocoa
class LogViewCell: NSTextField { class LogViewCell: NSTableCellView {
var text: String = "" {
didSet { textField?.stringValue = text }
}
init() { init() {
super.init(frame: .zero) super.init(frame: .zero)
isSelectable = false
isEditable = false let textField = NSTextField(wrappingLabelWithString: "")
isBordered = false addSubview(textField)
backgroundColor = .clear textField.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textField.leadingAnchor.constraint(equalTo: self.leadingAnchor),
textField.trailingAnchor.constraint(equalTo: self.trailingAnchor),
textField.topAnchor.constraint(equalTo: self.topAnchor),
textField.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
self.textField = textField
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@@ -17,19 +29,19 @@ class LogViewCell: NSTextField {
} }
override func prepareForReuse() { override func prepareForReuse() {
stringValue = "" textField?.stringValue = ""
preferredMaxLayoutWidth = 0
} }
} }
class LogViewTimestampCell: LogViewCell { class LogViewTimestampCell: LogViewCell {
override init() { override init() {
super.init() super.init()
maximumNumberOfLines = 1 if let textField = textField {
lineBreakMode = .byClipping textField.maximumNumberOfLines = 1
preferredMaxLayoutWidth = 0 textField.lineBreakMode = .byClipping
setContentCompressionResistancePriority(.defaultHigh, for: .vertical) textField.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
setContentHuggingPriority(.defaultLow, for: .vertical) textField.setContentHuggingPriority(.defaultLow, for: .vertical)
}
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@@ -40,10 +52,12 @@ class LogViewTimestampCell: LogViewCell {
class LogViewMessageCell: LogViewCell { class LogViewMessageCell: LogViewCell {
override init() { override init() {
super.init() super.init()
maximumNumberOfLines = 0 if let textField = textField {
lineBreakMode = .byWordWrapping textField.maximumNumberOfLines = 0
setContentCompressionResistancePriority(.required, for: .vertical) textField.lineBreakMode = .byWordWrapping
setContentHuggingPriority(.required, for: .vertical) textField.setContentCompressionResistancePriority(.required, for: .vertical)
textField.setContentHuggingPriority(.required, for: .vertical)
}
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@@ -146,7 +146,8 @@ class LogViewController: NSViewController {
]) ])
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
containerView.widthAnchor.constraint(equalToConstant: 640), containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: 640),
containerView.widthAnchor.constraint(lessThanOrEqualToConstant: 1200),
containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 240) containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 240)
]) ])
@@ -192,6 +193,10 @@ class LogViewController: NSViewController {
updateLogEntriesTimer = nil updateLogEntriesTimer = nil
} }
override func viewWillAppear() {
view.window?.setFrameAutosaveName(NSWindow.FrameAutosaveName("LogWindow"))
}
override func viewWillDisappear() { override func viewWillDisappear() {
super.viewWillDisappear() super.viewWillDisappear()
stopUpdatingLogEntries() stopUpdatingLogEntries()
@@ -250,12 +255,11 @@ extension LogViewController: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
if LogColumn.time.isRepresenting(tableColumn: tableColumn) { if LogColumn.time.isRepresenting(tableColumn: tableColumn) {
let cell: LogViewTimestampCell = tableView.dequeueReusableCell() let cell: LogViewTimestampCell = tableView.dequeueReusableCell()
cell.stringValue = logEntries[row].timestamp cell.text = logEntries[row].timestamp
return cell return cell
} else if LogColumn.logMessage.isRepresenting(tableColumn: tableColumn) { } else if LogColumn.logMessage.isRepresenting(tableColumn: tableColumn) {
let cell: LogViewMessageCell = tableView.dequeueReusableCell() let cell: LogViewMessageCell = tableView.dequeueReusableCell()
cell.stringValue = logEntries[row].message cell.text = logEntries[row].message
cell.preferredMaxLayoutWidth = tableColumn?.width ?? 0
return cell return cell
} else { } else {
fatalError() fatalError()
@@ -11,7 +11,7 @@ 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 lastPath: Network.NWPath?
private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator? private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator?
deinit { deinit {
@@ -143,18 +143,15 @@ 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 } if path != lastPath {
if !interfaces.elementsEqual(lastSeenInterfaces) { lastPath = path
lastSeenInterfaces = interfaces
wgBumpSockets(handle) wgBumpSockets(handle)
} }
} }
+1 -1
View File
@@ -26,7 +26,7 @@ export CGO_ENABLED := 1
build: $(DESTDIR)/libwg-go.a build: $(DESTDIR)/libwg-go.a
version-header: $(DESTDIR)/wireguard-go-version.h version-header: $(DESTDIR)/wireguard-go-version.h
GOBUILDVERSION_NEEDED := go version go1.12.1 darwin/amd64 GOBUILDVERSION_NEEDED := go version go1.12.5 darwin/amd64
GOBUILDVERSION_CURRENT := $(shell go version 2>/dev/null) GOBUILDVERSION_CURRENT := $(shell go version 2>/dev/null)
export REAL_GOROOT := $(shell go env GOROOT 2>/dev/null) export REAL_GOROOT := $(shell go env GOROOT 2>/dev/null)
export GOROOT := $(BUILDDIR)/goroot export GOROOT := $(BUILDDIR)/goroot