diff options
-rw-r--r-- | src/Common/BaseCom.cpp | 7 | ||||
-rw-r--r-- | src/Common/BaseCom.h | 2 | ||||
-rw-r--r-- | src/Common/BootEncryption.cpp | 28 | ||||
-rw-r--r-- | src/Common/BootEncryption.h | 1 | ||||
-rw-r--r-- | src/Common/Dlgcode.c | 32 | ||||
-rw-r--r-- | src/Common/Dlgcode.h | 4 | ||||
-rw-r--r-- | src/Format/FormatCom.cpp | 5 | ||||
-rw-r--r-- | src/Format/FormatCom.idl | 3 | ||||
-rw-r--r-- | src/Mount/MainCom.cpp | 5 | ||||
-rw-r--r-- | src/Mount/MainCom.idl | 3 | ||||
-rw-r--r-- | src/Mount/Mount.c | 124 | ||||
-rw-r--r-- | src/Mount/Mount.h | 38 | ||||
-rw-r--r-- | src/Setup/ComSetup.cpp | 12 |
13 files changed, 255 insertions, 9 deletions
diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp index a9ece557..dde4b55d 100644 --- a/src/Common/BaseCom.cpp +++ b/src/Common/BaseCom.cpp @@ -491,4 +491,9 @@ DWORD BaseCom::UpdateSetupConfigFile (BOOL bForInstall) } return ERROR_SUCCESS; -}
\ No newline at end of file +} + +DWORD BaseCom::NotifyService(DWORD dwNotifyCode) +{ + return SendServiceNotification(dwNotifyCode); +} diff --git a/src/Common/BaseCom.h b/src/Common/BaseCom.h index eaf0f8d1..937e37ec 100644 --- a/src/Common/BaseCom.h +++ b/src/Common/BaseCom.h @@ -119,6 +119,8 @@ public: 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); + }; diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index 71d39057..189d5a78 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -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(); diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index 03c30ea7..ddf6f3e5 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -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 diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index fabd39be..ed5d1844 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -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
\ No newline at end of file diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index cdd94938..4a7e40c7 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -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 diff --git a/src/Format/FormatCom.cpp b/src/Format/FormatCom.cpp index 147e4a15..18653761 100644 --- a/src/Format/FormatCom.cpp +++ b/src/Format/FormatCom.cpp @@ -182,6 +182,11 @@ public: return BaseCom::UpdateSetupConfigFile (bForInstall); } + virtual DWORD STDMETHODCALLTYPE NotifyService (DWORD dwNotifyCode) + { + return BaseCom::NotifyService (dwNotifyCode); + } + protected: DWORD MessageThreadId; LONG RefCount; diff --git a/src/Format/FormatCom.idl b/src/Format/FormatCom.idl index 9df43f6e..cae4e155 100644 --- a/src/Format/FormatCom.idl +++ b/src/Format/FormatCom.idl @@ -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); }; [ diff --git a/src/Mount/MainCom.cpp b/src/Mount/MainCom.cpp index 9752255b..9226e15b 100644 --- a/src/Mount/MainCom.cpp +++ b/src/Mount/MainCom.cpp @@ -203,6 +203,11 @@ public: return BaseCom::UpdateSetupConfigFile (bForInstall); } + virtual DWORD STDMETHODCALLTYPE NotifyService (DWORD dwNotifyCode) + { + return BaseCom::NotifyService (dwNotifyCode); + } + protected: DWORD MessageThreadId; LONG RefCount; diff --git a/src/Mount/MainCom.idl b/src/Mount/MainCom.idl index 816868d3..6ad9dd1b 100644 --- a/src/Mount/MainCom.idl +++ b/src/Mount/MainCom.idl @@ -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); }; [ diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 52eda175..83ae9a9c 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -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 ()) diff --git a/src/Mount/Mount.h b/src/Mount/Mount.h index d884ede4..cd2636b1 100644 --- a/src/Mount/Mount.h +++ b/src/Mount/Mount.h @@ -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 diff --git a/src/Setup/ComSetup.cpp b/src/Setup/ComSetup.cpp index 4883eaa1..96734303 100644 --- a/src/Setup/ComSetup.cpp +++ b/src/Setup/ComSetup.cpp @@ -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]; |