VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Core/Unix/CoreService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core/Unix/CoreService.cpp')
-rw-r--r--src/Core/Unix/CoreService.cpp8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp
index e543652a..6d0f05e5 100644
--- a/src/Core/Unix/CoreService.cpp
+++ b/src/Core/Unix/CoreService.cpp
@@ -30,61 +30,61 @@ namespace VeraCrypt
template <class T>
unique_ptr <T> CoreService::GetResponse ()
{
unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream));
Exception *deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
if (deserializedException)
deserializedException->Throw();
if (dynamic_cast <T *> (deserializedObject.get()) == nullptr)
throw ParameterIncorrect (SRC_POS);
return unique_ptr <T> (dynamic_cast <T *> (deserializedObject.release()));
}
void CoreService::ProcessElevatedRequests ()
{
int pid = fork();
throw_sys_if (pid == -1);
if (pid == 0)
{
try
{
int f = open ("/dev/null", 0);
throw_sys_sub_if (f == -1, "/dev/null");
throw_sys_if (dup2 (f, STDERR_FILENO) == -1);
// Wait for sync code
while (true)
{
- byte b;
+ uint8 b;
throw_sys_if (read (STDIN_FILENO, &b, 1) != 1);
if (b != 0x00)
continue;
throw_sys_if (read (STDIN_FILENO, &b, 1) != 1);
if (b != 0x11)
continue;
throw_sys_if (read (STDIN_FILENO, &b, 1) != 1);
if (b == 0x22)
break;
}
ElevatedPrivileges = true;
ProcessRequests (STDIN_FILENO, STDOUT_FILENO);
_exit (0);
}
catch (exception &e)
{
#ifdef DEBUG
SystemLog::WriteException (e);
#endif
}
catch (...) { }
_exit (1);
}
}
void CoreService::ProcessRequests (int inputFD, int outputFD)
{
@@ -282,61 +282,61 @@ namespace VeraCrypt
{
static Mutex mutex;
ScopeLock lock (mutex);
if (request.RequiresElevation())
{
request.ElevateUserPrivileges = true;
request.FastElevation = !ElevatedServiceAvailable;
request.ApplicationExecutablePath = Core->GetApplicationExecutablePath();
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", "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 | tr -d '[:blank:]'", "r"); // We redirect stderr to stdout (2>&1) to be able to catch the result of the command
if (pipe)
{
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);
}
}
if (authCheckDone)
{
// Set to false to force the 'WarningEvent' to be raised in case of and elevation exception.
request.FastElevation = false;
}
}
#endif
try
{
request.Serialize (ServiceInputStream);
@@ -516,88 +516,88 @@ namespace VeraCrypt
{
// Prevent defunct process
struct WaitFunctor : public Functor
{
WaitFunctor (int pid) : Pid (pid) { }
virtual void operator() ()
{
int status;
for (int t = 0; t < 10 && waitpid (Pid, &status, WNOHANG) == 0; t++)
Thread::Sleep (1000);
}
int Pid;
};
Thread thread;
thread.Start (new WaitFunctor (forkedPid));
throw ElevationFailed (SRC_POS, "sudo", 1, "");
}
waitRes = waitpid (forkedPid, &status, 0);
}
}
if (!errOutput.empty())
{
unique_ptr <Serializable> deserializedObject;
Exception *deserializedException = nullptr;
try
{
- shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((byte *) &errOutput[0], errOutput.size())));
+ shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((uint8 *) &errOutput[0], errOutput.size())));
deserializedObject.reset (Serializable::DeserializeNew (stream));
deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
}
catch (...) { }
if (deserializedException)
deserializedException->Throw();
}
throw_sys_if (waitRes == -1);
exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1);
if (exitCode != 0)
{
string strErrOutput;
if (!errOutput.empty())
strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end());
// sudo may require a tty even if -S is used
if (strErrOutput.find (" tty") != string::npos)
strErrOutput += "\nTo enable use of 'sudo' by applications without a terminal window, please disable 'requiretty' option in '/etc/sudoers'. Newer versions of sudo automatically determine whether a terminal is required ('requiretty' option is obsolete).";
throw ElevationFailed (SRC_POS, "sudo", exitCode, strErrOutput);
}
throw_sys_if (fcntl (outPipe->GetReadFD(), F_SETFL, 0) == -1);
ServiceInputStream = shared_ptr <Stream> (new FileStream (inPipe->GetWriteFD()));
ServiceOutputStream = shared_ptr <Stream> (new FileStream (outPipe->GetReadFD()));
// Send sync code
- byte sync[] = { 0, 0x11, 0x22 };
+ uint8 sync[] = { 0, 0x11, 0x22 };
ServiceInputStream->Write (ConstBufferPtr (sync, array_capacity (sync)));
AdminInputPipe = move_ptr(inPipe);
AdminOutputPipe = move_ptr(outPipe);
}
void CoreService::Stop ()
{
ExitRequest exitRequest;
exitRequest.Serialize (ServiceInputStream);
}
shared_ptr <GetStringFunctor> CoreService::AdminPasswordCallback;
unique_ptr <Pipe> CoreService::AdminInputPipe;
unique_ptr <Pipe> CoreService::AdminOutputPipe;
unique_ptr <Pipe> CoreService::InputPipe;
unique_ptr <Pipe> CoreService::OutputPipe;
shared_ptr <Stream> CoreService::ServiceInputStream;
shared_ptr <Stream> CoreService::ServiceOutputStream;
bool CoreService::ElevatedPrivileges = false;
bool CoreService::ElevatedServiceAvailable = false;
}