Fix XPC validation
This commit is contained in:
@@ -76,9 +76,15 @@ public struct AppView: View {
|
||||
Section {
|
||||
if rootHelperRegistrationStatus == .enabled {
|
||||
FormButton {
|
||||
performHelperAction {
|
||||
Task {
|
||||
do {
|
||||
try HelperServiceManager.unregisterRootHelper()
|
||||
try await Task.sleep(for: .seconds(1))
|
||||
try HelperServiceManager.registerRootHelper()
|
||||
refreshHelperStatus()
|
||||
} catch {
|
||||
alert = AlertState(error: error)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("Update", systemImage: "arrow.down.doc.fill")
|
||||
|
||||
@@ -8,46 +8,22 @@ class RootHelperService: NSObject {
|
||||
private var listener: NSXPCListener?
|
||||
|
||||
func start() {
|
||||
setupLogging()
|
||||
startXPCListener()
|
||||
}
|
||||
|
||||
private func setupLogging() {
|
||||
let basePath = "/var/log/sing-box"
|
||||
try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true)
|
||||
|
||||
let logPath = basePath + "/roothelper.log"
|
||||
freopen(logPath, "a", stderr)
|
||||
}
|
||||
|
||||
private func startXPCListener() {
|
||||
let machServiceName = getMachServiceName()
|
||||
listener = NSXPCListener(machServiceName: machServiceName)
|
||||
listener = NSXPCListener(machServiceName: AppConfiguration.rootHelperMachService)
|
||||
listener?.delegate = self
|
||||
listener?.resume()
|
||||
}
|
||||
|
||||
private func getMachServiceName() -> String {
|
||||
if let identifier = Bundle.main.object(forInfoDictionaryKey: "AppGroupIdentifier") as? String {
|
||||
return "\(identifier).helper"
|
||||
}
|
||||
fatalError("Missing AppGroupIdentifier in Info.plist")
|
||||
}
|
||||
}
|
||||
|
||||
extension RootHelperService: NSXPCListenerDelegate {
|
||||
func listener(_: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
|
||||
let allowedBundleIDs = [
|
||||
AppConfiguration.systemExtensionBundleID,
|
||||
AppConfiguration.packageName + ".standalone",
|
||||
]
|
||||
guard XPCConnectionValidator.validateConnection(
|
||||
newConnection,
|
||||
teamID: AppConfiguration.teamID,
|
||||
allowedBundleIDs: allowedBundleIDs
|
||||
) else {
|
||||
let info = XPCConnectionValidator.getConnectionInfo(newConnection)
|
||||
logger.warning("Rejected XPC connection: pid=\(info.pid), bundleID=\(info.bundleID ?? "unknown"), teamID=\(info.teamID ?? "unknown")")
|
||||
let systemExtensionID = AppConfiguration.systemExtensionBundleID
|
||||
let standaloneID = AppConfiguration.packageName + ".standalone"
|
||||
let teamID = AppConfiguration.teamID
|
||||
let requirement = "(identifier \"\(systemExtensionID)\" or identifier \"\(standaloneID)\") and anchor apple generic and certificate leaf[subject.OU] = \"\(teamID)\""
|
||||
do {
|
||||
try newConnection.setCodeSigningRequirement(requirement)
|
||||
} catch {
|
||||
logger.warning("Rejected XPC connection: \(error.localizedDescription)")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -106,4 +82,8 @@ extension RootHelperService: RootHelperProtocol {
|
||||
reply(error as NSError)
|
||||
}
|
||||
}
|
||||
|
||||
func getVersion(reply: @escaping (String) -> Void) {
|
||||
reply(Bundle.main.version)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,14 +53,12 @@
|
||||
}
|
||||
|
||||
func listener(_: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
|
||||
let allowedBundleIDs = [AppConfiguration.packageName + ".standalone"]
|
||||
guard XPCConnectionValidator.validateConnection(
|
||||
newConnection,
|
||||
teamID: AppConfiguration.teamID,
|
||||
allowedBundleIDs: allowedBundleIDs
|
||||
) else {
|
||||
let info = XPCConnectionValidator.getConnectionInfo(newConnection)
|
||||
logger.warning("Rejected XPC connection: pid=\(info.pid), bundleID=\(info.bundleID ?? "unknown"), teamID=\(info.teamID ?? "unknown")")
|
||||
let bundleID = AppConfiguration.packageName + ".standalone"
|
||||
let requirement = "identifier \"\(bundleID)\" and anchor apple generic and certificate leaf[subject.OU] = \"\(AppConfiguration.teamID)\""
|
||||
do {
|
||||
try newConnection.setCodeSigningRequirement(requirement)
|
||||
} catch {
|
||||
logger.warning("Rejected XPC connection: \(error.localizedDescription)")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#if os(macOS)
|
||||
import Foundation
|
||||
import os
|
||||
import ServiceManagement
|
||||
|
||||
private let logger = Logger(category: "HelperServiceManager")
|
||||
|
||||
public enum HelperServiceManager {
|
||||
private static var rootHelperService: SMAppService {
|
||||
SMAppService.daemon(plistName: "\(AppConfiguration.rootHelperBundleID).plist")
|
||||
@@ -21,5 +24,25 @@
|
||||
public static func unregisterRootHelper() throws {
|
||||
try rootHelperService.unregister()
|
||||
}
|
||||
|
||||
public static func updateRootHelperIfNeeded() async {
|
||||
guard rootHelperStatus == .enabled else { return }
|
||||
|
||||
do {
|
||||
let installedVersion = try RootHelperClient.shared.getVersion()
|
||||
let currentVersion = Bundle.main.version
|
||||
guard currentVersion != installedVersion else { return }
|
||||
} catch {
|
||||
logger.warning("Failed to get root helper version, updating: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
do {
|
||||
try unregisterRootHelper()
|
||||
try await Task.sleep(for: .seconds(1))
|
||||
try registerRootHelper()
|
||||
} catch {
|
||||
logger.error("Failed to update root helper: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
func getWorkingDirectorySize(reply: @escaping (Int64, NSError?) -> Void)
|
||||
func cleanWorkingDirectory(reply: @escaping (NSError?) -> Void)
|
||||
func getVersion(reply: @escaping (String) -> Void)
|
||||
}
|
||||
|
||||
public enum RootHelperXPC {
|
||||
@@ -217,5 +218,52 @@
|
||||
proxy.cleanWorkingDirectory(reply: reply)
|
||||
}
|
||||
}
|
||||
|
||||
public func getVersion() throws -> String {
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
var result: String?
|
||||
var resultError: NSError?
|
||||
|
||||
let conn = getConnection()
|
||||
guard let proxy = conn.remoteObjectProxyWithErrorHandler({ error in
|
||||
logger.error("getVersion XPC error: \(error.localizedDescription)")
|
||||
resultError = error as NSError
|
||||
semaphore.signal()
|
||||
}) as? RootHelperProtocol else {
|
||||
connectionLock.lock()
|
||||
connection = nil
|
||||
connectionLock.unlock()
|
||||
conn.invalidate()
|
||||
throw NSError(domain: "RootHelper", code: -1, userInfo: [
|
||||
NSLocalizedDescriptionKey: "Failed to get RootHelper proxy",
|
||||
])
|
||||
}
|
||||
|
||||
proxy.getVersion { version in
|
||||
result = version
|
||||
semaphore.signal()
|
||||
}
|
||||
|
||||
let timeout = DispatchTime.now() + .seconds(5)
|
||||
if semaphore.wait(timeout: timeout) == .timedOut {
|
||||
let error = NSError(domain: "RootHelper", code: -1, userInfo: [
|
||||
NSLocalizedDescriptionKey: "getVersion request timeout",
|
||||
])
|
||||
logger.error("getVersion: timeout")
|
||||
throw error
|
||||
}
|
||||
|
||||
if let error = resultError {
|
||||
throw error
|
||||
}
|
||||
|
||||
guard let value = result else {
|
||||
throw NSError(domain: "RootHelper", code: -1, userInfo: [
|
||||
NSLocalizedDescriptionKey: "getVersion returned nil",
|
||||
])
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -46,14 +46,12 @@
|
||||
}
|
||||
|
||||
public func listener(_: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
|
||||
let allowedBundleIDs = [AppConfiguration.systemExtensionBundleID]
|
||||
guard XPCConnectionValidator.validateConnection(
|
||||
newConnection,
|
||||
teamID: AppConfiguration.teamID,
|
||||
allowedBundleIDs: allowedBundleIDs
|
||||
) else {
|
||||
let info = XPCConnectionValidator.getConnectionInfo(newConnection)
|
||||
logger.warning("Rejected XPC connection: pid=\(info.pid), bundleID=\(info.bundleID ?? "unknown"), teamID=\(info.teamID ?? "unknown")")
|
||||
let bundleID = AppConfiguration.systemExtensionBundleID
|
||||
let requirement = "identifier \"\(bundleID)\" and anchor apple generic and certificate leaf[subject.OU] = \"\(AppConfiguration.teamID)\""
|
||||
do {
|
||||
try newConnection.setCodeSigningRequirement(requirement)
|
||||
} catch {
|
||||
logger.warning("Rejected XPC connection: \(error.localizedDescription)")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#if os(macOS)
|
||||
import Foundation
|
||||
import Security
|
||||
|
||||
public struct XPCConnectionInfo {
|
||||
public let pid: pid_t
|
||||
public let bundleID: String?
|
||||
public let teamID: String?
|
||||
}
|
||||
|
||||
public enum XPCConnectionValidator {
|
||||
private static func getSecCode(for connection: NSXPCConnection) -> SecCode? {
|
||||
let pid = connection.processIdentifier
|
||||
var code: SecCode?
|
||||
let attributes = [kSecGuestAttributePid: pid] as CFDictionary
|
||||
guard SecCodeCopyGuestWithAttributes(nil, attributes, [], &code) == errSecSuccess else {
|
||||
return nil
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
private static func getSigningInfo(_ code: SecCode) -> [String: Any]? {
|
||||
var staticCode: SecStaticCode?
|
||||
guard SecCodeCopyStaticCode(code, [], &staticCode) == errSecSuccess,
|
||||
let staticCode
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
var info: CFDictionary?
|
||||
guard SecCodeCopySigningInformation(staticCode, [], &info) == errSecSuccess else {
|
||||
return nil
|
||||
}
|
||||
return info as? [String: Any]
|
||||
}
|
||||
|
||||
public static func getConnectionInfo(_ connection: NSXPCConnection) -> XPCConnectionInfo {
|
||||
let pid = connection.processIdentifier
|
||||
|
||||
guard let secCode = getSecCode(for: connection),
|
||||
let signingInfo = getSigningInfo(secCode)
|
||||
else {
|
||||
return XPCConnectionInfo(pid: pid, bundleID: nil, teamID: nil)
|
||||
}
|
||||
|
||||
let bundleID = signingInfo[kSecCodeInfoIdentifier as String] as? String
|
||||
let teamID = signingInfo[kSecCodeInfoTeamIdentifier as String] as? String
|
||||
|
||||
return XPCConnectionInfo(pid: pid, bundleID: bundleID, teamID: teamID)
|
||||
}
|
||||
|
||||
public static func validateConnection(
|
||||
_ connection: NSXPCConnection,
|
||||
teamID: String,
|
||||
allowedBundleIDs: [String]
|
||||
) -> Bool {
|
||||
guard let secCode = getSecCode(for: connection) else {
|
||||
return false
|
||||
}
|
||||
|
||||
let requirement = "anchor apple generic and certificate leaf[subject.OU] = \"\(teamID)\""
|
||||
var secRequirement: SecRequirement?
|
||||
guard SecRequirementCreateWithString(requirement as CFString, [], &secRequirement) == errSecSuccess,
|
||||
let req = secRequirement,
|
||||
SecCodeCheckValidity(secCode, [], req) == errSecSuccess
|
||||
else {
|
||||
return false
|
||||
}
|
||||
|
||||
guard let signingInfo = getSigningInfo(secCode),
|
||||
let bundleID = signingInfo[kSecCodeInfoIdentifier as String] as? String,
|
||||
allowedBundleIDs.contains(bundleID)
|
||||
else {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
extension Bundle {
|
||||
public extension Bundle {
|
||||
var version: String {
|
||||
infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown"
|
||||
}
|
||||
|
||||
+162
-11
@@ -202,7 +202,14 @@
|
||||
}
|
||||
},
|
||||
"App Settings" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "应用设置"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Append `0.0.0.0/31` and `::/127` to `route_exclude_address` if not exists." : {
|
||||
"localizations" : {
|
||||
@@ -562,6 +569,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Context destroyed" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "上下文已销毁"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Copy" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
@@ -984,7 +1001,14 @@
|
||||
}
|
||||
},
|
||||
"Enable" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "启用"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enforceRoutes" : {
|
||||
"shouldTranslate" : false
|
||||
@@ -1068,6 +1092,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Failed to save rules" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "保存规则失败"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"false" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
@@ -1176,10 +1210,24 @@
|
||||
}
|
||||
},
|
||||
"Helper Service" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "辅助服务"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Helper Service Required" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "需要辅助服务"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Hide VPN Icon" : {
|
||||
"localizations" : {
|
||||
@@ -1355,7 +1403,14 @@
|
||||
}
|
||||
},
|
||||
"In the standalone version of SFM, reading WiFi state requires this app to be running. After you quit the SFM app, the sing-box service cannot continue to provide `wifi_ssid` and `wifi_bssid` routing rules." : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "在 SFM 独立版本中,读取 WiFi 状态需要应用保持运行。退出 SFM 应用后,sing-box 服务将无法继续提供 `wifi_ssid` 和 `wifi_bssid` 路由规则。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Inbound" : {
|
||||
"localizations" : {
|
||||
@@ -1381,7 +1436,14 @@
|
||||
"shouldTranslate" : false
|
||||
},
|
||||
"Install" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "安装"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Install Network Extension" : {
|
||||
"localizations" : {
|
||||
@@ -1424,6 +1486,7 @@
|
||||
}
|
||||
},
|
||||
"Invalid QR Code" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
@@ -1550,7 +1613,14 @@
|
||||
}
|
||||
},
|
||||
"Managing working directory requires Helper Service." : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "管理工作目录需要辅助服务。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Match Domains" : {
|
||||
"localizations" : {
|
||||
@@ -1585,6 +1655,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Missing access to selected file" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "无法访问所选文件"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Missing file" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "缺少文件"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Missing path" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
@@ -1897,6 +1987,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Profile missing" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "配置丢失"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Profile not found" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "未找到配置"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Profile Override" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
@@ -2075,6 +2185,7 @@
|
||||
}
|
||||
},
|
||||
"Scanner Error" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
@@ -2115,6 +2226,7 @@
|
||||
}
|
||||
},
|
||||
"Service Error" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
@@ -2451,7 +2563,14 @@
|
||||
}
|
||||
},
|
||||
"The sing-box service requires Helper Service to provide process lookup functionality, which supports `process_name` and `process_path` routing rules." : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "sing-box 服务需要辅助服务来提供进程查找功能,以支持 `process_name` 和 `process_path` 路由规则。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"This app needs to be placed under the Applications folder to work." : {
|
||||
"localizations" : {
|
||||
@@ -2464,7 +2583,14 @@
|
||||
}
|
||||
},
|
||||
"This helper service provides process lookup for `process_name` and `process_path` routing rules, and manages the working directory." : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "此辅助服务为 `process_name` 和 `process_path` 路由规则提供进程查找功能,并管理工作目录。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"To Clipboard" : {
|
||||
"localizations" : {
|
||||
@@ -2537,7 +2663,24 @@
|
||||
}
|
||||
},
|
||||
"Unavailable" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "不可用"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Unexpected message type %lld" : {
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "意外的消息类型 %lld"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Uninstall" : {
|
||||
"localizations" : {
|
||||
@@ -2570,6 +2713,7 @@
|
||||
}
|
||||
},
|
||||
"Update Failed" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
@@ -2663,7 +2807,14 @@
|
||||
}
|
||||
},
|
||||
"WiFi State Access" : {
|
||||
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "WiFi 状态访问"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Working Directory" : {
|
||||
"localizations" : {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
SHELL := /bin/bash
|
||||
.SHELLFLAGS := -o pipefail -c
|
||||
|
||||
build_all: build_ios build_macos build_tvos
|
||||
|
||||
build_ios:
|
||||
|
||||
@@ -12,6 +12,7 @@ class StandaloneApplicationDelegate: ApplicationDelegate {
|
||||
UserServiceEndpointPublisher.shared.start()
|
||||
Task {
|
||||
await setupSystemExtension()
|
||||
await HelperServiceManager.updateRootHelperIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1836,6 +1836,7 @@
|
||||
3AAAFB2F2EF5218F004C69AD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
APP_GROUP_IDENTIFIER = "group.$(BASE_PACKAGE_IDENTIFIER)";
|
||||
CODE_SIGN_ENTITLEMENTS = FileProviderExtension/FileProviderExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -1868,6 +1869,7 @@
|
||||
3AAAFB302EF5218F004C69AD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
APP_GROUP_IDENTIFIER = "group.$(BASE_PACKAGE_IDENTIFIER)";
|
||||
CODE_SIGN_ENTITLEMENTS = FileProviderExtension/FileProviderExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -2127,6 +2129,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = "1.13.0-alpha.21";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_PACKAGE_IDENTIFIER).helper";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO;
|
||||
@@ -2167,6 +2170,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = "1.13.0-alpha.21";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_PACKAGE_IDENTIFIER).helper";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO;
|
||||
@@ -2513,6 +2517,7 @@
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
STRIP_STYLE = "non-global";
|
||||
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
@@ -2536,7 +2541,6 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
STRIP_STYLE = "non-global";
|
||||
DEVELOPMENT_TEAM = 287TTNZF8L;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@@ -2561,6 +2565,7 @@
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
STRIP_STYLE = "non-global";
|
||||
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
|
||||
Reference in New Issue
Block a user