Custom pre-logon processing in MS Windows using GINA DLL hooks


This article describes how use GINA Logon hooks to perform custom actions that require the user's Winlogon and password prior to performing the domain logon. This for example can allow the Windows logon to perform 802.1X/WPA2 authentication using the domain login/pass credentials and establish network connection before contacting the AD server to authenticate the user.


Winlogon and GINA

GINA stands for Graphical Identification and Authentication dynamic-link library. The GINA is a replaceable DLL component that is loaded by the Winlogon executable. The purpose of a GINA DLL is to provide customizable user identification and authentication procedures. The default GINA does this by delegating SAS event monitoring to Winlogon, which receives and processes CTL+ALT+DEL secure attention sequences (SASs). A custom GINA is responsible for setting itself up to receive SAS events (other than the default CTRL+ALT+DEL SAS event) and notifying Winlogon when SAS events occur. Winlogon will evaluate its state to determine what is required to process the custom GINA's SAS. This processing usually includes calls to the GINA's SAS processing functions.

To customize the Windows logon process, we just need to overwrite some GINA functions. For this, we need to create a GINA DLL with the required set of exported functions and provide our customized implementation of some functions. The approach is to make the replacement GINA DLL load the original GINA DLL and obtain pointers to the original GINA functions. Then, our customized GINA DLL will export the required GINA functions by calling the original GINA functions. Where customization is needed, our GINA function will execute custom code before or after calling the original GINA function.

In this example, we will create a GINA function that will do something with the user's login/password before performing the domain logon. All other GINA functions will just be pass-thru to the original GINA DLL.


How to create a new GINA DLL

The best way to add custom winlogon functionality is to start from a GINA stub. You can get a GINA stub from Microsoft Platform SDK for Windows XP SP2. You can find it under :

C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Samples\Security\GINA\GinaStub

To build the GINA DLL, you need to have Microsoft Visual C/C++ installed.

Edit the Makfefile in the GinaStub directory and remove the Windows NT condition. The Makefile should look like this :

!include <win32.mak>

proj=ginastub

all: $(proj).dll

$(proj).obj: $(proj).c
  $(cc) $(cdebug) $(cflags) $*.c

$(proj).lib: $(proj).obj $(proj).def
  $(implib) -machine:$(CPU) -def:$(proj).def -out:$(proj).lib

$(proj).dll: $(proj).obj
  $(link) $(ldebug) $(dlllflags) $(guilibsdll) \
  $** -out:$(proj).dll -def:$(proj).def

From the MSVC++ console, cd to the GinaStub directory then type :

nmake

Where to add custom code that uses the user login/pass credentials

Winlogon calls the WlxLoggedOutSAS GINA function when an event occurs while no users are logged in the system (e.g. user inserts Smart card, or presses ALT-CTRL-DEL). To detect which exact event resulted in the call, the WlxLoggedOutSAS GINA function checks the variable dwSasType. If it equals WLX_SAS_TYPE_CTRL_ALT_DEL, the login/password input box is displayed. From here, the function takes care of authenticating the user and setting up its environment.

int WlxLoggedOutSAS(
  __in     PVOID pWlxContext,
  __in     DWORD dwSasType,
  __out    PLUID pAuthenticationId,
  __inout  PSID pLogonSid,
  __out    PDWORD pdwOptions,
  __out    PHANDLE phToken,
  __out    PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
  __out    PVOID *pProfile
);

Custom code before logon

One way thus to obtain the login/password pair before performing the logon, is to create our own login/password box (using WlxDialogBoxParam) to get the user credentials, then use the entered credentials to do custom processing before performing logon by calling LsaLogonUser.


Custom code after logon

This is much easier than the previous case. All we have to do is call the original WlxLoggedOutSAS function then get the login/password/domain from pMprNotifyInfo variable set by .

      pMprNotifyInfo->pszUserName
      pMprNotifyInfo->pszDomain
      pMprNotifyInfo->pszPassword
      pMprNotifyInfo->pszOldPassword

How to install the new GINA DLL

  1. Copy GinaStub.dll to %SystemRoot%\System32 directory.
  2. Run RegEdit (or RegEdt32).
  3. Create the following value under
    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon.
    Value Name: GinaDLL
    Value Type: REG_SZ
    Value Data: “GinaStub.dll”
  4. Exit RegEdit.
  5. Reboot.

Final notes


References



Wireless Internet Security Performance RADIUS server Wireless Internet Security Performance RADIUS server