diff --git a/EasyTierShared/EasyTierShared.swift b/EasyTierShared/EasyTierShared.swift index f326c3a..d56099e 100644 --- a/EasyTierShared/EasyTierShared.swift +++ b/EasyTierShared/EasyTierShared.swift @@ -1,11 +1,45 @@ +import Foundation @preconcurrency import NetworkExtension import os public let APP_BUNDLE_ID: String = "cn.easytier" -public let APP_GROUP_ID: String = "group.cn.easytier" +public let DEFAULT_APP_GROUP_ID: String = "group.cn.easytier" public let ICLOUD_CONTAINER_ID: String = "iCloud.cn.easytier" public let LOG_FILENAME: String = "easytier.log" +/// A re-signed build has its app group renamed rather than removed, so the compiled-in +/// identifier stops matching and every container and shared-defaults lookup returns nil -- +/// silently, while the tunnel keeps working. Take the identifier from the provisioning +/// profile in that case. +private let resolvedAppGroup: (id: String, source: String, available: Bool) = { + let hasContainer = { (group: String) in + FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: group) != nil + } + if hasContainer(DEFAULT_APP_GROUP_ID) { + return (DEFAULT_APP_GROUP_ID, "default", true) + } + // The profile is CMS-wrapped; its plist runs from the first . + guard let profile = try? Data(contentsOf: Bundle.main.bundleURL + .appendingPathComponent("embedded.mobileprovision")), + let start = profile.range(of: Data("".utf8), options: .backwards), + let plist = (try? PropertyListSerialization.propertyList( + from: Data(profile[start.lowerBound..