VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Main/UserInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Main/UserInterface.cpp')
-rw-r--r--src/Main/UserInterface.cpp201
1 files changed, 127 insertions, 74 deletions
diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp
index 8d046f87..b507d9a3 100644
--- a/src/Main/UserInterface.cpp
+++ b/src/Main/UserInterface.cpp
@@ -2,11 +2,11 @@
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-2017 IDRIX
+ and all other portions of this file are Copyright (c) 2013-2025 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.
*/
@@ -30,10 +30,19 @@
#include "FavoriteVolume.h"
#include "UserInterface.h"
namespace VeraCrypt
{
+ class AdminPasswordRequestHandler : public GetStringFunctor
+ {
+ public:
+ virtual void operator() (string &str)
+ {
+ throw ElevationFailed (SRC_POS, "sudo", 1, "");
+ }
+ };
+
UserInterface::UserInterface ()
{
}
UserInterface::~UserInterface ()
@@ -211,11 +220,11 @@ namespace VeraCrypt
if (Preferences.Verbose)
{
if (!message.IsEmpty())
message += L'\n';
- message += StringFormatter (LangString["LINUX_VOL_DISMOUNTED"], wstring (volume->Path));
+ message += StringFormatter (LangString["LINUX_VOL_UNMOUNTED"], wstring (volume->Path));
}
}
if (twoPassMode && firstPass)
{
@@ -388,11 +397,11 @@ namespace VeraCrypt
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 (LangString["LINUX_COMMAND_GET_ERROR"], execEx->GetCommand(), execEx->GetExitCode());
+ return errOutput + static_cast<wstring>(StringFormatter (LangString["LINUX_COMMAND_GET_ERROR"], execEx->GetCommand(), execEx->GetExitCode()));
return wxString (errOutput).Trim (true);
}
// PasswordIncorrect
@@ -485,12 +494,12 @@ namespace VeraCrypt
EX2MSG (PasswordIncorrect, LangString["PASSWORD_WRONG"]);
EX2MSG (PasswordKeyfilesIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"]);
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, LangString["PASSWORD_UTF8_TOO_LONG"]);
- EX2MSG (PasswordLegacyUTF8TooLong, LangString["LEGACY_PASSWORD_UTF8_TOO_LONG"]);
+ 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, LangString["LINUX_EX2MSG_PARTITIONDEVICEREQUIRED"]);
EX2MSG (ProtectionPasswordIncorrect, LangString["LINUX_EX2MSG_PROTECTIONPASSWORDINCORRECT"]);
EX2MSG (ProtectionPasswordKeyfilesIncorrect, LangString["LINUX_EX2MSG_PROTECTIONPASSWORDKEYFILESINCORRECT"]);
EX2MSG (RootDeviceUnavailable, LangString["NODRIVER"]);
@@ -508,13 +517,13 @@ namespace VeraCrypt
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["EMV_PAN_NOTFOUND"]);
- EX2MSG (EMVKeyfileDataNotFound, LangString["INVALID_EMV_PATH"]);
- EX2MSG (EMVPANNotFound, LangString["EMV_KEYFILE_DATA_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, LangString["LINUX_EX2MSG_UNSUPPORTEDSECTORSIZEHIDDENVOLUMEPROTECTION"]);
@@ -530,10 +539,13 @@ namespace VeraCrypt
#ifdef TC_MACOSX
EX2MSG (HigherFuseVersionRequired, LangString["LINUX_EX2MSG_HIGHERFUSEVERSIONREQUIRED"]);
#endif
+ EX2MSG (MountPointBlocked, LangString["MOUNTPOINT_BLOCKED"]);
+ EX2MSG (MountPointNotAllowed, LangString["MOUNTPOINT_NOTALLOWED"]);
+
#undef EX2MSG
return L"";
}
void UserInterface::Init ()
@@ -542,37 +554,35 @@ namespace VeraCrypt
SetClassName (Application::GetName());
#ifdef CRYPTOPP_CPUID_AVAILABLE
DetectX86Features ();
#endif
+#if CRYPTOPP_BOOL_ARMV8
+ DetectArmFeatures();
+#endif
LangString.Init();
Core->Init();
CmdLine.reset (new CommandLineInterface (argc, argv, InterfaceType));
SetPreferences (CmdLine->Preferences);
Core->SetApplicationExecutablePath (Application::GetExecutablePath());
+ Core->SetUserEnvPATH (getenv ("PATH"));
if (!Preferences.NonInteractive)
{
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));
}
-#if defined(TC_LINUX ) || defined (TC_FREEBSD)
Core->ForceUseDummySudoPassword (CmdLine->ArgUseDummySudoPassword);
+
+#if defined(TC_UNIX)
+ Core->SetAllowInsecureMount (CmdLine->ArgAllowInsecureMount);
#endif
Core->WarningEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnWarning));
Core->VolumeMountedEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnVolumeMounted));
@@ -649,10 +659,11 @@ namespace VeraCrypt
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())
continue;
@@ -691,10 +702,14 @@ namespace VeraCrypt
if (newMountedVolumes.back()->Protection == VolumeProtection::HiddenVolumeReadOnly)
protectedVolumeMounted = true;
if (newMountedVolumes.back()->EncryptionAlgorithmMinBlockSize == 8)
legacyVolumeMounted = true;
+
+ if (newMountedVolumes.back()->MasterKeyVulnerable)
+ vulnerableVolumeMounted = true;
+
}
catch (DriverError&) { }
catch (MissingVolumeData&) { }
catch (PasswordException&) { }
catch (SystemException&) { }
@@ -705,10 +720,13 @@ 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)
ShowWarning ("WARN_64_BIT_BLOCK_CIPHER");
@@ -738,21 +756,24 @@ namespace VeraCrypt
continue;
}
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();
if (prefs.CloseSecurityTokenSessionsAfterMount)
@@ -766,10 +787,13 @@ namespace VeraCrypt
if (!volume)
break;
newMountedVolumes.push_back (volume);
}
}
+
+ if (mountPerformed && newMountedVolumes.back()->MasterKeyVulnerable)
+ ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE");
}
if (!newMountedVolumes.empty() && GetPreferences().CloseSecurityTokenSessionsAfterMount)
SecurityToken::CloseAllSessions();
@@ -802,10 +826,13 @@ 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))
ShowWarning ("EXE_FILE_EXTENSION_MOUNT_WARNING");
@@ -853,10 +880,37 @@ namespace VeraCrypt
{
ExceptionEventArgs &e = dynamic_cast <ExceptionEventArgs &> (args);
ShowWarning (e.mException);
}
+#if !defined(TC_WINDOWS) && !defined(TC_MACOSX)
+// Define file manager structures with their required parameters
+struct FileManager {
+ const char* name;
+ const char* const* baseArgs;
+ size_t baseArgsCount;
+};
+
+// Array of supported file managers with their parameters
+static const char* const gioArgs[] = {"open"};
+static const char* const kioclient5Args[] = {"exec"};
+static const char* const kfmclientArgs[] = {"openURL"};
+static const char* const exoOpenArgs[] = {"--launch", "FileManager"};
+
+const FileManager fileManagers[] = {
+ {"gio", gioArgs, 1},
+ {"kioclient5", kioclient5Args, 1},
+ {"kfmclient", kfmclientArgs, 1},
+ {"exo-open", exoOpenArgs, 2},
+ {"nautilus", NULL, 0},
+ {"dolphin", NULL, 0},
+ {"caja", NULL, 0},
+ {"thunar", NULL, 0},
+ {"pcmanfm", NULL, 0}
+};
+#endif
+
void UserInterface::OpenExplorerWindow (const DirectoryPath &path)
{
if (path.IsEmpty())
return;
@@ -872,69 +926,58 @@ namespace VeraCrypt
#elif defined (TC_MACOSX)
args.push_back (string (path));
try
{
- Process::Execute ("open", args);
+ Process::Execute ("/usr/bin/open", args);
}
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))
+ string directoryPath = string(path);
+ // Primary attempt: Use xdg-open
+ string errorMsg;
+ string binPath = Process::FindSystemBinary("xdg-open", errorMsg);
+ if (!binPath.empty())
{
- // 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);
+ args.push_back(directoryPath);
+ Process::Execute(binPath, 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 size_t numFileManagers = sizeof(fileManagers) / sizeof(fileManagers[0]);
+ for (size_t i = 0; i < numFileManagers; ++i) {
+ const FileManager& fm = fileManagers[i];
+ string fmPath = Process::FindSystemBinary(fm.name, errorMsg);
+ if (!fmPath.empty()) {
args.clear();
- args.push_back ("openURL");
- args.push_back (string (path));
- try
- {
- Process::Execute ("kfmclient", args, 2000);
+
+ // Add base arguments first
+ for (size_t j = 0; j < fm.baseArgsCount; ++j) {
+ args.push_back(fm.baseArgs[j]);
+ }
+
+ // Add path argument
+ args.push_back(directoryPath);
+
+ try {
+ Process::Execute(fmPath, args, 2000);
+ return; // Success
}
catch (TimeOut&) { }
- catch (exception &e) { ShowError (e); }
- }
- }
- 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 (exception &) {}
}
- 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 ()
{
@@ -1131,11 +1174,11 @@ namespace VeraCrypt
" 1) Create an outer volume with no filesystem.\n"
" 2) Create a hidden volume within the outer volume.\n"
" 3) Mount the outer volume using hidden volume protection.\n"
" 4) Create a filesystem on the virtual device of the outer volume.\n"
" 5) Mount the new filesystem and fill it with data.\n"
- " 6) Dismount the outer volume.\n"
+ " 6) Unmount the outer volume.\n"
" If at any step the hidden volume protection is triggered, start again from 1).\n"
"\n"
"--create-keyfile[=FILE_PATH]\n"
" Create a new keyfile containing pseudo-random data.\n"
"\n"
@@ -1143,13 +1186,13 @@ namespace VeraCrypt
" Change a password and/or keyfile(s) of a volume. Most options are requested\n"
" from the user if not specified on command line. PKCS-5 PRF HMAC hash\n"
" algorithm can be changed with option --hash. See also options -k,\n"
" --new-keyfiles, --new-password, -p, --random-source.\n"
"\n"
- "-d, --dismount[=MOUNTED_VOLUME]\n"
- " Dismount a mounted volume. If MOUNTED_VOLUME is not specified, all\n"
- " volumes are dismounted. See below for description of MOUNTED_VOLUME.\n"
+ "-u, --unmount[=MOUNTED_VOLUME]\n"
+ " Unmount a mounted volume. If MOUNTED_VOLUME is not specified, all\n"
+ " volumes are unmounted. See below for description of MOUNTED_VOLUME.\n"
"\n"
"--delete-token-keyfiles\n"
" Delete keyfiles from security tokens. See also command --list-token-keyfiles.\n"
"\n"
"--export-token-keyfile\n"
@@ -1216,11 +1259,11 @@ namespace VeraCrypt
" with option -t. Default type is 'auto'. When creating a new volume, this\n"
" option specifies the filesystem to be created on the new volume.\n"
" Filesystem type 'none' disables mounting or creating a filesystem.\n"
"\n"
"--force\n"
- " Force mounting of a volume in use, dismounting of a volume in use, or\n"
+ " Force mounting of a volume in use, unmounting of a volume in use, or\n"
" overwriting a file. Note that this option has no effect on some platforms.\n"
"\n"
"--fs-options=OPTIONS\n"
" Filesystem mount options. The OPTIONS argument is passed to mount(8)\n"
" command with option -o when a filesystem on a VeraCrypt volume is mounted.\n"
@@ -1252,11 +1295,11 @@ namespace VeraCrypt
" headerbak: Use backup headers when mounting a volume.\n"
" nokernelcrypto: Do not use kernel cryptographic services.\n"
" readonly|ro: Mount volume as read-only.\n"
" system: Mount partition using system encryption.\n"
" timestamp|ts: Do not restore host-file modification timestamp when a volume\n"
- " is dismounted (note that the operating system under certain circumstances\n"
+ " is unmounted (note that the operating system under certain circumstances\n"
" does not alter host-file timestamps, which may be mistakenly interpreted\n"
" to mean that this option does not work).\n"
" See also option --fs-options.\n"
"\n"
"--new-keyfiles=KEYFILE1[,KEYFILE2,KEYFILE3,...]\n"
@@ -1287,11 +1330,11 @@ namespace VeraCrypt
" outer volume is mounted with all sectors belonging to the hidden volume\n"
" protected against write operations. When a write to the protected area is\n"
" prevented, the whole volume is switched to read-only mode. Verbose list\n"
" (-v -l) can be used to query the state of the hidden volume protection.\n"
" Warning message is displayed when a volume switched to read-only is being\n"
- " dismounted.\n"
+ " unmounted.\n"
"\n"
"--protection-keyfiles=KEYFILE1[,KEYFILE2,KEYFILE3,...]\n"
" Use specified keyfiles to open a hidden volume to be protected. This option\n"
" may be used only when mounting an outer volume with hidden volume protected.\n"
" See also options -k and --protect-hidden.\n"
@@ -1308,11 +1351,11 @@ namespace VeraCrypt
"--random-source=FILE\n"
" Use FILE as a source of random data (e.g., when creating a volume) instead\n"
" of requiring the user to type random characters.\n"
"\n"
"--slot=SLOT\n"
- " Use specified slot number when mounting, dismounting, or listing a volume.\n"
+ " Use specified slot number when mounting, unmounting, or listing a volume.\n"
"\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 KiB, MiB, GiB or TiB respectively.\n"
@@ -1353,15 +1396,15 @@ namespace VeraCrypt
"veracrypt --filesystem=none volume.hc\n"
"\n"
"Mount a volume prompting only for its password:\n"
"veracrypt -t -k \"\" --pim=0 --protect-hidden=no volume.hc /media/veracrypt1\n"
"\n"
- "Dismount a volume:\n"
- "veracrypt -d volume.hc\n"
+ "Unmount a volume:\n"
+ "veracrypt -u volume.hc\n"
"\n"
- "Dismount all mounted volumes:\n"
- "veracrypt -d\n"
+ "Unmount all mounted volumes:\n"
+ "veracrypt -u\n"
);
#ifndef TC_NO_GUI
if (Application::GetUserInterfaceType() == UserInterfaceType::Graphic)
{
@@ -1514,11 +1557,11 @@ namespace VeraCrypt
throw TestFailed (SRC_POS);
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);
throw TestFailed (SRC_POS);
@@ -1612,10 +1655,17 @@ namespace VeraCrypt
}
return sResult;
}
+#ifdef TC_UNIX
+ bool UserInterface::InsecureMountAllowed () const
+ {
+ return CmdLine->ArgAllowInsecureMount;
+ }
+#endif
+
#define VC_CONVERT_EXCEPTION(NAME) if (dynamic_cast<NAME*> (ex)) throw (NAME&) *ex;
void UserInterface::ThrowException (Exception* ex)
{
VC_CONVERT_EXCEPTION (PasswordIncorrect);
@@ -1700,8 +1750,11 @@ namespace VeraCrypt
VC_CONVERT_EXCEPTION (EMVCPLCNotFound);
VC_CONVERT_EXCEPTION (InvalidEMVPath);
VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound);
VC_CONVERT_EXCEPTION (EMVPANNotFound);
+ VC_CONVERT_EXCEPTION (MountPointBlocked);
+ VC_CONVERT_EXCEPTION (MountPointNotAllowed);
+
throw *ex;
}
}