VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Core
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2024-12-25 11:29:32 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2024-12-25 11:29:32 +0100
commitca331b8b349cf1a42e6219d8733ae581199961fc (patch)
treeb04dce61a60a793c5b519b5cbb9754bb7b4c6c4e /src/Core
parent341411e935621ee74e816cf83a149ce9cf1e6f9e (diff)
downloadVeraCrypt-ca331b8b349cf1a42e6219d8733ae581199961fc.tar.gz
VeraCrypt-ca331b8b349cf1a42e6219d8733ae581199961fc.zip
Linux/macOS: Simplify sudo session detection logic and extend it to macOS
This update simplifies the logic for detecting active sudo sessions by checking the exit code of the sudo -n -l command, which reliably returns 0 if a session is active. Additionally, this approach is now applicable to recent macOS versions, as they no longer have the sudo bug that previously prevented us from using this method.
Diffstat (limited to 'src/Core')
-rw-r--r--src/Core/CoreBase.h4
-rw-r--r--src/Core/Unix/CoreService.cpp55
2 files changed, 23 insertions, 36 deletions
diff --git a/src/Core/CoreBase.h b/src/Core/CoreBase.h
index e646fce3..7f830336 100644
--- a/src/Core/CoreBase.h
+++ b/src/Core/CoreBase.h
@@ -77,10 +77,8 @@ namespace VeraCrypt
virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const = 0;
virtual DirectoryPath SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const = 0;
virtual void WipePasswordCache () const = 0;
-#if defined(TC_LINUX ) || defined (TC_FREEBSD)
virtual void ForceUseDummySudoPassword (bool useDummySudoPassword) { UseDummySudoPassword = useDummySudoPassword;}
virtual bool GetUseDummySudoPassword () const { return UseDummySudoPassword;}
-#endif
Event VolumeDismountedEvent;
Event VolumeMountedEvent;
@@ -91,9 +89,7 @@ namespace VeraCrypt
bool DeviceChangeInProgress;
FilePath ApplicationExecutablePath;
-#if defined(TC_LINUX ) || defined (TC_FREEBSD)
bool UseDummySudoPassword;
-#endif
private:
CoreBase (const CoreBase &);
diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp
index 6d0f05e5..e4b75dd3 100644
--- a/src/Core/Unix/CoreService.cpp
+++ b/src/Core/Unix/CoreService.cpp
@@ -292,41 +292,33 @@ namespace VeraCrypt
while (!ElevatedServiceAvailable)
{
// Test if the user has an active "sudo" session.
- // This is only done under Linux / FreeBSD by executing the command 'sudo -n uptime'.
- // In case a "sudo" session is active, the result of the command contains the string 'load average'.
- // Otherwise, the result contains "sudo: a password is required".
- // This may not work on all OSX versions because of a bug in sudo in its version 1.7.10,
- // therefore we keep the old behaviour of sending a 'dummy' password under OSX.
- // See : https://superuser.com/questions/902826/why-does-sudo-n-on-mac-os-x-always-return-0
- //
- // If for some reason we are getting empty output from pipe, we revert to old behavior
- // We also use the old way if the user is forcing the use of dummy password for sudo
-
-#if defined(TC_LINUX ) || defined (TC_FREEBSD)
bool authCheckDone = false;
if (!Core->GetUseDummySudoPassword ())
- {
- std::vector<char> buffer(128, 0);
- std::string result;
-
- FILE* pipe = popen("sudo -n uptime 2>&1 | grep 'load average' | wc -l | tr -d '[:blank:]'", "r"); // We redirect stderr to stdout (2>&1) to be able to catch the result of the command
+ {
+ // sudo man page: "If the -l option was specified without a command, sudo, will exit
+ // with a value of 0 if the user is allowed to run sudo, and they authenticated successfully"
+ // 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.
if (pipe)
{
- while (!feof(pipe))
- {
- if (fgets(buffer.data(), 128, pipe) != nullptr)
- result += buffer.data();
- }
-
- fflush(pipe);
- pclose(pipe);
+ // We only care about the exit code
+ char buf[128];
+ while (!feof(pipe))
+ {
+ if (fgets(buf, sizeof(buf), pipe) == NULL)
+ break;
+ }
+ int status = pclose(pipe);
pipe = NULL;
- if (!result.empty() && strlen(result.c_str()) != 0)
- {
- authCheckDone = true;
- if (result[0] == '0') // no line found with "load average" text, rerquest admin password
- (*AdminPasswordCallback) (request.AdminPassword);
+ authCheckDone = true;
+
+ // If exit code != 0, user does NOT have an active session => request password
+ if (status != 0)
+ {
+ (*AdminPasswordCallback)(request.AdminPassword);
}
}
@@ -336,7 +328,7 @@ namespace VeraCrypt
request.FastElevation = false;
}
}
-#endif
+
try
{
request.Serialize (ServiceInputStream);
@@ -353,9 +345,8 @@ namespace VeraCrypt
}
request.FastElevation = false;
-#if defined(TC_LINUX ) || defined (TC_FREEBSD)
+
if(!authCheckDone)
-#endif
(*AdminPasswordCallback) (request.AdminPassword);
}
}