From e412c0458b9df6bb1f2482823d397acc2a656464 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 25 Mar 2018 20:35:15 +0200 Subject: 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. --- src/Common/Dlgcode.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'src/Common') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 56938518..112328b3 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -13131,6 +13131,7 @@ static BOOL GenerateRandomString (HWND hwndDlg, LPTSTR szName, DWORD maxCharsCou typedef struct { HDESK hDesk; + LPCWSTR szDesktopName; HINSTANCE hInstance; LPCWSTR lpTemplateName; DLGPROC lpDialogFunc; @@ -13138,16 +13139,90 @@ typedef struct INT_PTR retValue; } 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) { + volatile BOOL bStopMonitoring = FALSE; + HANDLE hMonitoringThread = NULL; + unsigned int monitoringThreadID = 0; SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter; + SecureDesktopMonitoringThreadParam monitorParam; SetThreadDesktop (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, NULL, pParam->lpDialogFunc, pParam->dwInitParam); + if (hMonitoringThread) + { + bStopMonitoring = TRUE; + + WaitForSingleObject (hMonitoringThread, INFINITE); + CloseHandle (hMonitoringThread); + } + return 0; } @@ -13210,6 +13285,7 @@ INT_PTR SecureDesktopDialogBoxParam( SecureDesktopThreadParam param; param.hDesk = hSecureDesk; + param.szDesktopName = szDesktopName; param.hInstance = hInstance; param.lpTemplateName = lpTemplateName; param.lpDialogFunc = lpDialogFunc; -- cgit v1.2.3