1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-07-06 04:58:01 -05:00
Files
VeraCrypt/src/Main/Unix/Main.cpp
T
Mounir IDRASSI 47786ddce8 Unix: add doas elevation support
Prefer sudo when available and fall back to doas on Unix. Run doas authentication through a PTY while keeping service communication on stdin/stdout pipes, and use a no-fork service mode for the doas path.

Keep doas authentication terminal descriptors close-on-exec and close the slave descriptor after attaching it as the controlling terminal. Preserve startup diagnostics through stderr until service synchronization completes, then redirect no-fork service stderr away from the closed parent pipe.

Use noninteractive privilege-helper auth checks for both sudo and doas so cached, nopass, or persisted sessions do not need an unnecessary VeraCrypt password prompt. Keep the PTY password path for doas when authentication is required.

Use a shared Unix DOAS_USER helper for FUSE and mount ownership, backed by getpwnam_r and guarded so non-OpenBSD platforms only trust it for VeraCrypt's internal doas no-fork service path. Detach asynchronous child-reaper threads to avoid leaking joinable pthread handles.
2026-06-25 14:40:34 +09:00

137 lines
3.3 KiB
C++

/*
Derived from source code of TrueCrypt 7.1a, which is
Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
by the TrueCrypt License 3.0.
Modifications and additions to the original source code (contained in this file)
and all other portions of this file are Copyright (c) 2013-2026 AM Crypto
and are governed by the Apache License 2.0 the full text of which is
contained in the file License.txt included in VeraCrypt binary and source
code distribution packages.
*/
#include "System.h"
#include <sys/mman.h>
#include "Platform/Platform.h"
#include "Platform/SystemLog.h"
#include "Volume/EncryptionThreadPool.h"
#include "Core/Unix/CoreService.h"
#include "Core/Unix/UnixUser.h"
#include "Main/Application.h"
#include "Main/Main.h"
#include "Main/UserInterface.h"
#if defined (TC_MACOSX) && !defined (TC_NO_GUI)
#include <ApplicationServices/ApplicationServices.h>
#endif
using namespace VeraCrypt;
int main (int argc, char **argv)
{
try
{
// Make sure all required commands can be executed via default search path
string sysPathStr = "/usr/sbin:/sbin:/usr/bin:/bin";
char *sysPath = getenv ("PATH");
if (sysPath)
{
sysPathStr += ":";
sysPathStr += sysPath;
}
setenv ("PATH", sysPathStr.c_str(), 1);
if (argc > 1 && (strcmp (argv[1], TC_CORE_SERVICE_CMDLINE_OPTION) == 0 || strcmp (argv[1], TC_CORE_SERVICE_NO_FORK_CMDLINE_OPTION) == 0))
{
// Process elevated requests
try
{
bool forkProcess = strcmp (argv[1], TC_CORE_SERVICE_CMDLINE_OPTION) == 0;
if (!forkProcess)
setenv (TC_DOAS_CORE_SERVICE_ENV, "1", 1);
CoreService::ProcessElevatedRequests (forkProcess);
return 0;
}
catch (exception &e)
{
#ifdef DEBUG
SystemLog::WriteException (e);
#endif
}
catch (...) { }
return 1;
}
// Start core service
CoreService::Start();
finally_do ({ CoreService::Stop(); });
// Start encryption thread pool
EncryptionThreadPool::Start();
finally_do ({ EncryptionThreadPool::Stop(); });
#ifdef TC_NO_GUI
bool forceTextUI = true;
#else
bool forceTextUI = false;
#endif
#ifdef __WXGTK__
if (!getenv ("DISPLAY") && !getenv ("WAYLAND_DISPLAY"))
forceTextUI = true;
#endif
// Initialize application
if (forceTextUI || (argc > 1 && (strcmp (argv[1], "-t") == 0 || strcmp (argv[1], "--text") == 0)))
{
Application::Initialize (UserInterfaceType::Text);
}
else
{
#if defined (TC_MACOSX) && !defined (TC_NO_GUI)
if (argc > 1 && !(argc == 2 && strstr (argv[1], "-psn_") == argv[1]))
{
ProcessSerialNumber p;
if (GetCurrentProcess (&p) == noErr)
{
TransformProcessType (&p, kProcessTransformToForegroundApplication);
SetFrontProcess (&p);
}
}
#endif
Application::Initialize (UserInterfaceType::Graphic);
}
Application::SetExitCode (1);
// Start application
if (::wxEntry (argc, argv) == 0)
Application::SetExitCode (0);
}
catch (ErrorMessage &e)
{
wcerr << wstring (e) << endl;
}
catch (SystemException &e)
{
wstringstream s;
if (e.GetSubject().empty())
s << e.what() << endl << e.SystemText();
else
s << e.what() << endl << e.SystemText() << endl << e.GetSubject();
wcerr << s.str() << endl;
}
catch (exception &e)
{
stringstream s;
s << StringConverter::GetTypeName (typeid (e)) << endl << e.what();
cerr << s.str() << endl;
}
return Application::GetExitCode();
}