4

I'm trying to extend the login screen in MacOSX 10.9.1 (Mavericks). As I found out, this is possible by implementing a new authentication plugin and install it in to the authorization database.

I've downloaded the NameAndPassword example which shows how to implement the interface and overwrite / extend the SFAuthorizationPluginView. But the problem is that I can't build it under Mavericks. So I decided to download the second example which is called NullAuthPlugin. This one compiles but I didn't find out how to install it.

So my question one is, if there is a good and updated tutorial for this (TechNotes are form 2008-09-16)?

And question number two is, if this could be developed with C# (Xamarin.Mac / MonoMac) because I'm not very good in developing Objective-C / C / C++.

Thank you!

Community
  • 1
  • 1
cansik
  • 1,924
  • 4
  • 19
  • 39
  • I have a plugin based on the NameAndPassword example, which works on Mavericks, but is compiled under Mountain Lion. What's the problem compiling under Mavericks? – TheDarkKnight Jan 13 '14 at 13:32
  • It's buildable after you specify the SDK to current(10.9) in the build options menu (the path in NameAndPassword is hardcoded to 10.5 sdk which does not exist in 10.9). You also need to do something with default platform list and then it builds with no problem. What is a problem, however, is that I cannot get the NameAndPassword example to authenticate - after typing my pasword and pressing the button or return nothing happens and I have to deactivate it through SSH. @Merlin069 do you think you could help with that? I know about debugging with Xcode but I have no other Mac nearby. – Michał Siwek Feb 18 '14 at 22:44
  • @MichałSiwek, can you please add it as a new question to SO, providing an example of any code, if it differs from the example? – TheDarkKnight Feb 19 '14 at 08:48
  • @MichałSiwek Try to use a virtual mac os to test your code. I use parallels for testing. But I didn't make any progress yet. – cansik Feb 19 '14 at 12:57
  • I just tried remote debugging, but it turns out it's no longer supported in Xcode > 3, so I'll have to try again some day with an older version. @Merlin069 the point is, I didn't make any modifications to the NameAndPassword example. After building it from source I just install it and it does not authenticate. – Michał Siwek Feb 19 '14 at 20:25
  • 1
    Are you using it at the login screen, or directly from a program? I've found, from experimentation, various factors can cause a failed authentication, especially based on the rules you're adding in the /etc/authorization database, which is done with AuthorizationRightSet. Also, look at the Console app to see what the logs state the problem is. – TheDarkKnight Feb 20 '14 at 08:46
  • @Merlin069 yes, I'm using it at the login screen - I click "login screen" from the fast user switch menu after writing the plugin to security database. These are the logs: http://pastebin.com/1WDGHutk I guess the most important line would be `com.apple.authd[35]: engine[14710]: evaluate returned -60008 returning errAuthorizationInternal` - the first lines come from using `security` command to write the policy. I modify the policy this way: http://stackoverflow.com/questions/21582995/custom-login-lock-screen-in-os-x-mavericks/21618085#21618085 – Michał Siwek Feb 20 '14 at 20:46
  • That does look like the problem. Can you post all the rules for the login from the authorization db? – TheDarkKnight Feb 21 '14 at 08:38
  • @Merlin069 sure: http://pastebin.com/NMAwKCwB (I put the `:invoke` line at the beginning because it does not work otherwise) – Michał Siwek Feb 21 '14 at 12:06
  • 1
    That looks ok to me. I'm guessing that the username and password are being preserved between mechanisms. Have you tried using the NullAuthPlugin to debug? You can place it in the mechanism list to print out info to the system logs: https://developer.apple.com/library/mac/samplecode/NullAuthPlugin/Introduction/Intro.html – TheDarkKnight Feb 24 '14 at 09:02
  • @Merlin069 tried it just now - this is what happens: http://pastebin.com/4qtVbuhR (NullAuthPlugin:before is called on top, then NameAndPassword:invoke, and then NullAuthPlugin:after. All that was in the policy by default I put right after them). I'm looking at it now, but perhaps you'll figure it out sooner than me. What seems important to me is that my username looks weird and there's no password - memory leak? – Michał Siwek Feb 24 '14 at 20:09
  • @Merlin069 I guess I found the problem - strlen return value was too short and one of the functions was used in wrong place. The whole diff file is here: http://pastebin.com/BihNyekN Now NullAuthPlugin does print the username and password(starred) fine in the logs, but there's still no authentication, so that's not a complete solution. Do you have any ideas? – Michał Siwek Feb 25 '14 at 21:23
  • When you say 'still no authentication', do you mean it doesn't log you in? – TheDarkKnight Feb 26 '14 at 08:30
  • @Merlin069 yes. This is the log from NullAuth without NameAndPassword plugin in the policy(so when authorization works fine): http://pastebin.com/SWdTRena and here is with the NameAndPassword invoked in the policy: http://pastebin.com/FvUE92UQ after clicking the button with NameAndPassword still nothing happens on the screen and it doesn't log me in. – Michał Siwek Feb 26 '14 at 09:42
  • 1
    It sounds like the credentials still aren't being propagated. One thing I note, is that in my code, after setting the username and password in the context, I call setHint with a key of "suggested-user" and value of the username. I can't remember why I ended up doing this, but perhaps that will help. Also, in the authorization database, my mechanism starts with push_hints_to_context, but that may not be anything to do with what you're doing. Looking at apple's source code, the credentials are stored passed around in the context, so long as the rules are set to shared. – TheDarkKnight Feb 26 '14 at 10:05
  • @Merlin069 so I found the right way. The line `[self callbacks]->SetContextValue([self engineRef], kAuthorizationEnvironmentUsername, 1, &userNameValue);` needs the flag set to 1 like I pasted here - not to 0 as it is by default. Also, you need to remove the `loginwindow:login` line from authorization policy. Then the plugin works just fine. A big thank you! :) – Michał Siwek Feb 26 '14 at 18:45
  • Ah, that makes sense. The flag, which is described as "A flag that indicates whether this value should be available to the authorization client." We got there in the end ;O) – TheDarkKnight Feb 27 '14 at 09:10
  • @Merlin069 I have another question concerning the nameandpassword sample - do you have any idea how to start authentication process other way than by pressing the button? It's quite annoying that I'm unable to simply press enter to login. Also, I'd like to start authenticating right after for example the finger has been scanned, without having to press the button. I tried moving the code from buttonPressed method to other, but then the whole mechanism refuses to work. – Michał Siwek Mar 29 '14 at 13:48
  • @MichałSiwek, sorry I've lost the context here. Which button are you referring to? – TheDarkKnight Mar 31 '14 at 07:55
  • The button with arrow next to the password field that you have to press in order to login. @Merlin069 – Michał Siwek Mar 31 '14 at 09:02
  • Ah, ok. Sorry but I don't know if it's possible to change that. – TheDarkKnight Mar 31 '14 at 09:12

2 Answers2

6

Well, the bugs have been reported to Apple multiple times but they didn't do anything about it so far. The simplest answer is: you need a patched version of the NameAndPassword plugin - the official one is broken. I put my fixed plugin on GitHub: https://github.com/skycocker/NameAndPassword

It is important that you replace the

<string>loginwindow:login</string>

line in the authorization policy database with

<string>NameAndPassword:invoke</string>

Otherwise it won't log you in. I wouldn't figure this out without Merlin69 help.

Community
  • 1
  • 1
Michał Siwek
  • 794
  • 1
  • 10
  • 25
-1

First of all: Never, EVER, EVER begin debugging a login plugin by placing it within the console login right. You need to create a special test "dummy" right in the auth db, completely independent of any other right that the OS might need to invoke during its operation. Call it anything like "MyTestRight-RemoveMeAfterTest".

Create a plist file that looks something like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>class</key>
    <string>evaluate-mechanisms</string>
    <key>comment</key>
    <string>Used to validate a terminal user.</string>
    <key>mechanisms</key>
    <array>
        <string>NameAndPassword:invoke</string>
    </array>
</dict>
</plist>

Install it with the "security" command from the terminal:

"security authorizationdb write MyTestRight-RemoveMeAfterTest < MyTestRight-RemoveMeAfterTest_plist_file"

DO NOT EVER edit the auth db by hand, even if you can still do it, which is the case on osx prior to 10.9. If you make a mistake, and the OS can't parse the file, you will be in a world of hurt. I have been there. I've been doing these plugins for years. If the os can't read the file, you will be in the same situation if your plugin hangs on login - up the creek without a paddle. If you have not had the foresight to enable SSH, you'll have to boot into another partition or boot up from a time machine backup. In the latter case, you had better have saved your very recent edits on some external drive.

After you have installed the right in the db, you should test it from an external program.

You need to call into the security infrastructure like is demonstrated in the readme file included with the name and password example and request your right, just like the OS would do.

Be cautious when using any of Apples samples. Use them only as a guide. NameAndPassword has errors and never could have run. It was last updated in 2006 and uses many features that are now obsolete. It actually does not do anything, but is just a shell.

Greg Nisbet
  • 6,710
  • 3
  • 25
  • 65