Skip to content

Commit

Permalink
reset and removed some useless things
Browse files Browse the repository at this point in the history
  • Loading branch information
federicocappelli committed Jan 30, 2025
1 parent 20b2408 commit cad6354
Show file tree
Hide file tree
Showing 108 changed files with 7,790 additions and 3,141 deletions.
6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ let package = Package(
"ContentBlocking",
"SecureStorage",
"Subscription",
"PixelKit"
"Networking",
"PixelKit",
],
resources: [
.process("ContentBlocking/UserScripts/contentblockerrules.js"),
Expand Down Expand Up @@ -340,7 +341,8 @@ let package = Package(
dependencies: [
.target(name: "WireGuardC"),
"Common",
"Networking"
"Networking",
"Subscription"
],
swiftSettings: [
.define("DEBUG", .when(configuration: .debug))
Expand Down
13 changes: 7 additions & 6 deletions Sources/Common/UserDefaultsCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class UserDefaultsCache<ObjectType: Codable> {
let object: ObjectType
}

let logger = { Logger(subsystem: Bundle.main.bundleIdentifier ?? "DuckDuckGo", category: "UserDefaultsCache") }()
let logger = { Logger(subsystem: "UserDefaultsCache", category: "") }()
private var userDefaults: UserDefaults
public private(set) var settings: UserDefaultsCacheSettings

Expand All @@ -65,8 +65,9 @@ public class UserDefaultsCache<ObjectType: Codable> {
do {
let data = try encoder.encode(cacheObject)
userDefaults.set(data, forKey: key.rawValue)
logger.debug("Cache Set: \(String(describing: cacheObject))")
logger.debug("Cache Set: \(String(describing: cacheObject), privacy: .public)")
} catch {
logger.fault("Failed to encode CacheObject: \(error, privacy: .public)")
assertionFailure("Failed to encode CacheObject: \(error)")
}
}
Expand All @@ -77,21 +78,21 @@ public class UserDefaultsCache<ObjectType: Codable> {
do {
let cacheObject = try decoder.decode(CacheObject.self, from: data)
if cacheObject.expires > Date() {
logger.debug("Cache Hit: \(ObjectType.self)")
logger.debug("Cache Hit: \(ObjectType.self, privacy: .public)")
return cacheObject.object
} else {
logger.debug("Cache Miss: \(ObjectType.self)")
logger.debug("Cache Miss: \(ObjectType.self, privacy: .public)")
reset() // Clear expired data
return nil
}
} catch let error {
logger.error("Cache Decode Error: \(error)")
logger.fault("Cache Decode Error: \(error, privacy: .public)")
return nil
}
}

public func reset() {
logger.debug("Cache Clean: \(ObjectType.self)")
logger.debug("Cache Clean: \(ObjectType.self, privacy: .public)")
userDefaults.removeObject(forKey: key.rawValue)
}
}
2 changes: 1 addition & 1 deletion Sources/DDGSync/internal/RemoteAPIRequestCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public struct RemoteAPIRequestCreator: RemoteAPIRequestCreating {
body: body)

if let body {
Logger.sync.debug("\(method.rawValue, privacy: .public) request body: \(String(bytes: body, encoding: .utf8) ?? "", privacy: .public)")
Logger.sync.debug("\(method.rawValue, privacy: .public) request body: \(String(bytes: body, encoding: .utf8) ?? "")")
}

return APIRequest(configuration: configuration, requirements: [.allowHTTPNotModified])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public enum NetworkProtectionError: LocalizedError, CustomNSError {
case setWireguardConfig(Error)

// Auth errors
case noAuthTokenFound
case noAuthTokenFound(Error)

// Subscription errors
case vpnAccessRevoked
Expand Down Expand Up @@ -130,7 +130,6 @@ public enum NetworkProtectionError: LocalizedError, CustomNSError {
.wireGuardCannotLocateTunnelFileDescriptor,
.wireGuardInvalidState,
.wireGuardDnsResolution,
.noAuthTokenFound,
.vpnAccessRevoked:
return [:]
case .failedToFetchServerList(let error),
Expand All @@ -149,6 +148,7 @@ public enum NetworkProtectionError: LocalizedError, CustomNSError {
.wireGuardSetNetworkSettings(let error),
.startWireGuardBackend(let error),
.setWireguardConfig(let error),
.noAuthTokenFound(let error),
.unhandledError(_, _, let error),
.failedToFetchServerStatus(let error),
.failedToParseServerStatusResponse(let error):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Network
import Common
import Combine
import os.log
import Subscription

public actor NetworkProtectionServerStatusMonitor {

Expand Down Expand Up @@ -49,13 +50,14 @@ public actor NetworkProtectionServerStatusMonitor {
}

private let networkClient: NetworkProtectionClient
private let tokenStore: NetworkProtectionTokenStore
private let tokenProvider: any SubscriptionTokenProvider

// MARK: - Init & deinit

init(networkClient: NetworkProtectionClient, tokenStore: NetworkProtectionTokenStore) {
init(networkClient: NetworkProtectionClient,
tokenProvider: any SubscriptionTokenProvider) {
self.networkClient = networkClient
self.tokenStore = tokenStore
self.tokenProvider = tokenProvider

Logger.networkProtectionMemory.debug("[+] \(String(describing: self), privacy: .public)")
}
Expand Down Expand Up @@ -99,11 +101,11 @@ public actor NetworkProtectionServerStatusMonitor {
// MARK: - Server Status Check

private func checkServerStatus(for serverName: String) async -> Result<NetworkProtectionServerStatus, NetworkProtectionClientError> {
guard let accessToken = try? tokenStore.fetchToken() else {
guard let accessToken = try? await VPNAuthTokenBuilder.getVPNAuthToken(from: tokenProvider, policy: .localValid) else {
Logger.networkProtection.fault("Failed to check server status due to lack of access token")
assertionFailure("Failed to check server status due to lack of access token")
return .failure(.invalidAuthToken)
}

return await networkClient.getServerStatus(authToken: accessToken, serverName: serverName)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ public final class NetworkProtectionKeychainKeyStore: NetworkProtectionKeyStore
// MARK: - EventMapping

private func handle(_ error: Error) {
Logger.networkProtectionKeyManagement.error("Failed to perform operation: \(error, privacy: .public)")

guard let error = error as? NetworkProtectionKeychainStoreError else {
assertionFailure("Failed to cast Network Protection Keychain store error")
errorEvents?.fire(NetworkProtectionError.unhandledError(function: #function, line: #line, error: error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ enum NetworkProtectionKeychainStoreError: Error, NetworkProtectionErrorConvertib
}

/// General Keychain access helper class for the NetworkProtection module. Should be used for specific KeychainStore types.
final class NetworkProtectionKeychainStore {
public final class NetworkProtectionKeychainStore {
private let label: String
private let serviceName: String
private let keychainType: KeychainType

init(label: String,
serviceName: String,
keychainType: KeychainType) {
public init(label: String,
serviceName: String,
keychainType: KeychainType) {

self.label = label
self.serviceName = serviceName
Expand All @@ -55,7 +55,8 @@ final class NetworkProtectionKeychainStore {

// MARK: - Keychain Interaction

func readData(named name: String) throws -> Data? {
public func readData(named name: String) throws -> Data? {
Logger.networkProtectionKeyManagement.debug("Reading key \(name, privacy: .public) from keychain")
var query = defaultAttributes()
query[kSecAttrAccount] = name
query[kSecReturnData] = true
Expand All @@ -78,7 +79,8 @@ final class NetworkProtectionKeychainStore {
}
}

func writeData(_ data: Data, named name: String) throws {
public func writeData(_ data: Data, named name: String) throws {
Logger.networkProtectionKeyManagement.debug("Writing key \(name, privacy: .public) to keychain")
var query = defaultAttributes()
query[kSecAttrAccount] = name
query[kSecAttrAccessible] = kSecAttrAccessibleAfterFirstUnlock
Expand All @@ -101,18 +103,20 @@ final class NetworkProtectionKeychainStore {
}

private func updateData(_ data: Data, named name: String) -> OSStatus {
Logger.networkProtectionKeyManagement.debug("Updating key \(name, privacy: .public) in keychain")
var query = defaultAttributes()
query[kSecAttrAccount] = name

let newAttributes = [
kSecValueData: data,
kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
kSecValueData: data,
kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
] as [CFString: Any]

return SecItemUpdate(query as CFDictionary, newAttributes as CFDictionary)
}

func deleteAll() throws {
public func deleteAll() throws {
Logger.networkProtectionKeyManagement.debug("Deleting all keys from keychain")
var query = defaultAttributes()
#if os(macOS)
// This line causes the delete to error with status -50 on iOS. Needs investigation but, for now, just delete the first item
Expand All @@ -125,6 +129,7 @@ final class NetworkProtectionKeychainStore {
case errSecItemNotFound, errSecSuccess:
break
default:
Logger.networkProtectionKeyManagement.error("🔴 Failed to delete all keys, SecItemDelete status \(String(describing: status), privacy: .public)")
throw NetworkProtectionKeychainStoreError.keychainDeleteError(status: status)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// NetworkProtectionKeychainTokenStore+LegacyAuthTokenStoring.swift
//
// Copyright © 2025 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation
import Networking

extension NetworkProtectionKeychainTokenStore: LegacyAuthTokenStoring {

public var token: String? {
get {
do {
return try fetchToken()
} catch {
assertionFailure("Failed to retrieve auth token: \(error)")
}
return nil
}
set(newValue) {
do {
guard let newValue else {
try deleteToken()
return
}
try store(newValue)
} catch {
assertionFailure("Failed set token: \(error)")
}
}
}
}
1 change: 1 addition & 0 deletions Sources/NetworkProtection/Logger+NetworkProtection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ public extension Logger {
static var networkProtectionStatusReporter = { Logger(subsystem: Logger.subsystem, category: "Status Reporter") }()
static var networkProtectionSleep = { Logger(subsystem: Logger.subsystem, category: "Sleep and Wake") }()
static var networkProtectionEntitlement = { Logger(subsystem: Logger.subsystem, category: "Entitlement Monitor") }()
static var networkProtectionWireGuard = { Logger(subsystem: Logger.subsystem, category: "WireGuardAdapter") }()
}
32 changes: 20 additions & 12 deletions Sources/NetworkProtection/NetworkProtectionDeviceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Foundation
import Common
import NetworkExtension
import os.log
import Subscription

public enum NetworkProtectionServerSelectionMethod: CustomDebugStringConvertible {
public var debugDescription: String {
Expand Down Expand Up @@ -73,27 +74,27 @@ public protocol NetworkProtectionDeviceManagement {

public actor NetworkProtectionDeviceManager: NetworkProtectionDeviceManagement {
private let networkClient: NetworkProtectionClient
private let tokenStore: NetworkProtectionTokenStore
private let tokenProvider: any SubscriptionTokenProvider
private let keyStore: NetworkProtectionKeyStore

private let errorEvents: EventMapping<NetworkProtectionError>?

public init(environment: VPNSettings.SelectedEnvironment,
tokenStore: NetworkProtectionTokenStore,
tokenProvider: any SubscriptionTokenProvider,
keyStore: NetworkProtectionKeyStore,
errorEvents: EventMapping<NetworkProtectionError>?) {
self.init(networkClient: NetworkProtectionBackendClient(environment: environment),
tokenStore: tokenStore,
tokenProvider: tokenProvider,
keyStore: keyStore,
errorEvents: errorEvents)
}

init(networkClient: NetworkProtectionClient,
tokenStore: NetworkProtectionTokenStore,
tokenProvider: any SubscriptionTokenProvider,
keyStore: NetworkProtectionKeyStore,
errorEvents: EventMapping<NetworkProtectionError>?) {
self.networkClient = networkClient
self.tokenStore = tokenStore
self.tokenProvider = tokenProvider
self.keyStore = keyStore
self.errorEvents = errorEvents
}
Expand All @@ -102,8 +103,11 @@ public actor NetworkProtectionDeviceManager: NetworkProtectionDeviceManagement {
/// This method will return the remote server list if available, or the local server list if there was a problem with the service call.
///
public func refreshServerList() async throws -> [NetworkProtectionServer] {
guard let token = try? tokenStore.fetchToken() else {
throw NetworkProtectionError.noAuthTokenFound
let token: String
do {
token = try await VPNAuthTokenBuilder.getVPNAuthToken(from: tokenProvider, policy: .localValid)
} catch {
throw NetworkProtectionError.noAuthTokenFound(error)
}
let result = await networkClient.getServers(authToken: token)
let completeServerList: [NetworkProtectionServer]
Expand Down Expand Up @@ -188,8 +192,12 @@ public actor NetworkProtectionDeviceManager: NetworkProtectionDeviceManagement {
private func register(keyPair: KeyPair,
selectionMethod: NetworkProtectionServerSelectionMethod) async throws -> (server: NetworkProtectionServer,
newExpiration: Date?) {

guard let token = try? tokenStore.fetchToken() else { throw NetworkProtectionError.noAuthTokenFound }
let token: String
do {
token = try await VPNAuthTokenBuilder.getVPNAuthToken(from: tokenProvider, policy: .localValid)
} catch {
throw NetworkProtectionError.noAuthTokenFound(error)
}

let serverSelection: RegisterServerSelection
let excludedServerName: String?
Expand Down Expand Up @@ -313,11 +321,11 @@ public actor NetworkProtectionDeviceManager: NetworkProtectionDeviceManagement {
}

private func handle(clientError: NetworkProtectionClientError) {
#if os(macOS)
#if os(macOS)
if case .invalidAuthToken = clientError {
try? tokenStore.deleteToken()
tokenProvider.removeTokenContainer()
}
#endif
#endif
errorEvents?.fire(clientError.networkProtectionError)
}

Expand Down
1 change: 1 addition & 0 deletions Sources/NetworkProtection/NetworkProtectionOptionKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public enum NetworkProtectionOptionKey {
public static let dnsSettings = "dnsSettings"
public static let excludeLocalNetworks = "excludeLocalNetworks"
public static let authToken = "authToken"
public static let tokenContainer = "tokenContainer"
public static let isOnDemand = "is-on-demand"
public static let activationAttemptId = "activationAttemptId"
public static let tunnelFailureSimulation = "tunnelFailureSimulation"
Expand Down
20 changes: 20 additions & 0 deletions Sources/NetworkProtection/Networking/NetworkProtectionClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ public enum NetworkProtectionClientError: CustomNSError, NetworkProtectionErrorC
return [:]
}
}

public var errorDescription: String? {
switch self {
case .failedToFetchLocationList: return "Failed to fetch location list"
case .failedToParseLocationListResponse: return "Failed to parse location list response"
case .failedToFetchServerList: return "Failed to fetch server list"
case .failedToParseServerListResponse: return "Failed to parse server list response"
case .failedToEncodeRegisterKeyRequest: return "Failed to encode register key request"
case .failedToFetchServerStatus(let error):
return "Failed to fetch server status: \(error)"
case .failedToParseServerStatusResponse(let error):
return "Failed to parse server status response: \(error)"
case .failedToFetchRegisteredServers(let error):
return "Failed to fetch registered servers: \(error)"
case .failedToParseRegisteredServersResponse(let error):
return "Failed to parse registered servers response: \(error)"
case .invalidAuthToken: return "Invalid auth token"
case .accessDenied: return "Access denied"
}
}
}

struct RegisterKeyRequestBody: Encodable {
Expand Down
Loading

0 comments on commit cad6354

Please sign in to comment.