/* Derived from source code of TrueCrypt 7.1a, which is Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2016 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "System.h" #include #ifdef TC_WINDOWS #include #endif #include "Common/SecurityToken.h" #include "Main/Main.h" #include "Main/Application.h" #include "Main/GraphicUserInterface.h" #include "Volume/Cipher.h" #include "PreferencesDialog.h" namespace VeraCrypt { PreferencesDialog::PreferencesDialog (wxWindow* parent) : PreferencesDialogBase (parent), LastVirtualKeyPressed (0), Preferences (Gui->GetPreferences()), RestoreValidatorBell (false) { #define TC_CHECK_BOX_VALIDATOR(NAME) (TC_JOIN(NAME,CheckBox))->SetValidator (wxGenericValidator (&Preferences.NAME)); #ifdef TC_MACOSX PreferencesNotebook->SetMinSize (wxSize (Gui->GetCharWidth (PreferencesNotebook) * 108, -1)); #endif // Security TC_CHECK_BOX_VALIDATOR (DismountOnLogOff); TC_CHECK_BOX_VALIDATOR (DismountOnPowerSaving); TC_CHECK_BOX_VALIDATOR (DismountOnScreenSaver); TC_CHECK_BOX_VALIDATOR (DismountOnInactivity); DismountOnInactivitySpinCtrl->SetValidator (wxGenericValidator (&Preferences.MaxVolumeIdleTime)); TC_CHECK_BOX_VALIDATOR (ForceAutoDismount); PreserveTimestampsCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.PreserveTimestamps)); TC_CHECK_BOX_VALIDATOR (WipeCacheOnAutoDismount); TC_CHECK_BOX_VALIDATOR (WipeCacheOnClose); // Mount options CachePasswordsCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.CachePassword)); MountReadOnlyCheckBox->SetValue (Preferences.DefaultMountOptions.Protection == VolumeProtection::ReadOnly); MountRemovableCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.Removable)); FilesystemOptionsTextCtrl->SetValue (Preferences.DefaultMountOptions.FilesystemOptions); TrueCryptModeCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.TrueCryptMode)); int index, prfInitialIndex = 0; Pkcs5PrfChoice->Append (LangString["AUTODETECTION"]); foreach_ref (const Pkcs5Kdf &kdf, Pkcs5Kdf::GetAvailableAlgorithms(false)) { index = Pkcs5PrfChoice->Append (kdf.GetName()); if (Preferences.DefaultMountOptions.Kdf && (Preferences.DefaultMountOptions.Kdf->GetName() == kdf.GetName()) ) { prfInitialIndex = index; } } Pkcs5PrfChoice->Select (prfInitialIndex); // Keyfiles TC_CHECK_BOX_VALIDATOR (UseKeyfiles); DefaultKeyfilesPanel = new KeyfilesPanel (DefaultKeyfilesPage, make_shared (Preferences.DefaultKeyfiles)); DefaultKeyfilesSizer->Add (DefaultKeyfilesPanel, 1, wxALL | wxEXPAND); DefaultKeyfilesSizer->Layout(); TC_CHECK_BOX_VALIDATOR (BackgroundTaskEnabled); TC_CHECK_BOX_VALIDATOR (CloseBackgroundTaskOnNoVolumes); CloseBackgroundTaskOnNoVolumesCheckBox->Show (!Core->IsInPortableMode()); TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuDismountItemsEnabled); TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuMountItemsEnabled); TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuOpenItemsEnabled); // Encryption AesHwCpuSupportedStaticText->SetLabel ( #ifdef TC_AES_HW_CPU (is_aes_hw_cpu_supported() ? LangString["UISTR_YES"] : LangString["UISTR_NO"])); #else LangString["NOT_APPLICABLE_OR_NOT_AVAILABLE"]); #endif NoHardwareCryptoCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.NoHardwareCrypto)); // Security tokens Pkcs11ModulePathTextCtrl->SetValue (wstring (Preferences.SecurityTokenModule)); TC_CHECK_BOX_VALIDATOR (CloseSecurityTokenSessionsAfterMount); // System integration TC_CHECK_BOX_VALIDATOR (StartOnLogon); TC_CHECK_BOX_VALIDATOR (MountDevicesOnLogon); TC_CHECK_BOX_VALIDATOR (MountFavoritesOnLogon); TC_CHECK_BOX_VALIDATOR (CloseExplorerWindowsOnDismount); TC_CHECK_BOX_VALIDATOR (OpenExplorerWindowAfterMount); NoKernelCryptoCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.NoKernelCrypto)); #ifdef TC_WINDOWS // Hotkeys TC_CHECK_BOX_VALIDATOR (BeepAfterHotkeyMountDismount); TC_CHECK_BOX_VALIDATOR (DisplayMessageAfterHotkeyDismount); #endif TransferDataToWindow(); // Code below relies on TransferDataToWindow() called at this point #if defined (TC_WINDOWS) || defined (TC_MACOSX) FilesystemSizer->Show (false); #else // Auto-dismount is not supported on Linux as dismount may require the user to enter admin password AutoDismountSizer->Show (false); WipeCacheOnAutoDismountCheckBox->Show (false); #endif #ifndef TC_WINDOWS LogOnSizer->Show (false); MountRemovableCheckBox->Show (false); CloseExplorerWindowsOnDismountCheckBox->Show (false); #endif #ifndef wxHAS_POWER_EVENTS DismountOnPowerSavingCheckBox->Show (false); #endif #ifdef TC_MACOSX DismountOnScreenSaverCheckBox->Show (false); DismountOnLogOffCheckBox->SetLabel (_("VeraCrypt quits")); OpenExplorerWindowAfterMountCheckBox->SetLabel (_("Open Finder window for successfully mounted volume")); MountRemovableCheckBox->Show (false); FilesystemSizer->Show (false); LogOnSizer->Show (false); CloseExplorerWindowsOnDismountCheckBox->Show (false); #endif #ifndef TC_LINUX KernelServicesSizer->Show (false); #endif #ifdef TC_WINDOWS // Hotkeys list colPermilles; HotkeyListCtrl->InsertColumn (ColumnHotkeyDescription, LangString["ACTION"], wxLIST_FORMAT_LEFT, 1); colPermilles.push_back (642); HotkeyListCtrl->InsertColumn (ColumnHotkey, LangString["SHORTCUT"], wxLIST_FORMAT_LEFT, 1); colPermilles.push_back (358); vector fields (HotkeyListCtrl->GetColumnCount()); UnregisteredHotkeys = Preferences.Hotkeys; Hotkey::UnregisterList (Gui->GetMainFrame(), UnregisteredHotkeys); foreach (shared_ptr hotkey, Preferences.Hotkeys) { fields[ColumnHotkeyDescription] = hotkey->Description; fields[ColumnHotkey] = hotkey->GetShortcutString(); Gui->AppendToListCtrl (HotkeyListCtrl, fields, -1, hotkey.get()); } Gui->SetListCtrlHeight (HotkeyListCtrl, 5); Layout(); Fit(); Gui->SetListCtrlColumnWidths (HotkeyListCtrl, colPermilles); RestoreValidatorBell = !wxTextValidator::IsSilent(); wxTextValidator::SuppressBellOnError (true); HotkeyTextCtrl->SetValidator (wxTextValidator (wxFILTER_INCLUDE_CHAR_LIST)); UpdateHotkeyButtons(); #endif // Page setup for (size_t page = 0; page < PreferencesNotebook->GetPageCount(); page++) { wxNotebookPage *np = PreferencesNotebook->GetPage (page); if (np == HotkeysPage) { #ifndef TC_WINDOWS PreferencesNotebook->RemovePage (page--); continue; #endif } np->Layout(); } Layout(); Fit(); Center(); StdButtonsOK->SetDefault(); #ifdef TC_WINDOWS // Hotkey timer class Timer : public wxTimer { public: Timer (PreferencesDialog *dialog) : Dialog (dialog) { } void Notify() { Dialog->OnTimer(); } PreferencesDialog *Dialog; }; mTimer.reset (dynamic_cast (new Timer (this))); mTimer->Start (25); #endif } PreferencesDialog::~PreferencesDialog () { #ifdef TC_WINDOWS if (RestoreValidatorBell) wxTextValidator::SuppressBellOnError (false); #endif } void PreferencesDialog::SelectPage (wxPanel *page) { for (size_t pageIndex = 0; pageIndex < PreferencesNotebook->GetPageCount(); pageIndex++) { if (PreferencesNotebook->GetPage (pageIndex) == page) PreferencesNotebook->ChangeSelection (pageIndex); } } void PreferencesDialog::OnAssignHotkeyButtonClick (wxCommandEvent& event) { #ifdef TC_WINDOWS foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl)) { Hotkey *hotkey = reinterpret_cast (HotkeyListCtrl->GetItemData (item)); int mods = 0; mods |= HotkeyShiftCheckBox->IsChecked() ? wxMOD_SHIFT : 0; mods |= HotkeyControlCheckBox->IsChecked() ? wxMOD_CONTROL : 0; mods |= HotkeyAltCheckBox->IsChecked() ? wxMOD_ALT : 0; mods |= HotkeyWinCheckBox->IsChecked() ? wxMOD_WIN : 0; // F1 is help and F12 is reserved for use by the debugger at all times if (mods == 0 && (LastVirtualKeyPressed == VK_F1 || LastVirtualKeyPressed == VK_F12)) { Gui->ShowError ("CANNOT_USE_RESERVED_KEY"); return; } // Test if the hotkey can be registered if (!this->RegisterHotKey (hotkey->Id, mods, LastVirtualKeyPressed)) { Gui->ShowError (SystemException (SRC_POS)); return; } UnregisterHotKey (hotkey->Id); foreach_ref (const Hotkey &h, Preferences.Hotkeys) { if (h.Id != hotkey->Id && h.VirtualKeyCode == LastVirtualKeyPressed && h.VirtualKeyModifiers == mods) { Gui->ShowError ("SHORTCUT_ALREADY_IN_USE"); return; } } hotkey->VirtualKeyCode = LastVirtualKeyPressed; hotkey->VirtualKeyModifiers = mods; vector fields (HotkeyListCtrl->GetColumnCount()); fields[ColumnHotkeyDescription] = hotkey->Description; fields[ColumnHotkey] = hotkey->GetShortcutString(); Gui->UpdateListCtrlItem (HotkeyListCtrl, item, fields); UpdateHotkeyButtons(); } #endif // TC_WINDOWS } void PreferencesDialog::OnBackgroundTaskEnabledCheckBoxClick (wxCommandEvent& event) { if (!event.IsChecked()) BackgroundTaskEnabledCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_BACKGROUND_TASK_DISABLED"], false, true)); } void PreferencesDialog::OnNoHardwareCryptoCheckBoxClick (wxCommandEvent& event) { if (event.IsChecked()) { if (Gui->AskYesNo (LangString["CONFIRM_SETTING_DEGRADES_PERFORMANCE"], true, true)) { #ifdef TC_LINUX Gui->ShowWarning (_("Please note that this setting takes effect only if use of the kernel cryptographic services is disabled.")); #endif } else NoHardwareCryptoCheckBox->SetValue (false); } Gui->ShowWarning (_("Please note that any currently mounted volumes need to be remounted before they can use this setting.")); } void PreferencesDialog::OnNoKernelCryptoCheckBoxClick (wxCommandEvent& event) { if (event.IsChecked()) NoKernelCryptoCheckBox->SetValue (Gui->AskYesNo (_("Disabling the use of kernel cryptographic services can degrade performance.\n\nAre you sure?"), false, true)); } void PreferencesDialog::OnClose (wxCloseEvent& event) { #ifdef TC_WINDOWS Hotkey::RegisterList (Gui->GetMainFrame(), UnregisteredHotkeys); #endif event.Skip(); } void PreferencesDialog::OnDismountOnPowerSavingCheckBoxClick (wxCommandEvent& event) { if (event.IsChecked() && !ForceAutoDismountCheckBox->IsChecked()) Gui->ShowWarning ("WARN_PREF_AUTO_DISMOUNT"); } void PreferencesDialog::OnDismountOnScreenSaverCheckBoxClick (wxCommandEvent& event) { if (event.IsChecked() && !ForceAutoDismountCheckBox->IsChecked()) Gui->ShowWarning ("WARN_PREF_AUTO_DISMOUNT"); } void PreferencesDialog::OnForceAutoDismountCheckBoxClick (wxCommandEvent& event) { if (!event.IsChecked()) ForceAutoDismountCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_NO_FORCED_AUTODISMOUNT"], false, true)); } void PreferencesDialog::OnHotkeyListItemDeselected (wxListEvent& event) { UpdateHotkeyButtons(); } void PreferencesDialog::OnHotkeyListItemSelected (wxListEvent& event) { UpdateHotkeyButtons(); HotkeyTextCtrl->ChangeValue (LangString ["PRESS_A_KEY_TO_ASSIGN"]); AssignHotkeyButton->Enable (false); } void PreferencesDialog::OnOKButtonClick (wxCommandEvent& event) { #ifdef TC_WINDOWS HotkeyTextCtrl->SetValidator (wxTextValidator (wxFILTER_NONE)); #endif if (!Validate()) return; shared_ptr selectedKdf; if (Pkcs5PrfChoice->GetSelection () != 0) { try { selectedKdf = Pkcs5Kdf::GetAlgorithm (wstring (Pkcs5PrfChoice->GetStringSelection ()), TrueCryptModeCheckBox->IsChecked ()); } catch (ParameterIncorrect&) { Gui->ShowWarning ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"); return; } } TransferDataFromWindow(); Preferences.DefaultMountOptions.Protection = MountReadOnlyCheckBox->IsChecked() ? VolumeProtection::ReadOnly : VolumeProtection::None; Preferences.DefaultMountOptions.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue(); Preferences.DefaultKeyfiles = *DefaultKeyfilesPanel->GetKeyfiles(); Preferences.DefaultMountOptions.Kdf = selectedKdf; Preferences.DefaultMountOptions.ProtectionKdf = selectedKdf; bool securityTokenModuleChanged = (Preferences.SecurityTokenModule != wstring (Pkcs11ModulePathTextCtrl->GetValue())); Preferences.SecurityTokenModule = wstring (Pkcs11ModulePathTextCtrl->GetValue()); Gui->SetPreferences (Preferences); try { if (securityTokenModuleChanged) { if (Preferences.SecurityTokenModule.IsEmpty()) { if (SecurityToken::IsInitialized()) SecurityToken::CloseLibrary (); } else { Gui->InitSecurityTokenLibrary(); } } } catch (exception &e) { Gui->ShowError (e); } #ifdef TC_WINDOWS // Hotkeys Hotkey::RegisterList (Gui->GetMainFrame(), Preferences.Hotkeys); #endif EndModal (wxID_OK); } void PreferencesDialog::OnPreserveTimestampsCheckBoxClick (wxCommandEvent& event) { #ifdef TC_LINUX if (!event.IsChecked()) Gui->ShowInfo (_("Please note that disabling this option may have no effect on volumes mounted using kernel cryptographic services.")); #endif } void PreferencesDialog::OnRemoveHotkeyButtonClick (wxCommandEvent& event) { #ifdef TC_WINDOWS foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl)) { Hotkey *hotkey = reinterpret_cast (HotkeyListCtrl->GetItemData (item)); hotkey->VirtualKeyCode = 0; hotkey->VirtualKeyModifiers = 0; vector fields (HotkeyListCtrl->GetColumnCount()); fields[ColumnHotkeyDescription] = hotkey->Description; fields[ColumnHotkey] = hotkey->GetShortcutString(); Gui->UpdateListCtrlItem (HotkeyListCtrl, item, fields); UpdateHotkeyButtons(); } #endif } void PreferencesDialog::OnSelectPkcs11ModuleButtonClick (wxCommandEvent& event) { list < pair > extensions; wxString libExtension; libExtension = wxDynamicLibrary::CanonicalizeName (L"x"); #ifdef TC_MACOSX extensions.push_back (make_pair (L"dylib", LangString["DLL_FILES"].ToStdWstring())); #endif if (!libExtension.empty()) { extensions.push_back (make_pair (libExtension.Mid (libExtension.find (L'.') + 1).ToStdWstring(), LangString["DLL_FILES"].ToStdWstring())); extensions.push_back (make_pair (L"*", L"")); } string libDir; #ifdef TC_WINDOWS char sysDir[TC_MAX_PATH]; GetSystemDirectoryA (sysDir, sizeof (sysDir)); libDir = sysDir; #elif defined (TC_MACOSX) libDir = "/usr/local/lib"; #elif defined (TC_UNIX) libDir = "/usr/lib"; #endif Gui->ShowInfo ("SELECT_PKCS11_MODULE_HELP"); FilePathList files = Gui->SelectFiles (this, LangString["SELECT_PKCS11_MODULE"], false, false, extensions, libDir); if (!files.empty()) Pkcs11ModulePathTextCtrl->SetValue (wstring (*files.front())); } void PreferencesDialog::OnTimer () { #ifdef TC_WINDOWS for (UINT vKey = 0; vKey <= 0xFF; vKey++) { if (GetAsyncKeyState (vKey) < 0) { bool shift = wxGetKeyState (WXK_SHIFT); bool control = wxGetKeyState (WXK_CONTROL); bool alt = wxGetKeyState (WXK_ALT); bool win = wxGetKeyState (WXK_WINDOWS_LEFT) || wxGetKeyState (WXK_WINDOWS_RIGHT); if (!Hotkey::GetVirtualKeyCodeString (vKey).empty()) // If the key is allowed and its name has been resolved { LastVirtualKeyPressed = vKey; HotkeyShiftCheckBox->SetValue (shift); HotkeyControlCheckBox->SetValue (control); HotkeyAltCheckBox->SetValue (alt); HotkeyWinCheckBox->SetValue (win); HotkeyTextCtrl->ChangeValue (Hotkey::GetVirtualKeyCodeString (LastVirtualKeyPressed)); UpdateHotkeyButtons(); return; } } } #endif } void PreferencesDialog::UpdateHotkeyButtons() { AssignHotkeyButton->Enable (!HotkeyTextCtrl->IsEmpty() && HotkeyListCtrl->GetSelectedItemCount() > 0); bool remove = false; foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl)) { if (reinterpret_cast (HotkeyListCtrl->GetItemData (item))->VirtualKeyCode != 0) remove = true; } RemoveHotkeyButton->Enable (remove); } } > 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521