From 40250bfbab09c7fa021a9e8c70b4d632974295f9 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 15 Feb 2019 01:06:44 +0100 Subject: [PATCH] macOS: Show privacy notice on adding first tunnel App store reviewers don't understand that this isn't a service. Revert this as soon as they come to their senses. --- WireGuard/WireGuard.xcodeproj/project.pbxproj | 4 +++ .../WireGuard/Base.lproj/Localizable.strings | 2 ++ .../UI/macOS/AppStorePrivacyNotice.swift | 29 +++++++++++++++++++ .../UI/macOS/ImportPanelPresenter.swift | 4 ++- .../TunnelEditViewController.swift | 16 +++++----- 5 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 WireGuard/WireGuard/UI/macOS/AppStorePrivacyNotice.swift diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj index 4dd14ff..65a4d89 100644 --- a/WireGuard/WireGuard.xcodeproj/project.pbxproj +++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj @@ -43,6 +43,7 @@ 6B653B86220DE2960050E69C /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FF4AC462120B9E0002C96EB /* NetworkExtension.framework */; }; 6B707D8421F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */; }; 6B707D8621F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */; }; + 6BAC16E6221634B300A5FB78 /* AppStorePrivacyNotice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BAC16E42216324B00A5FB78 /* AppStorePrivacyNotice.swift */; }; 6BD5C97B220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; }; 6BD5C97C220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; }; 6BD5C97D220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; }; @@ -255,6 +256,7 @@ 6B5C5E26220A48D30024272E /* Keychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = ""; }; 6B62E45E220A6FA900EF34A6 /* PrivateDataConfirmation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivateDataConfirmation.swift; sourceTree = ""; }; 6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelConfiguration+UapiConfig.swift"; sourceTree = ""; }; + 6BAC16E42216324B00A5FB78 /* AppStorePrivacyNotice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePrivacyNotice.swift; sourceTree = ""; }; 6BD5C979220D1AE100784E08 /* key.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = key.c; sourceTree = ""; }; 6BD5C97A220D1AE200784E08 /* key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = key.h; sourceTree = ""; }; 6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTableView+Reuse.swift"; sourceTree = ""; }; @@ -561,6 +563,7 @@ 6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */, 5F52D0BE21E3788900283CEA /* NSColor+Hex.swift */, 6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */, + 6BAC16E42216324B00A5FB78 /* AppStorePrivacyNotice.swift */, ); path = macOS; sourceTree = ""; @@ -1156,6 +1159,7 @@ 6FB1BDCB21D50F1700A991BF /* Curve25519.swift in Sources */, 6B586C55220CBA6D00427C51 /* Data+KeyEncoding.swift in Sources */, 6F9B582921E8D6D100544D02 /* PopupRow.swift in Sources */, + 6BAC16E6221634B300A5FB78 /* AppStorePrivacyNotice.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 b42d330..89f903c 100644 --- a/WireGuard/WireGuard/Base.lproj/Localizable.strings +++ b/WireGuard/WireGuard/Base.lproj/Localizable.strings @@ -333,3 +333,5 @@ "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."; +"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."; diff --git a/WireGuard/WireGuard/UI/macOS/AppStorePrivacyNotice.swift b/WireGuard/WireGuard/UI/macOS/AppStorePrivacyNotice.swift new file mode 100644 index 0000000..15aeb8d --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/AppStorePrivacyNotice.swift @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. + +import Cocoa + +class AppStorePrivacyNotice { + // The App Store Review Board does not comprehend the fact that this application + // is not a service and does not have any servers of its own. They therefore require + // us to give a notice regarding collection of user data using our non-existent + // servers. This demand is obviously impossible to fulfill, since it doesn't make sense, + // but we do our best here to show something in that category. + static func show(from sourceVC: NSViewController?, into tunnelsManager: TunnelsManager, _ callback: @escaping () -> Void) { + if tunnelsManager.numberOfTunnels() > 0 { + callback() + return + } + let alert = NSAlert() + + alert.messageText = tr("macPrivacyNoticeMessage") + alert.informativeText = tr("macPrivacyNoticeInfo") + alert.alertStyle = NSAlert.Style.warning + if let window = sourceVC?.view.window { + alert.beginSheetModal(for: window) { _ in callback() } + } else { + alert.runModal() + callback() + } + } +} diff --git a/WireGuard/WireGuard/UI/macOS/ImportPanelPresenter.swift b/WireGuard/WireGuard/UI/macOS/ImportPanelPresenter.swift index 3281142..1ef8f75 100644 --- a/WireGuard/WireGuard/UI/macOS/ImportPanelPresenter.swift +++ b/WireGuard/WireGuard/UI/macOS/ImportPanelPresenter.swift @@ -13,7 +13,9 @@ class ImportPanelPresenter { guard let tunnelsManager = tunnelsManager else { return } guard response == .OK else { return } guard let url = openPanel.url else { return } - TunnelImporter.importFromFile(url: url, into: tunnelsManager, sourceVC: sourceVC, errorPresenterType: ErrorPresenter.self) + AppStorePrivacyNotice.show(from: sourceVC, into: tunnelsManager) { + TunnelImporter.importFromFile(url: url, into: tunnelsManager, sourceVC: sourceVC, errorPresenterType: ErrorPresenter.self) + } } } } diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift index 395eeb4..efb3fd7 100644 --- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift +++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift @@ -219,14 +219,16 @@ class TunnelEditViewController: NSViewController { } } else { // We're creating a new tunnel - tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: onDemandSetting) { [weak self] result in - if let error = result.error { - ErrorPresenter.showErrorAlert(error: error, from: self) - return + AppStorePrivacyNotice.show(from: self, into: tunnelsManager) { [weak self] in + self?.tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: onDemandSetting) { [weak self] result in + if let error = result.error { + ErrorPresenter.showErrorAlert(error: error, from: self) + return + } + let tunnel: TunnelContainer = result.value! + self?.dismiss(self) + self?.delegate?.tunnelSaved(tunnel: tunnel) } - let tunnel: TunnelContainer = result.value! - self?.dismiss(self) - self?.delegate?.tunnelSaved(tunnel: tunnel) } } }