Linux/FreeBSD: Fix regression causing admin password to be requested too many times in some cases

This commit is contained in:
Mounir IDRASSI 2019-11-03 15:35:53 +01:00
parent bd7200e2b5
commit 80cc18f667
No known key found for this signature in database
GPG Key ID: 02C30AE90FAE4A6F

View File

@ -289,6 +289,8 @@ namespace VeraCrypt
request.FastElevation = !ElevatedServiceAvailable; request.FastElevation = !ElevatedServiceAvailable;
request.ApplicationExecutablePath = Core->GetApplicationExecutablePath(); request.ApplicationExecutablePath = Core->GetApplicationExecutablePath();
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'. // 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'. // In case a "sudo" session is active, the result of the command contains the string 'load average'.
@ -296,14 +298,14 @@ namespace VeraCrypt
// This may not work on all OSX versions because of a bug in sudo in its version 1.7.10, // 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. // 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 // 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
#if defined(TC_LINUX ) || defined (TC_FREEBSD) #if defined(TC_LINUX ) || defined (TC_FREEBSD)
// Set to false to force the 'WarningEvent' to be raised in case of and elevation exception.
request.FastElevation = false;
std::vector<char> buffer(128, 0); std::vector<char> buffer(128, 0);
std::string result; std::string result;
bool authCheckDone = false;
FILE* pipe = popen("sudo -n uptime 2>&1 | grep 'load average' | wc -l", "r"); // We redirect stderr to stdout (2>&1) to be able to catch the result of the command FILE* pipe = popen("sudo -n uptime 2>&1 | grep 'load average' | wc -l", "r"); // We redirect stderr to stdout (2>&1) to be able to catch the result of the command
if (pipe) if (pipe)
@ -318,14 +320,20 @@ namespace VeraCrypt
pclose(pipe); pclose(pipe);
pipe = NULL; pipe = NULL;
if (!result.empty() && strlen(result.c_str()) != 0 && !memcmp(result.c_str(), "0", 1)) 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); (*AdminPasswordCallback) (request.AdminPassword);
} }
} }
#endif
while (!ElevatedServiceAvailable) if (authCheckDone)
{ {
// Set to false to force the 'WarningEvent' to be raised in case of and elevation exception.
request.FastElevation = false;
}
#endif
try try
{ {
request.Serialize (ServiceInputStream); request.Serialize (ServiceInputStream);
@ -432,7 +440,7 @@ namespace VeraCrypt
vector <char> adminPassword (request.AdminPassword.size() + 1); vector <char> adminPassword (request.AdminPassword.size() + 1);
int timeout = 6000; int timeout = 6000;
// 'request.FastElevation' is always false under Linux / FreeBSD // 'request.FastElevation' is always false under Linux / FreeBSD when "sudo -n" works properly
if (request.FastElevation) if (request.FastElevation)
{ {
string dummyPassword = "dummy\n"; string dummyPassword = "dummy\n";