1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 11:08: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 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 &);

View File

@@ -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);
}
}

View File

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

View File

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

View File

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