SFAuthorizationPluginView

I’ve developed an authorization plug-in with a mechanism that runs an SFAuthorizationPluginView subclass and I’m facing a couple issues:

- Glitch after successful login

After setting kAuthorizationResultAllow in the context the user is successfully logged in and brought to the desktop but the login controls remain onscreen for a few seconds after login is complete, resulting in them being visible at the same time as the dock, menu bar and desktop.
 I’ve also tried what’s mentioned here https://developer.apple.com/forums/thread/780212 but without any luck. It’s also worth mentioning that the deinit() in my SFAuthorizationPluginView subclass never gets called when the plugin it’s loaded at the login stage but it does get called the plugin is used to re-authenticate the user after they locked their screen.

- update() doesn't trigger the plugin to call view(for:)

I’m trying to update the UI elements out of my control (like buttons and user avatar images) in order to have them placed at the proper position on the screen after a resize of my inner NSView. To do that I call update() but it appears that does not trigger the plugin to call view(for:) and update system UI elements placement. Is this the expected behavior?

- setButton not working as expected


I’m trying to disable the login button by calling the setButton(_:enabled:) passing a SFButtonTypeLogin as inButtonType, as suggested here: https://developer.apple.com/forums/thread/777432. When the method is called at the login screen it has no effect on the button (the one with the forward-arrow icon) but when it’s called by the plugin loaded at the ‘unlock screen’ stage it successfully disable the ‘OK’ button.

- Certificate issue

When trying to run a network request from the plugin loaded in the ‘unlock screen’ scenario, I always get this type of error:

The certificate for this server is invalid. You might be connecting to a server that is pretending to be <<server_url>> which could put your confidential information at risk

Everything works as expected when the plugin is loaded either at login screen or for authorizing an operation that requires admin privileges while the user is logged in.

Hmmm, it sounds like this is a new effort, in which case I’m going to ask you to start a DTS code-level support request so that we can have a short private conversation about this. Once that’s done, I’d be happy to respond to any remaining questions here.

IMPORTANT When you open the support request, the form will ask whether anyone from Apple sent you that way. Enter the URL of this forums thread into that field.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi Quinn,

thanks for your support. After reviewing your code I still have a couple questions that remains unanswered:

  • Glitch after successful login: It's clear this is a known bug (FB12074874) but in my tests it happens all the time, not just in specific scenarios like when screen mirroring is active, is there any sort of known workaround/solution to this?
  • update() doesn't trigger the plugin to call view(for:): this is still an unresolved issue unless it's an expected behavior as mentioned in previous message
  • setButton not working as expected: same here, see previous message
  • Plugin update: I've noticed that on plugin updates, after logging the user out, the engine is still running the old version of the plugin instead of the updated one. A reboot is basically needed to apply the changes, is this the expected behavior?
  • Certificate issue: Following your suggestion I've moved the networking code into a daemon and had my plug-in use XPC to communicate with it. Now I'm facing some issue trying to set code signing requirements with setCodeSigningRequirement: on the service side, since the plug-in is hosted in a system process, there's not much I can do but verify that the identifier of the process sending the request corresponds to the Security Agent Helper, which, as you can imagine, is not that helpful. On the client side I can instead be more specific since I own the service process but during screen unlock any verification fails, possibly for the same reason that prevented me to do trust evaluations directly from the plugin in the first place. If so, what's your take on this and how would you go about trying to make the connection to the daemon more secure?

I’m going to tackle a few of your issues now, and we can come back to the others once we’ve driven these to a conclusion.

… is there any sort of known workaround/solution to this?

Not that I’ve seen.

However, if you can reproduce this reliably then I encourage you to file your own bug with the details. Part of the issue with getting traction on FB12074874 is that it only reproduces in odd situations, at least IME.

Please post your bug number, just for the record.


It depends on the exact sequencing. When you’re at the login window, the system has already loaded your plug-in so updating it on disk doesn’t help. I typically update my plug-in when I’m logged in and then log out. The system will then pick up the new plug-in as part of bringing up loginwindow for the new session.

Alternatively, if I’m not logged in I update the plug-in and then log in and log straight back out again.

If those techniques don’t work for you then I’m not really sure what’s going on.

Oh, one more thing: You need to be careful about how you update your plug-in, as is the case with all Mac software. See Updating Mac Software. So, if you’re overwriting the Mach-O image then stop doing that. Rather, move the plug-in out of the way and then copy in the new one.


… If so, what's your take on this and how would you go about trying to make the connection to the daemon more secure?

Honestly, I would do minimal authentication here.

  • On the client side, I’d simply set the privileged flag; see the discussion linked to by XPC Resources.
  • On the server side, I’d only check that the client process is signed by Apple as Apple code (anchor apple) and running as root (or _securityagent). Alternatively, check for one of the known authorisation plug-in hosts.

You have to consider what you’re protecting against here. Both of the things your concerned about — someone impersonating the server to the client or vice versa — require that the attacker be able to run code as root. It’s hard to defend yourself against an attacker in that position, and it’s easy to write code that you think provides some defence but in reality just shuffles the deckchairs.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

SFAuthorizationPluginView
 
 
Q