VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Core/Unix/CoreService.cpp72
1 files changed, 40 insertions, 32 deletions
diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp
index 5eca15de..b02bd211 100644
--- a/src/Core/Unix/CoreService.cpp
+++ b/src/Core/Unix/CoreService.cpp
@@ -289,43 +289,51 @@ namespace VeraCrypt
request.FastElevation = !ElevatedServiceAvailable;
request.ApplicationExecutablePath = Core->GetApplicationExecutablePath();
- // 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 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::string result;
-
- 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)
+ while (!ElevatedServiceAvailable)
{
- while (!feof(pipe))
+ // 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
+
+#if defined(TC_LINUX ) || defined (TC_FREEBSD)
+
+ std::vector<char> buffer(128, 0);
+ 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
+ if (pipe)
{
- if (fgets(buffer.data(), 128, pipe) != nullptr)
- result += buffer.data();
+ while (!feof(pipe))
+ {
+ if (fgets(buffer.data(), 128, pipe) != nullptr)
+ result += buffer.data();
+ }
+
+ fflush(pipe);
+ 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);
+ }
}
- fflush(pipe);
- pclose(pipe);
- pipe = NULL;
-
- if (!result.empty() && strlen(result.c_str()) != 0 && !memcmp(result.c_str(), "0", 1))
+ if (authCheckDone)
{
- (*AdminPasswordCallback) (request.AdminPassword);
+ // Set to false to force the 'WarningEvent' to be raised in case of and elevation exception.
+ request.FastElevation = false;
}
- }
-#endif
- while (!ElevatedServiceAvailable)
- {
+#endif
try
{
request.Serialize (ServiceInputStream);
@@ -432,7 +440,7 @@ namespace VeraCrypt
vector <char> adminPassword (request.AdminPassword.size() + 1);
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)
{
string dummyPassword = "dummy\n";