mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-24 03:53:29 +01:00
Windows: Fix false positive detection of new device insertion when clear keys option is enable
When this option is enabled, we first build the list of currently inserted devices then we start listening to insertion events. When a device insertion occurs, we check if this device is on our list and if yes, we ignore its insertion. We also ignore devices whose Device ID starts with "SWD\" and "ROOT\" since these are not real devices.
This commit is contained in:
parent
5a6b445f0e
commit
e8f83544ea
@ -491,4 +491,9 @@ DWORD BaseCom::UpdateSetupConfigFile (BOOL bForInstall)
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD BaseCom::NotifyService(DWORD dwNotifyCode)
|
||||
{
|
||||
return SendServiceNotification(dwNotifyCode);
|
||||
}
|
||||
|
@ -119,6 +119,8 @@ class BaseCom
|
||||
static DWORD WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg);
|
||||
static DWORD UpdateSetupConfigFile (BOOL bForInstall);
|
||||
static DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
|
||||
static DWORD NotifyService (DWORD dwNotifyCode);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -667,6 +667,18 @@ namespace VeraCrypt
|
||||
}
|
||||
}
|
||||
|
||||
static void NotifyService (DWORD dwNotifyCmd)
|
||||
{
|
||||
Elevate();
|
||||
|
||||
DWORD result = ElevatedComInstance->NotifyService (dwNotifyCmd);
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (result);
|
||||
throw SystemException(SRC_POS);
|
||||
}
|
||||
}
|
||||
|
||||
static void Release ()
|
||||
{
|
||||
if (--ReferenceCount == 0 && ElevatedComInstance)
|
||||
@ -5708,6 +5720,22 @@ namespace VeraCrypt
|
||||
throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value));
|
||||
}
|
||||
|
||||
void BootEncryption::NotifyService (DWORD dwNotifyCmd)
|
||||
{
|
||||
if (!IsAdmin() && IsUacSupported())
|
||||
{
|
||||
Elevator::NotifyService (dwNotifyCmd);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwRet = SendServiceNotification(dwNotifyCmd);
|
||||
if (dwRet != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(dwRet);
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
}
|
||||
|
||||
void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors)
|
||||
{
|
||||
BootEncryptionStatus encStatus = GetStatus();
|
||||
|
@ -314,6 +314,7 @@ namespace VeraCrypt
|
||||
static void UpdateSetupConfigFile (bool bForInstall);
|
||||
void GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
|
||||
bool IsUsingUnsupportedAlgorithm(LONG driverVersion);
|
||||
void NotifyService (DWORD dwNotifyCmd);
|
||||
protected:
|
||||
static const uint32 RescueIsoImageSize = 1835008; // Size of ISO9660 image with bootable emulated 1.44MB floppy disk image
|
||||
|
||||
|
@ -15711,4 +15711,36 @@ bool OneOfKBsInstalled (const wchar_t* szKBs[], int count)
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
DWORD SendServiceNotification (DWORD dwNotificationCmd)
|
||||
{
|
||||
DWORD dwRet = ERROR_INVALID_PARAMETER;
|
||||
// We only support clearing keys on new device insertion
|
||||
if (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION == dwNotificationCmd)
|
||||
{
|
||||
DWORD dwServiceControlCode = VC_SERVICE_CONTROL_BUILD_DEVICE_LIST;
|
||||
// send this control code to VeraCrypt SystemFavorites service
|
||||
SC_HANDLE hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
|
||||
if (hSCManager != NULL)
|
||||
{
|
||||
SC_HANDLE hService = OpenService (hSCManager, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS);
|
||||
if (hService != NULL)
|
||||
{
|
||||
SERVICE_STATUS ss;
|
||||
if (ControlService (hService, dwServiceControlCode, &ss))
|
||||
dwRet = ERROR_SUCCESS;
|
||||
else
|
||||
dwRet = GetLastError ();
|
||||
CloseServiceHandle (hService);
|
||||
}
|
||||
else
|
||||
dwRet = GetLastError ();
|
||||
CloseServiceHandle (hSCManager);
|
||||
}
|
||||
else
|
||||
dwRet = GetLastError ();
|
||||
}
|
||||
|
||||
return dwRet;
|
||||
}
|
||||
#endif // VC_COMREG
|
@ -84,6 +84,9 @@ enum
|
||||
|
||||
#define VC_FILENAME_RENAMED_SUFFIX L"_old"
|
||||
|
||||
/* customer service control code to build device list */
|
||||
#define VC_SERVICE_CONTROL_BUILD_DEVICE_LIST 128
|
||||
|
||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||
#define USER_DEFAULT_SCREEN_DPI 96
|
||||
#endif
|
||||
@ -585,6 +588,7 @@ BOOL EnableProcessProtection();
|
||||
void SafeOpenURL (LPCWSTR szUrl);
|
||||
BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter);
|
||||
BOOL IsTestSigningModeEnabled ();
|
||||
DWORD SendServiceNotification (DWORD dwNotificationCmd);
|
||||
#ifdef _WIN64
|
||||
void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed);
|
||||
#endif
|
||||
|
@ -182,6 +182,11 @@ class TrueCryptFormatCom : public ITrueCryptFormatCom
|
||||
return BaseCom::UpdateSetupConfigFile (bForInstall);
|
||||
}
|
||||
|
||||
virtual DWORD STDMETHODCALLTYPE NotifyService (DWORD dwNotifyCode)
|
||||
{
|
||||
return BaseCom::NotifyService (dwNotifyCode);
|
||||
}
|
||||
|
||||
protected:
|
||||
DWORD MessageThreadId;
|
||||
LONG RefCount;
|
||||
|
@ -16,7 +16,7 @@ import "..\Common\Password.h";
|
||||
[
|
||||
uuid(56327DDA-F1A7-4e13-B128-520D129BDEF6),
|
||||
helpstring("VeraCrypt Format UAC Support Library"),
|
||||
version(2.9) // Update ComSetup.cpp when changing version number
|
||||
version(2.10) // Update ComSetup.cpp when changing version number
|
||||
]
|
||||
library TrueCryptFormatCom
|
||||
{
|
||||
@ -49,6 +49,7 @@ library TrueCryptFormatCom
|
||||
DWORD WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg);
|
||||
DWORD UpdateSetupConfigFile (BOOL bForInstall);
|
||||
DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
|
||||
DWORD NotifyService (DWORD dwNotifyCode);
|
||||
};
|
||||
|
||||
[
|
||||
|
@ -203,6 +203,11 @@ class TrueCryptMainCom : public ITrueCryptMainCom
|
||||
return BaseCom::UpdateSetupConfigFile (bForInstall);
|
||||
}
|
||||
|
||||
virtual DWORD STDMETHODCALLTYPE NotifyService (DWORD dwNotifyCode)
|
||||
{
|
||||
return BaseCom::NotifyService (dwNotifyCode);
|
||||
}
|
||||
|
||||
protected:
|
||||
DWORD MessageThreadId;
|
||||
LONG RefCount;
|
||||
|
@ -16,7 +16,7 @@ import "..\Common\Password.h";
|
||||
[
|
||||
uuid(9ACF6176-5FC4-4690-A025-B3306A50EB6A),
|
||||
helpstring("VeraCrypt Main UAC Support Library"),
|
||||
version(2.12) // Update ComSetup.cpp when changing version number
|
||||
version(2.13) // Update ComSetup.cpp when changing version number
|
||||
]
|
||||
library TrueCryptMainCom
|
||||
{
|
||||
@ -53,6 +53,7 @@ library TrueCryptMainCom
|
||||
DWORD WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg);
|
||||
DWORD UpdateSetupConfigFile (BOOL bForInstall);
|
||||
DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
|
||||
DWORD NotifyService (DWORD dwNotifyCode);
|
||||
};
|
||||
|
||||
[
|
||||
|
@ -54,7 +54,12 @@
|
||||
#include <Strsafe.h>
|
||||
#include <InitGuid.h>
|
||||
#include <devguid.h>
|
||||
#include <devpkey.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <Cfgmgr32.h>
|
||||
#include <intrin.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#pragma intrinsic(_InterlockedCompareExchange, _InterlockedExchange)
|
||||
|
||||
@ -9640,6 +9645,70 @@ static HDEVNOTIFY SystemFavoriteServiceNotify = NULL;
|
||||
|
||||
DEFINE_GUID(OCL_GUID_DEVCLASS_SOFTWARECOMPONENT, 0x5c4c3332, 0x344d, 0x483c, 0x87, 0x39, 0x25, 0x9e, 0x93, 0x4c, 0x9c, 0xc8);
|
||||
|
||||
// This functions returns a vector containing all devices currently connected to the system
|
||||
void BuildDeviceList(std::vector<CDevice>& devices)
|
||||
{
|
||||
devices.clear();
|
||||
|
||||
// Get device info set for all devices
|
||||
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
|
||||
if (hDevInfo != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SP_DEVINFO_DATA deviceInfoData;
|
||||
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
|
||||
// Enumerate through all devices in set
|
||||
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &deviceInfoData); i++)
|
||||
{
|
||||
// Get device path
|
||||
WCHAR szDeviceID[MAX_PATH];
|
||||
if (CR_SUCCESS == CM_Get_Device_IDW(deviceInfoData.DevInst, szDeviceID, MAX_PATH, 0))
|
||||
{
|
||||
// Add to vector
|
||||
devices.push_back(CDevice(szDeviceID));
|
||||
}
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo); // Cleanup
|
||||
}
|
||||
}
|
||||
|
||||
// This function build a device ID value from the dbcc_name field of a DEV_BROADCAST_DEVICEINTERFACE structure
|
||||
// In case of error, the device ID is set to an empty string
|
||||
// Algorithm taken from https://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal#premain174347
|
||||
void GetDeviceID(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WCHAR* szDevId)
|
||||
{
|
||||
szDevId[0] = L'\0';
|
||||
if (lstrlen(pDevInf->dbcc_name) < 4) return;
|
||||
if (lstrlen(pDevInf->dbcc_name) - 4 >= MAX_PATH) return;
|
||||
|
||||
StringCchCopyW(szDevId, MAX_PATH, pDevInf->dbcc_name + 4);
|
||||
|
||||
// find last occurrence of '#'
|
||||
wchar_t *idx = wcsrchr(szDevId, L'#');
|
||||
if(!idx)
|
||||
{
|
||||
szDevId[0] = L'\0';
|
||||
return;
|
||||
}
|
||||
|
||||
// truncate string at last '#'
|
||||
*idx = L'\0';
|
||||
|
||||
// replace '#' with '\\' and convert string to upper case
|
||||
for (wchar_t *p = szDevId; *p; ++p)
|
||||
{
|
||||
if (*p == L'#')
|
||||
{
|
||||
*p = L'\\';
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = towupper((unsigned)*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SystemFavoritesServiceLogMessage (const wstring &errorMessage, WORD wType)
|
||||
{
|
||||
HANDLE eventSource = RegisterEventSource (NULL, TC_SYSTEM_FAVORITES_SERVICE_NAME);
|
||||
@ -9719,6 +9788,9 @@ static void SystemFavoritesServiceUpdateLoaderProcessing (BOOL bForce)
|
||||
}
|
||||
}
|
||||
|
||||
// Global vector containing all devices previsouly knwon to the system
|
||||
std::vector<CDevice> g_Devices;
|
||||
|
||||
static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
|
||||
DWORD dwEventType,
|
||||
LPVOID lpEventData,
|
||||
@ -9756,6 +9828,18 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VC_SERVICE_CONTROL_BUILD_DEVICE_LIST:
|
||||
{
|
||||
/* build a list of all devices currently connected to the system */
|
||||
/* ignore if clear keys configuration is already set */
|
||||
if (!(ReadDriverConfigurationFlags() & VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION))
|
||||
{
|
||||
SystemFavoritesServiceLogInfo (L"VC_SERVICE_CONTROL_BUILD_DEVICE_LIST received");
|
||||
g_Devices.clear ();
|
||||
BuildDeviceList (g_Devices);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SERVICE_CONTROL_DEVICEEVENT:
|
||||
if (DBT_DEVICEARRIVAL == dwEventType)
|
||||
{
|
||||
@ -9777,13 +9861,44 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
|
||||
{
|
||||
bClearKeys = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR szDevId[MAX_PATH];
|
||||
GetDeviceID(pInf, szDevId);
|
||||
// device ID must contain "VID_" and "PID_" to be valid and it must not start with "SWD\" or "ROOT\"
|
||||
if (wcsstr(szDevId, L"VID_") && wcsstr(szDevId, L"PID_") && wcsstr(szDevId, L"SWD\\") != szDevId && wcsstr(szDevId, L"ROOT\\") != szDevId)
|
||||
{
|
||||
CDevice dev(szDevId);
|
||||
// look for the device in the list of devices already known to us and if it is there, then don't clear keys
|
||||
if (std::find(g_Devices.begin(), g_Devices.end(), dev) != g_Devices.end())
|
||||
{
|
||||
bClearKeys = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// trace the device ID of the new device in the log
|
||||
WCHAR szMsg[2*MAX_PATH];
|
||||
StringCbPrintfW(szMsg, sizeof(szMsg), L"SERVICE_CONTROL_DEVICEEVENT - New device ID: %s", szDevId);
|
||||
SystemFavoritesServiceLogInfo (szMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bClearKeys = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bClearKeys)
|
||||
{
|
||||
DWORD cbBytesReturned = 0;
|
||||
|
||||
DeviceIoControl (hDriver, VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS, NULL, 0, NULL, 0, &cbBytesReturned, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemFavoritesServiceLogInfo (L"SERVICE_CONTROL_DEVICEEVENT - DBT_DEVICEARRIVAL ignored");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11449,6 +11564,13 @@ void SetServiceConfigurationFlag (uint32 flag, BOOL state)
|
||||
BootEncObj->SetServiceConfigurationFlag (flag, state ? true : false);
|
||||
}
|
||||
|
||||
|
||||
void NotifyService (DWORD dwNotifyCmd)
|
||||
{
|
||||
if (BootEncObj)
|
||||
BootEncObj->NotifyService (dwNotifyCmd);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WORD lw = LOWORD (wParam);
|
||||
@ -12213,6 +12335,8 @@ static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARA
|
||||
SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD, bPasswordCacheEnabled);
|
||||
SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PIM, (bPasswordCacheEnabled && bPimCacheEnabled)? TRUE : FALSE);
|
||||
SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION, IsDlgButtonChecked (hwndDlg, IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION));
|
||||
if (bClearKeysEnabled)
|
||||
NotifyService (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION);
|
||||
SetDriverConfigurationFlag (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION, bClearKeysEnabled);
|
||||
SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER, bAutoFixBootloader? FALSE : TRUE);
|
||||
if (!IsHiddenOSRunning ())
|
||||
|
@ -128,4 +128,42 @@ void SetDriverConfigurationFlag (uint32 flag, BOOL state);
|
||||
BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites = FALSE, BOOL logOnMount = FALSE, BOOL hotKeyMount = FALSE, const VeraCrypt::FavoriteVolume &favoriteVolumeToMount = VeraCrypt::FavoriteVolume());
|
||||
void __cdecl mountFavoriteVolumeThreadFunction (void *pArg);
|
||||
|
||||
// A class that represents a device based on its device ID
|
||||
class CDevice
|
||||
{
|
||||
public:
|
||||
WCHAR m_szDeviceID[MAX_PATH];
|
||||
|
||||
CDevice()
|
||||
{
|
||||
ZeroMemory(m_szDeviceID, sizeof(m_szDeviceID));
|
||||
}
|
||||
|
||||
CDevice(WCHAR* szDevicePath)
|
||||
{
|
||||
StringCchCopyW(m_szDeviceID, MAX_PATH, szDevicePath);
|
||||
}
|
||||
|
||||
CDevice(const CDevice& src)
|
||||
{
|
||||
StringCchCopyW(m_szDeviceID, MAX_PATH, src.m_szDeviceID);
|
||||
}
|
||||
|
||||
CDevice& operator=(const CDevice& src)
|
||||
{
|
||||
StringCchCopyW(m_szDeviceID, MAX_PATH, src.m_szDeviceID);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOL operator==(const CDevice& src)
|
||||
{
|
||||
return wcscmp(m_szDeviceID, src.m_szDeviceID) == 0;
|
||||
}
|
||||
|
||||
~CDevice()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -11,10 +11,10 @@
|
||||
*/
|
||||
|
||||
#define TC_MAIN_COM_VERSION_MAJOR 2
|
||||
#define TC_MAIN_COM_VERSION_MINOR 12
|
||||
#define TC_MAIN_COM_VERSION_MINOR 13
|
||||
|
||||
#define TC_FORMAT_COM_VERSION_MAJOR 2
|
||||
#define TC_FORMAT_COM_VERSION_MINOR 9
|
||||
#define TC_FORMAT_COM_VERSION_MINOR 10
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <comdef.h>
|
||||
@ -39,9 +39,9 @@ extern "C" BOOL RegisterComServers (wchar_t *modulePath)
|
||||
UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR, 0, SYS_WIN32);
|
||||
UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR, 0, SYS_WIN32);
|
||||
// unregister older versions that may still exist
|
||||
for (WORD i = 8; i >= 1; i--)
|
||||
for (WORD i = 9; i >= 1; i--)
|
||||
UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR-i, 0, SYS_WIN32);
|
||||
for (WORD i = 5; i >= 1; i--)
|
||||
for (WORD i = 6; i >= 1; i--)
|
||||
UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR-i, 0, SYS_WIN32);
|
||||
|
||||
wchar_t setupModule[MAX_PATH];
|
||||
@ -78,9 +78,9 @@ extern "C" BOOL UnregisterComServers (wchar_t *modulePath)
|
||||
return FALSE;
|
||||
|
||||
// unregister older versions that may still exist
|
||||
for (WORD i = 8; i >= 1; i--)
|
||||
for (WORD i = 9; i >= 1; i--)
|
||||
UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR-i, 0, SYS_WIN32);
|
||||
for (WORD i = 5; i >= 1; i--)
|
||||
for (WORD i = 6; i >= 1; i--)
|
||||
UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR-i, 0, SYS_WIN32);
|
||||
|
||||
wchar_t module[1024];
|
||||
|
Loading…
Reference in New Issue
Block a user