This commit is contained in:
DavidXanatos 2023-01-23 22:48:51 +01:00
parent 151b74f9a9
commit bfa7d98dc7
11 changed files with 199 additions and 31 deletions

View File

@ -8,6 +8,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.6.7 / 5.61.7] - 2023-01-?
### Added
- added option to the classic ui to apply a supporter certificate
### Changed
- time limited certificates now have 1 extra free month of validity, to improve the renewal expirience
### Fixed
- fixed issue with Hebrew language (Classic UI) [#2608](https://github.com/sandboxie-plus/Sandboxie/issues/2608)
- fixed issue with startmenu integration and snapshots

View File

@ -1,6 +1,6 @@
/*
* Copyright 2004-2020 Sandboxie Holdings, LLC
* Copyright 2020 David Xanatos, xanasoft.com
* Copyright 2020-2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -28,6 +28,8 @@
#include "common/my_version.h"
#include "apps/common/MyGdi.h"
#include "apps/common/RunBrowser.h"
#include "common/win32_ntddk.h"
#include "core/drv/api_defs.h"
//---------------------------------------------------------------------------
@ -154,6 +156,14 @@ BOOL CAboutDialog::OnInitDialog()
text.Format(L"%S\r\n%S", MY_COPYRIGHT_STRING, MY_COPYRIGHT_STRING_OLD);
GetDlgItem(ID_ABOUT_COPYRIGHT)->SetWindowText(text);
ULONG64 CertInfo = 0;
SbieApi_Call(API_QUERY_DRIVER_INFO, 3, -1, (ULONG_PTR)&CertInfo, sizeof(CertInfo));
if (CertInfo & 1) // valid
GetDlgItem(ID_ABOUT_INFO)->SetWindowText(CMyMsg(MSG_7988));
else if (CertInfo & 2) // expired
GetDlgItem(ID_ABOUT_INFO)->SetWindowText(CMyMsg(MSG_7989));
GetDlgItem(IDOK)->SetWindowText(CMyMsg(MSG_3001));
return TRUE;
@ -169,3 +179,70 @@ void CAboutDialog::OnOK()
{
EndDialog(0);
}
//---------------------------------------------------------------------------
// ApplyCertificate
//---------------------------------------------------------------------------
void ApplyCertificate()
{
if (CMyApp::MsgBox(NULL, MSG_7990, MB_OKCANCEL) != IDOK)
return;
WCHAR CertPath[MAX_PATH];
GetTempPath(MAX_PATH, CertPath);
wcscat(CertPath, L"Sbie+Certificate.dat");
ULONG lenWritten = 0;
if (OpenClipboard(nullptr)) {
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
if (hData != nullptr) {
WCHAR* pszText = static_cast<WCHAR*>(GlobalLock(hData));
if (pszText != nullptr) {
HANDLE hFile = CreateFile(CertPath, FILE_GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
ULONG utf8_len = WideCharToMultiByte(CP_UTF8, 0, pszText, wcslen(pszText), NULL, 0, NULL, NULL);
char* text_utf8 = (char*)HeapAlloc(GetProcessHeap(), 0, utf8_len);
if (text_utf8) {
ULONG lenToWrite = WideCharToMultiByte(CP_UTF8, 0, pszText, wcslen(pszText), text_utf8, utf8_len, NULL, NULL);
if (! WriteFile(hFile, (void*)text_utf8, lenToWrite, &lenWritten, NULL))
lenWritten = 0;
HeapFree(GetProcessHeap(), 0, text_utf8);
}
CloseHandle(hFile);
}
GlobalUnlock(hData);
}
}
CloseClipboard();
}
if (lenWritten == 0) {
CMyApp::MsgBox(NULL, MSG_7991, MB_OK | MB_ICONERROR);
return;
}
WCHAR HomePath[MAX_PATH];
SbieApi_GetHomePath(NULL, 0, HomePath, MAX_PATH);
wcscat(HomePath, L"\\Certificate.dat");
SHFILEOPSTRUCT SHFileOp;
memset(&SHFileOp, 0, sizeof(SHFILEOPSTRUCT));
SHFileOp.hwnd = NULL;
SHFileOp.wFunc = FO_MOVE; // FO_DELETE;
SHFileOp.pFrom = CertPath;
SHFileOp.pTo = HomePath;
SHFileOp.fFlags = NULL;
SHFileOperation(&SHFileOp);
NTSTATUS status = SbieApi_Call(API_RELOAD_CONF, 2, -1, SBIE_CONF_FLAG_RELOAD_CERT);
if (!NT_SUCCESS(status)) {
CMyApp::MsgBox(NULL, MSG_7992, MB_OK | MB_ICONWARNING);
return;
}
CMyApp::MsgBox(NULL, MSG_7993, MB_OK | MB_ICONINFORMATION);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2004-2020 Sandboxie Holdings, LLC
* Copyright 2020-2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -147,6 +148,8 @@ BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
ON_COMMAND(ID_HELP_UPDATE, OnCmdHelpUpdate)
ON_COMMAND(ID_HELP_UPGRADE, OnCmdHelpUpgrade)
ON_COMMAND(ID_HELP_MIGRATION, OnCmdHelpMigrate)
ON_COMMAND(ID_HELP_GET_CERT, OnCmdHelpGetCert)
ON_COMMAND(ID_HELP_SET_CERT, OnCmdHelpSetCert)
ON_COMMAND(ID_HELP_ABOUT, OnCmdHelpAbout)
//ON_MESSAGE(WM_UPDATERESULT, OnUpdateResult)
@ -1074,6 +1077,30 @@ void CMyFrame::OnCmdHelpMigrate()
OpenWebView(url, text);
}
//---------------------------------------------------------------------------
// OnCmdHelpGetCert
//---------------------------------------------------------------------------
void CMyFrame::OnCmdHelpGetCert()
{
CRunBrowser x(this, L"https://sandboxie-plus.com/go.php?to=sbie-get-cert");
}
//---------------------------------------------------------------------------
// OnCmdHelpSetCert
//---------------------------------------------------------------------------
void ApplyCertificate();
void CMyFrame::OnCmdHelpSetCert()
{
ApplyCertificate();
}
//---------------------------------------------------------------------------
// OnCmdHelpAbout
//---------------------------------------------------------------------------

View File

@ -127,6 +127,8 @@ class CMyFrame : public CFrameWnd
afx_msg void OnCmdHelpUpdate();
afx_msg void OnCmdHelpUpgrade();
afx_msg void OnCmdHelpMigrate();
afx_msg void OnCmdHelpGetCert();
afx_msg void OnCmdHelpSetCert();
afx_msg void OnCmdHelpAbout();
//afx_msg LRESULT OnUpdateResult(WPARAM wParam, LPARAM lParam);
afx_msg void OnCmdTerminateProcess();

View File

@ -134,6 +134,9 @@ BEGIN
MENUITEM "3454", ID_HELP_UPDATE
MENUITEM "3467", ID_HELP_UPGRADE
MENUITEM SEPARATOR
MENUITEM "3506", ID_HELP_GET_CERT
MENUITEM "3507", ID_HELP_SET_CERT
MENUITEM SEPARATOR
MENUITEM "3456", ID_HELP_ABOUT
END
MENUITEM "3467", ID_HELP_UPGRADE
@ -253,6 +256,7 @@ BEGIN
CONTROL "",ID_ABOUT_LOGO,"Static",SS_BITMAP | WS_GROUP,35,15,5,5
CTEXT "",ID_ABOUT_VERSION,15,80,255,10
CTEXT "",ID_ABOUT_COPYRIGHT,15,95,255,20
CTEXT "",ID_ABOUT_INFO,15,130,255,20
DEFPUSHBUTTON "",IDOK,115,180,55,14
END

View File

@ -55,6 +55,8 @@
#define ID_HELP_UPGRADE 40046
#define ID_HELP_MIGRATION 40047
#define ID_HELP_CONTRIBUTION 40048
#define ID_HELP_GET_CERT 40054
#define ID_HELP_SET_CERT 40055
#define ID_HELP_ABOUT 40045
#define ID_PROCESS_TERMINATE 40051
#define ID_PROCESS_SETTINGS 40052
@ -197,6 +199,7 @@
#define ID_ABOUT_LOGO 41751
#define ID_ABOUT_VERSION 41752
#define ID_ABOUT_COPYRIGHT 41753
#define ID_ABOUT_INFO 41754
#define ID_ABOUT_FRAME 41756
#define ID_ABOUT_TUTORIAL 41757
#define ID_FILE_LIST 41801

View File

@ -487,12 +487,13 @@ union _SCertInfo {
ULONGLONG State;
struct {
ULONG
valid : 1, // certificate is active
expired : 1, // certificate is expired but may be active
outdated : 1, // certificate is expired, not anymore valid for the current build
business : 1, // certificate is suitable for business use
evaluation: 1, // evaluation certificate
reservd_1 : 3,
valid : 1, // certificate is active
expired : 1, // certificate is expired but may be active
outdated : 1, // certificate is expired, not anymore valid for the current build
business : 1, // certificate is suitable for business use
evaluation: 1, // evaluation certificate
grace_period: 1, // the certificate is expired and or outdated but we keep it valid for 1 extra month to allof wor a seamless renewal
reservd_1 : 2,
reservd_2 : 8,
reservd_3 : 8,
reservd_4 : 8;
@ -728,21 +729,34 @@ _FX NTSTATUS KphValidateCertificate(void)
} \
Verify_CertInfo.expirers_in_sec = (ULONG)(((cert_date.QuadPart + KphGetDateInterval(days, months, years)) - LocalTime.QuadPart) / 10000000ll); // 100ns steps -> 1sec
// certs with a validity >= 3 months get 1 extra month of functionality
#define TEST_GRACE_PERIODE(days, months, years) \
if (months >= 3 || years > 0){ \
if ((cert_date.QuadPart + KphGetDateInterval(days, months + 1, years)) >= LocalTime.QuadPart) \
Verify_CertInfo.grace_period = 1; \
} \
// Check if the certificate is valid for the current build, failing this locks features out
#define TEST_VALIDITY(days, months, years) \
TEST_CERT_DATE(days, months, years) \
if ((cert_date.QuadPart + KphGetDateInterval(days, months, years)) < BuildDate.QuadPart){ \
Verify_CertInfo.outdated = 1; \
Verify_CertInfo.valid = 0; \
status = STATUS_ACCOUNT_EXPIRED; \
TEST_GRACE_PERIODE(days, months, years) \
if(!Verify_CertInfo.grace_period){ \
Verify_CertInfo.valid = 0; \
status = STATUS_ACCOUNT_EXPIRED; \
} \
}
// Check if the certificate is expired, failing this locks features out
#define TEST_EXPIRATION(days, months, years) \
TEST_CERT_DATE(days, months, years) \
if(Verify_CertInfo.expired == 1) { \
Verify_CertInfo.valid = 0; \
status = STATUS_ACCOUNT_EXPIRED; \
TEST_GRACE_PERIODE(days, months, years) \
if(!Verify_CertInfo.grace_period){ \
Verify_CertInfo.valid = 0; \
status = STATUS_ACCOUNT_EXPIRED; \
} \
}
@ -774,7 +788,7 @@ _FX NTSTATUS KphValidateCertificate(void)
//
}
else if (level && _wcsicmp(level, L"LARGE") == 0 && cert_date.QuadPart < KphGetDate(1,04,2022)) { // valid for all builds released with 2 years
TEST_CERT_DATE(0, 0, 2); // no real expiration just ui reminder
TEST_CERT_DATE(0, 0, 2); // no real expiration just ui reminder - old certs
}
else if (level && _wcsicmp(level, L"LARGE") == 0) { // valid for all builds released with 2 years
TEST_VALIDITY(0, 0, 2);

View File

@ -1251,6 +1251,14 @@ Re&load Configuration
Contribute to Sandboxie
.
3506;txt;01
Get Supporter Certificate
.
3507;txt;01
Apply Supporter Certificate
.
3451;txt;01
&Help
.
@ -3871,6 +3879,31 @@ The default settings in Sandboxie provide full protection, but you may wish to r
# Product Key was cancelled because the order was refunded.
# .
7988;txt;01
Your Supporter Certificate is valid, Thank You :-)
.
7989;txt;01
The Supporter Certificate has expired :'(
.
7990;txt;01
Please copy the entire Suppoter Certificate into the clipboard and press OK.
.
7991;txt;01
Failed to save certificate to file.
.
7992;txt;01
The certificate is not valid.
.
7993;txt;01
The certificate is valid and has been successfully applied.
.
#----------------------------------------------------------------------------
# SandboxieInstall
#----------------------------------------------------------------------------

View File

@ -2111,7 +2111,7 @@ void CSandMan::UpdateCertState()
// outdated always implicates it is no longer valid
else if (g_CertInfo.expired) // may be still valid for the current and older builds
OnLogMessage(tr("The supporter certificate has expired%1, please get an updated certificate")
.arg(g_CertInfo.valid ? tr(", but it remains valid for the current build") : ""));
.arg(!g_CertInfo.outdated ? tr(", but it remains valid for the current build") : ""));
else if (g_CertInfo.about_to_expire)
OnLogMessage(tr("The supporter certificate will expire in %1 days, please get an updated certificate").arg(g_CertInfo.expirers_in_sec / (60 * 60 * 24)));
}

View File

@ -322,6 +322,7 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
connect(ui.lblSupport, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
connect(ui.lblSupportCert, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
connect(ui.lblCertExp, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
connect(ui.lblInsiderInfo, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
m_CertChanged = false;
connect(ui.txtCertificate, SIGNAL(textChanged()), this, SLOT(CertChanged()));
@ -745,13 +746,17 @@ void CSettingsWindow::UpdateCert()
QPalette palette = QApplication::palette();
if (theGUI->m_DarkTheme)
palette.setColor(QPalette::Text, Qt::black);
if (g_CertInfo.expired
#ifdef _DEBUG
|| (GetKeyState(VK_CONTROL) & 0x8000) != 0
#endif
) {
if (g_CertInfo.expired) {
palette.setColor(QPalette::Base, QColor(255, 255, 192));
ui.lblCertExp->setText(tr("This supporter certificate has expired, please <a href=\"sbie://update/cert\">get an updated certificate</a>."));
QString infoMsg = tr("This supporter certificate has expired, please <a href=\"sbie://update/cert\">get an updated certificate</a>.");
if (g_CertInfo.valid) {
if (g_CertInfo.grace_period)
infoMsg.append(tr("<br /><font color='red'>Plus features will be disabled in %1 days.</font>").arg(30 + g_CertInfo.expirers_in_sec / (60*60*24)));
else if (!g_CertInfo.outdated) // must be an expiren medium or large cert on an old build
infoMsg.append(tr("<br /><font color='red'>For this build Plus features remain enabled.</font>"));
} else
infoMsg.append(tr("<br />Plus features are no longer enabled."));
ui.lblCertExp->setText(infoMsg);
ui.lblCertExp->setVisible(true);
}
else {
@ -1055,11 +1060,7 @@ void CSettingsWindow::SaveSettings()
palette.setColor(QPalette::Base, Qt::white);
else if (!bRet)
palette.setColor(QPalette::Base, QColor(255, 192, 192));
else if (g_CertInfo.expired || g_CertInfo.outdated) {
palette.setColor(QPalette::Base, QColor(255, 255, 192));
ui.lblCertExp->setVisible(true);
}
else
else
palette.setColor(QPalette::Base, QColor(192, 255, 192));
ui.txtCertificate->setPalette(palette);
@ -1129,6 +1130,7 @@ bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* w
if (!theAPI->ReloadCert().IsError())
{
g_FeatureFlags = theAPI->GetFeatureFlags();
g_Certificate = Certificate;
theGUI->UpdateCertState();
if (g_CertInfo.expired || g_CertInfo.outdated) {
@ -1141,7 +1143,6 @@ bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* w
QMessageBox::information(widget, "Sandboxie-Plus", tr("Thank you for supporting the development of Sandboxie-Plus."));
}
g_Certificate = Certificate;
return true;
}
else

View File

@ -171,12 +171,13 @@ union SCertInfo {
quint64 State;
struct {
quint32
valid : 1, // certificate is active
expired : 1, // certificate is expired but may be active
outdated : 1, // certificate is expired, not anymore valid for the current build
business : 1, // certificate is suitable for business use
evaluation: 1, // evaluation certificate
reservd_1 : 3,
valid : 1, // certificate is active
expired : 1, // certificate is expired but may be active
outdated : 1, // certificate is expired, not anymore valid for the current build
business : 1, // certificate is suitable for business use
evaluation: 1, // evaluation certificate
grace_period: 1, // the certificate is expired and or outdated but we keep it valid for 1 extra month to allof wor a seamless renewal
reservd_1 : 2,
reservd_2 : 8,
reservd_3 : 8,
reservd_4 : 8;