This commit is contained in:
DavidXanatos 2023-08-02 08:25:47 +02:00
parent 0ac2ef30b4
commit 9cc96b169f
7 changed files with 265 additions and 45 deletions

View File

@ -499,7 +499,7 @@ bool CSbieUtils::CreateShortcut(const QString& StartExe, QString LinkPath, const
StartArgs += "/box:" + boxname;
if (!arguments.isEmpty()) {
if (!StartArgs.isEmpty()) StartArgs += " ";
if(arguments.contains(" "))
if(arguments.contains(" ") && arguments.left(1) != "\"")
StartArgs += "\"" + arguments + "\"";
else
StartArgs += arguments;

View File

@ -45,6 +45,9 @@ CBoxEngine::~CBoxEngine()
void CBoxEngine::Stop()
{
if (!isRunning())
return;
m_Mutex.lock();
if (m_State == eQuery || m_State == eReady)
Continue(true, eCanceled);

View File

@ -676,7 +676,7 @@ bool COnlineUpdater::ApplyUpdate(bool bSilent)
if (Scope == eFull)
Params.append("/open:sandman.exe");
SB_RESULT(int) status = RunUpdater(Params, bSilent, Scope != eFull);
SB_RESULT(int) status = RunUpdater(Params, true, Scope != eFull);
if (!status.IsError()) {
if(bSilent)
theConf->DelValue("Updater/UpdateVersion");

View File

@ -2209,7 +2209,7 @@ void CSandMan::OnStatusChanged()
}
}
if (theConf->GetBool("Options/AutoRunSoftCompat", true))
if (theConf->GetBool("Options/AutoRunSoftCompat", true) && g_PendingMessage.isEmpty())
CheckCompat(this, "OpenCompat");
}
else
@ -2575,6 +2575,8 @@ bool CSandMan::CheckCertificate(QWidget* pWidget)
return false;
}
void InitCertSlot();
void CSandMan::UpdateCertState()
{
g_CertInfo.State = theAPI->GetCertState();
@ -2623,6 +2625,9 @@ void CSandMan::UpdateCertState()
}
}
if (CERT_IS_TYPE(g_CertInfo, eCertBusiness))
InitCertSlot();
if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation))
{
if (g_CertInfo.expired)
@ -3824,3 +3829,153 @@ QT_TRANSLATE_NOOP("CSandBox", "Finishing Snapshot Merge..."),
#include "SbieFindWnd.cpp"
std::wstring g_SlotName;
HANDLE g_MailThread = NULL;
bool g_MailRun = false;
wchar_t g_MyName[MAX_COMPUTERNAME_LENGTH + 1];
ULONGLONG g_LastSlotScan = 0;
std::map<std::wstring, ULONGLONG> g_CertUsers;
std::mutex g_CertUsersLock;
int g_CertAmount = 0;
void SlotSend(const std::wstring& message)
{
std::wstring strSlotName = L"\\\\*\\mailslot\\" + g_SlotName;
HANDLE hSlot = CreateFile(strSlotName.c_str(),
GENERIC_WRITE,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hSlot == INVALID_HANDLE_VALUE)
{
//GetLastError();
return;
}
DWORD cbWritten;
WriteFile(hSlot, message.c_str(), (DWORD)(message.size() + 1) * sizeof(wchar_t), &cbWritten, NULL);
CloseHandle(hSlot);
}
void CleanUpSeats()
{
std::lock_guard<std::mutex> lock(g_CertUsersLock);
for (auto I = g_CertUsers.begin(); I != g_CertUsers.end();) {
if (I->second + 10 * 1000 < g_LastSlotScan)
I = g_CertUsers.erase(I);
else
++I;
}
}
void ScanForSeats()
{
if (g_LastSlotScan + 5 * 1000 < GetTickCount64())
SlotSend(L"?");
}
int CountSeats()
{
std::lock_guard<std::mutex> lock(g_CertUsersLock);
return g_CertUsers.size();
}
DWORD WINAPI MailThreadFunc(LPVOID lpParam)
{
std::wstring strSlotName = L"\\\\.\\mailslot\\" + g_SlotName;
HANDLE hSlot = CreateMailslot(strSlotName.c_str(),
0, // no maximum message size
MAILSLOT_WAIT_FOREVER, // no time-out for operations
(LPSECURITY_ATTRIBUTES) NULL); // default security
if (hSlot == INVALID_HANDLE_VALUE) {
//GetLastError()
return FALSE;
}
ScanForSeats();
int EvalCounter = 0;
while (g_MailRun)
{
DWORD cbMessage;
DWORD dwMessageCount;
if(!GetMailslotInfo(hSlot, // mailslot handle
(LPDWORD)NULL, // no maximum message size
&cbMessage, // size of next message
&dwMessageCount, // number of messages
(LPDWORD)NULL)) // no read time-out
{
//GetLastError();
continue;
}
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
if (EvalCounter && --EvalCounter == 0) {
if (CountSeats() > g_CertAmount) {
QTimer::singleShot(0, theGUI, []() {
if(!CSupportDialog::ShowDialog())
PostQuitMessage(0);
});
}
}
//printf("Waiting for a message...\n");
Sleep(100);
continue;
}
DWORD cbRead;
wchar_t* lpszBuffer = (wchar_t*)GlobalAlloc(GPTR, (cbMessage + 1) * sizeof(wchar_t));
if (ReadFile(hSlot, lpszBuffer, cbMessage, &cbRead, NULL))
{
lpszBuffer[cbRead/sizeof(wchar_t)] = L'\0';
if (_wcsicmp(lpszBuffer, L"?") == 0)
{
if (g_LastSlotScan + 10 * 1000 < GetTickCount64()) {
CleanUpSeats();
g_LastSlotScan = GetTickCount64();
if(g_CertAmount)
EvalCounter = 30; // 3 sec
}
SlotSend(g_MyName);
}
else
{
std::lock_guard<std::mutex> lock(g_CertUsersLock);
g_CertUsers[lpszBuffer] = GetTickCount64();
}
}
GlobalFree((HGLOBAL)lpszBuffer);
}
return TRUE;
}
void InitCertSlot()
{
DWORD dwSize = ARRSIZE(g_MyName);
GetComputerNameW(g_MyName, &dwSize);
if (g_MailRun) {
g_MailRun = false;
if (WaitForSingleObject(g_MailThread, 10 * 1000) != WAIT_OBJECT_0)
TerminateThread(g_MailThread, -2);
g_MailThread = NULL;
}
auto CertData = GetArguments(g_Certificate, L'\n', L':');
QString UpdateKey = CertData.value("UPDATEKEY");
g_SlotName = L"sbie-plus_" + UpdateKey.toStdWString();
g_CertAmount = CertData.value("AMOUNT").toInt();
g_MailRun = true;
g_MailThread = CreateThread(NULL, 0, MailThreadFunc, NULL, 0, NULL);
}

View File

@ -122,6 +122,9 @@ bool CSupportDialog::CheckSupport(bool bOnRun)
return true;
}
extern int g_CertAmount;
int CountSeats();
bool CSupportDialog::ShowDialog(bool NoGo, int Wait)
{
QDateTime InstallDate = GetSbieInstallationDate();
@ -137,12 +140,18 @@ bool CSupportDialog::ShowDialog(bool NoGo, int Wait)
}
else
#endif
if (IsBusinessUse())
if (CountSeats() > g_CertAmount)
{
Message = tr("The installed supporter certificate allows for <b>%1 seats</b> to be active.<br /><br />").arg(g_CertAmount);
Message += tr("<b>There seams to be howeever %1 Sandboxie-Plus instances on your network, <font color='red'>you need to obtain additional <a href=\"https://sandboxie-plus.com/go.php?to=sbie-obtain-cert&tip=more\">support certificates</a></font>.</b><br /><br />").arg(CountSeats());
}
else if (IsBusinessUse())
{
if (g_CertInfo.expired) {
Days = -g_CertInfo.expirers_in_sec / (24 * 3600);
Message += tr("The installed supporter certificate <b>has expired %1 days ago</b> and <a href=\"https://sandboxie-plus.com/go.php?to=sbie-renew-cert\">must be renewed</a>.<br /><br />").arg(Days);
Message = tr("The installed supporter certificate <b>has expired %1 days ago</b> and <a href=\"https://sandboxie-plus.com/go.php?to=sbie-renew-cert\">must be renewed</a>.<br /><br />").arg(Days);
} else
Message = tr("<b>You have installed Sandboxie-Plus more than %1 days ago.</b><br /><br />").arg(Days);
@ -153,9 +162,9 @@ bool CSupportDialog::ShowDialog(bool NoGo, int Wait)
bool bOnARM64 = (g_FeatureFlags & CSbieAPI::eSbieFeatureARM64) != 0;
if (g_CertInfo.outdated)
Message += tr("The installed supporter certificate is <b>outdated</b> and it is <u>not valid for<b> this version</b></u> of Sandboxie-Plus.<br /><br />");
Message = tr("The installed supporter certificate is <b>outdated</b> and it is <u>not valid for<b> this version</b></u> of Sandboxie-Plus.<br /><br />");
else if (g_CertInfo.expired)
Message += tr("The installed supporter certificate is <b>expired</b> and <u>should be renewed</u>.<br /><br />");
Message = tr("The installed supporter certificate is <b>expired</b> and <u>should be renewed</u>.<br /><br />");
else
Message = tr("<b>You have been using Sandboxie-Plus for more than %1 days now.</b><br /><br />").arg(Days);

View File

@ -3,7 +3,7 @@
#define VERSION_MJR 1
#define VERSION_MIN 10
#define VERSION_REV 2
#define VERSION_UPD 1
#define VERSION_UPD 2
#ifndef STR
#define STR2(X) #X

View File

@ -19,6 +19,7 @@
#include <shellapi.h>
#include <io.h>
#include <fcntl.h>
#include <aclapi.h>
#include <iostream>
#include "../Common/helpers.h"
#include "../Common/WebUtils.h"
@ -105,6 +106,73 @@ struct SAddon : SFiles
typedef std::map<std::wstring, std::shared_ptr<SAddon>> TAddonMap;
std::wstring Arch2Str(ULONG architecture)
{
switch (architecture)
{
case IMAGE_FILE_MACHINE_ARM64: return L"a64";
case PROCESSOR_ARCHITECTURE_AMD64: return L"x64";
case PROCESSOR_ARCHITECTURE_INTEL: return L"x86";
default: return L"";
}
}
extern "C"
{
NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformationEx(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
}
ULONG GetSysArch()
{
USHORT architecture = 0;
NTSTATUS status;
HANDLE ProcessHandle = GetCurrentProcess();
ULONG bufferLength;
SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION* buffer;
ULONG returnLength;
bufferLength = sizeof(SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION[5]);
buffer = (SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION*)malloc(bufferLength);
const ULONG SystemSupportedProcessorArchitectures = 181;
status = NtQuerySystemInformationEx((SYSTEM_INFORMATION_CLASS)SystemSupportedProcessorArchitectures, &ProcessHandle, sizeof(ProcessHandle), buffer, bufferLength, &returnLength);
if (NT_SUCCESS(status))
{
for (ULONG i = 0; i < returnLength / sizeof(SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION); i++)
{
if (buffer[i].Native)
{
architecture = (USHORT)buffer[i].Machine;
break;
}
}
}
else // windows 7 fallback
{
SYSTEM_INFO SystemInfo = {0};
GetNativeSystemInfo(&SystemInfo);
switch (SystemInfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_AMD64: architecture = IMAGE_FILE_MACHINE_AMD64; break;
//case PROCESSOR_ARCHITECTURE_ARM: architecture = ; break;
case PROCESSOR_ARCHITECTURE_ARM64: architecture = IMAGE_FILE_MACHINE_ARM64; break;
//case PROCESSOR_ARCHITECTURE_IA64: architecture = IMAGE_FILE_MACHINE_IA64; break; // itanium
case PROCESSOR_ARCHITECTURE_INTEL: architecture = IMAGE_FILE_MACHINE_I386; break;
}
}
free(buffer);
return Arch2Str(architecture)
}
std::wstring ReadRegistryStringValue(std::wstring key, const std::wstring& valueName)
{
@ -133,9 +201,9 @@ std::wstring ReadRegistryStringValue(std::wstring key, const std::wstring& value
return L"";
}
std::wstring GetBinaryArch(const std::wstring& file)
ULONG GetBinaryArch(const std::wstring& file)
{
std::wstring arch;
ULONG arch = 0;
HANDLE hFile = CreateFile(file.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
@ -157,12 +225,7 @@ std::wstring GetBinaryArch(const std::wstring& file)
if (ntHeader.Signature != IMAGE_NT_SIGNATURE)
goto finish;
switch (ntHeader.FileHeader.Machine)
{
case IMAGE_FILE_MACHINE_I386: arch = L"x86"; break;
case IMAGE_FILE_MACHINE_AMD64: arch = L"x64"; break;
case IMAGE_FILE_MACHINE_ARM64: arch = L"a64"; break;
}
arch = ntHeader.FileHeader.Machine;
finish:
if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
@ -643,9 +706,15 @@ int ApplyUpdate(std::wstring base_dir, std::wstring temp_dir, std::shared_ptr<SF
if (!path_name.first.empty())
CreateDirectoryTree(base_dir, path_name.first);
if(MoveFileExW(src.c_str(), dest.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
if (MoveFileExW(src.c_str(), dest.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
// inherit parent folder permissions
ACL g_null_acl = { 0 };
InitializeAcl(&g_null_acl, sizeof(g_null_acl), ACL_REVISION);
DWORD error = SetNamedSecurityInfoW((wchar_t*)dest.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, (PACL)&g_null_acl, NULL);
std::wcout << L" done" << std::endl;
else
} else
std::wcout << L" FAILED" << std::endl;
}
@ -1141,21 +1210,14 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
std::wstring arch = GetArgument(arguments, L"arch");
if (!arch.empty()) {
// normalize architecture
if (arch == L"x64")
arch = L"x86_64";
else if (arch == L"x86")
arch = L"i386";
else if (arch == L"ARM64" || arch == L"A64" || arch == L"a64")
arch = L"arm64";
}
else
#ifdef _M_ARM64
arch = L"ARM64";
#elif _WIN64
arch = L"x86_64";
#else
arch = L"i386";
#endif
if (arch == L"x86_64")
arch = L"x64";
else if (arch == L"i386")
arch = L"x86";
else if (arch == L"ARM64" || arch == L"A64" || arch == L"arm64")
arch = L"a64";
} else
arch = Arch2Str(GetSysArch());
if (arguments.size() >= 2 && arguments[0] == L"download") // download file to disk
{
@ -1397,21 +1459,12 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
std::shared_ptr<TAddonMap> pAddons;
if (jsonAddons)
{
std::wstring core_arch = GetBinaryArch(base_dir + L"\\sbiesvc.exe");
if (core_arch.empty()) {
// convert to new format
if (arch == L"x86_64")
core_arch = L"x64";
else if (arch == L"i386")
core_arch = L"x86";
else if (arch == L"arm64")
core_arch = L"a64";
}
std::wstring core_arch = Arch2Str(GetBinaryArch(base_dir + L"\\sbiesvc.exe"));
std::wstring agent_arch = GetArgument(arguments, L"agent_arch");
if (agent_arch.empty()) {
agent_arch = GetBinaryArch(base_dir + L"\\SandMan.exe");
if (agent_arch.empty()) agent_arch = GetBinaryArch(base_dir + L"\\SbieCtrl.exe");
agent_arch = Arch2Str(GetBinaryArch(base_dir + L"\\SandMan.exe"));
if (agent_arch.empty()) agent_arch = Arch2Str(GetBinaryArch(base_dir + L"\\SbieCtrl.exe"));
}
std::wstring framework = GetArgument(arguments, L"framework");