Post

Replies

Boosts

Views

Activity

Communication between system extension and the app
I have a working NEPacketTunnelProvider app extension macOS app on the App Store. The company wants to explore the possibility of switching to system extension, so that we can distribute the app outside of the appstore too. I managed to do the switch and the extension works. But the communication is broken. DistributedNotificationCenter stopped working for me after switching to system extension, events are not received and I don't see any errors so I cannot say what's wrong. I tried to adopt XPC from this Filtering Network Traffic Apple's sample, but I get sandbox error - domain code 4099, failed at lookup with error 159 - Sandbox restriction. I get the same error if I try to run the sample with my company team id. I do these changes: NEMachServiceName to $(TeamIdentifierPrefix)com.mycompanyname.macos.dev App Groups to $(TeamIdentifierPrefix)com.mycompanyname.macos.dev Bundle ids to com.mycompanyname.macos.dev and com.mycompanyname.macos.dev.tunnelprovider com.mycompanyname.macos.dev has capabilities - App Groups, Network Extensions, System Extensions com.mycompanyname.macos.dev.tunnelprovider - Network Extensions, System Extensions Could you help me find the reason why DistributedNotificationCenter could stop receiving notifications? Or are you able to run Apple's sample? What changes do you make to run it under your team? Because it looks like my changes are wrong Either DistributedNotificationCenter or XPC would solve my problem
3
1
1.2k
Nov ’22
Use System Keychain from System Extension
I need to store auth keys somewhere, previously app network extension would store them in a shared keychain. Now we're trying to move to system extensions, for out of appstore distribution, and shared keychain will no longer work. Is it possible to write to system keychain from system extension? If yes, how do I specify that I want to use system keychain? Our current code returns errSecNotAvailable if run in System Extension instead of App Extension. The code looks like this. If uncommented, it will work from the App Extension.   NSString *teamID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"Development Team"];   NSString *groupID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"App Group ID"];   NSMutableDictionary *query = [NSMutableDictionary dictionaryWithDictionary:@{     (id)kSecClass: (id)kSecClassGenericPassword, //    (id)kSecAttrAccessGroup: [NSString stringWithFormat:@"%@.%@", teamID, groupID],     (id)kSecAttrService: groupID, //    (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly   }];   [query setObject:(id)kCFBooleanTrue forKey:(id)kSecUseDataProtectionKeychain];   [query setObject:@(key) forKey:(id)kSecAttrAccount]; [query setObject:[NSData dataWithBytes:buffer length:length] forKey:(id)kSecValueData]; SecItemAdd(cfQuery, NULL);
5
0
1.6k
Dec ’22
Logging. App and System Extension attempting to share logs with each other
Before: We had an app with app extension. Both had user privilege. Both wrote file logs to FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) - /Users/myuser/Library/Group Containers/mygroupid/ Now: We have to change app extension to system extension. Our previous logging approach broke, because system extension has root context. Result of FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) for system extension is /private/var/root/Library/Group Containers/mygroupid/ They do not have privilege to write to each other's folder. We can open logs folder for the user, but now the app does not have privilege to open Finder window for root logs folder. Ideally we would write file in a single folder. Question: Please suggest where to write logs from user and root process. Maybe there is a different approach on how to store a few days worth of logs and being able to upload them to our backend, or display them to the user, upon request.
2
1
1.4k
May ’23
makeFileSystemObjectSource does not monitor changes made with nano
I have folder monitoring code using makeFileSystemObjectSource. The events are triggered for everything else, but not for when I edit a file with nano terminal command. Am I doing something wrong? Is it a bug? Is this intended and unfixable? Code sample: monitoredFolderFileDescriptor = open(currentlyMonitoredPath, O_EVTONLY) folderMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: monitoredFolderFileDescriptor, eventMask: .all, queue: .main) folderMonitorSource?.setEventHandler { // ... } folderMonitorSource?.setCancelHandler { // ... } folderMonitorSource?.resume()
2
0
854
Nov ’23
Make my app quit and reopen when updating it with .pkg
Context: Our app has a network system extension. After updating it via MDM sometimes the app and the extension have different versions until you restart the app. I suspect that it is because the app is not quit before installing. As a fix I am trying to create a .pkg with preinstall and postinstall script, that would close the app before installation and open it after installation. My code: FileUtils.mkdir_p("install_scripts") File.open('install_scripts/preinstall', 'w') do |file| file.puts "#!/bin/bash\nosascript -e 'quit app \"#{options[:app_name]}\"'\nexit 0" end File.open('install_scripts/postinstall', 'w') do |file| file.puts "#!/bin/bash\nopen -a '#{options[:app_name]}'\nexit 0'" end sh "chmod a+x install_scripts/preinstall" sh "chmod a+x install_scripts/postinstall" sh( "pkgbuild", "--scripts", "install_scripts", "--identifier", ***_identifier(options), "--component", "../#{options[:build_path]}/#{options[:app_name]}.app", "--install-location", "/Applications/#{options[:app_name]}.app", "Distribution.pkg" ) sh( "productbuild", "--synthesize", "--package", "Distribution.pkg", "Distribution.xml" ) sh( "productbuild", "--distribution", "Distribution.xml", "--sign", "Developer ID Installer: *** Inc. (#{ENV["APPLE_TEAM_ID"]})", "--package-path", ".", "../artifacts/#{options[:app_name]}.pkg" ) Issue: I haven't got it to actually install the app or to close or open the running app. I've tried several changes. The code above fails with this error. Do you see an issue in my code, or could you point me to alternative implementation? installd[1101]: PackageKit: Install Failed: Error Domain=NSCocoaErrorDomain Code=516 ""Myapp Dev.app" couldn't be moved to "Applications" because an item with the same name already exists." UserInfo={NSSourceFilePathErrorKey=/Library/InstallerSandboxes/.PKInstallSandboxManager/8E84CB81-4724-4D4E-BE76-3A24DECC60A6.activeSandbox/Root/Applications/Myapp Dev.app/Myapp Dev.app, NSUserStringVariant=( Move ), NSDestinationFilePath=/Library/InstallerSandboxes/.PKInstallSandboxManager/8E84CB81-4724-4D4E-BE76-3A24DECC60A6.activeSandbox/Root/Applications/Myapp Dev.app, NSFilePath=/Library/InstallerSandboxes/.PKInstallSandboxManager/8E84CB81-4724-4D4E-BE76-3A24DECC60A6.activeSandbox/Root/Applications/Myapp Dev.app/Myapp Dev.app, NSUnderlyingError=0x117e304b0 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}} { NSDestinationFilePath = "/Library/InstallerSandboxes/.PKInstallSandboxManager/8E84CB81-4724-4D4E-BE76-3A24DECC60A6.activeSandbox/Root/Applications/Myapp Dev.app"; NSFilePath = "/Library/InstallerSandboxes/.PKInstallSandboxManager/8E84CB81-4724-4D4E-BE76-3A24DECC60A6.activeSandbox/Root/Applications/Myapp Dev.app/Myapp Dev.app"; NSSourceFilePathErrorKey = "/Library/InstallerSandboxes/.PKInstallSandboxManager/8E84CB81-4724-4D4E-BE76-3A24DECC60A6.activeSandbox/Root/Applications/Myapp Dev.app/Myapp Dev.app"; NSUnderlyingError = "Error Domain=NSPOSIXErrorDomain Code=17 "File exists""; NSUserStringVariant = ( Move ); }
2
0
762
Mar ’24
Browser Extension Native Messaging Security
For browser extension to communicate with a native app there must be a helper app. It is launched by the browser and the communication happens via stdin and stdout. I wrote such a helper app in Swift, it works. I'd like to add security checks to the helper app. To make sure that the parent process is one of the approved browsers - I can do this with NSRunningApplication(processIdentifier: getppid())?.bundleIdentifier To make sure the parent process has valid signature To make sure that the other peer of the stdin/stdout pipes is the parent process Do you know ways to achieve 2 and 3? Does the way I am doing 1 look correct to you?
5
0
356
Jul ’24
Pre-approving network extension VPN permission with MDM
I have a macOS app with Network Extension. It requests VPN permission with the code like this: self.tunnelManager = [NETunnelProviderManager new]; NETunnelProviderProtocol *protocol = [NETunnelProviderProtocol new]; protocol.providerBundleIdentifier = @"com.myapp.macos.tunnelprovider"; self.tunnelManager.protocolConfiguration = protocol; [self.tunnelManager setOnDemandRules:nil]; [self.tunnelManager setOnDemandEnabled:NO]; [self.tunnelManager setEnabled:YES]; [self.tunnelManager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable saveError) {}]; A lot of my app users are businesses and they would like to have pre-install VPN config. We currently do it like this: <array> <dict> <key>PayloadDisplayName</key> <string>MyAppName</string> <key>PayloadType</key> <string>com.apple.vpn.managed</string> <key>UserDefinedName</key> <string>MyAppName</string> <key>VPN</key> <dict> <key>AuthenticationMethod</key> <string>Password</string> <key>ProviderBundleIdentifier</key> <string>com.myapp.macos.tunnelprovider</string> <key>ProviderDesignatedRequirement</key> <string>anchor apple generic and identifier "com.myapp.macos.tunnelprovider" and (certificate leaf[field.1.2.3] /* exists */ or certificate 1[field.1.2.3] /* exists */ and certificate leaf[field.1.2.3] /* exists */ and certificate leaf[subject.OU] = "123")</string> <key>RemoteAddress</key> <string/> </dict> <key>VPNSubType</key> <string>com.myapp.macos</string> <key>VPNType</key> <string>VPN</string> </dict> </array> Now, if the users installs my app first and allows the VPN permission, then MDM will set the profile above to the user, the user will end up with two VPN profiles in settings. They will be called "My App" and "My App 1" At first we thought it's harmless, but users with two VPN profiles sometimes have app update issues, where after update the newer version of client fails to communicate with the older version of tunnel, it cannot even tell it to quit. The tunnel must be force-quit by the user in this case. We suspect two profiles to be the reason for that. Is there a way to make sure duplicate VPN profiles do not happen?
2
0
196
Oct ’24
NEPacketTunnelProvider stopped connecting on arm macOS 14 during tests
I have tests where I connect to NEPacketTunnelProvider. I run tests with circleci and fastlane, on self hosted intel and arm macs. I updated macs from macOS 13 to macOS 14 and the tests on arm stopped connecting, while the same tests on intel kept working as usual. Moreover, I noticed the tests don't work when run from circleci and fastlane. If I cancel the job and click "connect" myself on the app that stayed hanging from the cancelled tests, the connection will succeed. But if the tests are running, the connection will fails. Running the tests from xcode succeeds too. These are the logs from the tunnel. Could you suggest me where to dig? Or maybe you can see the issue from the logs? Tunnel logs when they fail
0
0
47
20h