Winlogon Using Mobile Disk
Introduction
PCLock is a system to allow user to use his/ her mobile disk to logon to Microsoft®
Windows® operating systems. It works as SmartCard and user does not need to know
the password to logon. All information required to logon is kept in a file in the
mobile disk (User.Info). This file contains some information about the mobile disk.
Copying the file to another disk does not work. User logon to windows by inserting
the disk and logout by removing the disk (optional).
Overview
PCLock is designed around the Win32 Winlogon. Winlogon is a component of the Microsoft®
Windows NT®/Windows® 2000/Windows® XP operating system that provides interactive
logon support. Winlogon is designed around an interactive logon model that consists
of three components (as shown in the following illustration Fig: 1): the Winlogon
executable program, a Graphical Identification and Authentication dynamic-link library
(DLL)-referred to as the GINA-and any number of network providers.

Fig: 1
Winlogon handles interface functions that are independent of authentication policy.
The GINA is a replaceable DLL component that is loaded by Winlogon. The GINA implements
the authentication policy of the interactive logon model, and is expected to perform
all identification and authentication user interactions. For example, replacement
GINA DLLs can implement smart card, retinal-scan, or other authentication mechanisms
in place of the standard Windows NT/Windows 2000 user name and password authentication.
Network provider dll is not used in our case.
Security
Each client requires a security key at the time of setup. This key should be same
for a group of PCs. Several groups can exist but user can login only on same group.
If there is only one group (all PC use same key) everyone can login to every PC.
The security key is kept with windows. This key is required while creating authentication
disk. Every disk contains windows user information and this is checked using Local
Security Authority (LSA) of windows.
The User.Info File
The KeyGen application is used to create User.Info file on mobile disk. The file
created for a disk is unique and does not work on any other disk. User can only
use the disk as storage. Any change or format of the disk can cause the file invalid.
The KeyGen requires a security key while creating the disk that must be similar
to the security key that is used while setup the client. Validity of a disk can
be checked using the KeyGen. Windows user information is not checked here. Wrong
information about logon cause a popup dialog box to appear asking username and password.
It is possible to use a domain. But this feature is not tested. All information
on the disk is encrypted but it should be kept securely. Having the disk anyone
can logon to client systems.
Authentication Process
When computer boots up the Winlogon initializes and negotiates with GINA. The GINA
shows a dialog box and waits for user to insert his/ her mobile disk (Fig: 2).
Fig: 2
When a Removable device is inserted into or replaced from a computer a system wide
WM_DEVICECHANGE message is broadcasted by OS. The WM_DEVICECHANGE device message
notifies an application of a change to the hardware configuration of a device or
the computer. The GINA checks for a valid user information file. If found it logs
on to windows using LogonUser API. The DevMon application monitors the WM_DEVICECHANGE
message and if it finds no valid disk inserted into the system it sends a logout
request to the Winlogon. If application fails to quit properly this may fail. Force
termination of an application may cause data loss. So force is not applied. Users
are suggested to logout the system manually from start button. DevMon is a helper
application and it is optional.
Implementation
The application has four parts:
- 1. The Custom GINA
- 2. The KeyGen Application
- 3. The DevMon Appliation
- 4. The Setup Application
Now let me give a short description of them.
Custom GINA
Heart of the project. It is used by windows to interact with user to manage user
session. It is a DLL with predefined functions. We make our GINA implementation
to be used with mobile disk. Here I show the WlxLoggedOutSAS function that shows
a dialog box (fig 2) and waits for user to insert the mobile disk that can be used
to login that user.
int WINAPI WlxLoggedOutSAS (
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
PVOID * pProfile)
{
if(MY_SAS_TYPE!=dwSasType)
return WLX_SAS_ACTION_NONE;
PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
int ret = pgContext->pWlxFuncs->WlxDialogBox(pgContext->hWlx,
pgContext->hDllInstance,
(LPWSTR)MAKEINTRESOURCE(IDD_INSERT_CARD_NOTICE_DIALOG),
NULL,
DisplaySASNoticeDlgProc
);
if(ret==IDCANCEL)
{
return WLX_SAS_ACTION_SHUTDOWN;
}
if (ret != IDC_LOGON_BUTTON)
{
return WLX_SAS_ACTION_NONE;
}
TOKEN_STATISTICS userStats;
TOKEN_GROUPS * pGroups;
DWORD cbStats;
if (!phToken)
return WLX_SAS_ACTION_NONE;
while(1)
{
if (!LogonUser(g_lpUserName,
g_lpDomain,
g_lpPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
phToken))
{
//Logon failed. Give user a chance to update his disk
ret = pgContext->pWlxFuncs->WlxDialogBox(pgContext->hWlx,
pgContext->hDllInstance,
(LPWSTR)MAKEINTRESOURCE(IDD_WIN_LOGON_DIALOG),
NULL,
UpdateWindowsUserDlgProc
);
if (ret != IDOK)
{
return WLX_SAS_ACTION_NONE;
}
}
else
break;
}
pgContext->hUserToken=*phToken;
// Pass back null profile and options.
*pdwOptions = 0;
*pProfile =NULL;
// Get the authenticationid from the user token.
if (!GetTokenInformation(*phToken,
TokenStatistics,
(PVOID) &userStats,
sizeof(TOKEN_STATISTICS),
&cbStats)
)
{
return WLX_SAS_ACTION_NONE;
}
else
{
*pAuthenticationId = userStats.AuthenticationId;
}
DWORD size,i;
pGroups = (TOKEN_GROUPS *)LocalAlloc(LMEM_FIXED, 1024);
GetTokenInformation(*phToken,
TokenGroups,
pGroups,
1024,
&size);
if (size > 1024)
{
pGroups = (TOKEN_GROUPS *)LocalReAlloc(pGroups, LMEM_FIXED, size);
GetTokenInformation(*phToken,
TokenGroups,
pGroups,
size,
&size);
}
for (i = 0; i < pGroups->GroupCount ; i++)
{
if ((pGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
{
CopySid(GetLengthSid(pLogonSid),
pLogonSid,
pGroups->Groups[i].Sid );
break;
}
}
LocalFree(pGroups);
pMprNotifyInfo->pszUserName=DupMbToWsString(g_lpUserName);
pMprNotifyInfo->pszDomain=DupMbToWsString(g_lpDomain);
pMprNotifyInfo->pszPassword=DupMbToWsString(g_lpPassword);
pMprNotifyInfo->pszOldPassword = NULL;
return WLX_SAS_ACTION_LOGON;
}
The dialog procedure is as follows:
int CALLBACK DisplaySASNoticeDlgProc(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
PDEV_BROADCAST_HDR pheadBC;
PDEV_BROADCAST_VOLUME pVol;
HWND hMsg=GetDlgItem(hDlg,IDC_STATUS_STATIC);
CUserInfo ui;
int drv;
char lpPath[255];
switch (Message)
{
case WM_DEVICECHANGE:
Sleep(2000);
pheadBC=(PDEV_BROADCAST_HDR)lParam;
if(wParam==DBT_DEVICEARRIVAL && pheadBC->dbch_devicetype==DBT_DEVTYP_VOLUME)
{
pVol=(PDEV_BROADCAST_VOLUME)lParam;
drv=ui.ValidDiskPresent();
lpPath[255];
if(drv)
{
sprintf(lpPath,"%c:\\%s",'A'+drv,DISK_FILE_NAME);
USER_INFO user_info=ui.LoadUserInfo(lpPath);
user_info=ui.Decode(user_info);
strcpy(g_lpUserName,user_info.lpWindowsUser);
strcpy(g_lpPassword,user_info.lpWindowsPassword);
if(strlen(user_info.lpDomain))
strcpy(g_lpDomain,user_info.lpDomain);
else
{
strcpy(g_lpDomain,".");
}
g_nLoginType=user_info.dwLogonType;
EndDialog(hDlg, ID_LOGON_SUCCESS);
}
}
break;
}
return(FALSE);
}
Device Monitor Application
This application is used to monitor the mobile disk. If user removes a mobile disk
system sends WM_DEVICECHANGE message to the application. Now we check if it is the
disk used to login user and if tru end user session by calling ExitWindows API.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_DEVICECHANGE:
if(wParam==DBT_DEVICEREMOVECOMPLETE)
{
if(!g_bLogoutOnDiskRemove) break;
//MessageBox(0,"Device Removed",0,0);
if(!g_UserInfo.ValidDiskPresent())
ExitWindows(EWX_LOGOFF,EWX_FORCEIFHUNG);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
We need to check if a valid disk is still present on system to make sure the actual
logon disk is removed.
BOOL CUserInfo::ValidDiskPresent()
{
TCHAR drive[10], lpPath[100];
DWORD dwDrives=GetLogicalDrives();
for(int i=2;i<26;i++)
{
int bit=(int)pow((double)2,i);
if(dwDrives&bit)
{
sprintf(drive,"%c:",'A'+i);
if(FIND_DRIVE_TYPE==GetDriveType(drive))
{
sprintf(lpPath,"%c:\\%s",'A'+i,DISK_FILE_NAME);
if(!PathFileExists(lpPath))continue;
USER_INFO user_info=LoadUserInfo(lpPath);
user_info=Decode(user_info);
if(CheckDisk(user_info,i))
return i;
}
}
}
return 0;
}
The KeyGen Application
This application is used to generate userinfo file on mobile disk. It takes input
from user. It shows a combo box of all users to select from. To enumerate users
in a combo box we use following function.
void CSelectUserDlg::EnumUsers()
{
LPUSER_INFO_0 pBuf = NULL;
LPUSER_INFO_0 pTmpBuf;
DWORD dwLevel = 0;
DWORD dwPrefMaxLen = -1;
DWORD dwEntriesRead = 0;
DWORD dwTotalEntries = 0;
DWORD dwResumeHandle = 0;
DWORD i;
DWORD dwTotalCount = 0;
NET_API_STATUS nStatus;
char *pmbbuf = (char *)malloc( 100 );
// Call the NetUserEnum function, specifying level 0;
// enumerate global user account types only.
//
do // begin do
{
nStatus = NetUserEnum((LPCWSTR)pszServerName,
dwLevel,
FILTER_NORMAL_ACCOUNT, // global/domain users
(LPBYTE*)&pBuf,
dwPrefMaxLen,
&dwEntriesRead,
&dwTotalEntries,
&dwResumeHandle);
if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
{
if ((pTmpBuf = pBuf) != NULL)
{
for (i = 0; (i < dwEntriesRead); i++)
{
if (pTmpBuf == NULL)
{
return;
}
wcstombs( pmbbuf, pTmpBuf->usri0_name, 99 );
m_UsersCombo.AddString((char *)pmbbuf);
pTmpBuf++;
dwTotalCount++;
}
}
}
if (pBuf != NULL)
{
NetApiBufferFree(pBuf);
pBuf = NULL;
}
}
while (nStatus == ERROR_MORE_DATA); // end do
if (pBuf != NULL)
NetApiBufferFree(pBuf);
}
The Setup Application
It stores all two of previous applications (excluding KeyGen) in its resource section.
It extracts those on client machine and creates registry settings as appropriate.
Please refer to source code for details.
Installation
Use setup.exe to install on client PC. Please be careful while entering security
key. If this key is wrong you may not logon to windows locally even you are the
administrator.
Create Logon Disk
Use KeyGen application to create authentication disk. You may use this tool on any
computer. But you can check the disk validity only where the PCLock is installed.
Provide valid windows logon user information when asked for. If you change password
on client computer the user is asked for valid information when he/she insert his/her
disk. Invalid security key on the disk will cause logon failure. Remove the user.info
file from root of mobile disk and the disk is no more valid. Do NOT format the disk
or change the label of the disk. If you copy the same file it may not work. The
user.info file is only valid for a single disk. The disk information is kept on
the disk. You cannot copy the file to another disk even it is from the same manufacturer.
Uninstall
Logon to an administrator account and use setup.exe to uninstall PCLock. You need
to provide the security key. After uninstall restart the computer and run setup.exe
again for optional clean up.