Windows Mobile 5.0 Local Authentication Sub System (LASS) - Part 2
In Part 1 we looked at the power-on-password replacement options for Windows Mobile 2003. In this blog I want to take you through the new Local Authentication Sub System (LASS).
This new architecture can be found in Windows CE 5.0 and Windows Mobile 5.0 devices and brings a uniform authentication system to both Smartphone and Pocket PC - prior to Windows Mobile 5.0 it was not possible to replace the PIN lock screen for Smartphone, but with the unified LASS architecture found on both Pocket PC and Smartphone its now (although I haven’t proved it with code yet J) possible.
The MSDN docs for LASS are here.
Architechture
The LASS architecture looks a bit like this:
Taking each of the key components:
LASS:
This is the system module responsible for joining user applications to a specific authentication plug-in. It doesn’t provide any authentication stuff in its own right but relies on the LAP to do the work of capturing and verifying credentials. The LASS module exposes a number of API’s:
LASSReloadConfig
Causes the LASS module to reload registry information.
CreateEnrollmentConfigDialog
Call’s to this API are forwarded to the active LAP to display the enrolment dialog. If you click the Password applet in settings on Pocket PC 2005 this API is called.
VerifyUser
Call’s to this API are forwarded to the active LAP to capture and verify the user credential.
Header file: lass.h
Lib: coredll.lib
LAP:
This module is responsible for capturing and verifying user credentials, either by displaying a form for input or integrating with hardware. A custom LAP must export the following methods:
LAPCreateEnrollmentConfigDialog
Display and capture initialization information – replacement for password control panel app.
VerifyUser
Called to capture and verify credentials.
InitLAP
Called when the LAP is loaded.
DeinitLAP
Called when the LAP is unloaded
The following are optional exports:
VerifyUserStart
Called before verification takes place – can be used to spin up hardware that might be used during the verification process.
VerifyUserStop
Called after verification has completed – use it to close down hardware ect.
VerifyUserToTop
Move the credentials capture to top in the Z-order (I’ve never seen this called on my LAP).
Authentication Events:
These are registry entries identified with a GUID that define certain parameters about how to verify the user through a LAP. For example if the user only needs to enter a password when the device has been unused for a certain period of time.
Values that can be set:
AEFrequencyValue
AEFrequencyType
DisplayText
How it all fits together:
Let’s start with power on. When a password has been configured the shell will check the registry to see which LAP dll is set as active and load the DLL. First InitLAP is called, then VerifyUserStart (if available) and then VerifyUser. The LAP is handed an AE GUID, a tile and a number of options. Based on the options and the AE settings the LAP will then capture and validate the user before returning success or failure. If authentication is successful VerifyUserStop is called, otherwise the LASS will update the Lockout registry information and rerun the LAP appropriately.
The shell still uses the old password registry settings [HKCU\ControlPanel\owner\PowrPass] to decide if authentication is required at power on, and desktop ActiveSync password protection operates in the same way as before using the password string stored in the OS.
Replacing the password control panel application is no longer necessary because the new CPL application simply calls the exported LAPCreateEnrollmentConfigDialog on the active LAP.
Replacing the Active LAP
It’s pretty straight forward although requires native code – you can’t do this in managed code. The one step that caught me out is the signing step: remember Windows Mobile 5.0 brings a one tier security model to Pocket PC, and part of that security means a trusted application can’t load an un-trusted DLL. The LASS components are running trusted so any LAP dll must be signed with a trusted cert.
Here are the basic steps for creating and registering a custom LAP:
- Create a C++ DLL that exports at least LAPCreateEnrollmentConfigDialog, VerifyUser, InitLAP and DeinitLAP. Here is about the most basic one I could come up with .
- Sign it with a cert derived from something that’s in privileged store on the device – the simplest way to do this is to select a cert in VS2005 signing tab and select ‘provision the device’
- Deploy the dll to the windows directory
- Update the registry of the device:
- Create a new key [HKLM\Comm\Security\LASSD\LAP\<mylap>]
- Create a string value under that key: dll=<name of LAP dll>.dll
- Update the default LAP setting [HKLM\Comm\Security\LASSD\LAP] ActiveLap=<mylap>
- Soft reset the device
To test it’s all working go into Settings and select Password to see the LAP enroller display.
SimpleLAP
Here is the code for a very simple LAP I created for Pocket PC. You will need to have Visual Studio 2005 (standard or above) and Windows Mobile 5.0 Pocket PC SDK installed.
This C++ project includes a DEF file exporting the required API’s:
LIBRARY "SimpleLAP"
EXPORTS
LAPCreateEnrollmentConfigDialog
VerifyUser
InitLAP
DeinitLAP
The implementation of each is very simple:
BOOL InitLAP(
InitLap* il
)
{
return TRUE;
}
void DeinitLAP()
{
return;
}
BOOL VerifyUser(const GUID *AEKey,
LPCWSTR pwszAEDisplayText,
HWND hwndParent,
DWORD dwOptions,
PVOID pExtended)
{
return DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_VERIFY_SQUARE), hwndParent,
Verify_DlgProc, (LPARAM)false );
}
BOOL LAPCreateEnrollmentConfigDialog(HWND hwndParent,DWORD dwOptions)
{
DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_ENROLE_SQUARE), hwndParent,
Enrole_DlgProc, (LPARAM)false );
return true;
}
Two dialogs are displayed, one for enrolment:
And one for password validation:
The interesting bits are in the dialog handler routines:
case IDC_ENABLE: // Enabling the password
{
…
// Is a password active? Check with OS
if (GetPasswordActive())
{
// Password is set, change value
// Now check the old password is OK with the system
if (CheckPassword(OldPwd))
{
// Change password values
if (!SetPassword( OldPwd, NewPwd))
{… error handling}
}
}
// Enable for the first time - set OS password
else
{
// Change password value to the new entry
if (!SetPassword( NULL, NewPwd))
{… error handling}
// Now make it active
if (!SetPasswordActive( TRUE, NewPwd ))
{… error handling}
// Now tell OS to use password on power up
HKEY hkey;
RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("ControlPanel\\Owner"), 0, 0, 0, 0, 0, &hkey, 0 );
RegSetValueEx( hkey, TEXT("PowrPass"), 0, REG_BINARY, (CONST BYTE*)"\x01", 1 );
RegCloseKey( hkey );
}
}
break;
case IDC_DISSABLE: // Dissabling password
{
// Check the OLD password is correct
if (CheckPassword(ItemText))
{
// Turn it off
if (!SetPasswordActive(FALSE,ItemText))
{… error handling}
// Change pwd value to null
if (!SetPassword(ItemText,NULL))
{… error handling}
HKEY hkey;
// Dissable power-on dialog.
RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("ControlPanel\\Owner"), 0, 0, 0, 0, 0, &hkey, 0 );
RegSetValueEx( hkey, TEXT("PowrPass"), 0, REG_BINARY, (CONST BYTE*)"\x00", 1 );
RegCloseKey( hkey );
}
EndDialog( hDlg, 1 );
}
Registering and Enabling a new LAP
I’ve been working with the emulator to build my LAP modules as its much easier to hard reset the emulator than a real device when it all goes horribly wrong (which has happened several times!). However the one thing the emulator is not quick at is a soft reset which is a complete pain when that’s what’s needed to update an active LAP.
The good news: there is another way. LASS supports an API LASSReloadConfig that causes the registry information to be reloaded and the active LAP to be unloaded and allow the dll to be updated. So I also built a test hardness to set up the reg key and call the reload api. It’s in C# and requires CF 2.0 to be on the device. Grab the project here.
The UI isn’t pretty but it gets the job done:
These are the important bits of code:
Three imports are used to interact with LASS:
[DllImport("coredll.dll")]
private static extern int LASSReloadConfig();
[DllImport("coredll.dll")]
private static extern int VerifyUser(IntPtr AEKey, string DisplayText, IntPtr ParentWindow, int Options, IntPtr Extended);
[DllImport("coredll.dll")]
private static extern int CreateEnrollmentConfigDialog(IntPtr ParentWindow);
Reload just calls the OS api:
private void Reload_Click(object sender, EventArgs e)
{
bool ok = (0!=LASSReloadConfig());
MessageBox.Show("Reload " + (ok ? "Succeeded" : "Failed"));
}
Reg Clear sets the active LAP back to the default value (for the emulator) and deletes the key used for the custom LAP.
private void ClearReg_Click(object sender, EventArgs e)
{
// Clear the info from HKLM\Comm\Security\LASSD\LAP\ActiveLAP
Registry.SetValue(@"HKEY_LOCAL_MACHINE\comm\Security\LASSD\LAP", "ActiveLAP", "lap_pw");
Registry.LocalMachine.DeleteSubKey(@"Comm\Security\LASSD\LAP\" + DLLName.Text);
}
Set Reg creates the new LAP sub key and sets the active lap to point at it.
private void SetReg_Click(object sender, EventArgs e)
{
Registry.LocalMachine.CreateSubKey(@"Comm\Security\LASSD\LAP\" + DLLName.Text);
Registry.SetValue(@"HKEY_LOCAL_MACHINE\comm\Security\LASSD\LAP\" + DLLName.Text, "Dll", DLLName.Text +".dll");
Registry.SetValue(@"HKEY_LOCAL_MACHINE\comm\Security\LASSD\LAP", "ActiveLAP", DLLName.Text);
}
Verify calls through to the LASS and requests validation from the active LAP
private void CallVerify_Click(object sender, EventArgs e)
{
VerifyUser(IntPtr.Zero, "Called from tool", this.Handle, 0, IntPtr.Zero);
}
Enrole calls through to the active LAP and shows the enrolement dialog.
private void CallEnrole_Click(object sender, EventArgs e)
{
CreateEnrollmentConfigDialog(this.Handle);
}
I think that’s probably enough for this post. In part 3 we will look at porting the LetMeIn SDK sample from Windows Mobile 2003 to WM5.0
Marcus