Skip to content

Commit

Permalink
Kill switch (#1408)
Browse files Browse the repository at this point in the history
  • Loading branch information
mallexxx authored Aug 4, 2023
1 parent ebe7b19 commit f8df91f
Show file tree
Hide file tree
Showing 30 changed files with 855 additions and 567 deletions.
101 changes: 51 additions & 50 deletions DuckDuckGo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
"state" : {
"revision" : "aa10614509aa838d11b0b7540615eab7bd47e851",
"version" : "71.4.1"
"revision" : "f419ede296e0b30d680fcd80364962ea1c1b1365",
"version" : "72.0.0"
}
},
{
Expand Down Expand Up @@ -129,7 +129,7 @@
{
"identity" : "trackerradarkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/TrackerRadarKit",
"location" : "https://github.com/duckduckgo/TrackerRadarKit.git",
"state" : {
"revision" : "4684440d03304e7638a2c8086895367e90987463",
"version" : "1.2.1"
Expand Down
7 changes: 6 additions & 1 deletion DuckDuckGo/AppDelegate/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel
#if NETWORK_PROTECTION

private func startupNetworkProtection() {
guard #available(macOS 11.4, *) else { return }

let loginItemsManager = NetworkProtectionLoginItemsManager()
let networkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore()

Expand All @@ -320,6 +322,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel
refreshNetworkProtectionServers()
}

@available(macOS 11.4, *)
private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) {
let currentVersion = AppVersion.shared.versionNumber
let versionStore = NetworkProtectionLastVersionRunStore()
Expand All @@ -342,21 +345,23 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel
}
}

@available(macOS 11.4, *)
private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) {
loginItemsManager.restartLoginItems()

Task {
let provider = NetworkProtectionTunnelController()

// Restart NetP SysEx on app update
if await provider.isConnected() {
if await provider.isConnected {
await provider.stop()
await provider.start()
}
}
}

/// Fetches a new list of Network Protection servers, and updates the existing set.
@available(macOS 11.4, *)
private func refreshNetworkProtectionServers() {
Task {
let serverCount: Int
Expand Down
8 changes: 8 additions & 0 deletions DuckDuckGo/Common/Extensions/BundleExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extension Bundle {
static let notificationsAgentBundleId = "NOTIFICATIONS_AGENT_BUNDLE_ID"
static let notificationsAgentProductName = "NOTIFICATIONS_AGENT_PRODUCT_NAME"
#endif
static let appGroup = "NETP_APP_GROUP"
}

var displayName: String? {
Expand Down Expand Up @@ -78,4 +79,11 @@ extension Bundle {
}
#endif

var appGroupName: String {
guard let appGroup = object(forInfoDictionaryKey: Keys.appGroup) as? String else {
fatalError("Info.plist is missing \(Keys.appGroup)")
}
return appGroup
}

}
7 changes: 4 additions & 3 deletions DuckDuckGo/Common/Extensions/NSApplicationExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,16 @@ extension NSApplication {
}
}
}
@objc dynamic var runType: RunType { .normal }
@objc dynamic class var runType: RunType { .normal }
var runType: RunType { Self.runType }

var isRunningUnitTests: Bool {
if case .unitTests = runType { return true }
if case .unitTests = Self.runType { return true }
return false
}

var isRunningIntegrationTests: Bool {
if case .integrationTests = runType { return true }
if case .integrationTests = Self.runType { return true }
return false
}

Expand Down
34 changes: 32 additions & 2 deletions DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
import AppKit
import Foundation

extension UserDefaults {
/// The app group's shared UserDefaults
static let shared = UserDefaults(suiteName: Bundle.main.appGroupName)
}

@propertyWrapper
public struct UserDefaultsWrapper<T> {

Expand Down Expand Up @@ -121,8 +126,21 @@ public struct UserDefaultsWrapper<T> {
// Temporary for activetion pixel
case firstLaunchDate = "first.app.launch.date"

// Network Protection
case networkProtectionOnDemandActivation = "netp.ondemand"
case networkProtectionShouldEnforceRoutes = "netp.enforce-routes"
case networkProtectionShouldIncludeAllNetworks = "netp.include-all-networks"

case networkProtectionExcludedRoutes = "netp.excluded-routes"
case networkProtectionShouldExcludeLocalRoutes = "netp.exclude-local-routes"
case networkProtectionConnectionTesterEnabled = "netp.connection-tester-enabled"

case networkProtectionConnectOnLogIn = "netp.connect-on-login"

case networkProtectionRegistrationKeyValidity = "com.duckduckgo.network-protection.NetworkProtectionTunnelController.registrationKeyValidityKey"

case agentLaunchTime = "netp.agent.launch-time"

// Experiments
case pixelExperimentInstalled = "pixel.experiment.installed"
case pixelExperimentCohort = "pixel.experiment.cohort"
Expand All @@ -146,10 +164,10 @@ public struct UserDefaultsWrapper<T> {

static var sharedDefaults: UserDefaults {
#if DEBUG && !(NETP_SYSTEM_EXTENSION && NETWORK_EXTENSION) // Avoid looking up special user defaults when running inside the system extension
if case .normal = NSApp.runType {
if case .normal = NSApplication.runType {
return .standard
} else {
return UserDefaults(suiteName: Bundle.main.bundleIdentifier! + "." + NSApp.runType.description)!
return UserDefaults(suiteName: Bundle.main.bundleIdentifier! + "." + NSApplication.runType.description)!
}
#else
return .standard
Expand Down Expand Up @@ -203,4 +221,16 @@ public struct UserDefaultsWrapper<T> {
sharedDefaults.removeObject(forKey: key.rawValue)
}

func clear() {
defaults.removeObject(forKey: key.rawValue)
}

}

extension UserDefaultsWrapper where T: OptionalProtocol {

init(key: Key, defaults: UserDefaults? = nil) {
self.init(key: key, defaultValue: .none, defaults: defaults)
}

}
59 changes: 32 additions & 27 deletions DuckDuckGo/Main/Main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,40 +39,42 @@ final class AppMain {

static func main() {
#if NETWORK_PROTECTION
switch (CommandLine.arguments.first! as NSString).lastPathComponent {
case "startVPN":
swizzleMainBundle()
if #available(macOS 11.4, *) {
switch (CommandLine.arguments.first! as NSString).lastPathComponent {
case "startVPN":
swizzleMainBundle()

Task {
await NetworkProtectionTunnelController().start(enableLoginItems: false)
exit(0)
}
Task {
await NetworkProtectionTunnelController().start(enableLoginItems: false)
exit(0)
}

dispatchMain()
case "stopVPN":
swizzleMainBundle()
dispatchMain()
case "stopVPN":
swizzleMainBundle()

Task {
await NetworkProtectionTunnelController().stop()
exit(0)
}
Task {
await NetworkProtectionTunnelController().stop()
exit(0)
}

dispatchMain()
case "enableOnDemand":
swizzleMainBundle()
dispatchMain()
case "enableOnDemand":
swizzleMainBundle()

Task {
do {
try await NetworkProtectionTunnelController().enableOnDemand()
exit(0)
} catch {
fatalError("Could not enable on demand due to error: \(String(describing: error))")
Task {
do {
try await NetworkProtectionTunnelController().enableOnDemandRequestedByExtension()
exit(0)
} catch {
fatalError("Could not enable on demand due to error: \(String(describing: error))")
}
}
}

dispatchMain()
default:
break
dispatchMain()
default:
break
}
}
#endif

Expand All @@ -85,5 +87,8 @@ final class AppMain {
let m1 = class_getClassMethod(Bundle.self, #selector(getter: Bundle.main))!
let m2 = class_getClassMethod(Bundle.self, #selector(Bundle.nonMain))!
method_exchangeImplementations(m1, m2)

// since initially our bundle id doesn‘t match the main app, UserDefaults won‘t be loaded by default
UserDefaults.standard.addSuite(named: Bundle.main.bundleIdentifier!)
}
}
Loading

0 comments on commit f8df91f

Please sign in to comment.