I had to first disable SIP by booting into recovery mode, opening terminal, csrutil disable, restart (risks seemed acceptable to me). Then systemextensionsctl developer on -- then i was able to get the sample app working.
Post
Replies
Boosts
Views
Activity
Matt, thanks for your reply. I'm going to carefully look at the link you provided and explore testing it in the alternate way you mention.
That said, I was just doing some more testing this morning, and I wanted to add one useful (I think) piece of info, that I wonder if you'd be willing to look into.
To rule out any mistakes on my part, this morning I downloaded a fresh copy of the FilteringNetworkContent sample code ("SimpleFirewall" app). I opened it up on Xcode, and the only change I made was to connect it to my appstoreconnect account with a provisioning profile including my secondary test target machine. Then I made an archive directly from the untouched example code, moved the app file over to the test machine.
When I did this, I got the exact same error:
Failed to find a com.apple.networkextension.filter-data extension inside of app com.example.apple-samplecode.SimpleFirewall.MYTEAMID
So here's what I'm wondering. Would you be so kind as to try the same thing? I understand you have a network extension you use for testing, but I'm wondering if you'd be able to try a pristine copy of the SimpleFirewall app and see if you can install it on a different machine after building from Xcode. It seems like if the sample app won't run properly when built without modifications, maybe there's a fix or some additional information that could be useful to a lot of people trying to work with this type of app.
Also, I'm not sure if this is relevant or not, but when I created the archive (both with my app, and with the pristine SimpleFirewall test), I went through the process of "Validate App" from the Organizer screen. That required me to go to my App store connect account and create a dummy app for the validation process to succeed. I mention this just in case somehow my having done that caused this problem. All of these steps and options are pretty overwhelming and confusing for me, I admit.
Ok, took me a long time to figure out all of the signing, provisioning, entitlements, and notarization stuff, but when I finally successfully signed it with a developer ID and notarized it, it started working on the test machine. So maybe the error messages were misleading me and the true issue might have been less about the extension being built properly within the bundle, and more about permissions and entitlements.
Appreciate the help very much, thanks for your time.
Brilliant, thanks so much for the info, much appreciated.
So, no one has replied to my plaintive cry for help yet, so I'll add a few thoughts here, for the sake of anyone else who might be struggling with similar stuff, or if someone would still be so kind as to offer any thoughts, I would greatly appreciate it.
I forgot to mention in my first writeup that in in my NEFilterDataProvider class I asked to intercept ALL traffic, not just .TCP or .UDP, I set it to .any. I mention this, because after a lot of poking through system logs, it seems that the problem had to do with DNS requests not resolving.
DNS seems like a tricky thing if you want to filter all traffic. I don't honestly care about stopping DNS requests, but I do care about some other UDP traffic, so in my provider I tried to allow all DNS traffic through by testing if the request was a UDP request to port 53 -- I let all of those pass through unblocked.
And again, the problem only manifests after waking from sleep after running well for a number of hours, so DNS things do work for a while at least. But it makes me wonder if there is something having to do with DNS cache, or some other issue I can't quite put my finger on...
I also did some more research to see if the Content Filter system extension seemed fully stable for Catalina, trying to answer my question about whether there were known problems with the framework, or if people were successfully deploying production apps with this filter. I found an article detailing that Apple had put in a set of exclusions into Catalina -- apps that were not subject to filtering. I found that interesting because I had noticed some odd that seemed like my filter never got a chance to see them. I definitely believe the responses from Apple quoted in the article saying that it wasn't some ill-intended plot to circumvent the filter secretly, but rather that there were problems getting the feature ready in time for Catalina, and so the exclusion list was a temporary workaround. But I mention it because this seems to provide fairly strong evidence that (in Catalina at least, which is the only OS version I've tested against so far), the content filter system extension might not be 100% stable or reliable. I can't post the link to the article here, but just google "apple content filter exclusion security researcher big sur catalina" and you'll find it.
I'd still be interested in any (even off-the-cuff) ideas about what to troubleshoot, or whether any of my thoughts outlined above prompt any ideas. I'm considering doing some testing on a recent version of Big Sur to see if things work better.
I'd still definitely be interested if anyone could talk about how many production apps are using this framework, especially in Catalina. Or if anyone could shed light on or had any experience with filtering ALL requests, including (necessarily) DNS requests.
I'd be happy to communicate directly with anyone working on a similar app, if anyone wants to form an informal support-group/griefshare you can reach me at jared [at] netrivet [dot] com. The app I'm working on is still experimental and for various reasons I don't feel much commercial pressure at all about it, so I'm happy to share lessons learned, and would definitely appreciate some feedback or insight from anyone else working on something similar.
@meaton That all sounds really helpful, exactly the kind of hints I was hoping for. Truly appreciate it. I'll try some of these things and report back any findings that could be useful to others. 👍
@eskimo -- yup, totally understand that, which is why I was trying to partially answer my question for future googlers. thanks for taking a look.
@eskimo So I've taken a couple stabs at trying to implement this, and I'm really struggling. Tonight I spent a couple hours scouring the internet for more clues as to how to pull this off in Swift, and I can't find any tutorial or code fragments that seem to be up to date with Swift 5.2.
The tech note you linked to I've read and re-read, but I'm trying to implement this in Swift, not objc, and I'm really struggling. Do you know of any tutorial or sample code for a recent swift version that covers this API, AuthorizationCreate, or something like it?
I have a couple specific questions:
I'm not trying to actually escalate permissions, or run a script as root, or anything like that, I just want to force the entry of an admin user/pass to protect an area of my app. Do I need to create my own custom policy right for that? Or is there some default right I can ask for, something like system.privelege.admin?
If I'm testing while logged in as an admin, will the attempt to authorize immediately succeed? Do I have to build my app and install it on a non-admin user to see if it's working?
I'd like to prompt for the admin user/pass every time even if the admin is logged in... Is this possible?
Would you be willing to write up a snippet or two of Swift to cover this use case? I (and I guess many future googlers) would really appreciate it! 🙏
@eskimo -- thank you SO much, that is fantastic information, very much appreciated. I think your code snippets will be really useful to a lot of future googlers.
Ok, so in addition to what eskimo posted above, the below seems to be working using the higher-level SFAuthorization class, although it seems to be less configurable (for instance I don't think you can change the message "Your App wants to make changes"), so YMMV:
swift
func authenticateAsAdmin() - Bool {
guard
let authorization = SFAuthorization.authorization() as? SFAuthorization,
let right = NSString(string: kAuthorizationRuleAuthenticateAsAdmin).utf8String
else {
/* or maybe throw an error */
return false
}
do {
try authorization.obtain(withRight: right, flags: [.extendRights, .interactionAllowed, .destroyRights])
} catch {
return false
}
return true
}
Furthermore, I figured out that one of my problems was I forgot to check if my app was in sandbox mode, in which case these API's don't work and you only get vague permission denied errors.
@meaton Thanks for this, I appreciate it. I'm still struggling to implement this. I'm having a hard time finding ANY documentation for audit_token_to_ruid, so I'm fumbling in the dark a bit here.
I did find this thread - https://developer.apple.com/forums/thread/122482, and so I'm trying code like this:
swift
private func auditTokenT(_ token: Data?) - audit_token_t? {
guard
let token = token,
token.count == MemoryLayoutaudit_token_t.size
else { return nil }
return token.withUnsafeBytes { buf in
buf.baseAddress!.assumingMemoryBound(to: audit_token_t.self).pointee
}
}
/* ... */
let token = auditTokenT(flow.sourceAppAuditToken) /* `flow` is a NEFilterFlow */
let ruid = audit_token_to_ruid(token)
With this code, Xcode is not showing any compiler errors or warning, but when I try to build I get:
Undefined symbol: _audit_token_to_ruid
I tried importing Darwin, Darwin.bsm, but no dice. Do I have to do something special for this function to be available? If so, would you mind explaining what it would be?
This is driven by the right specification. You’re getting generic text because you’re using kAuthorizationRuleAuthenticateAsAdmin, which is what I’m trying to steer you away from. If you use a custom right you can customise this.
Aha, yes, that makes sense. Really appreciate it, thanks!
Also running into this problem, with a React Native project that compiles fine in Xcode 12. Is this a Swift 5.5 change? An Xcode 13 issue?
@Claude31 Thank you very much, that was my issue.
for what it's worth, the most helpful article i've found on this topic is here: https://scriptingosx.com/2020/02/getting-the-current-user-in-macos-update/