Windows: ensure that out secure desktop has always user input to avoid cases where another application switch to default desktop while our password dialog is displayed.

This commit is contained in:
Mounir IDRASSI 2018-03-25 20:35:15 +02:00
parent 6ebc83bbed
commit e412c0458b
No known key found for this signature in database
GPG Key ID: DD0C382D5FCFB8FC

View File

@ -13131,6 +13131,7 @@ static BOOL GenerateRandomString (HWND hwndDlg, LPTSTR szName, DWORD maxCharsCou
typedef struct typedef struct
{ {
HDESK hDesk; HDESK hDesk;
LPCWSTR szDesktopName;
HINSTANCE hInstance; HINSTANCE hInstance;
LPCWSTR lpTemplateName; LPCWSTR lpTemplateName;
DLGPROC lpDialogFunc; DLGPROC lpDialogFunc;
@ -13138,16 +13139,90 @@ typedef struct
INT_PTR retValue; INT_PTR retValue;
} SecureDesktopThreadParam; } SecureDesktopThreadParam;
typedef struct
{
LPCWSTR szVCDesktopName;
HDESK hVcDesktop;
volatile BOOL* pbStopMonitoring;
} SecureDesktopMonitoringThreadParam;
#define SECUREDESKTOP_MONOTIR_PERIOD 500
// This thread checks if VeraCrypt secure desktop is the one that has user input
// and if it is not then it will call SwitchDesktop to make it the input desktop
static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadParameter )
{
SecureDesktopMonitoringThreadParam* pMonitorParam = (SecureDesktopMonitoringThreadParam*) lpThreadParameter;
if (pMonitorParam)
{
volatile BOOL* pbStopMonitoring = pMonitorParam->pbStopMonitoring;
LPCWSTR szVCDesktopName = pMonitorParam->szVCDesktopName;
HDESK hVcDesktop = pMonitorParam->hVcDesktop;
while (!*pbStopMonitoring)
{
// check that our secure desktop is still the input desktop
// otherwise, switch to it
BOOL bPerformSwitch = FALSE;
HDESK currentDesk = OpenInputDesktop (0, FALSE, GENERIC_READ);
if (currentDesk)
{
LPWSTR szName = NULL;
DWORD dwLen = 0;
if (!GetUserObjectInformation (currentDesk, UOI_NAME, NULL, 0, &dwLen))
{
szName = (LPWSTR) malloc (dwLen);
if (szName)
{
if (GetUserObjectInformation (currentDesk, UOI_NAME, szName, dwLen, &dwLen))
{
if (0 != _wcsicmp (szName, szVCDesktopName))
bPerformSwitch = TRUE;
}
free (szName);
}
}
CloseDesktop (currentDesk);
}
if (bPerformSwitch)
SwitchDesktop (hVcDesktop);
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
}
}
return 0;
}
static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter) static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter)
{ {
volatile BOOL bStopMonitoring = FALSE;
HANDLE hMonitoringThread = NULL;
unsigned int monitoringThreadID = 0;
SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter; SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter;
SecureDesktopMonitoringThreadParam monitorParam;
SetThreadDesktop (pParam->hDesk); SetThreadDesktop (pParam->hDesk);
SwitchDesktop (pParam->hDesk); SwitchDesktop (pParam->hDesk);
// create the thread that will ensure that VeraCrypt secure desktop has always user input
monitorParam.szVCDesktopName = pParam->szDesktopName;
monitorParam.hVcDesktop = pParam->hDesk;
monitorParam.pbStopMonitoring = &bStopMonitoring;
hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName, pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
NULL, pParam->lpDialogFunc, pParam->dwInitParam); NULL, pParam->lpDialogFunc, pParam->dwInitParam);
if (hMonitoringThread)
{
bStopMonitoring = TRUE;
WaitForSingleObject (hMonitoringThread, INFINITE);
CloseHandle (hMonitoringThread);
}
return 0; return 0;
} }
@ -13210,6 +13285,7 @@ INT_PTR SecureDesktopDialogBoxParam(
SecureDesktopThreadParam param; SecureDesktopThreadParam param;
param.hDesk = hSecureDesk; param.hDesk = hSecureDesk;
param.szDesktopName = szDesktopName;
param.hInstance = hInstance; param.hInstance = hInstance;
param.lpTemplateName = lpTemplateName; param.lpTemplateName = lpTemplateName;
param.lpDialogFunc = lpDialogFunc; param.lpDialogFunc = lpDialogFunc;