Post not yet marked as solved
I have ran some latency tests (measuring download and upload from the internet).When filtering via a NEFilterData, the speed stays almost the same (about a 5% decrease).However, when filtering via a NEFilterPacket, even when doing only this:override func startFilter(completionHandler: @escaping (Error?) -> Void) {
packetHandler = { (context:NEFilterPacketContext, interface:nw_interface_t, direction:NETrafficDirection, packetBytes:UnsafeRawPointer, packetLength:Int) in
return .allow
}
completionHandler(nil)
}Then the speed is about 40% of the speed without filtering.Is that expected? Is there anything I can do to prevent this?I tried to setfilterManager.grade = .inspectorbut that did not help either.
Post not yet marked as solved
For an NEDataFilter, I am trying to filter a large list of IP addresses (computed from the domain names). I can see 2 ways of doing this:1) I create many rules NEFilterRule, and apply them via NEFilterSettings, and select .drop2) I apple the NEFilterSettings with no rule, change a default action to .fitlerData, and then do the lookup of the IP addresses inside the handleNewFlow function.What would be the best solution, latency wise ? The 2nd seems faster to me, as I can implement O(log(n)) lookup, but are there useful tricks that 1 is doing, that means I should consider it ?
Post not yet marked as solved
I want to evaluate whether processes installed and running on a macOS system are legitimate.I understand (thanks Eskimo) that checking their identifier is not a good way to identify processes, as any developer can use any identifier. I also understand that I should use DesignatedRequirements.I have the following code at the moment:// Get code signing information.
var infoOpt: CFDictionary? = nil
err = SecCodeCopySigningInformation(staticCode, SecCSFlags(rawValue:kSecCSRequirementInformation), &infoOpt)
guard err == errSecSuccess, let info = infoOpt as? [String:Any] else {
return nil
}
let processId = info[kSecCodeInfoIdentifier as String] as? String // nil iif code is not signed
let designatedRequirement = info[kSecCodeInfoDesignatedRequirement as String] as! SecRequirement
var designatedRequirementCFStr : CFString?
SecRequirementCopyString(designatedRequirement, [], &designatedRequirementCFStr)
let designatedRequirementStr = designatedRequirementCFStr as String?But how can I use the designated requirement to ensure that the app is legitimate ?More specifically :- If I want the anchor (root certificate) to be Apple's, how can I programatically check it ? There must be something better than parsing the string above.- I am not very familair with the certificate process. What is the anchor "apple generic" ?- What is a reasonable rule to accept the process as legitimate? Is it all about the anchor and I can disregard the certificate leaf?Thanks!
Post not yet marked as solved
I am looking to convey some information to the user and request his input from a system extension (a Network extension).I couldn't get an Alert to work on systemExtensions. Am I missing something or is it indeed not possible/not advisable ?What about UserNotifications, is it advisable to do that from the system extension itself, or should I just use xpc to foward the information to a normal app, which will take care of display the info ?
Post not yet marked as solved
Inside my NEFilterDataProvider, I am retrieving the code signature informations from socketFlow.sourceAppAuditToken (thanks to the good advice of Eskimo).This takes a little bit of time though. Is it reasonable to cache the sourceAppAuditToken ?I am thinking of keeping a dictionary that would map the sourceAppAuditToken to their String identifier. Is it reasonable, or is it insecure to do so?Separately, I have seen that socketFlow.description contains a lot of really useful information, including bundleId, etc.How is that bundleId computed? (there is an insecure way : just retrieving it from the Info.plist, and a secure way: retrieving it from the code signature). Also, is there a better way to access this information that parsing the socketFlow.description string itself?
Post not yet marked as solved
In NEFilterDataProvider, the system helpfully provides NEFIlterFlow.sourceAppAuditToken. How should I interpret it though?This is of Data type, how can I map it to an app, for example via its BundleID?In another question, it was suggested to look at <bsm/libbsm.h>. However this seems to be objective-c and deprecated ? How can I do this in swift ?Thanks!
Post not yet marked as solved
If I take the SimpleFirewall example provided by Apple, remove the SimpleFirewallExtension, add a new target that is also a NetworkExtension for content filtering, except where the language is objective-c, I have a weird problem. startFilter and stopFilter will be called correctly, but the packetHandler is never called.I made sure the plist and entitlements are populated similarly as the swift example.Why is that? What is different in objective-c for Network Extension?
I am implementing a NetworkExtension, based on NEFilterPacketProvider. My issue is that the NEFilterPacketContext is always empty. I assume that's not expected, but my code is as simple as it gets. What's the issue?Maybe loking at attributeKeys is the wrong thing to do, but in that case, how to access context info? Specifically, I'd like to know things like which applications generated the packet, on which port, what external IP, etc.class FilterPacketProvider: NEFilterPacketProvider {
override init() {
super.init()
os_log("FilterPacketProvider init")
}
override func startFilter(completionHandler: @escaping (Error?) -> Void) {
os_log("FilterPacketProvider startFilter")
packetHandler = { (context:NEFilterPacketContext,
interface:nw_interface_t,
direction:NETrafficDirection,
packetBytes:UnsafeRawPointer,
packetLength:Int)
in
os_log("FilterPacketProvider packet context=%{public}s %{public}s interface=%{public}s dir=%d length=%d",
context.attributeKeys.description,
context.debugDescription,
interface.description,
direction.rawValue,
packetLength
)
return .allow //.allow, .drop or .delay
}
completionHandler(nil)
}
override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
os_log("FilterPacketProvider stopFilter")
completionHandler()
}
}
Post not yet marked as solved
I want to use the XPC technology simply to launch an app on macOS. I do not need any interprocess communication, or any of the other feature of XPC.
The only documents that I can find on the internet show a complex structure, with code for the XPC service, separate code to launch the XPCservice via a script, and app code to communicate with the service.In other words, I only want something that does the equivalent of this:NSWorkspace.shared.openApplication(at: path, configuration: configuration, completionHandler: nil)but with XPC. So I would need something along the lines of:let listener = NSXPCListener.service("/path/to/my_app.app")listener.resume()RunLoop.main.run()Obviously, the service method does not take an argument that would be an executable path, so this does not work.How can I do that ?PS: to explain the motivation, launching an XPC service will preserve sandbox restriction form the launching app, whereas launching the app directly via NSWorkspace.shared.openApplication will not preserve sandbox restrictions (because the spawned app does not have "com.apple.security.inherit" as entitlement).
Post not yet marked as solved
I have a very simple macOS app, built with latest swift, latest xcode. Is it sandboxed, and only launches another app (from the app store - with its own code signing).I have placed this other app in my launcher's app bundle, and launch it with NSWorkspace.shared.openApplication.My issue is that while the launcher app itself is sandboxed, its restrictions are not applied to the launched app. The launched app is sandboxed (it was sandboxed by the original developer), but has wider permissions.It seems either a security flaw or I am misunderstanding something. Can anyone shed lights on this? Thanks!