From bd3f91254288ec0b9872966dfbb9ac251f890bfa Mon Sep 17 00:00:00 2001 From: Jamil Date: Tue, 3 Dec 2024 21:34:25 -0800 Subject: [PATCH] refactor(apple/macos): Use System Extension packaging mode for macOS Network Extension (#7344) To allow macOS users to rollback, it would be helpful to distribute a standalone macOS app, similar to how we distribute the GUI client. The first step in this process is to refactor the macOS client to use a System Extension -based Network Extension rather than an App Extension based one. This offers us the flexibility to distribute the macOS client outside the Mac App Store in addition to via the store. For this PR I focused on making the minimal set of changes necessary to support this change. This PR intentionally doesn't update the CI pipeline to notarize and attach a standalone bundle that will run ad-hoc on other Macs. That will come in a subsequent PR. One thing to note about System Extensions is that they're slightly more finicky when it comes to getting the signing and packaging right. Thus, the README.md is updated to account for the gotchas involved in developing System Extensions locally. Related: #7071. --- .../apple/Firezone.xcodeproj/project.pbxproj | 345 +++++++++--------- .../FirezoneNetworkExtensionmacOS.xcscheme | 67 ++++ swift/apple/Firezone/ExportOptions.plist | 4 +- swift/apple/Firezone/Firezone.entitlements | 2 + swift/apple/Firezone/xcconfig/debug.xcconfig | 2 +- .../apple/Firezone/xcconfig/release.xcconfig | 10 +- .../Managers/SystemExtensionManager.swift | 59 +++ .../FirezoneKit/Managers/TunnelManager.swift | 39 +- ... => FirezoneNetworkExtension.entitlements} | 0 ...irezoneNetworkExtension_macOS.entitlements | 20 - .../apple/FirezoneNetworkExtension/Info.plist | 12 + .../apple/FirezoneNetworkExtension/main.swift | 16 + swift/apple/README.md | 48 ++- website/src/app/kb/administer/logs/readme.mdx | 2 +- 14 files changed, 393 insertions(+), 233 deletions(-) create mode 100644 swift/apple/Firezone.xcodeproj/xcshareddata/xcschemes/FirezoneNetworkExtensionmacOS.xcscheme create mode 100644 swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/SystemExtensionManager.swift rename swift/apple/FirezoneNetworkExtension/{FirezoneNetworkExtension_iOS.entitlements => FirezoneNetworkExtension.entitlements} (100%) delete mode 100644 swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension_macOS.entitlements create mode 100644 swift/apple/FirezoneNetworkExtension/main.swift diff --git a/swift/apple/Firezone.xcodeproj/project.pbxproj b/swift/apple/Firezone.xcodeproj/project.pbxproj index 315b317ce..9bca8f727 100644 --- a/swift/apple/Firezone.xcodeproj/project.pbxproj +++ b/swift/apple/Firezone.xcodeproj/project.pbxproj @@ -8,56 +8,42 @@ /* Begin PBXBuildFile section */ 05CF1CF1290B1CEE00CF4755 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05D3BB1628FDBD8A00BC3727 /* NetworkExtension.framework */; }; - 05CF1CF9290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 05CF1CF0290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 05CF1D04290B1DCD00CF4755 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05D3BB1628FDBD8A00BC3727 /* NetworkExtension.framework */; platformFilters = (macos, ); }; - 05CF1D0C290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 05CF1D03290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS.appex */; platformFilters = (macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 05CF1D16290B1FE700CF4755 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05833DFA28F73B070008FAB0 /* PacketTunnelProvider.swift */; }; 05CF1D17290B1FE700CF4755 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05833DFA28F73B070008FAB0 /* PacketTunnelProvider.swift */; }; 05D3BB2128FDE9C000BC3727 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05D3BB1628FDBD8A00BC3727 /* NetworkExtension.framework */; }; 6FE454F62A5BFB93006549B1 /* Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE454EA2A5BFABA006549B1 /* Adapter.swift */; }; - 6FE454F72A5BFB93006549B1 /* Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE454EA2A5BFABA006549B1 /* Adapter.swift */; }; 6FE455092A5D110D006549B1 /* CallbackHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455082A5D110D006549B1 /* CallbackHandler.swift */; }; - 6FE4550A2A5D110D006549B1 /* CallbackHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455082A5D110D006549B1 /* CallbackHandler.swift */; }; 6FE4550C2A5D111E006549B1 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE4550B2A5D111D006549B1 /* SwiftBridgeCore.swift */; }; - 6FE4550D2A5D111E006549B1 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE4550B2A5D111D006549B1 /* SwiftBridgeCore.swift */; }; 6FE4550F2A5D112C006549B1 /* connlib-client-apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE4550E2A5D112C006549B1 /* connlib-client-apple.swift */; }; - 6FE455102A5D112C006549B1 /* connlib-client-apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE4550E2A5D112C006549B1 /* connlib-client-apple.swift */; }; 6FE93AFB2A738D7E002D278A /* NetworkSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE93AFA2A738D7E002D278A /* NetworkSettings.swift */; }; - 6FE93AFC2A738D7E002D278A /* NetworkSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE93AFA2A738D7E002D278A /* NetworkSettings.swift */; }; - 6FFECD5C2AD6998400E00273 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FFECD5B2AD6998400E00273 /* SystemConfiguration.framework */; }; 794C38152970A2660029F38F /* FirezoneKit in Frameworks */ = {isa = PBXBuildFile; productRef = 794C38142970A2660029F38F /* FirezoneKit */; }; - 794C38172970A26A0029F38F /* FirezoneKit in Frameworks */ = {isa = PBXBuildFile; productRef = 794C38162970A26A0029F38F /* FirezoneKit */; }; 79756C6629704A7A0018E2D5 /* FirezoneKit in Frameworks */ = {isa = PBXBuildFile; productRef = 79756C6529704A7A0018E2D5 /* FirezoneKit */; }; + 8D5047F52CE6AA1E009802E9 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5047F32CE6AA1E009802E9 /* libresolv.9.tbd */; }; + 8D5047F62CE6AA1E009802E9 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5047F42CE6AA1E009802E9 /* libresolv.tbd */; }; + 8D5047F82CE6AA22009802E9 /* FirezoneKit in Frameworks */ = {isa = PBXBuildFile; productRef = 8D5047F72CE6AA22009802E9 /* FirezoneKit */; }; + 8D5047FA2CE6AA2E009802E9 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5047F92CE6AA2E009802E9 /* SystemConfiguration.framework */; }; + 8D5047FB2CE6AA37009802E9 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455112A5D13A2006549B1 /* FirezoneNetworkExtension-Bridging-Header.h */; }; + 8D5047FC2CE6AA47009802E9 /* CallbackHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455082A5D110D006549B1 /* CallbackHandler.swift */; }; + 8D5047FD2CE6AA47009802E9 /* connlib-client-apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE4550E2A5D112C006549B1 /* connlib-client-apple.swift */; }; + 8D5047FE2CE6AA54009802E9 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05833DFA28F73B070008FAB0 /* PacketTunnelProvider.swift */; }; + 8D5047FF2CE6AA54009802E9 /* Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE454EA2A5BFABA006549B1 /* Adapter.swift */; }; + 8D5048002CE6AA60009802E9 /* SystemConfigurationResolvers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D6939312BA2521A00AF4396 /* SystemConfigurationResolvers.swift */; }; + 8D5048012CE6AA60009802E9 /* NetworkSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE93AFA2A738D7E002D278A /* NetworkSettings.swift */; }; + 8D5048042CE6B0AE009802E9 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE4550B2A5D111D006549B1 /* SwiftBridgeCore.swift */; }; 8D69392C2BA24FE600AF4396 /* BindResolvers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D69392B2BA24FE600AF4396 /* BindResolvers.swift */; }; - 8D6939322BA2521A00AF4396 /* SystemConfigurationResolvers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D6939312BA2521A00AF4396 /* SystemConfigurationResolvers.swift */; }; 8DA12C332BB7DA04007D91EB /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 8DA12C322BB7DA04007D91EB /* PrivacyInfo.xcprivacy */; }; - 8DA12C342BB7DA04007D91EB /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 8DA12C322BB7DA04007D91EB /* PrivacyInfo.xcprivacy */; }; 8DC08BCB2B296C4500675F46 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BCA2B296C4500675F46 /* libresolv.9.tbd */; }; - 8DC08BCD2B296C5900675F46 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BCC2B296C5900675F46 /* libresolv.9.tbd */; }; - 8DC08BD22B297B7B00675F46 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BD12B297B7B00675F46 /* libresolv.tbd */; }; 8DC08BD42B297B8200675F46 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BD32B297B8200675F46 /* libresolv.tbd */; }; - 8DC08BD62B297DA400675F46 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455112A5D13A2006549B1 /* FirezoneNetworkExtension-Bridging-Header.h */; }; 8DC08BD72B297DB400675F46 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455112A5D13A2006549B1 /* FirezoneNetworkExtension-Bridging-Header.h */; }; + 8DC1699D2CFF77D1006801B5 /* dev.firezone.firezone.network-extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 05CF1CF0290B1CEE00CF4755 /* dev.firezone.firezone.network-extension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 8DC169A02CFF77D1006801B5 /* dev.firezone.firezone.network-extension.systemextension in Embed System Extensions */ = {isa = PBXBuildFile; fileRef = 8D5047E32CE6A8F4009802E9 /* dev.firezone.firezone.network-extension.systemextension */; platformFilters = (macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 8DC9FB852CF5A738001BCE6A /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05D3BB1628FDBD8A00BC3727 /* NetworkExtension.framework */; }; 8DCC021D28D512AC007E12D2 /* FirezoneApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DCC021C28D512AC007E12D2 /* FirezoneApp.swift */; }; 8DCC022628D512AE007E12D2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DCC022528D512AE007E12D2 /* Assets.xcassets */; }; 8DCC022A28D512AE007E12D2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DCC022928D512AE007E12D2 /* Preview Assets.xcassets */; }; + 8DE452A82CE6C194004CEDF9 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D5047E82CE6A8F4009802E9 /* main.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 05CF1CF7290B1CEE00CF4755 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8DCC021128D512AC007E12D2 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 05CF1CEF290B1CEE00CF4755; - remoteInfo = FirezoneNetworkExtensioniOS; - }; - 05CF1D0A290B1DCD00CF4755 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8DCC021128D512AC007E12D2 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 05CF1D02290B1DCD00CF4755; - remoteInfo = FirezoneNetworkExtensionmacOS; - }; 6F3E231B2A5DC0DB00737CF1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8DCC021128D512AC007E12D2 /* Project object */; @@ -65,34 +51,48 @@ remoteGlobalIDString = 6FE454BC2A5BC5F3006549B1; remoteInfo = "Build Connlib"; }; - 6F3E231D2A5DC0DF00737CF1 /* PBXContainerItemProxy */ = { + 8D5048022CE6AA75009802E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8DCC021128D512AC007E12D2 /* Project object */; proxyType = 1; remoteGlobalIDString = 6FE454BC2A5BC5F3006549B1; remoteInfo = "Build Connlib"; }; + 8DC1699E2CFF77D1006801B5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DCC021128D512AC007E12D2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 05CF1CEF290B1CEE00CF4755; + remoteInfo = FirezoneNetworkExtensioniOS; + }; + 8DC169A12CFF77D1006801B5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DCC021128D512AC007E12D2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D5047E22CE6A8F4009802E9; + remoteInfo = FirezoneNetworkExtensionmacOS; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 0556189428EF883500DF9E3C /* Embed Foundation Extensions */ = { + 8DC169A32CFF77D1006801B5 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( - 05CF1CF9290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS.appex in Embed Foundation Extensions */, - 05CF1D0C290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS.appex in Embed Foundation Extensions */, + 8DC1699D2CFF77D1006801B5 /* dev.firezone.firezone.network-extension.appex in Embed Foundation Extensions */, ); name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; - 05CF1C8A290B11A500CF4755 /* Embed System Extensions */ = { + 8DC169A42CFF77D1006801B5 /* Embed System Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = "$(SYSTEM_EXTENSIONS_FOLDER_PATH)"; dstSubfolderSpec = 16; files = ( + 8DC169A02CFF77D1006801B5 /* dev.firezone.firezone.network-extension.systemextension in Embed System Extensions */, ); name = "Embed System Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -101,12 +101,8 @@ /* Begin PBXFileReference section */ 05833DFA28F73B070008FAB0 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; }; - 05B6467B292C36140014A4D4 /* AuthenticationServiceStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceStub.swift; sourceTree = ""; }; - 05CF1C39290995DA00CF4755 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 05CF1CDE290B1A9000CF4755 /* FirezoneNetworkExtension_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FirezoneNetworkExtension_macOS.entitlements; sourceTree = ""; }; - 05CF1CF0290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FirezoneNetworkExtensioniOS.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 05CF1CF6290B1CEE00CF4755 /* FirezoneNetworkExtension_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FirezoneNetworkExtension_iOS.entitlements; sourceTree = ""; }; - 05CF1D03290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FirezoneNetworkExtensionmacOS.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 05CF1CF0290B1CEE00CF4755 /* dev.firezone.firezone.network-extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "dev.firezone.firezone.network-extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; + 05CF1CF6290B1CEE00CF4755 /* FirezoneNetworkExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FirezoneNetworkExtension.entitlements; sourceTree = ""; }; 05D3BB1628FDBD8A00BC3727 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; 6FE454EA2A5BFABA006549B1 /* Adapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Adapter.swift; sourceTree = ""; }; 6FE455082A5D110D006549B1 /* CallbackHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallbackHandler.swift; sourceTree = ""; }; @@ -115,6 +111,14 @@ 6FE455112A5D13A2006549B1 /* FirezoneNetworkExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FirezoneNetworkExtension-Bridging-Header.h"; sourceTree = ""; }; 6FE93AFA2A738D7E002D278A /* NetworkSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSettings.swift; sourceTree = ""; }; 6FFECD5B2AD6998400E00273 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 8D1D405C2CFF6F5200E669F9 /* Firezone.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Firezone.entitlements; sourceTree = ""; }; + 8D1D405D2CFF6F5D00E669F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8D1D40602CFF6F7400E669F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8D5047E32CE6A8F4009802E9 /* dev.firezone.firezone.network-extension.systemextension */ = {isa = PBXFileReference; explicitFileType = "wrapper.system-extension"; includeInIndex = 0; path = "dev.firezone.firezone.network-extension.systemextension"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D5047E82CE6A8F4009802E9 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 8D5047F32CE6AA1E009802E9 /* libresolv.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.9.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.1.sdk/usr/lib/libresolv.9.tbd; sourceTree = DEVELOPER_DIR; }; + 8D5047F42CE6AA1E009802E9 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.1.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; }; + 8D5047F92CE6AA2E009802E9 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.1.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; 8D69392B2BA24FE600AF4396 /* BindResolvers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BindResolvers.swift; sourceTree = ""; }; 8D6939312BA2521A00AF4396 /* SystemConfigurationResolvers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemConfigurationResolvers.swift; sourceTree = ""; }; 8DA12C322BB7DA04007D91EB /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; @@ -125,7 +129,6 @@ 8DCC021928D512AC007E12D2 /* Firezone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Firezone.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8DCC021C28D512AC007E12D2 /* FirezoneApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirezoneApp.swift; sourceTree = ""; }; 8DCC022528D512AE007E12D2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 8DCC022728D512AE007E12D2 /* Firezone.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Firezone.entitlements; sourceTree = ""; }; 8DCC022928D512AE007E12D2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 8DD2C4C3297B37BA00F984BF /* FirezoneKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = FirezoneKit; sourceTree = ""; }; 8DDD0E8B2ADC6657001FA7E9 /* config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = config.xcconfig; path = xcconfig/config.xcconfig; sourceTree = ""; }; @@ -143,15 +146,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 05CF1D00290B1DCD00CF4755 /* Frameworks */ = { + 8D5047E02CE6A8F4009802E9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8DC08BD22B297B7B00675F46 /* libresolv.tbd in Frameworks */, - 8DC08BCD2B296C5900675F46 /* libresolv.9.tbd in Frameworks */, - 794C38172970A26A0029F38F /* FirezoneKit in Frameworks */, - 05CF1D04290B1DCD00CF4755 /* NetworkExtension.framework in Frameworks */, - 6FFECD5C2AD6998400E00273 /* SystemConfiguration.framework in Frameworks */, + 8D5047F52CE6AA1E009802E9 /* libresolv.9.tbd in Frameworks */, + 8D5047F62CE6AA1E009802E9 /* libresolv.tbd in Frameworks */, + 8D5047F82CE6AA22009802E9 /* FirezoneKit in Frameworks */, + 8DC9FB852CF5A738001BCE6A /* NetworkExtension.framework in Frameworks */, + 8D5047FA2CE6AA2E009802E9 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -167,21 +170,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0580451B29385C150080D1F0 /* Recovered References */ = { - isa = PBXGroup; - children = ( - 05B6467B292C36140014A4D4 /* AuthenticationServiceStub.swift */, - ); - name = "Recovered References"; - sourceTree = ""; - }; 05833DF928F73B070008FAB0 /* FirezoneNetworkExtension */ = { isa = PBXGroup; children = ( + 8D1D40602CFF6F7400E669F9 /* Info.plist */, 8D6939312BA2521A00AF4396 /* SystemConfigurationResolvers.swift */, 8D69392B2BA24FE600AF4396 /* BindResolvers.swift */, - 05CF1CF6290B1CEE00CF4755 /* FirezoneNetworkExtension_iOS.entitlements */, - 05CF1CDE290B1A9000CF4755 /* FirezoneNetworkExtension_macOS.entitlements */, + 05CF1CF6290B1CEE00CF4755 /* FirezoneNetworkExtension.entitlements */, + 8D5047E82CE6A8F4009802E9 /* main.swift */, 05833DFA28F73B070008FAB0 /* PacketTunnelProvider.swift */, 6FE454EA2A5BFABA006549B1 /* Adapter.swift */, 6FE93AFA2A738D7E002D278A /* NetworkSettings.swift */, @@ -204,10 +200,13 @@ 8D3F90C328D64FAD00980124 /* Frameworks */ = { isa = PBXGroup; children = ( + 8D5047F92CE6AA2E009802E9 /* SystemConfiguration.framework */, 8DC08BD12B297B7B00675F46 /* libresolv.tbd */, 8DC08BD32B297B8200675F46 /* libresolv.tbd */, + 8D5047F42CE6AA1E009802E9 /* libresolv.tbd */, 8DC08BCA2B296C4500675F46 /* libresolv.9.tbd */, 8DC08BCC2B296C5900675F46 /* libresolv.9.tbd */, + 8D5047F32CE6AA1E009802E9 /* libresolv.9.tbd */, 6FFECD5B2AD6998400E00273 /* SystemConfiguration.framework */, 05D3BB1628FDBD8A00BC3727 /* NetworkExtension.framework */, ); @@ -223,7 +222,6 @@ 05833DF928F73B070008FAB0 /* FirezoneNetworkExtension */, 8DCC021A28D512AC007E12D2 /* Products */, 8D3F90C328D64FAD00980124 /* Frameworks */, - 0580451B29385C150080D1F0 /* Recovered References */, ); sourceTree = ""; }; @@ -231,8 +229,8 @@ isa = PBXGroup; children = ( 8DCC021928D512AC007E12D2 /* Firezone.app */, - 05CF1CF0290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS.appex */, - 05CF1D03290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS.appex */, + 05CF1CF0290B1CEE00CF4755 /* dev.firezone.firezone.network-extension.appex */, + 8D5047E32CE6A8F4009802E9 /* dev.firezone.firezone.network-extension.systemextension */, ); name = Products; sourceTree = ""; @@ -240,11 +238,11 @@ 8DCC021B28D512AC007E12D2 /* Firezone */ = { isa = PBXGroup; children = ( + 8D1D405C2CFF6F5200E669F9 /* Firezone.entitlements */, + 8D1D405D2CFF6F5D00E669F9 /* Info.plist */, 8DDD0E8B2ADC6657001FA7E9 /* config.xcconfig */, 05E1505F28FF398000170F82 /* Application */, 8DCC022528D512AE007E12D2 /* Assets.xcassets */, - 8DCC022728D512AE007E12D2 /* Firezone.entitlements */, - 05CF1C39290995DA00CF4755 /* Info.plist */, 8DCC022828D512AE007E12D2 /* Preview Content */, ); path = Firezone; @@ -305,30 +303,30 @@ 794C38142970A2660029F38F /* FirezoneKit */, ); productName = FirezoneNetworkExtensioniOS; - productReference = 05CF1CF0290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS.appex */; + productReference = 05CF1CF0290B1CEE00CF4755 /* dev.firezone.firezone.network-extension.appex */; productType = "com.apple.product-type.app-extension"; }; - 05CF1D02290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS */ = { + 8D5047E22CE6A8F4009802E9 /* FirezoneNetworkExtensionmacOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 05CF1D0D290B1DCD00CF4755 /* Build configuration list for PBXNativeTarget "FirezoneNetworkExtensionmacOS" */; + buildConfigurationList = 8D5047F02CE6A8F4009802E9 /* Build configuration list for PBXNativeTarget "FirezoneNetworkExtensionmacOS" */; buildPhases = ( - 6F3E23192A5D823500737CF1 /* Copy Connlib Headers and Swift Files */, - 05CF1CFF290B1DCD00CF4755 /* Sources */, - 05CF1D00290B1DCD00CF4755 /* Frameworks */, - 05CF1D01290B1DCD00CF4755 /* Resources */, + 8D5048072CE6B243009802E9 /* Copy Connlib Headers and Swift Files */, + 8D5047DF2CE6A8F4009802E9 /* Sources */, + 8D5047E02CE6A8F4009802E9 /* Frameworks */, + 8D5047E12CE6A8F4009802E9 /* Resources */, ); buildRules = ( ); dependencies = ( - 6F3E231E2A5DC0DF00737CF1 /* PBXTargetDependency */, + 8D5048032CE6AA75009802E9 /* PBXTargetDependency */, ); name = FirezoneNetworkExtensionmacOS; packageProductDependencies = ( - 794C38162970A26A0029F38F /* FirezoneKit */, + 8D5047F72CE6AA22009802E9 /* FirezoneKit */, ); - productName = FirezoneNetworkExtensionmacOS; - productReference = 05CF1D03290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS.appex */; - productType = "com.apple.product-type.app-extension"; + productName = FirezoneNetworkExtensionStandalonemacOS; + productReference = 8D5047E32CE6A8F4009802E9 /* dev.firezone.firezone.network-extension.systemextension */; + productType = "com.apple.product-type.system-extension"; }; 8DCC021828D512AC007E12D2 /* Firezone */ = { isa = PBXNativeTarget; @@ -338,14 +336,14 @@ 8DCC021528D512AC007E12D2 /* Sources */, 8DCC021628D512AC007E12D2 /* Frameworks */, 8DCC021728D512AC007E12D2 /* Resources */, - 0556189428EF883500DF9E3C /* Embed Foundation Extensions */, - 05CF1C8A290B11A500CF4755 /* Embed System Extensions */, + 8DC169A32CFF77D1006801B5 /* Embed Foundation Extensions */, + 8DC169A42CFF77D1006801B5 /* Embed System Extensions */, ); buildRules = ( ); dependencies = ( - 05CF1CF8290B1CEE00CF4755 /* PBXTargetDependency */, - 05CF1D0B290B1DCD00CF4755 /* PBXTargetDependency */, + 8DC1699F2CFF77D1006801B5 /* PBXTargetDependency */, + 8DC169A22CFF77D1006801B5 /* PBXTargetDependency */, ); name = Firezone; packageProductDependencies = ( @@ -362,20 +360,19 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1400; - LastUpgradeCheck = 1430; + LastSwiftUpdateCheck = 1610; + LastUpgradeCheck = 1610; TargetAttributes = { 05CF1CEF290B1CEE00CF4755 = { CreatedOnToolsVersion = 14.0.1; LastSwiftMigration = 1430; }; - 05CF1D02290B1DCD00CF4755 = { - CreatedOnToolsVersion = 14.0.1; - LastSwiftMigration = 1430; - }; 6FE454BC2A5BC5F3006549B1 = { CreatedOnToolsVersion = 14.3; }; + 8D5047E22CE6A8F4009802E9 = { + CreatedOnToolsVersion = 16.1; + }; 8DCC021828D512AC007E12D2 = { CreatedOnToolsVersion = 14.0; LastSwiftMigration = 1400; @@ -399,7 +396,7 @@ targets = ( 8DCC021828D512AC007E12D2 /* Firezone */, 05CF1CEF290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS */, - 05CF1D02290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS */, + 8D5047E22CE6A8F4009802E9 /* FirezoneNetworkExtensionmacOS */, 6FE454BC2A5BC5F3006549B1 /* Build Connlib */, ); }; @@ -414,11 +411,10 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 05CF1D01290B1DCD00CF4755 /* Resources */ = { + 8D5047E12CE6A8F4009802E9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8DA12C342BB7DA04007D91EB /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -434,7 +430,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 6F3E23192A5D823500737CF1 /* Copy Connlib Headers and Swift Files */ = { + 6F3E231A2A5D830D00737CF1 /* Copy Connlib Headers and Swift Files */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -454,7 +450,7 @@ shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n./copy_generated_connlib_files.sh\n"; showEnvVarsInLog = 0; }; - 6F3E231A2A5D830D00737CF1 /* Copy Connlib Headers and Swift Files */ = { + 8D5048072CE6B243009802E9 /* Copy Connlib Headers and Swift Files */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -511,18 +507,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 05CF1CFF290B1DCD00CF4755 /* Sources */ = { + 8D5047DF2CE6A8F4009802E9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8DC08BD62B297DA400675F46 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */, - 6FE4550A2A5D110D006549B1 /* CallbackHandler.swift in Sources */, - 6FE455102A5D112C006549B1 /* connlib-client-apple.swift in Sources */, - 05CF1D16290B1FE700CF4755 /* PacketTunnelProvider.swift in Sources */, - 6FE454F72A5BFB93006549B1 /* Adapter.swift in Sources */, - 6FE4550D2A5D111E006549B1 /* SwiftBridgeCore.swift in Sources */, - 6FE93AFC2A738D7E002D278A /* NetworkSettings.swift in Sources */, - 8D6939322BA2521A00AF4396 /* SystemConfigurationResolvers.swift in Sources */, + 8DE452A82CE6C194004CEDF9 /* main.swift in Sources */, + 8D5047FB2CE6AA37009802E9 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */, + 8D5048042CE6B0AE009802E9 /* SwiftBridgeCore.swift in Sources */, + 8D5047FD2CE6AA47009802E9 /* connlib-client-apple.swift in Sources */, + 8D5047FC2CE6AA47009802E9 /* CallbackHandler.swift in Sources */, + 8D5047FE2CE6AA54009802E9 /* PacketTunnelProvider.swift in Sources */, + 8D5048002CE6AA60009802E9 /* SystemConfigurationResolvers.swift in Sources */, + 8D5048012CE6AA60009802E9 /* NetworkSettings.swift in Sources */, + 8D5047FF2CE6AA54009802E9 /* Adapter.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -537,29 +534,29 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 05CF1CF8290B1CEE00CF4755 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - platformFilter = ios; - target = 05CF1CEF290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS */; - targetProxy = 05CF1CF7290B1CEE00CF4755 /* PBXContainerItemProxy */; - }; - 05CF1D0B290B1DCD00CF4755 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - platformFilters = ( - macos, - ); - target = 05CF1D02290B1DCD00CF4755 /* FirezoneNetworkExtensionmacOS */; - targetProxy = 05CF1D0A290B1DCD00CF4755 /* PBXContainerItemProxy */; - }; 6F3E231C2A5DC0DB00737CF1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6FE454BC2A5BC5F3006549B1 /* Build Connlib */; targetProxy = 6F3E231B2A5DC0DB00737CF1 /* PBXContainerItemProxy */; }; - 6F3E231E2A5DC0DF00737CF1 /* PBXTargetDependency */ = { + 8D5048032CE6AA75009802E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6FE454BC2A5BC5F3006549B1 /* Build Connlib */; - targetProxy = 6F3E231D2A5DC0DF00737CF1 /* PBXContainerItemProxy */; + targetProxy = 8D5048022CE6AA75009802E9 /* PBXContainerItemProxy */; + }; + 8DC1699F2CFF77D1006801B5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilter = ios; + target = 05CF1CEF290B1CEE00CF4755 /* FirezoneNetworkExtensioniOS */; + targetProxy = 8DC1699E2CFF77D1006801B5 /* PBXContainerItemProxy */; + }; + 8DC169A22CFF77D1006801B5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilters = ( + macos, + ); + target = 8D5047E22CE6A8F4009802E9 /* FirezoneNetworkExtensionmacOS */; + targetProxy = 8DC169A12CFF77D1006801B5 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -568,7 +565,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension_iOS.entitlements; + CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension.entitlements; CODE_SIGN_IDENTITY = "$(inherited)"; CODE_SIGN_STYLE = "$(inherited)"; CURRENT_PROJECT_VERSION = 0; @@ -578,6 +575,7 @@ INFOPLIST_FILE = FirezoneNetworkExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = FirezoneNetworkExtension; INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSSystemExtensionUsageDescription = "Firezone tunnel service"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -588,8 +586,8 @@ MARKETING_VERSION = 1.3.10; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-lconnlib"; - PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).debug.network-extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).network-extension"; + PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)"; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "$(IOS_NE_PROVISIONING_PROFILE_IDENTIFIER)"; SDKROOT = iphoneos; @@ -610,7 +608,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension_iOS.entitlements; + CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension.entitlements; CODE_SIGN_IDENTITY = "$(inherited)"; CODE_SIGN_STYLE = "$(inherited)"; CURRENT_PROJECT_VERSION = 0; @@ -620,6 +618,7 @@ INFOPLIST_FILE = FirezoneNetworkExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = FirezoneNetworkExtension; INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSSystemExtensionUsageDescription = "Firezone tunnel service"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -630,7 +629,7 @@ MARKETING_VERSION = 1.3.10; OTHER_LDFLAGS = "-lconnlib"; PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).network-extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)"; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "$(IOS_NE_PROVISIONING_PROFILE_IDENTIFIER)"; SDKROOT = iphoneos; @@ -647,15 +646,40 @@ }; name = Release; }; - 05CF1D0E290B1DCD00CF4755 /* Debug */ = { + 6FE454BE2A5BC5F3006549B1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension_macOS.entitlements; + CODE_SIGN_STYLE = "$(inherited)"; + DEBUGGING_SYMBOLS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6FE454BF2A5BC5F3006549B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = "$(inherited)"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)"; + }; + name = Release; + }; + 8D5047F12CE6A8F4009802E9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension.entitlements; CODE_SIGN_IDENTITY = "$(inherited)"; CODE_SIGN_STYLE = "$(inherited)"; CURRENT_PROJECT_VERSION = 0; - DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = "$(inherited)"; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; @@ -673,28 +697,23 @@ "LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(CONNLIB_TARGET_DIR)/x86_64-apple-darwin/debug"; MARKETING_VERSION = 1.3.10; OTHER_LDFLAGS = "-lconnlib"; - PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).debug.network-extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).network-extension"; + PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "$(MACOS_NE_PROVISIONING_PROFILE_IDENTIFIER)"; SDKROOT = macosx; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = macosx; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "FirezoneNetworkExtension/FirezoneNetworkExtension-Bridging-Header.h"; - SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = ""; - WATCHOS_DEPLOYMENT_TARGET = ""; }; name = Debug; }; - 05CF1D0F290B1DCD00CF4755 /* Release */ = { + 8D5047F22CE6A8F4009802E9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension_macOS.entitlements; + CODE_SIGN_ENTITLEMENTS = FirezoneNetworkExtension/FirezoneNetworkExtension.entitlements; CODE_SIGN_IDENTITY = "$(inherited)"; CODE_SIGN_STYLE = "$(inherited)"; CURRENT_PROJECT_VERSION = 0; @@ -717,7 +736,7 @@ MARKETING_VERSION = 1.3.10; OTHER_LDFLAGS = "-lconnlib"; PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).network-extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)"; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "$(MACOS_NE_PROVISIONING_PROFILE_IDENTIFIER)"; SDKROOT = macosx; @@ -725,35 +744,7 @@ SUPPORTED_PLATFORMS = macosx; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "FirezoneNetworkExtension/FirezoneNetworkExtension-Bridging-Header.h"; - SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = ""; - WATCHOS_DEPLOYMENT_TARGET = ""; - }; - name = Release; - }; - 6FE454BE2A5BC5F3006549B1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEBUGGING_SYMBOLS = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6FE454BF2A5BC5F3006549B1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; @@ -811,8 +802,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MACOSX_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MACOSX_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -870,8 +861,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MACOSX_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MACOSX_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SUPPORTED_PLATFORMS = "macosx iphoneos"; @@ -991,15 +982,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 05CF1D0D290B1DCD00CF4755 /* Build configuration list for PBXNativeTarget "FirezoneNetworkExtensionmacOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 05CF1D0E290B1DCD00CF4755 /* Debug */, - 05CF1D0F290B1DCD00CF4755 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 6FE454BD2A5BC5F3006549B1 /* Build configuration list for PBXLegacyTarget "Build Connlib" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1009,6 +991,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 8D5047F02CE6A8F4009802E9 /* Build configuration list for PBXNativeTarget "FirezoneNetworkExtensionmacOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8D5047F12CE6A8F4009802E9 /* Debug */, + 8D5047F22CE6A8F4009802E9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 8DCC021428D512AC007E12D2 /* Build configuration list for PBXProject "Firezone" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1034,11 +1025,11 @@ isa = XCSwiftPackageProductDependency; productName = FirezoneKit; }; - 794C38162970A26A0029F38F /* FirezoneKit */ = { + 79756C6529704A7A0018E2D5 /* FirezoneKit */ = { isa = XCSwiftPackageProductDependency; productName = FirezoneKit; }; - 79756C6529704A7A0018E2D5 /* FirezoneKit */ = { + 8D5047F72CE6AA22009802E9 /* FirezoneKit */ = { isa = XCSwiftPackageProductDependency; productName = FirezoneKit; }; diff --git a/swift/apple/Firezone.xcodeproj/xcshareddata/xcschemes/FirezoneNetworkExtensionmacOS.xcscheme b/swift/apple/Firezone.xcodeproj/xcshareddata/xcschemes/FirezoneNetworkExtensionmacOS.xcscheme new file mode 100644 index 000000000..e94fe2b81 --- /dev/null +++ b/swift/apple/Firezone.xcodeproj/xcshareddata/xcschemes/FirezoneNetworkExtensionmacOS.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/swift/apple/Firezone/ExportOptions.plist b/swift/apple/Firezone/ExportOptions.plist index 90d492ecd..ffb295f7b 100644 --- a/swift/apple/Firezone/ExportOptions.plist +++ b/swift/apple/Firezone/ExportOptions.plist @@ -7,10 +7,10 @@ provisioningProfiles dev.firezone.firezone - 9aafa0f8-4b68-49c8-b023-0d4576142e1f + 07102026-065f-4cc0-800b-5f8595c50ce8 dev.firezone.firezone.network-extension - 49b53dcc-efaf-4171-9f3b-ca8c46e41069 + c6feb05e-063a-4429-8563-57c1d2755067 diff --git a/swift/apple/Firezone/Firezone.entitlements b/swift/apple/Firezone/Firezone.entitlements index 80144f1fd..92c8fb3e8 100644 --- a/swift/apple/Firezone/Firezone.entitlements +++ b/swift/apple/Firezone/Firezone.entitlements @@ -12,6 +12,8 @@ $(APP_GROUP_ID) + com.apple.developer.system-extension.install + com.apple.security.files.user-selected.read-write com.apple.security.network.client diff --git a/swift/apple/Firezone/xcconfig/debug.xcconfig b/swift/apple/Firezone/xcconfig/debug.xcconfig index 4d7dca5f6..40024bc3a 100644 --- a/swift/apple/Firezone/xcconfig/debug.xcconfig +++ b/swift/apple/Firezone/xcconfig/debug.xcconfig @@ -1,6 +1,6 @@ // Apple Developer account-specific configuration DEVELOPMENT_TEAM = 47R2M6779T PRODUCT_BUNDLE_IDENTIFIER = dev.firezone.firezone -APP_GROUP_ID[sdk=macosx*] = 47R2M6779T.group.dev.firezone.firezone +APP_GROUP_ID[sdk=macosx*] = 47R2M6779T.dev.firezone.firezone APP_GROUP_ID[sdk=iphoneos*] = group.dev.firezone.firezone CODE_SIGN_STYLE = Automatic diff --git a/swift/apple/Firezone/xcconfig/release.xcconfig b/swift/apple/Firezone/xcconfig/release.xcconfig index 78ce67608..2911175c8 100644 --- a/swift/apple/Firezone/xcconfig/release.xcconfig +++ b/swift/apple/Firezone/xcconfig/release.xcconfig @@ -1,11 +1,11 @@ // Apple Developer account-specific configuration DEVELOPMENT_TEAM = 47R2M6779T PRODUCT_BUNDLE_IDENTIFIER = dev.firezone.firezone -APP_GROUP_ID[sdk=macosx*] = 47R2M6779T.group.dev.firezone.firezone +APP_GROUP_ID[sdk=macosx*] = 47R2M6779T.dev.firezone.firezone APP_GROUP_ID[sdk=iphoneos*] = group.dev.firezone.firezone CODE_SIGN_STYLE = Manual CODE_SIGN_IDENTITY = Apple Distribution: Firezone, Inc. (47R2M6779T) -IOS_APP_PROVISIONING_PROFILE_IDENTIFIER = 9aafa0f8-4b68-49c8-b023-0d4576142e1f -MACOS_APP_PROVISIONING_PROFILE_IDENTIFIER = 5a382464-185f-456c-8e21-da43c920f958 -IOS_NE_PROVISIONING_PROFILE_IDENTIFIER = 49b53dcc-efaf-4171-9f3b-ca8c46e41069 -MACOS_NE_PROVISIONING_PROFILE_IDENTIFIER = b79986e4-4b54-43b3-9634-724e4a98ed64 +IOS_APP_PROVISIONING_PROFILE_IDENTIFIER = 07102026-065f-4cc0-800b-5f8595c50ce8 +MACOS_APP_PROVISIONING_PROFILE_IDENTIFIER = 9933ad98-3698-4782-ba8c-7e2da4c9835a +IOS_NE_PROVISIONING_PROFILE_IDENTIFIER = c6feb05e-063a-4429-8563-57c1d2755067 +MACOS_NE_PROVISIONING_PROFILE_IDENTIFIER = 789f5daf-bc9a-49fd-befd-bcfc88dd97a1 diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/SystemExtensionManager.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/SystemExtensionManager.swift new file mode 100644 index 000000000..ee7c48681 --- /dev/null +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/SystemExtensionManager.swift @@ -0,0 +1,59 @@ +// +// SystemExtensionManager.swift +// (c) 2024 Firezone, Inc. +// LICENSE: Apache-2.0 +// + +#if os(macOS) +import SystemExtensions + +enum SystemExtensionError: Error { + case UnexpectedResult(result: OSSystemExtensionRequest.Result) + case NeedsUserApproval +} + +public class SystemExtensionManager: NSObject, OSSystemExtensionRequestDelegate { + private var completionHandler: ((Error?) -> Void)? + + public func installSystemExtension( + identifier: String?, + completionHandler: @escaping (Error?) -> Void + ) { + guard let identifier = identifier else { return } + self.completionHandler = completionHandler + + let request = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: identifier, queue: .main) + request.delegate = self + + // Install extension + OSSystemExtensionManager.shared.submitRequest(request) + } + + // MARK: - OSSystemExtensionRequestDelegate + + public func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) { + guard result == .completed else { + completionHandler?(SystemExtensionError.UnexpectedResult(result: result)) + + return + } + + // Success + completionHandler?(nil) + } + + public func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) { + completionHandler?(error) + } + + public func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) { + completionHandler?(SystemExtensionError.NeedsUserApproval) + + // TODO: Inform the user to approve the system extension in System Preferences > Security & Privacy. + } + + public func request(_ request: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction { + return .replace + } +} +#endif diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift index c9be6aa2a..62e98d327 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift @@ -93,18 +93,12 @@ public class TunnelManager { // Encoder used to send messages to the tunnel private let encoder = PropertyListEncoder() - // Use separate bundle IDs for release and debug. - // Helps with testing releases and dev builds on the same Mac. - #if DEBUG - private let bundleIdentifier = Bundle.main.bundleIdentifier.map { - "\($0).debug.network-extension" - } +#if os(macOS) + private let systemExtensionManager = SystemExtensionManager() +#endif - private let bundleDescription = "Firezone (Debug)" - #else - private let bundleIdentifier = Bundle.main.bundleIdentifier.map { "\($0).network-extension" } - private let bundleDescription = "Firezone" - #endif + private let bundleIdentifier = "\(Bundle.main.bundleIdentifier!).network-extension" + private let bundleDescription = "Firezone" init() { manager = nil @@ -236,6 +230,29 @@ public class TunnelManager { options = ["token": token as NSObject] } +#if os(macOS) + // On macOS we use System Extensions, and we need to wait for them to be activated + // before we can continue starting the tunnel. Otherwise, the tunnel will come up, + // but then be killed immediately after since the system will reap its process as + // the system extension is moved in place. This is more of an issue in development + // where the system will replace the extension on each call to this API, ignoring the + // version check that typically prevents extensions from being reactivated if they have the + // same marketing version. + systemExtensionManager.installSystemExtension(identifier: bundleIdentifier) { error in + if let error = error { + Log.app.error("\(#function): Installing system extension failed! \(error.localizedDescription)") + + return + } + + self.startTunnel(options: options) + } +#else + startTunnel(options: options) +#endif + } + + func startTunnel(options: [String: NSObject]?) { do { try session().startTunnel(options: options) } catch { diff --git a/swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension_iOS.entitlements b/swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension.entitlements similarity index 100% rename from swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension_iOS.entitlements rename to swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension.entitlements diff --git a/swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension_macOS.entitlements b/swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension_macOS.entitlements deleted file mode 100644 index 51a75c689..000000000 --- a/swift/apple/FirezoneNetworkExtension/FirezoneNetworkExtension_macOS.entitlements +++ /dev/null @@ -1,20 +0,0 @@ - - - - - com.apple.developer.networking.networkextension - - packet-tunnel-provider - - com.apple.security.application-groups - - $(APP_GROUP_ID) - - com.apple.security.app-sandbox - - com.apple.security.network.client - - com.apple.security.network.server - - - diff --git a/swift/apple/FirezoneNetworkExtension/Info.plist b/swift/apple/FirezoneNetworkExtension/Info.plist index 6be51008c..9227ee6ee 100644 --- a/swift/apple/FirezoneNetworkExtension/Info.plist +++ b/swift/apple/FirezoneNetworkExtension/Info.plist @@ -11,5 +11,17 @@ AppGroupIdentifier $(APP_GROUP_ID) + NetworkExtension + + NEMachServiceName + $(APP_GROUP_ID) + NEProviderClasses + + com.apple.networkextension.packet-tunnel + $(PRODUCT_MODULE_NAME).PacketTunnelProvider + + + NSSystemExtensionUsageDescription + The Firezone System Extension is required for Firezone to function properly. diff --git a/swift/apple/FirezoneNetworkExtension/main.swift b/swift/apple/FirezoneNetworkExtension/main.swift new file mode 100644 index 000000000..a4c464bcb --- /dev/null +++ b/swift/apple/FirezoneNetworkExtension/main.swift @@ -0,0 +1,16 @@ +// +// main.swift +// (c) 2024 Firezone, Inc. +// LICENSE: Apache-2.0 +// + +import Foundation +import FirezoneKit +import NetworkExtension + +// Entrypoint for the macOS app +autoreleasepool { + NEProvider.startSystemExtensionMode() +} + +dispatchMain() diff --git a/swift/apple/README.md b/swift/apple/README.md index ef5ebd942..ec203d032 100644 --- a/swift/apple/README.md +++ b/swift/apple/README.md @@ -6,23 +6,35 @@ Firezone clients for macOS and iOS. 1. Rust: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` 1. Request your Firezone email added to our Apple Developer Account -1. Open Xcode, go to Settings -> Account and log in. Click "Download manual - profiles" button. -1. Install signing keys from 1password "Engineering" vault. +1. Open Xcode, go to Settings -> Account and log in. -Automatic signing has been disabled because it doesn't easily work with our -CI/CD pipeline. +If you're working on the macOS client, you'll need to disable SIP and enable +system extension development mode: + +1. Follow [these instructions](https://developer.apple.com/documentation/security/disabling-and-enabling-system-integrity-protection) to disable SIP. +1. After that's complete, turn on system extension development mode: + +```bash +systemextensionsctl developer on +``` + +This will prevent macOS from blocking the Network Extension from loading due to notarization or filepath restrictions. + +**Be sure to re-enable SIP to test the app in a production-like environment.** + +You may consider using a macOS VM (such as Parallels Desktop) to develop the macOS client, as it's easier to +disable SIP, take snapshots, and muck around with your system configuration without risking your main machine. ## Building -1. Set up Rust to cross-compile for iOS: +1. Add required Rust targets: Ensure you've activated the correct toolchain version for your local environment with `rustup default ` (find this from `/rust/rust-toolchain.toml` file), then run: ``` - rustup target add aarch64-apple-ios + rustup target add aarch64-apple-ios aarch64-apple-darwin x86_64-apple-darwin ``` 1. Clone this repo: @@ -37,12 +49,14 @@ CI/CD pipeline. cd swift/apple ``` -1. Copy an appropriate xcconfig and edit as necessary: +1. Copy an appropriate xcconfig: - ```bash - cp Firezone/xcconfig/debug.xcconfig Firezone/xcconfig/config.xcconfig - vim Firezone/xcconfig/config.xcconfig - ``` +If building for Development, the debug.xcconfig should work out-of-the-box. + +```bash +cp Firezone/xcconfig/debug.xcconfig Firezone/xcconfig/config.xcconfig +vim Firezone/xcconfig/config.xcconfig +``` 1. Open project in Xcode: @@ -50,21 +64,23 @@ CI/CD pipeline. open Firezone.xcodeproj ``` -1. Build the Firezone target +1. Build and run the `Firezone` target. ## Debugging [This Network Extension debugging guide](https://developer.apple.com/forums/thread/725805) is a great resource to use as a starting point. -### Debugging on ios simulator +### Debugging on iOS simulator Network Extensions [can't be debugged](https://developer.apple.com/forums/thread/101663) in the iOS -simulator, so you'll need a physical iOS device or Mac to debug. +simulator, so you'll need a physical iOS device to develop the iOS build on. ### NetworkExtension not loading (macOS) +If the tunnel fails to come up after signing in, it can be for a large number of reasons. Here are some of the more common ones: + Try clearing your LaunchAgent db: ```bash @@ -118,7 +134,7 @@ cd swift/apple ### Wiping connlib log directory ``` -rm -rf $HOME/Library/Group\ Containers/47R2M6779T.group.dev.firezone.firezone/Library/Caches/logs/connlib +rm -rf $HOME/Library/Group\ Containers/47R2M6779T.dev.firezone.firezone/Library/Caches/logs/connlib ``` ### Clearing the Keychain item diff --git a/website/src/app/kb/administer/logs/readme.mdx b/website/src/app/kb/administer/logs/readme.mdx index 5373027f1..e47b6898a 100644 --- a/website/src/app/kb/administer/logs/readme.mdx +++ b/website/src/app/kb/administer/logs/readme.mdx @@ -14,7 +14,7 @@ by advanced users and admins. | Component | Log directory | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| macOS Client | `~/Library/Group Containers/47R2M6779T.group.dev.firezone.firezone/Library/Caches/logs` | +| macOS Client | `~/Library/Group Containers/47R2M6779T.dev.firezone.firezone/Library/Caches/logs` | | iOS Client | N/A | | Android/ChromeOS Client | `/data/data/dev.firezone.android/caches/logs` | | Linux Client | Set by the user via the `LOG_DIR` environment variable, otherwise STDOUT |