diff options
Diffstat (limited to 'src/Main/UserInterface.cpp')
-rw-r--r-- | src/Main/UserInterface.cpp | 364 |
1 files changed, 232 insertions, 132 deletions
diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index c79cef2b..4bb8bcda 100644 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -3,9 +3,9 @@ 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 all other portions of this file are Copyright (c) 2013-2017 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. */ @@ -16,8 +16,9 @@ #include <wx/apptrait.h> #include <wx/cmdline.h> #include "Crypto/cpu.h" #include "Platform/PlatformTest.h" +#include "Common/PCSCException.h" #ifdef TC_UNIX #include <errno.h> #include "Platform/Unix/Process.h" #endif @@ -30,8 +31,17 @@ #include "UserInterface.h" namespace VeraCrypt { + class AdminPasswordRequestHandler : public GetStringFunctor + { + public: + virtual void operator() (string &str) + { + throw ElevationFailed (SRC_POS, "sudo", 1, ""); + } + }; + UserInterface::UserInterface () { } @@ -53,9 +63,9 @@ namespace VeraCrypt #ifdef TC_LINUX if (!Preferences.NonInteractive) { if (!SystemInfo::IsVersionAtLeast (2, 6, 24)) - ShowWarning (_("Your system uses an old version of the Linux kernel.\n\nDue to a bug in the Linux kernel, your system may stop responding when writing data to a VeraCrypt volume. This problem can be solved by upgrading the kernel to version 2.6.24 or later.")); + ShowWarning (LangString["LINUX_KERNEL_OLD"]); } #endif // TC_LINUX } @@ -211,9 +221,9 @@ namespace VeraCrypt if (Preferences.Verbose) { if (!message.IsEmpty()) message += L'\n'; - message += StringFormatter (_("Volume \"{0}\" has been dismounted."), wstring (volume->Path)); + message += StringFormatter (LangString["LINUX_VOL_DISMOUNTED"], wstring (volume->Path)); } } if (twoPassMode && firstPass) @@ -246,16 +256,16 @@ namespace VeraCrypt wxString prop; foreach_ref (const VolumeInfo &volume, volumes) { - prop << _("Slot") << L": " << StringConverter::FromNumber (volume.SlotNumber) << L'\n'; + prop << LangString["TOKEN_SLOT_ID"] << L": " << StringConverter::FromNumber (volume.SlotNumber) << L'\n'; prop << LangString["VOLUME"] << L": " << wstring (volume.Path) << L'\n'; #ifndef TC_WINDOWS prop << LangString["VIRTUAL_DEVICE"] << L": " << wstring (volume.VirtualDevice) << L'\n'; #endif prop << LangString["MOUNT_POINT"] << L": " << wstring (volume.MountPoint) << L'\n'; prop << LangString["SIZE"] << L": " << SizeToString (volume.Size) << L'\n'; - prop << LangString["TYPE"] << L": " << VolumeTypeToString (volume.Type, volume.TrueCryptMode, volume.Protection) << L'\n'; + prop << LangString["TYPE"] << L": " << VolumeTypeToString (volume.Type, volume.Protection) << L'\n'; prop << LangString["READ_ONLY"] << L": " << LangString [volume.Protection == VolumeProtection::ReadOnly ? "UISTR_YES" : "UISTR_NO"] << L'\n'; wxString protection; @@ -354,9 +364,9 @@ namespace VeraCrypt // bad_alloc const bad_alloc *outOfMemory = dynamic_cast <const bad_alloc *> (&ex); if (outOfMemory) - return _("Out of memory."); + return LangString["LINUX_OOM"]; // Unresolved exceptions string typeName (StringConverter::GetTypeName (typeid (ex))); size_t pos = typeName.find ("VeraCrypt::"); @@ -383,14 +393,14 @@ namespace VeraCrypt wstring errOutput; // ElevationFailed if (dynamic_cast <const ElevationFailed*> (&ex)) - errOutput += wxString (_("Failed to obtain administrator privileges")) + (StringConverter::Trim (execEx->GetErrorOutput()).empty() ? L". " : L": "); + errOutput += wxString (LangString["LINUX_CANT_GET_ADMIN_PRIV"]) + (StringConverter::Trim (execEx->GetErrorOutput()).empty() ? L". " : L": "); errOutput += StringConverter::ToWide (execEx->GetErrorOutput()); if (errOutput.empty()) - return errOutput + StringFormatter (_("Command \"{0}\" returned error {1}."), execEx->GetCommand(), execEx->GetExitCode()); + return errOutput + static_cast<wstring>(StringFormatter (LangString["LINUX_COMMAND_GET_ERROR"], execEx->GetCommand(), execEx->GetExitCode())); return wxString (errOutput).Trim (true); } @@ -405,9 +415,9 @@ namespace VeraCrypt #endif if (Keyfile::WasHiddenFilePresentInKeyfilePath()) { #ifdef TC_UNIX - message += _("\n\nWarning: Hidden files are present in a keyfile path. If you need to use them as keyfiles, remove the leading dot from their filenames. Hidden files are visible only if enabled in system options."); + message += LangString["LINUX_HIDDEN_FILES_PRESENT_IN_KEYFILE_PATH"]; #else message += LangString["HIDDEN_FILES_PRESENT_IN_KEYFILE_PATH"]; #endif } @@ -435,66 +445,101 @@ namespace VeraCrypt return LangString["SECURITY_TOKEN_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString); } + + // PCSC Exception + if (dynamic_cast <const PCSCException *> (&ex)) + { + string errorString = string (dynamic_cast <const PCSCException &> (ex)); + + if (LangString.Exists (errorString)) + return LangString[errorString]; + + if (errorString.find("SCARD_E_") == 0 || errorString.find("SCARD_F_") == 0 || errorString.find("SCARD_W_") == 0) + { + errorString = errorString.substr(8); + for (size_t i = 0; i < errorString.size(); ++i) + { + if (errorString[i] == '_') + errorString[i] = ' '; + } + } + return LangString["PCSC_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString); + } + // Other library exceptions return ExceptionTypeToString (typeid (ex)); } wxString UserInterface::ExceptionTypeToString (const std::type_info &ex) { + #define EX2MSG(exception, message) do { if (ex == typeid (exception)) return (message); } while (false) EX2MSG (DriveLetterUnavailable, LangString["DRIVE_LETTER_UNAVAILABLE"]); - EX2MSG (EncryptedSystemRequired, _("This operation must be performed only when the system hosted on the volume is running.")); + EX2MSG (DeviceSectorSizeMismatch, LangString["LINUX_EX2MSG_DEVICESECTORSIZEMISMATCH"]); + EX2MSG (EncryptedSystemRequired, LangString["LINUX_EX2MSG_ENCRYPTEDSYSTEMREQUIRED"]); EX2MSG (ExternalException, LangString["EXCEPTION_OCCURRED"]); - EX2MSG (InsufficientData, _("Not enough data available.")); + EX2MSG (InsufficientData, LangString["LINUX_EX2MSG_INSUFFICIENTDATA"]); EX2MSG (InvalidSecurityTokenKeyfilePath, LangString["INVALID_TOKEN_KEYFILE_PATH"]); EX2MSG (HigherVersionRequired, LangString["NEW_VERSION_REQUIRED"]); - EX2MSG (KernelCryptoServiceTestFailed, _("Kernel cryptographic service test failed. The cryptographic service of your kernel most likely does not support volumes larger than 2 TB.\n\nPossible solutions:\n- Upgrade the Linux kernel to version 2.6.33 or later.\n- Disable use of the kernel cryptographic services (Settings > Preferences > System Integration) or use 'nokernelcrypto' mount option on the command line.")); + EX2MSG (KernelCryptoServiceTestFailed, LangString["LINUX_EX2MSG_KERNELCRYPTOSERVICETESTFAILED"]); EX2MSG (KeyfilePathEmpty, LangString["ERR_KEYFILE_PATH_EMPTY"]); - EX2MSG (LoopDeviceSetupFailed, _("Failed to set up a loop device.")); - EX2MSG (MissingArgument, _("A required argument is missing.")); - EX2MSG (MissingVolumeData, _("Volume data missing.")); - EX2MSG (MountPointRequired, _("Mount point required.")); - EX2MSG (MountPointUnavailable, _("Mount point is already in use.")); + EX2MSG (LoopDeviceSetupFailed, LangString["LINUX_EX2MSG_LOOPDEVICESETUPFAILED"]); + EX2MSG (MissingArgument, LangString["LINUX_EX2MSG_MISSINGARGUMENT"]); + EX2MSG (MissingVolumeData, LangString["LINUX_EX2MSG_MISSINGVOLUMEDATA"]); + EX2MSG (MountPointRequired, LangString["LINUX_EX2MSG_MOUNTPOINTREQUIRED"]); + EX2MSG (MountPointUnavailable, LangString["LINUX_EX2MSG_MOUNTPOINTUNAVAILABLE"]); EX2MSG (NoDriveLetterAvailable, LangString["NO_FREE_DRIVES"]); - EX2MSG (PasswordEmpty, _("No password or keyfile specified.")); + EX2MSG (PasswordEmpty, LangString["LINUX_EX2MSG_PASSWORDEMPTY"]); EX2MSG (PasswordIncorrect, LangString["PASSWORD_WRONG"]); EX2MSG (PasswordKeyfilesIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"]); - EX2MSG (PasswordOrKeyboardLayoutIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"] + _("\n\nNote that pre-boot authentication passwords need to be typed in the pre-boot environment where non-US keyboard layouts are not available. Therefore, pre-boot authentication passwords must always be typed using the standard US keyboard layout (otherwise, the password will be typed incorrectly in most cases). However, note that you do NOT need a real US keyboard; you just need to change the keyboard layout in your operating system.")); - EX2MSG (PasswordOrMountOptionsIncorrect, LangString["PASSWORD_OR_KEYFILE_OR_MODE_WRONG"] + _("\n\nNote: If you are attempting to mount a partition located on an encrypted system drive without pre-boot authentication or to mount the encrypted system partition of an operating system that is not running, you can do so by selecting 'Options >' > 'Mount partition using system encryption'.")); - EX2MSG (PasswordTooLong, StringFormatter (_("Password is longer than {0} characters."), (int) VolumePassword::MaxSize)); - EX2MSG (PasswordUTF8TooLong, LangString["PASSWORD_UTF8_TOO_LONG"]); + EX2MSG (PasswordOrKeyboardLayoutIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"] + LangString["LINUX_EX2MSG_PASSWORDORKEYBOARDLAYOUTINCORRECT"]); + EX2MSG (PasswordOrMountOptionsIncorrect, LangString["PASSWORD_OR_KEYFILE_OR_MODE_WRONG"] + LangString["LINUX_EX2MSG_PASSWORDORMOUNTOPTIONSINCORRECT"]); + EX2MSG (PasswordTooLong, StringFormatter (LangString["LINUX_EX2MSG_PASSWORDTOOLONG"], (int) VolumePassword::MaxSize)); + EX2MSG (PasswordUTF8TooLong, StringFormatter (LangString["PASSWORD_UTF8_TOO_LONG"], (int) VolumePassword::MaxSize)); + EX2MSG (PasswordLegacyUTF8TooLong, StringFormatter (LangString["LEGACY_PASSWORD_UTF8_TOO_LONG"], (int) VolumePassword::MaxLegacySize)); EX2MSG (PasswordUTF8Invalid, LangString["PASSWORD_UTF8_INVALID"]); - EX2MSG (PartitionDeviceRequired, _("Partition device required.")); - EX2MSG (ProtectionPasswordIncorrect, _("Incorrect password to the protected hidden volume or the hidden volume does not exist.")); - EX2MSG (ProtectionPasswordKeyfilesIncorrect,_("Incorrect keyfile(s) and/or password to the protected hidden volume or the hidden volume does not exist.")); + EX2MSG (PartitionDeviceRequired, LangString["LINUX_EX2MSG_PARTITIONDEVICEREQUIRED"]); + EX2MSG (ProtectionPasswordIncorrect, LangString["LINUX_EX2MSG_PROTECTIONPASSWORDINCORRECT"]); + EX2MSG (ProtectionPasswordKeyfilesIncorrect, LangString["LINUX_EX2MSG_PROTECTIONPASSWORDKEYFILESINCORRECT"]); EX2MSG (RootDeviceUnavailable, LangString["NODRIVER"]); EX2MSG (SecurityTokenKeyfileAlreadyExists, LangString["TOKEN_KEYFILE_ALREADY_EXISTS"]); EX2MSG (SecurityTokenKeyfileNotFound, LangString["TOKEN_KEYFILE_NOT_FOUND"]); EX2MSG (SecurityTokenLibraryNotInitialized, LangString["PKCS11_MODULE_INIT_FAILED"]); - EX2MSG (StringConversionFailed, _("Invalid characters encountered.")); - EX2MSG (StringFormatterException, _("Error while parsing formatted string.")); - EX2MSG (TemporaryDirectoryFailure, _("Failed to create a file or directory in a temporary directory.\n\nPlease make sure that the temporary directory exists, its security permissions allow you to access it, and there is sufficient disk space.")); + EX2MSG (StringConversionFailed, LangString["LINUX_EX2MSG_STRINGCONVERSIONFAILED"]); + EX2MSG (StringFormatterException, LangString["LINUX_EX2MSG_STRINGFORMATTEREXCEPTION"]); + EX2MSG (TemporaryDirectoryFailure, LangString["LINUX_EX2MSG_TEMPORARYDIRECTORYFAILURE"]); EX2MSG (UnportablePassword, LangString["UNSUPPORTED_CHARS_IN_PWD"]); + EX2MSG (CommandAPDUNotValid, LangString["COMMAND_APDU_INVALID"]); + EX2MSG (ExtendedAPDUNotSupported, LangString["EXTENDED_APDU_UNSUPPORTED"]); + EX2MSG (ScardLibraryInitializationFailed, LangString["SCARD_MODULE_INIT_FAILED"]); + EX2MSG (EMVUnknownCardType, LangString["EMV_UNKNOWN_CARD_TYPE"]); + EX2MSG (EMVSelectAIDFailed, LangString["EMV_SELECT_AID_FAILED"]); + EX2MSG (EMVIccCertNotFound, LangString["EMV_ICC_CERT_NOTFOUND"]); + EX2MSG (EMVIssuerCertNotFound, LangString["EMV_ISSUER_CERT_NOTFOUND"]); + EX2MSG (EMVCPLCNotFound, LangString["EMV_CPLC_NOTFOUND"]); + EX2MSG (InvalidEMVPath, LangString["INVALID_EMV_PATH"]); + EX2MSG (EMVKeyfileDataNotFound, LangString["EMV_KEYFILE_DATA_NOTFOUND"]); + EX2MSG (EMVPANNotFound, LangString["EMV_PAN_NOTFOUND"]); + #if defined (TC_LINUX) + EX2MSG (TerminalNotFound, LangString["LINUX_EX2MSG_TERMINALNOTFOUND"]); EX2MSG (UnsupportedSectorSize, LangString["SECTOR_SIZE_UNSUPPORTED"]); - EX2MSG (UnsupportedSectorSizeHiddenVolumeProtection, _("Error: The drive uses a sector size other than 512 bytes.\n\nDue to limitations of components available on your platform, outer volumes hosted on the drive cannot be mounted using hidden volume protection.\n\nPossible solutions:\n- Use a drive with 512-byte sectors.\n- Create a file-hosted volume (container) on the drive.\n- Backup the contents of the hidden volume and then update the outer volume.")); - EX2MSG (UnsupportedSectorSizeNoKernelCrypto, _("Error: The drive uses a sector size other than 512 bytes.\n\nDue to limitations of components available on your platform, partition/device-hosted volumes on the drive can only be mounted using kernel cryptographic services.\n\nPossible solutions:\n- Enable use of the kernel cryptographic services (Preferences > System Integration).\n- Use a drive with 512-byte sectors.\n- Create a file-hosted volume (container) on the drive.")); + EX2MSG (UnsupportedSectorSizeHiddenVolumeProtection, LangString["LINUX_EX2MSG_UNSUPPORTEDSECTORSIZEHIDDENVOLUMEPROTECTION"]); + EX2MSG (UnsupportedSectorSizeNoKernelCrypto, LangString["LINUX_EX2MSG_UNSUPPORTEDSECTORSIZENOKERNELCRYPTO"]); #else - EX2MSG (UnsupportedSectorSize, _("Error: The drive uses a sector size other than 512 bytes.\n\nDue to limitations of components available on your platform, partition/device-hosted volumes cannot be created/used on the drive.\n\nPossible solutions:\n- Create a file-hosted volume (container) on the drive.\n- Use a drive with 512-byte sectors.\n- Use VeraCrypt on another platform.")); + EX2MSG (UnsupportedSectorSize, LangString["LINUX_EX2MSG_UNSUPPORTEDSECTORSIZE"]); #endif EX2MSG (VolumeAlreadyMounted, LangString["VOL_ALREADY_MOUNTED"]); EX2MSG (VolumeEncryptionNotCompleted, LangString["ERR_ENCRYPTION_NOT_COMPLETED"]); - EX2MSG (VolumeHostInUse, _("The host file/device is already in use.")); - EX2MSG (VolumeSlotUnavailable, _("Volume slot unavailable.")); - EX2MSG (UnsupportedAlgoInTrueCryptMode, LangString["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]); - EX2MSG (UnsupportedTrueCryptFormat, LangString["UNSUPPORTED_TRUECRYPT_FORMAT"]); + EX2MSG (VolumeHostInUse, LangString["LINUX_EX2MSG_VOLUMEHOSTINUSE"]); + EX2MSG (VolumeSlotUnavailable, LangString["LINUX_EX2MSG_VOLUMESLOTUNAVAILABLE"]); #ifdef TC_MACOSX - EX2MSG (HigherFuseVersionRequired, _("VeraCrypt requires OSXFUSE 2.5 or above.")); + EX2MSG (HigherFuseVersionRequired, LangString["LINUX_EX2MSG_HIGHERFUSEVERSIONREQUIRED"]); #endif #undef EX2MSG return L""; @@ -521,19 +566,13 @@ namespace VeraCrypt Core->SetAdminPasswordCallback (GetAdminPasswordRequestHandler()); } else { - struct AdminPasswordRequestHandler : public GetStringFunctor - { - virtual void operator() (string &str) - { - throw ElevationFailed (SRC_POS, "sudo", 1, ""); - } - }; - Core->SetAdminPasswordCallback (shared_ptr <GetStringFunctor> (new AdminPasswordRequestHandler)); } + Core->ForceUseDummySudoPassword (CmdLine->ArgUseDummySudoPassword); + Core->WarningEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnWarning)); Core->VolumeMountedEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnVolumeMounted)); if (!CmdLine->Preferences.SecurityTokenModule.IsEmpty() && !SecurityToken::IsInitialized()) @@ -595,20 +634,24 @@ namespace VeraCrypt HostDeviceList devices; foreach (shared_ptr <HostDevice> device, Core->GetHostDevices (true)) { - devices.push_back (device); - - foreach (shared_ptr <HostDevice> partition, device->Partitions) - devices.push_back (partition); + if (device->Partitions.empty()) + devices.push_back (device); + else + { + foreach (shared_ptr <HostDevice> partition, device->Partitions) + devices.push_back (partition); + } } set <wstring> mountedVolumes; foreach_ref (const VolumeInfo &v, Core->GetMountedVolumes()) mountedVolumes.insert (v.Path); bool protectedVolumeMounted = false; bool legacyVolumeMounted = false; + bool vulnerableVolumeMounted = false; foreach_ref (const HostDevice &device, devices) { if (mountedVolumes.find (wstring (device.Path)) != mountedVolumes.end()) @@ -649,8 +692,12 @@ namespace VeraCrypt protectedVolumeMounted = true; if (newMountedVolumes.back()->EncryptionAlgorithmMinBlockSize == 8) legacyVolumeMounted = true; + + if (newMountedVolumes.back()->MasterKeyVulnerable) + vulnerableVolumeMounted = true; + } catch (DriverError&) { } catch (MissingVolumeData&) { } catch (PasswordException&) { } @@ -663,8 +710,11 @@ namespace VeraCrypt ShowWarning (LangString [options.Keyfiles && !options.Keyfiles->empty() ? "PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT" : "PASSWORD_WRONG_AUTOMOUNT"]); } else { + if (vulnerableVolumeMounted) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + if (someVolumesShared) ShowWarning ("DEVICE_IN_USE_INFO"); if (legacyVolumeMounted) @@ -696,19 +746,22 @@ namespace VeraCrypt } favorite.ToMountOptions (options); + bool mountPerformed = false; if (Preferences.NonInteractive) { BusyScope busy (this); newMountedVolumes.push_back (Core->MountVolume (options)); + mountPerformed = true; } else { try { BusyScope busy (this); newMountedVolumes.push_back (Core->MountVolume (options)); + mountPerformed = true; } catch (...) { UserPreferences prefs = GetPreferences(); @@ -724,8 +777,11 @@ namespace VeraCrypt break; newMountedVolumes.push_back (volume); } } + + if (mountPerformed && newMountedVolumes.back()->MasterKeyVulnerable) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); } if (!newMountedVolumes.empty() && GetPreferences().CloseSecurityTokenSessionsAfterMount) SecurityToken::CloseAllSessions(); @@ -760,8 +816,11 @@ namespace VeraCrypt throw_err (LangString["FILE_IN_USE_FAILED"]); } } + if (volume->MasterKeyVulnerable) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + if (volume->EncryptionAlgorithmMinBlockSize == 8) ShowWarning ("WARN_64_BIT_BLOCK_CIPHER"); if (VolumeHasUnrecommendedExtension (*options.Path)) @@ -790,9 +849,9 @@ namespace VeraCrypt ShowError (e); } catch (...) { - ShowError (_("Unknown exception occurred.")); + ShowError (LangString["LINUX_UNKNOWN_EXC_OCCURRED"]); } Yield(); Application::SetExitCode (1); @@ -811,8 +870,16 @@ namespace VeraCrypt ExceptionEventArgs &e = dynamic_cast <ExceptionEventArgs &> (args); ShowWarning (e.mException); } +#if !defined(TC_WINDOWS) && !defined(TC_MACOSX) +// Function to check if a given executable exists and is executable +static bool IsExecutable(const string& exe) { + return wxFileName::IsFileExecutable("/usr/bin/" + exe) || + wxFileName::IsFileExecutable("/usr/local/bin/" + exe); +} +#endif + void UserInterface::OpenExplorerWindow (const DirectoryPath &path) { if (path.IsEmpty()) return; @@ -835,62 +902,60 @@ namespace VeraCrypt } catch (exception &e) { ShowError (e); } #else - // MIME handler for directory seems to be unavailable through wxWidgets - wxString desktop = GetTraits()->GetDesktopEnvironment(); - bool xdgOpenPresent = wxFileName::IsFileExecutable (wxT("/usr/bin/xdg-open")) || wxFileName::IsFileExecutable (wxT("/usr/local/bin/xdg-open")); - bool nautilusPresent = wxFileName::IsFileExecutable (wxT("/usr/bin/nautilus")) || wxFileName::IsFileExecutable (wxT("/usr/local/bin/nautilus")); - - if (desktop == L"GNOME" || (desktop.empty() && !xdgOpenPresent && nautilusPresent)) - { - // args.push_back ("--no-default-window"); // This option causes nautilus not to launch under FreeBSD 11 - args.push_back ("--no-desktop"); - args.push_back (string (path)); - try - { - Process::Execute ("nautilus", args, 2000); + string directoryPath = string(path); + // Primary attempt: Use xdg-open + if (IsExecutable("xdg-open")) { + try { + args.push_back(directoryPath); + Process::Execute("xdg-open", args, 2000); + return; } catch (TimeOut&) { } - catch (exception &e) { ShowError (e); } + catch (exception&) {} } - else if (desktop == L"KDE") - { - try - { - args.push_back (string (path)); - Process::Execute ("dolphin", args, 2000); - } - catch (TimeOut&) { } - catch (exception&) - { + + // Fallback attempts: Try known file managers + const char* fallbackFileManagers[] = { "gio", "kioclient5", "kfmclient", "exo-open", "nautilus", "dolphin", "caja", "thunar", "pcmanfm" }; + const size_t numFileManagers = sizeof(fallbackFileManagers) / sizeof(fallbackFileManagers[0]); + + for (size_t i = 0; i < numFileManagers; ++i) { + const char* fm = fallbackFileManagers[i]; + if (IsExecutable(fm)) { args.clear(); - args.push_back ("openURL"); - args.push_back (string (path)); - try - { - Process::Execute ("kfmclient", args, 2000); + if (strcmp(fm, "gio") == 0) { + args.push_back("open"); + args.push_back(directoryPath); + } + else if (strcmp(fm, "kioclient5") == 0) { + args.push_back("exec"); + args.push_back(directoryPath); + } + else if (strcmp(fm, "kfmclient") == 0) { + args.push_back("openURL"); + args.push_back(directoryPath); + } + else if (strcmp(fm, "exo-open") == 0) { + args.push_back("--launch"); + args.push_back("FileManager"); + args.push_back(directoryPath); + } + else { + args.push_back(directoryPath); + } + + try { + Process::Execute(fm, args, 2000); + return; // Success } catch (TimeOut&) { } - catch (exception &e) { ShowError (e); } + catch (exception &) {} } } - else if (xdgOpenPresent) - { - // Fallback on the standard xdg-open command - // which is not always available by default - args.push_back (string (path)); - try - { - Process::Execute ("xdg-open", args, 2000); - } - catch (TimeOut&) { } - catch (exception &e) { ShowError (e); } - } - else - { - ShowWarning (wxT("Unable to find a file manager to open the mounted volume")); - } + + ShowWarning(wxT("Unable to find a file manager to open the mounted volume.\n" + "Please install xdg-utils or set a default file manager.")); #endif } bool UserInterface::ProcessCommandLine () @@ -904,9 +969,10 @@ namespace VeraCrypt { wstring pwdInput; getline(wcin, pwdInput); - cmdLine.ArgPassword = ToUTF8Password ( pwdInput.c_str (), pwdInput.size ()); + size_t maxUtf8Len = cmdLine.ArgUseLegacyPassword? VolumePassword::MaxLegacySize : VolumePassword::MaxSize; + cmdLine.ArgPassword = ToUTF8Password ( pwdInput.c_str (), pwdInput.size (), maxUtf8Len); } switch (cmdLine.ArgCommand) { @@ -920,12 +986,11 @@ namespace VeraCrypt cmdLine.ArgMountOptions.Password = cmdLine.ArgPassword; cmdLine.ArgMountOptions.Pim = cmdLine.ArgPim; cmdLine.ArgMountOptions.Keyfiles = cmdLine.ArgKeyfiles; cmdLine.ArgMountOptions.SharedAccessAllowed = cmdLine.ArgForce; - cmdLine.ArgMountOptions.TrueCryptMode = cmdLine.ArgTrueCryptMode; if (cmdLine.ArgHash) { - cmdLine.ArgMountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash, cmdLine.ArgTrueCryptMode); + cmdLine.ArgMountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash); } VolumeInfoList mountedVolumes; @@ -996,9 +1061,9 @@ namespace VeraCrypt foreach_ref (const VolumeInfo &volume, mountedVolumes) { if (!message.IsEmpty()) message += L'\n'; - message += StringFormatter (_("Volume \"{0}\" has been mounted."), wstring (volume.Path)); + message += StringFormatter (LangString["LINUX_VOL_MOUNTED"], wstring (volume.Path)); } ShowInfo (message); } } @@ -1008,9 +1073,9 @@ namespace VeraCrypt BackupVolumeHeaders (cmdLine.ArgVolumePath); return true; case CommandId::ChangePassword: - ChangePassword (cmdLine.ArgVolumePath, cmdLine.ArgPassword, cmdLine.ArgPim, cmdLine.ArgHash, cmdLine.ArgTrueCryptMode, cmdLine.ArgKeyfiles, cmdLine.ArgNewPassword, cmdLine.ArgNewPim, cmdLine.ArgNewKeyfiles, cmdLine.ArgNewHash); + ChangePassword (cmdLine.ArgVolumePath, cmdLine.ArgPassword, cmdLine.ArgPim, cmdLine.ArgHash, cmdLine.ArgKeyfiles, cmdLine.ArgNewPassword, cmdLine.ArgNewPim, cmdLine.ArgNewKeyfiles, cmdLine.ArgNewHash); return true; case CommandId::CreateKeyfile: CreateKeyfile (cmdLine.ArgFilePath); @@ -1021,9 +1086,9 @@ namespace VeraCrypt make_shared_auto (VolumeCreationOptions, options); if (cmdLine.ArgHash) { - options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash, false); + options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash); RandomNumberGenerator::SetHash (cmdLine.ArgHash); } options->EA = cmdLine.ArgEncryptionAlgorithm; @@ -1109,9 +1174,9 @@ namespace VeraCrypt "--delete-token-keyfiles\n" " Delete keyfiles from security tokens. See also command --list-token-keyfiles.\n" "\n" "--export-token-keyfile\n" - " Export a keyfile from a security token. See also command --list-token-keyfiles.\n" + " Export a keyfile from a token. See also command --list-token-keyfiles.\n" "\n" "--import-token-keyfiles\n" " Import keyfiles to a security token. See also option --token-lib.\n" "\n" @@ -1121,11 +1186,17 @@ namespace VeraCrypt " device, and mount point. A more detailed list can be enabled by verbose\n" " output option (-v). See below for description of MOUNTED_VOLUME.\n" "\n" "--list-token-keyfiles\n" - " Display a list of all available security token keyfiles. See also command\n" + " Display a list of all available token keyfiles. See also command\n" " --import-token-keyfiles.\n" - "\n" + "\n""--list-securitytoken-keyfiles\n" + " Display a list of all available security token keyfiles. See also command\n" + " --import-token-keyfiles.\n" + "\n" + "\n""--list-emvtoken-keyfiles\n" + " Display a list of all available emv token keyfiles. See also command\n" + "\n" "--mount[=VOLUME_PATH]\n" " Mount a volume. Volume path and other options are requested from the user\n" " if not specified on command line.\n" "\n" @@ -1158,9 +1229,10 @@ namespace VeraCrypt "--display-password\n" " Display password characters while typing.\n" "\n" "--encryption=ENCRYPTION_ALGORITHM\n" - " Use specified encryption algorithm when creating a new volume.\n" + " Use specified encryption algorithm when creating a new volume. When cascading\n" + " algorithms, they must be separated by a dash. For example: AES-Twofish.\n" "\n" "--filesystem=TYPE\n" " Filesystem type to mount. The TYPE argument is passed to mount(8) command\n" " with option -t. Default type is 'auto'. When creating a new volume, this\n" @@ -1186,11 +1258,14 @@ namespace VeraCrypt " and/or keyfiles. When a directory is specified, all files inside it will be\n" " used (non-recursively). Multiple keyfiles must be separated by comma.\n" " Use double comma (,,) to specify a comma contained in keyfile's name.\n" " Keyfile stored on a security token must be specified as\n" - " token://slot/SLOT_NUMBER/file/FILENAME. An empty keyfile (-k \"\") disables\n" + " token://slot/SLOT_NUMBER/file/FILENAME for a security token keyfile\n" + " and emv://slot/SLOT_NUMBER for an EMV token keyfile.\n" + " An empty keyfile (-k \"\") disables\n" " interactive requests for keyfiles. See also options --import-token-keyfiles,\n" - " --list-token-keyfiles, --new-keyfiles, --protection-keyfiles.\n" + " --list-token-keyfiles, --list-securitytoken-keyfiles, --list-emvtoken-keyfiles,\n" + " --new-keyfiles, --protection-keyfiles.\n" "\n" "--load-preferences\n" " Load user preferences.\n" "\n" @@ -1212,14 +1287,22 @@ namespace VeraCrypt "\n" "--new-password=PASSWORD\n" " Specifies a new password. This option can only be used with command -C.\n" "\n" + "--new-pim=PIM\n" + " Specifies a new PIM. This option can only be used with command -C.\n" + "\n" "-p, --password=PASSWORD\n" " Use specified password to mount/open a volume. An empty password can also be\n" " specified (-p \"\"). Note that passing a password on the command line is\n" " potentially insecure as the password may be visible in the process list\n" " (see ps(1)) and/or stored in a command history file or system logs.\n" "\n" + "--pim=PIM\n" + " Use specified PIM to mount/open a volume. Note that passing a PIM on the \n" + " command line is potentially insecure as the PIM may be visible in the process \n" + " list (see ps(1)) and/or stored in a command history file or system logs.\n" + "\n" "--protect-hidden=yes|no\n" " Write-protect a hidden volume when mounting an outer volume. Before mounting\n" " the outer volume, the user will be prompted for a password to open the hidden\n" " volume. The size and position of the hidden volume is then determined and the\n" @@ -1250,22 +1333,18 @@ namespace VeraCrypt "\n" "--slot=SLOT\n" " Use specified slot number when mounting, dismounting, or listing a volume.\n" "\n" - "--size=SIZE[K|M|G|T]\n" + "--size=SIZE[K|KiB|M|MiB|G|GiB|T|TiB] or --size=max\n" " Use specified size when creating a new volume. If no suffix is indicated,\n" " then SIZE is interpreted in bytes. Suffixes K, M, G or T can be used to\n" - " indicate a value in KB, MB, GB or TB respectively.\n" + " indicate a value in KiB, MiB, GiB or TiB respectively.\n" + " If max is specified, the new volume will use all available free disk space.\n" "\n" "-t, --text\n" " Use text user interface. Graphical user interface is used by default if\n" " available. This option must be specified as the first argument.\n" "\n" - "-tc, --truecrypt\n" - " Enable TrueCrypt compatibility mode to enable mounting volumes created\n" - " by TrueCrypt 6.x or 7.x. This option must be specified as the first\n" - " argument, or immediately after --text.\n" - "\n" "--token-lib=LIB_PATH\n" " Use specified PKCS #11 security token library.\n" "\n" "--volume-type=TYPE\n" @@ -1289,27 +1368,27 @@ namespace VeraCrypt "Mount a volume:\n" "veracrypt volume.hc /media/veracrypt1\n" "\n" "Mount a volume as read-only, using keyfiles:\n" - "veracrypt -m ro -k keyfile1,keyfile2 volume.tc\n" + "veracrypt -m ro -k keyfile1,keyfile2 volume.hc\n" "\n" "Mount a volume without mounting its filesystem:\n" - "veracrypt --filesystem=none volume.tc\n" + "veracrypt --filesystem=none volume.hc\n" "\n" "Mount a volume prompting only for its password:\n" - "veracrypt -t -k \"\" --protect-hidden=no volume.hc /media/veracrypt1\n" + "veracrypt -t -k \"\" --pim=0 --protect-hidden=no volume.hc /media/veracrypt1\n" "\n" "Dismount a volume:\n" - "veracrypt -d volume.tc\n" + "veracrypt -d volume.hc\n" "\n" "Dismount all mounted volumes:\n" "veracrypt -d\n" ); #ifndef TC_NO_GUI if (Application::GetUserInterfaceType() == UserInterfaceType::Graphic) { - wxDialog dialog (nullptr, wxID_ANY, _("VeraCrypt Command Line Help"), wxDefaultPosition); + wxDialog dialog (nullptr, wxID_ANY, LangString["LINUX_CMD_HELP"], wxDefaultPosition); wxTextCtrl *textCtrl = new wxTextCtrl (&dialog, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY); textCtrl->SetFont (wxFont (wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Courier")); textCtrl->SetValue (helpText); @@ -1319,9 +1398,9 @@ namespace VeraCrypt dialog.SetSize (wxSize (fontWidth * 85, fontHeight * 29)); wxBoxSizer *sizer = new wxBoxSizer (wxVERTICAL); sizer->Add (textCtrl, 1, wxALL | wxEXPAND, 5); - sizer->Add (new wxButton (&dialog, wxID_OK, _("OK")), 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 5); + sizer->Add (new wxButton (&dialog, wxID_OK, LangString["IDOK"]), 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 5); dialog.SetSizer (sizer); dialog.Layout(); dialog.ShowModal(); @@ -1334,20 +1413,28 @@ namespace VeraCrypt } } return true; - case CommandId::ExportSecurityTokenKeyfile: - ExportSecurityTokenKeyfile(); + case CommandId::ExportTokenKeyfile: + ExportTokenKeyfile(); return true; - case CommandId::ImportSecurityTokenKeyfiles: - ImportSecurityTokenKeyfiles(); + case CommandId::ImportTokenKeyfiles: + ImportTokenKeyfiles(); return true; - case CommandId::ListSecurityTokenKeyfiles: - ListSecurityTokenKeyfiles(); + case CommandId::ListTokenKeyfiles: + ListTokenKeyfiles(); return true; + case CommandId::ListSecurityTokenKeyfiles: + ListSecurityTokenKeyfiles(); + return true; + + case CommandId::ListEMVTokenKeyfiles: + ListEMVTokenKeyfiles(); + return true; + case CommandId::ListVolumes: if (Preferences.Verbose) DisplayVolumeProperties (cmdLine.ArgVolumes); else @@ -1450,9 +1537,9 @@ namespace VeraCrypt EncryptionTest::TestAll(); // StringFormatter - if (StringFormatter (L"{9} {8} {7} {6} {5} {4} {3} {2} {1} {0} {{0}}", "1", L"2", '3', L'4', 5, 6, 7, 8, 9, 10) != L"10 9 8 7 6 5 4 3 2 1 {0}") + if (static_cast<wstring>(StringFormatter (L"{9} {8} {7} {6} {5} {4} {3} {2} {1} {0} {{0}}", "1", L"2", '3', L'4', 5, 6, 7, 8, 9, 10)) != L"10 9 8 7 6 5 4 3 2 1 {0}") throw TestFailed (SRC_POS); try { StringFormatter (L"{0} {1}", 1); @@ -1527,9 +1614,9 @@ namespace VeraCrypt #endif return dateStr; } - wxString UserInterface::VolumeTypeToString (VolumeType::Enum type, bool truecryptMode, VolumeProtection::Enum protection) const + wxString UserInterface::VolumeTypeToString (VolumeType::Enum type, VolumeProtection::Enum protection) const { wxString sResult; switch (type) { @@ -1545,10 +1632,8 @@ namespace VeraCrypt sResult = L"?"; break; } - if (truecryptMode) - sResult = wxT("TrueCrypt-") + sResult; return sResult; } #define VC_CONVERT_EXCEPTION(NAME) if (dynamic_cast<NAME*> (ex)) throw (NAME&) *ex; @@ -1563,14 +1648,16 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); VC_CONVERT_EXCEPTION (PasswordEmpty); VC_CONVERT_EXCEPTION (PasswordTooLong); VC_CONVERT_EXCEPTION (PasswordUTF8TooLong); + VC_CONVERT_EXCEPTION (PasswordLegacyUTF8TooLong); VC_CONVERT_EXCEPTION (PasswordUTF8Invalid); VC_CONVERT_EXCEPTION (UnportablePassword); VC_CONVERT_EXCEPTION (ElevationFailed); VC_CONVERT_EXCEPTION (RootDeviceUnavailable); VC_CONVERT_EXCEPTION (DriveLetterUnavailable); VC_CONVERT_EXCEPTION (DriverError); + VC_CONVERT_EXCEPTION (DeviceSectorSizeMismatch); VC_CONVERT_EXCEPTION (EncryptedSystemRequired); VC_CONVERT_EXCEPTION (HigherFuseVersionRequired); VC_CONVERT_EXCEPTION (KernelCryptoServiceTestFailed); VC_CONVERT_EXCEPTION (LoopDeviceSetupFailed); @@ -1597,8 +1684,9 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (ParameterIncorrect); VC_CONVERT_EXCEPTION (ParameterTooLarge); VC_CONVERT_EXCEPTION (PartitionDeviceRequired); VC_CONVERT_EXCEPTION (StringConversionFailed); + VC_CONVERT_EXCEPTION (TerminalNotFound); VC_CONVERT_EXCEPTION (TestFailed); VC_CONVERT_EXCEPTION (TimeOut); VC_CONVERT_EXCEPTION (UnknownException); VC_CONVERT_EXCEPTION (UserAbort) @@ -1617,13 +1705,25 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (InvalidSecurityTokenKeyfilePath); VC_CONVERT_EXCEPTION (SecurityTokenLibraryNotInitialized); VC_CONVERT_EXCEPTION (SecurityTokenKeyfileAlreadyExists); VC_CONVERT_EXCEPTION (SecurityTokenKeyfileNotFound); - VC_CONVERT_EXCEPTION (UnsupportedAlgoInTrueCryptMode); - VC_CONVERT_EXCEPTION (UnsupportedTrueCryptFormat); VC_CONVERT_EXCEPTION (SystemException); VC_CONVERT_EXCEPTION (CipherException); VC_CONVERT_EXCEPTION (VolumeException); VC_CONVERT_EXCEPTION (PasswordException); + + VC_CONVERT_EXCEPTION (PCSCException); + VC_CONVERT_EXCEPTION (CommandAPDUNotValid); + VC_CONVERT_EXCEPTION (ExtendedAPDUNotSupported); + VC_CONVERT_EXCEPTION (ScardLibraryInitializationFailed); + VC_CONVERT_EXCEPTION (EMVUnknownCardType); + VC_CONVERT_EXCEPTION (EMVSelectAIDFailed); + VC_CONVERT_EXCEPTION (EMVIccCertNotFound); + VC_CONVERT_EXCEPTION (EMVIssuerCertNotFound); + VC_CONVERT_EXCEPTION (EMVCPLCNotFound); + VC_CONVERT_EXCEPTION (InvalidEMVPath); + VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound); + VC_CONVERT_EXCEPTION (EMVPANNotFound); + throw *ex; } } |