VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Core/Unix/CoreService.cpp30
-rw-r--r--src/Core/Unix/CoreUnix.cpp128
-rw-r--r--src/Core/Unix/FreeBSD/CoreFreeBSD.cpp4
-rw-r--r--src/Core/Unix/MacOSX/CoreMacOSX.cpp10
-rw-r--r--src/Core/Unix/OpenBSD/CoreOpenBSD.cpp4
-rw-r--r--src/Core/Unix/Solaris/CoreSolaris.cpp4
-rw-r--r--src/Main/UserInterface.cpp80
-rw-r--r--src/Platform/Unix/Process.cpp63
-rw-r--r--src/Platform/Unix/Process.h2
9 files changed, 226 insertions, 99 deletions
diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp
index 7071f71c..c2eb2bf0 100644
--- a/src/Core/Unix/CoreService.cpp
+++ b/src/Core/Unix/CoreService.cpp
@@ -300,7 +300,14 @@ namespace VeraCrypt
// We are using -n to avoid prompting the user for a password.
// We are redirecting stderr to stdout and discarding both to avoid any output.
// This approach also works on newer macOS versions (12.0 and later).
- FILE* pipe = popen("sudo -n -l > /dev/null 2>&1", "r"); // redirect stderr to stdout and discard both.
+ std::string errorMsg;
+
+ string sudoAbsolutePath = Process::FindSystemBinary("sudo", errorMsg);
+ if (sudoAbsolutePath.empty())
+ throw SystemException(SRC_POS, errorMsg);
+
+ std::string popenCommand = sudoAbsolutePath + " -n -l > /dev/null 2>&1"; // We redirect stderr to stdout (2>&1) to be able to catch the result of the command
+ FILE* pipe = popen(popenCommand.c_str(), "r");
if (pipe)
{
// We only care about the exit code
@@ -396,15 +403,26 @@ namespace VeraCrypt
{
try
{
+ // Throw exception if sudo is not found in secure locations
+ std::string errorMsg;
+ string sudoPath = Process::FindSystemBinary("sudo", errorMsg);
+ if (sudoPath.empty())
+ throw SystemException(SRC_POS, errorMsg);
+
+ string appPath = request.ApplicationExecutablePath;
+ // if appPath is empty or not absolute, use FindSystemBinary to get the full path of veracrpyt executable
+ if (appPath.empty() || appPath[0] != '/')
+ {
+ appPath = Process::FindSystemBinary("veracrypt", errorMsg);
+ if (appPath.empty())
+ throw SystemException(SRC_POS, errorMsg);
+ }
+
throw_sys_if (dup2 (inPipe->GetReadFD(), STDIN_FILENO) == -1);
throw_sys_if (dup2 (outPipe->GetWriteFD(), STDOUT_FILENO) == -1);
throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1);
- string appPath = request.ApplicationExecutablePath;
- if (appPath.empty())
- appPath = "veracrypt";
-
- const char *args[] = { "sudo", "-S", "-p", "", appPath.c_str(), TC_CORE_SERVICE_CMDLINE_OPTION, nullptr };
+ const char *args[] = { sudoPath.c_str(), "-S", "-p", "", appPath.c_str(), TC_CORE_SERVICE_CMDLINE_OPTION, nullptr };
execvp (args[0], ((char* const*) args));
throw SystemException (SRC_POS, args[0]);
}
diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp
index 5cdbfda6..f6827806 100644
--- a/src/Core/Unix/CoreUnix.cpp
+++ b/src/Core/Unix/CoreUnix.cpp
@@ -29,6 +29,41 @@ namespace VeraCrypt
static bool SamePath (const string& path1, const string& path2);
#endif
+ // Struct to hold terminal emulator information
+ struct TerminalInfo {
+ const char* name;
+ const char** args;
+ const char** dependency_path;
+ };
+
+ // Popular terminal emulators data and arguments
+ static const char* xterm_args[] = {"-T", "fsck", "-e", NULL};
+
+ static const char* gnome_args[] = {"--title", "fsck", "--", "sh", "-c", NULL};
+ static const char* gnome_deps[] = {"dbus-launch", NULL};
+
+ static const char* konsole_args[] = {"--hold", "-p", "tabtitle=fsck", "-e", "sh", "-c", NULL};
+ static const char* xfce4_args[] = {"--title=fsck", "-x", "sh", "-c", NULL};
+ static const char* mate_args[] = {"--title", "fsck", "--", "sh", "-c", NULL};
+ static const char* lxterminal_args[] = {"--title=fsck", "-e", "sh", "-c", NULL};
+ static const char* terminator_args[] = {"-T", "fsck", "-x", "sh", "-c", NULL};
+ static const char* urxvt_args[] = {"-title", "fsck", "-e", "sh", "-c", NULL};
+ static const char* st_args[] = {"-t", "fsck", "-e", "sh", "-c", NULL};
+
+ // List of popular terminal emulators
+ static const TerminalInfo TERMINALS[] = {
+ {"xterm", xterm_args, NULL},
+ {"gnome-terminal", gnome_args, gnome_deps},
+ {"konsole", konsole_args, NULL},
+ {"xfce4-terminal", xfce4_args, NULL},
+ {"mate-terminal", mate_args, NULL},
+ {"lxterminal", lxterminal_args, NULL},
+ {"terminator", terminator_args, NULL},
+ {"urxvt", urxvt_args, NULL},
+ {"st", st_args, NULL},
+ {NULL, NULL, NULL}
+ };
+
CoreUnix::CoreUnix ()
{
signal (SIGPIPE, SIG_IGN);
@@ -47,14 +82,16 @@ namespace VeraCrypt
if (!mountedVolume->MountPoint.IsEmpty())
DismountFilesystem (mountedVolume->MountPoint, false);
- list <string> args;
-
- args.push_back ("-T");
- args.push_back ("fsck");
+ // Find system fsck first
+ std::string errorMsg;
+ std::string fsckPath = Process::FindSystemBinary("fsck", errorMsg);
+ if (fsckPath.empty()) {
+ throw SystemException(SRC_POS, errorMsg);
+ }
- args.push_back ("-e");
+ list <string> args;
- string xargs = "fsck ";
+ string xargs = fsckPath + " "; // Use absolute fsck path
#ifdef TC_LINUX
if (!repair)
@@ -64,49 +101,48 @@ namespace VeraCrypt
#endif
xargs += string (mountedVolume->VirtualDevice) + "; echo '[Done]'; read W";
- args.push_back (xargs);
+ // Try each terminal
+ for (const TerminalInfo* term = TERMINALS; term->name != NULL; ++term) {
+ errno = 0;
+ std::string termPath = Process::FindSystemBinary(term->name, errorMsg);
+ if (termPath.length() > 0) {
+ // check dependencies
+ if (term->dependency_path) {
+ bool depFound = true;
+ for (const char** dep = term->dependency_path; *dep != NULL; ++dep) {
+ string depPath = Process::FindSystemBinary(*dep, errorMsg);
+ if (depPath.empty()) {
+ depFound = false;
+ break;
+ }
+ }
- try
- {
- Process::Execute ("xterm", args, 1000);
- } catch (TimeOut&) { }
-#ifdef TC_LINUX
- catch (SystemException&)
- {
- // xterm not available. Try with KDE konsole if it exists
- struct stat sb;
- if (stat("/usr/bin/konsole", &sb) == 0)
- {
- args.clear ();
- args.push_back ("-p");
- args.push_back ("tabtitle=fsck");
- args.push_back ("-e");
- args.push_back ("sh");
- args.push_back ("-c");
- args.push_back (xargs);
- try
- {
- Process::Execute ("konsole", args, 1000);
- } catch (TimeOut&) { }
- }
- else if (stat("/usr/bin/gnome-terminal", &sb) == 0 && stat("/usr/bin/dbus-launch", &sb) == 0)
- {
- args.clear ();
- args.push_back ("--title");
- args.push_back ("fsck");
- args.push_back ("--");
- args.push_back ("sh");
- args.push_back ("-c");
- args.push_back (xargs);
- try
- {
- Process::Execute ("gnome-terminal", args, 1000);
- } catch (TimeOut&) { }
+ if (!depFound) {
+ continue; // dependency not found, skip
+ }
+ }
+
+ // Build args
+ std::list<std::string> args;
+ for (const char** arg = term->args; *arg != NULL; ++arg) {
+ args.push_back(*arg);
+ }
+ args.push_back(xargs);
+
+ try {
+ Process::Execute (termPath, args, 1000);
+ return;
+ }
+ catch (TimeOut&) {
+ return;
+ }
+ catch (SystemException&) {
+ // Continue to next terminal
+ }
}
- else
- throw TerminalNotFound();
}
-#endif
+
+ throw TerminalNotFound();
}
void CoreUnix::DismountFilesystem (const DirectoryPath &mountPoint, bool force) const
diff --git a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
index 0192bcff..8f5b8048 100644
--- a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
+++ b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
@@ -46,7 +46,7 @@ namespace VeraCrypt
args.push_back ("-f");
args.push_back (filePath);
- string dev = StringConverter::Trim (Process::Execute ("mdconfig", args));
+ string dev = StringConverter::Trim (Process::Execute ("/sbin/mdconfig", args));
if (dev.find ("/") == string::npos)
dev = string ("/dev/") + dev;
@@ -65,7 +65,7 @@ namespace VeraCrypt
{
try
{
- Process::Execute ("mdconfig", args);
+ Process::Execute ("/sbin/mdconfig", args);
break;
}
catch (ExecutedProcessFailed&)
diff --git a/src/Core/Unix/MacOSX/CoreMacOSX.cpp b/src/Core/Unix/MacOSX/CoreMacOSX.cpp
index ccbd5a58..762552de 100644
--- a/src/Core/Unix/MacOSX/CoreMacOSX.cpp
+++ b/src/Core/Unix/MacOSX/CoreMacOSX.cpp
@@ -47,7 +47,7 @@ namespace VeraCrypt
try
{
- Process::Execute ("hdiutil", args);
+ Process::Execute ("/usr/bin/hdiutil", args);
}
catch (ExecutedProcessFailed &e)
{
@@ -84,7 +84,7 @@ namespace VeraCrypt
{
try
{
- Process::Execute ("umount", args);
+ Process::Execute ("/usr/bin/umount", args);
break;
}
catch (ExecutedProcessFailed&)
@@ -114,7 +114,7 @@ namespace VeraCrypt
else
args.push_back ("/System/Applications/Utilities/Disk Utility.app");
- Process::Execute ("open", args);
+ Process::Execute ("/usr/bin/open", args);
}
void CoreMacOSX::MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const
@@ -190,7 +190,7 @@ namespace VeraCrypt
{
try
{
- xml = Process::Execute ("hdiutil", args);
+ xml = Process::Execute ("/usr/bin/hdiutil", args);
break;
}
catch (ExecutedProcessFailed &e)
@@ -233,7 +233,7 @@ namespace VeraCrypt
args.push_back (volImage);
args.push_back ("-force");
- Process::Execute ("hdiutil", args);
+ Process::Execute ("/usr/bin/hdiutil", args);
}
catch (ExecutedProcessFailed&) { }
throw;
diff --git a/src/Core/Unix/OpenBSD/CoreOpenBSD.cpp b/src/Core/Unix/OpenBSD/CoreOpenBSD.cpp
index b3ff3bd1..161d4a79 100644
--- a/src/Core/Unix/OpenBSD/CoreOpenBSD.cpp
+++ b/src/Core/Unix/OpenBSD/CoreOpenBSD.cpp
@@ -75,7 +75,7 @@ namespace VeraCrypt
args.push_back (filePath);
- Process::Execute ("vnconfig", args);
+ Process::Execute ("/sbin/vnconfig", args);
return "/dev/" + freePath.str() + "c";
}
@@ -90,7 +90,7 @@ namespace VeraCrypt
{
try
{
- Process::Execute ("vnconfig", args);
+ Process::Execute ("/sbin/vnconfig", args);
break;
}
catch (ExecutedProcessFailed&)
diff --git a/src/Core/Unix/Solaris/CoreSolaris.cpp b/src/Core/Unix/Solaris/CoreSolaris.cpp
index e840cceb..c436be8f 100644
--- a/src/Core/Unix/Solaris/CoreSolaris.cpp
+++ b/src/Core/Unix/Solaris/CoreSolaris.cpp
@@ -35,7 +35,7 @@ namespace VeraCrypt
args.push_back ("-a");
args.push_back (filePath);
- return StringConverter::Trim (Process::Execute ("lofiadm", args));
+ return StringConverter::Trim (Process::Execute ("/usr/sbin/lofiadm", args));
}
void CoreSolaris::DetachLoopDevice (const DevicePath &devicePath) const
@@ -48,7 +48,7 @@ namespace VeraCrypt
{
try
{
- Process::Execute ("lofiadm", args);
+ Process::Execute ("/usr/sbin/lofiadm", args);
break;
}
catch (ExecutedProcessFailed&)
diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp
index 76d090e6..5798cb31 100644
--- a/src/Main/UserInterface.cpp
+++ b/src/Main/UserInterface.cpp
@@ -872,11 +872,30 @@ namespace VeraCrypt
}
#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);
-}
+// 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)
@@ -898,17 +917,21 @@ static bool IsExecutable(const string& exe) {
args.push_back (string (path));
try
{
- Process::Execute ("open", args);
+ Process::Execute ("/usr/bin/open", args);
}
catch (exception &e) { ShowError (e); }
#else
string directoryPath = string(path);
// Primary attempt: Use xdg-open
- if (IsExecutable("xdg-open")) {
- try {
+ string errorMsg;
+ string binPath = Process::FindSystemBinary("xdg-open", errorMsg);
+ if (!binPath.empty())
+ {
+ try
+ {
args.push_back(directoryPath);
- Process::Execute("xdg-open", args, 2000);
+ Process::Execute(binPath, args, 2000);
return;
}
catch (TimeOut&) { }
@@ -916,36 +939,23 @@ static bool IsExecutable(const string& exe) {
}
// 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]);
-
+ const size_t numFileManagers = sizeof(fileManagers) / sizeof(fileManagers[0]);
for (size_t i = 0; i < numFileManagers; ++i) {
- const char* fm = fallbackFileManagers[i];
- if (IsExecutable(fm)) {
+ const FileManager& fm = fileManagers[i];
+ string fmPath = Process::FindSystemBinary(fm.name, errorMsg);
+ if (!fmPath.empty()) {
args.clear();
- 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);
+
+ // 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(fm, args, 2000);
+ Process::Execute(fmPath, args, 2000);
return; // Success
}
catch (TimeOut&) { }
@@ -954,7 +964,7 @@ static bool IsExecutable(const string& exe) {
}
ShowWarning(wxT("Unable to find a file manager to open the mounted volume.\n"
- "Please install xdg-utils or set a default file manager."));
+ "Please install xdg-utils or set a default file manager."));
#endif
}
diff --git a/src/Platform/Unix/Process.cpp b/src/Platform/Unix/Process.cpp
index 45106918..0c2a9c59 100644
--- a/src/Platform/Unix/Process.cpp
+++ b/src/Platform/Unix/Process.cpp
@@ -27,12 +27,73 @@
namespace VeraCrypt
{
- string Process::Execute (const string &processName, const list <string> &arguments, int timeOut, ProcessExecFunctor *execFunctor, const Buffer *inputData)
+
+ bool Process::IsExecutable(const std::string& path) {
+ struct stat sb;
+ if (stat(path.c_str(), &sb) == 0) {
+ return S_ISREG(sb.st_mode) && (sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH));
+ }
+ return false;
+ }
+
+ // Find executable in system paths
+ std::string Process::FindSystemBinary(const char* name, std::string& errorMsg) {
+ if (!name) {
+ errno = EINVAL; // Invalid argument
+ errorMsg = "Invalid input: name or paths is NULL";
+ return "";
+ }
+
+ // Default system directories to search for executables
+#ifdef TC_MACOSX
+ const char* defaultDirs[] = {"/usr/local/bin", "/usr/bin", "/bin", "/user/sbin", "/sbin"};
+#elseif TC_FREEBSD
+ const char* defaultDirs[] = {"/sbin", "/bin", "/usr/sbin", "/usr/bin", "/usr/local/sbin", "/usr/local/bin"};
+#elseif TC_OPENBSD
+ const char* defaultDirs[] = {"/sbin", "/bin", "/usr/sbin", "/usr/bin", "/usr/X11R6/bin", "/usr/local/sbin", "/usr/local/bin"};
+#else
+ const char* defaultDirs[] = {"/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "/bin"};
+#endif
+ const size_t defaultDirCount = sizeof(defaultDirs) / sizeof(defaultDirs[0]);
+
+ std::string currentPath(name);
+
+ // If path doesn't start with '/', prepend default directories
+ if (currentPath[0] != '/') {
+ for (size_t i = 0; i < defaultDirCount; ++i) {
+ std::string combinedPath = std::string(defaultDirs[i]) + "/" + currentPath;
+ if (IsExecutable(combinedPath)) {
+ return combinedPath;
+ }
+ }
+ } else if (IsExecutable(currentPath)) {
+ return currentPath;
+ }
+
+ // Prepare error message
+ errno = ENOENT; // No such file or directory
+ errorMsg = std::string(name) + " not found in system directories";
+ return "";
+ }
+
+ string Process::Execute (const string &processNameArg, const list <string> &arguments, int timeOut, ProcessExecFunctor *execFunctor, const Buffer *inputData)
{
char *args[32];
if (array_capacity (args) <= (arguments.size() + 1))
throw ParameterTooLarge (SRC_POS);
+ // if execFunctor is null and processName is not absolute path, find it in system paths
+ string processName;
+ if (!execFunctor && (processNameArg[0] != '/'))
+ {
+ std::string errorMsg;
+ processName = FindSystemBinary(processNameArg.c_str(), errorMsg);
+ if (processName.empty())
+ throw SystemException(SRC_POS, errorMsg);
+ }
+ else
+ processName = processNameArg;
+
#if 0
stringstream dbg;
dbg << "exec " << processName;
diff --git a/src/Platform/Unix/Process.h b/src/Platform/Unix/Process.h
index a796ed6a..83215956 100644
--- a/src/Platform/Unix/Process.h
+++ b/src/Platform/Unix/Process.h
@@ -31,6 +31,8 @@ namespace VeraCrypt
Process ();
virtual ~Process ();
+ static bool IsExecutable(const std::string& path);
+ static std::string FindSystemBinary(const char* name, std::string& errorMsg);
static string Execute (const string &processName, const list <string> &arguments, int timeOut = -1, ProcessExecFunctor *execFunctor = nullptr, const Buffer *inputData = nullptr);
protected: