DisableFDEAutoLogin and SFAuthorizationPluginView

Hi,

I have a set of plugins which are registered for login. One of them is a custom ui view for the login screen.

The scenario:

1.DisableFDEAutoLogin is false. 2.The User logs in to the file vault login screen. 3.The security plugins are activated, and working. 4.We get any kind of an error from the plugins, and therefore the login fails. 5.We get a native login screen, after the denial of authorization. 6.In case that DisableFDEAutoLogin is true, I do get the custom login screen, after the file vault login.

My question:

Why dont I see the custom login screen, after the auto login fails?

Cheers Sivan

Answered by DTS Engineer in 859199022

Thanks for that.

To summarise:

  builtin:prelogin
  builtin:policy-banner
  loginwindow:login
  builtin:login-begin
  builtin:reset-password,privileged
  loginwindow:FDESupport,privileged
  builtin:forward-login,privileged
  builtin:auto-login,privileged
+ myplugin:auth,privileged
  builtin:authenticate,privileged
  PKINITMechanism:auth,privileged
  builtin:login-success
  loginwindow:success
  HomeDirMechanism:login,privileged
  HomeDirMechanism:status
  MCXMechanism:login
+ myplugin:config,privileged
  CryptoTokenKit:login
  loginwindow:done

Given that setup, I’m not surprised you’re seeing the built-in UI, because you’ve left it in the list (line 3).

Let’s start with a quick recap of how this stuff works. When the user logs in, the system attempts to acquire the system.login.console right. This runs the mechanisms it order, from top to bottom. Normally loginwindow:login presents the login UI, which acquires the user’s credentials and stores them in the context. Later on, builtin:authenticate,privileged runs, which checks the credentials, and either allows or denies the login.

If any of these mechanisms fails, the system starts again at the top of the list [1]. loginwindow:login runs again, gets a new credential from the user, and the whole process repeats.

When FileVault is enabled it stashes the credential that it acquired in a location that’s available to loginwindow:login. loginwindow:login detects this and uses it to populate the context without presenting any UI. This is then picked up by builtin:authenticate,privileged which does its normal thing.

You can disable this credential transfer by setting DisableFDEAutoLogin. In that case, loginwindow:login presents the login UI like it usually would.

Most folks who implement a SFAuthorizationPluginView replace loginwindow:login with the mechanism that presents their SFAuthorizationPluginView subclass. That way there’s only ever one login UI.

If, as is the case here, you don’t replace loginwindow:login, but instead present your SFAuthorizationPluginView subclass from a mechanism that doesn’t replace loginwindow:login, you may well end up seeing two login UIs. I’ve worked with some developers that want that, but if you don’t want it, replace loginwindow:login with your mechanism.

Share and Enjoy

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

[1] Either internally, or the entire attempt to acquire the right fails and the system retries that.

I need more context in order to offer any insight here:

  • What version of macOS are you testing this on?
  • Is this Intel or Apple silicon?
  • Are you testing on real hardware? Or in a VM?
  • You say you “have a set of plugins”. Are you talking about multiple plug-ins? Or multiple mechanisms for the same plug-in?
  • How exactly as your configuring your authorisation plug-in? Normally I’d just assume you were replacing loginwindow:login in the system.login.console, with your mechanism, but if you have multiple plug-ins, or multiple mechanisms, things aren’t that simple.

Share and Enjoy

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

Hi,

macOS - Sequoia 15.3.1 Apple silicon Real hardware 2 plugins - custom login view plugin, and auth plugin.

Everything works fine in a "regular" login scenario. Things turn south when using FDEAutoLogin, and our plugin set result to .deny. Then the user gets the native login screen. instead of the custom one.

So what does the mechanisms array for system.login.console look like?

Share and Enjoy

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

Hi,

Here is the array:

  • <array>
  •   <string>builtin:prelogin</string>
    
  •   <string>builtin:policy-banner</string>
    
  •   <string>loginwindow:login</string>
    
  •   <string>builtin:login-begin</string>
    
  •   <string>builtin:reset-password,privileged</string>
    
  •   <string>loginwindow:FDESupport,privileged</string>
    
  •   <string>builtin:forward-login,privileged</string>
    
  •   <string>builtin:auto-login,privileged</string>
    
  •   <string>myplugin:auth,privileged</string>
    
  •   <string>builtin:authenticate,privileged</string>
    
  •   <string>PKINITMechanism:auth,privileged</string>
    
  •   <string>builtin:login-success</string>
    
  •   <string>loginwindow:success</string>
    
  •   <string>HomeDirMechanism:login,privileged</string>
    
  •   <string>HomeDirMechanism:status</string>
    
  •   <string>MCXMechanism:login</string>
    
  •   <string>myplugin:config,privileged</string>
    
  •   <string>CryptoTokenKit:login</string>
    
  •   <string>loginwindow:done</string>
    
  • </array>

Thanks for that.

To summarise:

  builtin:prelogin
  builtin:policy-banner
  loginwindow:login
  builtin:login-begin
  builtin:reset-password,privileged
  loginwindow:FDESupport,privileged
  builtin:forward-login,privileged
  builtin:auto-login,privileged
+ myplugin:auth,privileged
  builtin:authenticate,privileged
  PKINITMechanism:auth,privileged
  builtin:login-success
  loginwindow:success
  HomeDirMechanism:login,privileged
  HomeDirMechanism:status
  MCXMechanism:login
+ myplugin:config,privileged
  CryptoTokenKit:login
  loginwindow:done

Given that setup, I’m not surprised you’re seeing the built-in UI, because you’ve left it in the list (line 3).

Let’s start with a quick recap of how this stuff works. When the user logs in, the system attempts to acquire the system.login.console right. This runs the mechanisms it order, from top to bottom. Normally loginwindow:login presents the login UI, which acquires the user’s credentials and stores them in the context. Later on, builtin:authenticate,privileged runs, which checks the credentials, and either allows or denies the login.

If any of these mechanisms fails, the system starts again at the top of the list [1]. loginwindow:login runs again, gets a new credential from the user, and the whole process repeats.

When FileVault is enabled it stashes the credential that it acquired in a location that’s available to loginwindow:login. loginwindow:login detects this and uses it to populate the context without presenting any UI. This is then picked up by builtin:authenticate,privileged which does its normal thing.

You can disable this credential transfer by setting DisableFDEAutoLogin. In that case, loginwindow:login presents the login UI like it usually would.

Most folks who implement a SFAuthorizationPluginView replace loginwindow:login with the mechanism that presents their SFAuthorizationPluginView subclass. That way there’s only ever one login UI.

If, as is the case here, you don’t replace loginwindow:login, but instead present your SFAuthorizationPluginView subclass from a mechanism that doesn’t replace loginwindow:login, you may well end up seeing two login UIs. I’ve worked with some developers that want that, but if you don’t want it, replace loginwindow:login with your mechanism.

Share and Enjoy

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

[1] Either internally, or the entire attempt to acquire the right fails and the system retries that.

DisableFDEAutoLogin and SFAuthorizationPluginView
 
 
Q