1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 02:58:02 -06:00

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.
This commit is contained in:
Mounir IDRASSI
2024-12-25 11:29:32 +01:00
parent 341411e935
commit ca331b8b34
5 changed files with 23 additions and 44 deletions

View File

@@ -77,10 +77,8 @@ namespace VeraCrypt
virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const = 0; virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const = 0;
virtual DirectoryPath SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const = 0; virtual DirectoryPath SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const = 0;
virtual void WipePasswordCache () const = 0; virtual void WipePasswordCache () const = 0;
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
virtual void ForceUseDummySudoPassword (bool useDummySudoPassword) { UseDummySudoPassword = useDummySudoPassword;} virtual void ForceUseDummySudoPassword (bool useDummySudoPassword) { UseDummySudoPassword = useDummySudoPassword;}
virtual bool GetUseDummySudoPassword () const { return UseDummySudoPassword;} virtual bool GetUseDummySudoPassword () const { return UseDummySudoPassword;}
#endif
Event VolumeDismountedEvent; Event VolumeDismountedEvent;
Event VolumeMountedEvent; Event VolumeMountedEvent;
@@ -91,9 +89,7 @@ namespace VeraCrypt
bool DeviceChangeInProgress; bool DeviceChangeInProgress;
FilePath ApplicationExecutablePath; FilePath ApplicationExecutablePath;
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
bool UseDummySudoPassword; bool UseDummySudoPassword;
#endif
private: private:
CoreBase (const CoreBase &); CoreBase (const CoreBase &);

View File

@@ -292,41 +292,33 @@ namespace VeraCrypt
while (!ElevatedServiceAvailable) while (!ElevatedServiceAvailable)
{ {
// Test if the user has an active "sudo" session. // 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; bool authCheckDone = false;
if (!Core->GetUseDummySudoPassword ()) if (!Core->GetUseDummySudoPassword ())
{ {
std::vector<char> buffer(128, 0); // sudo man page: "If the -l option was specified without a command, sudo, will exit
std::string result; // 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.
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 // 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) if (pipe)
{ {
// We only care about the exit code
char buf[128];
while (!feof(pipe)) while (!feof(pipe))
{ {
if (fgets(buffer.data(), 128, pipe) != nullptr) if (fgets(buf, sizeof(buf), pipe) == NULL)
result += buffer.data(); break;
} }
int status = pclose(pipe);
fflush(pipe);
pclose(pipe);
pipe = NULL; pipe = NULL;
if (!result.empty() && strlen(result.c_str()) != 0)
{
authCheckDone = true; authCheckDone = true;
if (result[0] == '0') // no line found with "load average" text, rerquest admin password
(*AdminPasswordCallback) (request.AdminPassword); // 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; request.FastElevation = false;
} }
} }
#endif
try try
{ {
request.Serialize (ServiceInputStream); request.Serialize (ServiceInputStream);
@@ -353,9 +345,8 @@ namespace VeraCrypt
} }
request.FastElevation = false; request.FastElevation = false;
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
if(!authCheckDone) if(!authCheckDone)
#endif
(*AdminPasswordCallback) (request.AdminPassword); (*AdminPasswordCallback) (request.AdminPassword);
} }
} }

View File

@@ -32,9 +32,7 @@ namespace VeraCrypt
ArgAllowScreencapture (false), ArgAllowScreencapture (false),
ArgDisableFileSizeCheck (false), ArgDisableFileSizeCheck (false),
ArgUseLegacyPassword (false), ArgUseLegacyPassword (false),
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
ArgUseDummySudoPassword (false), ArgUseDummySudoPassword (false),
#endif
StartBackgroundTask (false) StartBackgroundTask (false)
{ {
wxCmdLineParser parser; wxCmdLineParser parser;
@@ -376,9 +374,7 @@ namespace VeraCrypt
ArgDisableFileSizeCheck = parser.Found (L"no-size-check"); ArgDisableFileSizeCheck = parser.Found (L"no-size-check");
ArgUseLegacyPassword = parser.Found (L"legacy-password-maxlength"); ArgUseLegacyPassword = parser.Found (L"legacy-password-maxlength");
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
ArgUseDummySudoPassword = parser.Found (L"use-dummy-sudo-password"); ArgUseDummySudoPassword = parser.Found (L"use-dummy-sudo-password");
#endif
#if !defined(TC_WINDOWS) && !defined(TC_MACOSX) #if !defined(TC_WINDOWS) && !defined(TC_MACOSX)
if (parser.Found (L"fs-options", &str)) if (parser.Found (L"fs-options", &str))

View File

@@ -87,9 +87,7 @@ namespace VeraCrypt
bool ArgAllowScreencapture; bool ArgAllowScreencapture;
bool ArgDisableFileSizeCheck; bool ArgDisableFileSizeCheck;
bool ArgUseLegacyPassword; bool ArgUseLegacyPassword;
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
bool ArgUseDummySudoPassword; bool ArgUseDummySudoPassword;
#endif
bool StartBackgroundTask; bool StartBackgroundTask;
UserPreferences Preferences; UserPreferences Preferences;

View File

@@ -570,9 +570,7 @@ namespace VeraCrypt
Core->SetAdminPasswordCallback (shared_ptr <GetStringFunctor> (new AdminPasswordRequestHandler)); Core->SetAdminPasswordCallback (shared_ptr <GetStringFunctor> (new AdminPasswordRequestHandler));
} }
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
Core->ForceUseDummySudoPassword (CmdLine->ArgUseDummySudoPassword); Core->ForceUseDummySudoPassword (CmdLine->ArgUseDummySudoPassword);
#endif
Core->WarningEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnWarning)); Core->WarningEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnWarning));
Core->VolumeMountedEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnVolumeMounted)); Core->VolumeMountedEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnVolumeMounted));