1.10.0
This commit is contained in:
parent
cf87504694
commit
675ef0dfb7
|
@ -39,6 +39,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- the main injection detour code is now written in C instead of Assembler and can properly report SbieDll.dll loading errors as SBIE2181
|
||||
- improved session agent startup to be more flexible
|
||||
- improved SBIEMSG help handling, the link now contains message details allowing to point to a more exact document (if available)
|
||||
- updated certificate validation code
|
||||
|
||||
### Fixed
|
||||
- fixed uninstall issue in the Sandboxie Classic installer [d1863ff](https://github.com/sandboxie-plus/Sandboxie/commit/d1863ffadfe105c695de71c9e841c2fd568116fe)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2016 wj32
|
||||
* Copyright (C) 2021 David Xanatos, xanasoft.com
|
||||
* Copyright (C) 2021-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -481,27 +481,11 @@ _FX LONGLONG KphGetDateInterval(CSHORT days, CSHORT months, CSHORT years)
|
|||
return ((LONGLONG)days + (LONGLONG)months * 30ll + (LONGLONG)years * 365ll) * 24ll * 3600ll * 10000000ll; // 100ns steps -> 1sec
|
||||
}
|
||||
|
||||
#define SOFTWARE_NAME L"Sandboxie-Plus"
|
||||
#include "verify.h"
|
||||
|
||||
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
|
||||
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;
|
||||
ULONG expirers_in_sec;
|
||||
};
|
||||
} Verify_CertInfo = {0};
|
||||
SCertInfo Verify_CertInfo = { 0 };
|
||||
|
||||
_FX NTSTATUS KphValidateCertificate(void)
|
||||
_FX NTSTATUS KphValidateCertificate()
|
||||
{
|
||||
BOOLEAN CertDbg = FALSE;
|
||||
|
||||
|
@ -689,7 +673,7 @@ _FX NTSTATUS KphValidateCertificate(void)
|
|||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
Verify_CertInfo.valid = 1;
|
||||
Verify_CertInfo.active = 1;
|
||||
|
||||
if(CertDbg) DbgPrint("Sbie Cert type: %S-%S\n", type, level);
|
||||
|
||||
|
@ -722,89 +706,99 @@ _FX NTSTATUS KphValidateCertificate(void)
|
|||
level = NULL;
|
||||
}
|
||||
|
||||
// Checks if the certificate is within its validity period, otherwise it has no effect except for UI notification
|
||||
#define TEST_CERT_DATE(days, months, years) \
|
||||
if ((cert_date.QuadPart + KphGetDateInterval(days, months, years)) < LocalTime.QuadPart){ \
|
||||
Verify_CertInfo.expired = 1; \
|
||||
} \
|
||||
Verify_CertInfo.expirers_in_sec = (ULONG)(((cert_date.QuadPart + KphGetDateInterval(days, months, years)) - LocalTime.QuadPart) / 10000000ll); // 100ns steps -> 1sec
|
||||
LARGE_INTEGER expiration_date = { 0 };
|
||||
|
||||
// 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; \
|
||||
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) { \
|
||||
TEST_GRACE_PERIODE(days, months, years) \
|
||||
if(!Verify_CertInfo.grace_period){ \
|
||||
Verify_CertInfo.valid = 0; \
|
||||
status = STATUS_ACCOUNT_EXPIRED; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
if (type && _wcsicmp(type, L"CONTRIBUTOR") == 0) {
|
||||
// forever - nothing to check here
|
||||
if (!type) // type is mandatory
|
||||
;
|
||||
else if (_wcsicmp(type, L"CONTRIBUTOR") == 0)
|
||||
Verify_CertInfo.type = eCertContributor;
|
||||
else if (_wcsicmp(type, L"ETERNAL") == 0)
|
||||
Verify_CertInfo.type = eCertEternal;
|
||||
else if (_wcsicmp(type, L"BUSINESS") == 0)
|
||||
Verify_CertInfo.type = eCertBusiness;
|
||||
else if (_wcsicmp(type, L"EVALUATION") == 0 || _wcsicmp(type, L"TEST") == 0)
|
||||
Verify_CertInfo.type = eCertEvaluation;
|
||||
else if (_wcsicmp(type, L"SUBSCRIPTION") == 0)
|
||||
Verify_CertInfo.type = eCertSubscription;
|
||||
else if (_wcsicmp(type, L"FAMILY") == 0)
|
||||
Verify_CertInfo.type = eCertFamily;
|
||||
// patreon >>>
|
||||
else if (wcsstr(type, L"PATREON") != NULL) // TYPE: [CLASS]_PATREON-[LEVEL]
|
||||
{
|
||||
if(_wcsnicmp(type, L"GREAT", 5) == 0)
|
||||
Verify_CertInfo.type = eCertGreatPatreon;
|
||||
else if (_wcsnicmp(type, L"ENTRY", 5) == 0) { // new patreons get only 3 montgs for start
|
||||
Verify_CertInfo.type = eCertEntryPatreon;
|
||||
expiration_date.QuadPart = cert_date.QuadPart + KphGetDateInterval(0, 3, 0);
|
||||
} else
|
||||
Verify_CertInfo.type = eCertPatreon;
|
||||
|
||||
}
|
||||
else if (type && _wcsicmp(type, L"BUSINESS") == 0) {
|
||||
Verify_CertInfo.business = 1;
|
||||
if (level) { // in months
|
||||
TEST_EXPIRATION(0, (CSHORT)_wtoi(level), 0);
|
||||
}
|
||||
else { // 1 year default
|
||||
TEST_EXPIRATION(0, 0, 1);
|
||||
}
|
||||
// <<< patreon
|
||||
else //if (_wcsicmp(type, L"PERSONAL") == 0 || _wcsicmp(type, L"SUPPORTER") == 0)
|
||||
{
|
||||
Verify_CertInfo.type = eCertPersonal;
|
||||
}
|
||||
else if (type && _wcsicmp(type, L"EVALUATION") == 0) {
|
||||
Verify_CertInfo.evaluation = 1;
|
||||
// evaluation
|
||||
if (level) { // in days
|
||||
TEST_EXPIRATION((CSHORT)_wtoi(level), 0, 0);
|
||||
}
|
||||
else { // 5 days default
|
||||
TEST_EXPIRATION(5, 0, 0);
|
||||
}
|
||||
|
||||
if(CertDbg) DbgPrint("Sbie Cert type: %X\n", Verify_CertInfo.type);
|
||||
|
||||
if (CERT_IS_TYPE(Verify_CertInfo, eCertEvaluation))
|
||||
{
|
||||
expiration_date.QuadPart = cert_date.QuadPart + KphGetDateInterval((CSHORT)(level ? _wtoi(level) : 7), 0, 0); // x days, default 7
|
||||
}
|
||||
else /*if (!type || _wcsicmp(type, L"PERSONAL") == 0 || _wcsicmp(type, L"PATREON") == 0 || _wcsicmp(type, L"SUPPORTER") == 0) */ {
|
||||
// persistent
|
||||
// scheme 1.1 >>>
|
||||
else if (CERT_IS_TYPE(Verify_CertInfo, eCertPersonal) || CERT_IS_TYPE(Verify_CertInfo, eCertPatreon))
|
||||
{
|
||||
if (level && _wcsicmp(level, L"HUGE") == 0) {
|
||||
//
|
||||
}
|
||||
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 - old certs
|
||||
Verify_CertInfo.type = eCertEternal;
|
||||
}
|
||||
else if (level && _wcsicmp(level, L"LARGE") == 0) { // valid for all builds released with 2 years
|
||||
TEST_VALIDITY(0, 0, 2);
|
||||
else if (level && _wcsicmp(level, L"LARGE") == 0) { // 2 years - personal
|
||||
expiration_date.QuadPart = cert_date.QuadPart + KphGetDateInterval(0, 0, 2); // 2 years
|
||||
}
|
||||
else if (level && _wcsicmp(level, L"MEDIUM") == 0) { // valid for all builds released with 1 year
|
||||
TEST_VALIDITY(0, 0, 1);
|
||||
else if (level && _wcsicmp(level, L"MEDIUM") == 0) { // 1 year - personal
|
||||
}
|
||||
// subscriptions
|
||||
else if (level && _wcsicmp(level, L"TEST") == 0) { // test certificate 5 days only
|
||||
TEST_EXPIRATION(5, 0, 0);
|
||||
else if (level && _wcsicmp(level, L"ENTRY") == 0) { // PATREON-ENTRY new patreons get only 3 montgs for start
|
||||
if(CERT_IS_TYPE(Verify_CertInfo, eCertPatreon))
|
||||
Verify_CertInfo.type = eCertEntryPatreon;
|
||||
expiration_date.QuadPart = cert_date.QuadPart + KphGetDateInterval(0, 3, 0);
|
||||
}
|
||||
else if (level && _wcsicmp(level, L"ENTRY") == 0) { // patreon entry level, first 3 months, later longer
|
||||
TEST_EXPIRATION(0, 3, 0);
|
||||
else if (level && _wcsicmp(type, L"SMALL") == 0) { // 1 year - subscription
|
||||
Verify_CertInfo.type = eCertSubscription;
|
||||
}
|
||||
else /*if (!level || _wcsicmp(level, L"SMALL") == 0)*/ { // valid for 1 year
|
||||
TEST_EXPIRATION(0, 0, 1);
|
||||
}
|
||||
// <<< scheme 1.1
|
||||
|
||||
if (CERT_IS_TYPE(Verify_CertInfo, eCertEternal))
|
||||
expiration_date.QuadPart = -1; // at the end of time (never)
|
||||
else if(!expiration_date.QuadPart)
|
||||
expiration_date.QuadPart = cert_date.QuadPart + KphGetDateInterval(0, 0, 1); // default 1 year, unless set differently already
|
||||
|
||||
// check if this is a subscription type sertificate
|
||||
BOOLEAN isSubscription = CERT_IS_SUBSCRIPTION(Verify_CertInfo);
|
||||
|
||||
if (expiration_date.QuadPart != -1)
|
||||
{
|
||||
// check if this certificate is expired
|
||||
if (expiration_date.QuadPart < LocalTime.QuadPart)
|
||||
Verify_CertInfo.expired = 1;
|
||||
Verify_CertInfo.expirers_in_sec = (ULONG)((expiration_date.QuadPart - LocalTime.QuadPart) / 10000000ll); // 100ns steps -> 1sec
|
||||
|
||||
// check if a non subscription type certificate is valid for the current build
|
||||
if (!isSubscription && expiration_date.QuadPart < BuildDate.QuadPart)
|
||||
Verify_CertInfo.outdated = 1;
|
||||
}
|
||||
|
||||
// check if the certificate is valid
|
||||
if (isSubscription ? Verify_CertInfo.expired : Verify_CertInfo.outdated)
|
||||
{
|
||||
if (!CERT_IS_TYPE(Verify_CertInfo, eCertEvaluation)) { // non eval certs get 1 month extra
|
||||
if (expiration_date.QuadPart + KphGetDateInterval(0, 1, 0) >= LocalTime.QuadPart)
|
||||
Verify_CertInfo.grace_period = 1;
|
||||
}
|
||||
|
||||
if (!Verify_CertInfo.grace_period) {
|
||||
Verify_CertInfo.active = 0;
|
||||
status = STATUS_ACCOUNT_EXPIRED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (C) 2021-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Process Hacker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define SOFTWARE_NAME L"Sandboxie-Plus"
|
||||
|
||||
typedef union _SCertInfo {
|
||||
unsigned long long State;
|
||||
struct {
|
||||
unsigned long
|
||||
active : 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
|
||||
unused_1 : 2, // DEPRECTED
|
||||
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_2 : 2,
|
||||
|
||||
type : 5,
|
||||
level : 3,
|
||||
|
||||
reservd_3 : 8,
|
||||
|
||||
reservd_4 : 8;
|
||||
|
||||
unsigned long expirers_in_sec;
|
||||
};
|
||||
} SCertInfo;
|
||||
|
||||
enum ECertType {
|
||||
eCertNoType = 0b00000,
|
||||
|
||||
eCertEternal = 0b00100,
|
||||
eCertContributor = 0b00101,
|
||||
// eCert = 0b00110,
|
||||
// eCert = 0b00111,
|
||||
|
||||
eCertBusiness = 0b01000,
|
||||
// eCert = 0b01001,
|
||||
// eCert = 0b01010,
|
||||
// eCert = 0b01011,
|
||||
|
||||
eCertPersonal = 0b01100,
|
||||
// eCert = 0b01101,
|
||||
// eCert = 0b01110,
|
||||
// eCert = 0b01111,
|
||||
|
||||
eCertSubscription = 0b10000,
|
||||
eCertFamily = 0b10001,
|
||||
// eCert = 0b10010,
|
||||
// eCert = 0b10011,
|
||||
|
||||
// eCertOther = 0b10100,
|
||||
// eCert = 0b10101,
|
||||
// eCert = 0b10110,
|
||||
// eCert = 0b10111,
|
||||
|
||||
eCertPatreon = 0b11000,
|
||||
eCertGreatPatreon = 0b11001,
|
||||
eCertEntryPatreon = 0b11010,
|
||||
// eCert = 0b11011,
|
||||
|
||||
eCertEvaluation = 0b11100
|
||||
};
|
||||
|
||||
#define CERT_IS_TYPE(cert,t) ((cert.type & 0b11100) == t)
|
||||
|
||||
enum ECertLevel {
|
||||
eCertNoLevel = 0b000,
|
||||
eCertStandard = 0b010,
|
||||
eCertAdvanced = 0b100,
|
||||
eCertMaxLevel = 0b111,
|
||||
};
|
||||
|
||||
#define CERT_IS_SUBSCRIPTION(cert) (CERT_IS_TYPE(cert, eCertBusiness) || CERT_IS_TYPE(cert, eCertSubscription) || cert.type == eCertEntryPatreon || CERT_IS_TYPE(cert, eCertEvaluation))
|
||||
#define CERT_IS_INSIDER(cert) (CERT_IS_TYPE(cert, eCertEternal) || cert.type == eCertGreatPatreon)
|
|
@ -13,7 +13,7 @@ bool TestWriteRight(const QString& Path)
|
|||
return TestFile.remove();
|
||||
}
|
||||
|
||||
CSettings::CSettings(const QString& AppDir, const QString& AppName, bool bShared, QMap<QString, SSetting> DefaultValues, QObject* qObject) : QObject(qObject)
|
||||
CSettings::CSettings(const QString& AppDir, const QString& AppName, QMap<QString, SSetting> DefaultValues, QObject* qObject) : QObject(qObject)
|
||||
{
|
||||
m_ConfigDir = AppDir;
|
||||
if (!(m_bPortable = QFile::exists(m_ConfigDir + "/" + AppName + ".ini")))
|
||||
|
@ -22,13 +22,9 @@ CSettings::CSettings(const QString& AppDir, const QString& AppName, bool bShared
|
|||
if (dirs.isEmpty())
|
||||
m_ConfigDir = QDir::homePath() + "/." + AppName;
|
||||
//
|
||||
// if shared is set a new ini is created in the shared location
|
||||
// and if present take precedence over an ini in a user location
|
||||
// however if the only existing ini is in a user location it will be used
|
||||
// if ini is present in the shared location it take precedence over an ini in a user location
|
||||
//
|
||||
else if(bShared && dirs.count() > 2 && (
|
||||
QFile::exists(dirs[1] + "/" + AppName + "/" + AppName + ".ini") ||
|
||||
!QFile::exists(dirs[0] + "/" + AppName + "/" + AppName + ".ini") ))
|
||||
else if(dirs.count() > 2 && QFile::exists(dirs[1] + "/" + AppName + "/" + AppName + ".ini"))
|
||||
m_ConfigDir = dirs[1] + "/" + AppName;
|
||||
else
|
||||
m_ConfigDir = dirs[0] + "/" + AppName;
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
virtual bool IsBlob() const {return true;}
|
||||
};
|
||||
|
||||
CSettings(const QString& AppDir, const QString& AppName, bool bShared = false, QMap<QString, SSetting> DefaultValues = QMap<QString, SSetting>(), QObject* qObject = NULL);
|
||||
CSettings(const QString& AppDir, const QString& AppName, QMap<QString, SSetting> DefaultValues = QMap<QString, SSetting>(), QObject* qObject = NULL);
|
||||
virtual ~CSettings();
|
||||
|
||||
void DelValue(const QString& key);
|
||||
|
|
|
@ -221,7 +221,7 @@ void CSbieObject::LogMessage(const QVariant& Message, bool bNotify)
|
|||
theGUI->OnLogMessage(Message.toString(), bNotify);
|
||||
}
|
||||
|
||||
bool JSbieObject::isCertValid()
|
||||
bool JSbieObject::testFeature(const QString& name)
|
||||
{
|
||||
return g_CertInfo.valid;
|
||||
return theAPI->GetFeatureStr().contains(name, Qt::CaseInsensitive);
|
||||
}
|
|
@ -156,7 +156,7 @@ public:
|
|||
QMetaObject::invokeMethod(m_pObject, "LogMessage", Qt::BlockingQueuedConnection, Q_ARG(const QVariant&, Message), Q_ARG(bool, bNotify));
|
||||
}
|
||||
|
||||
Q_INVOKABLE bool isCertValid();
|
||||
Q_INVOKABLE bool testFeature(const QString& name);
|
||||
|
||||
protected:
|
||||
CBoxEngine* m_pEngine;
|
||||
|
|
|
@ -171,8 +171,8 @@ void COnlineUpdater::GetUpdates(QObject* receiver, const char* member, const QVa
|
|||
Query.addQueryItem("language", QLocale::system().name());
|
||||
|
||||
QString UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY");
|
||||
if (UpdateKey.isEmpty())
|
||||
UpdateKey = theAPI->GetGlobalSettings()->GetText("UpdateKey"); // theConf->GetString("Options/UpdateKey");
|
||||
//if (UpdateKey.isEmpty())
|
||||
// UpdateKey = theAPI->GetGlobalSettings()->GetText("UpdateKey"); // theConf->GetString("Options/UpdateKey");
|
||||
//if (UpdateKey.isEmpty())
|
||||
// UpdateKey = "00000000000000000000000000000000";
|
||||
if (!UpdateKey.isEmpty())
|
||||
|
@ -1029,11 +1029,8 @@ bool COnlineUpdater::IsVersionNewer(const QString& VersionStr)
|
|||
|
||||
void COnlineUpdater::UpdateCert(bool bWait)
|
||||
{
|
||||
QString UpdateKey; // for now only patreons can update the cert automatically
|
||||
TArguments args = GetArguments(g_Certificate, L'\n', L':');
|
||||
if(args.value("TYPE").contains("PATREON"))
|
||||
UpdateKey = args.value("UPDATEKEY");
|
||||
if (UpdateKey.isEmpty()) {
|
||||
// for now only patreons can update the cert automatically
|
||||
if (!CERT_IS_TYPE(g_CertInfo, eCertPatreon)) {
|
||||
theGUI->OpenUrl("https://sandboxie-plus.com/go.php?to=sbie-get-cert");
|
||||
return;
|
||||
}
|
||||
|
@ -1048,6 +1045,7 @@ void COnlineUpdater::UpdateCert(bool bWait)
|
|||
if (m_RequestManager == NULL)
|
||||
m_RequestManager = new CNetworkAccessManager(30 * 1000, this);
|
||||
|
||||
QString UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY");
|
||||
|
||||
QUrlQuery Query;
|
||||
Query.addQueryItem("UpdateKey", UpdateKey);
|
||||
|
|
|
@ -2139,9 +2139,9 @@ void CSandMan::OnStatusChanged()
|
|||
|
||||
uchar UsageFlags = 0;
|
||||
if (theAPI->GetSecureParam("UsageFlags", &UsageFlags, sizeof(UsageFlags))) {
|
||||
if (!g_CertInfo.business) {
|
||||
if (!CERT_IS_TYPE(g_CertInfo, eCertBusiness)) {
|
||||
if ((UsageFlags & (2 | 1)) != 0) {
|
||||
if(g_CertInfo.valid)
|
||||
if(g_CertInfo.active)
|
||||
appTitle.append(tr(" for Personal use"));
|
||||
else
|
||||
appTitle.append(tr(" - for Non-Commercial use ONLY"));
|
||||
|
@ -2545,7 +2545,7 @@ void CSandMan::SaveMessageLog(QIODevice* pFile)
|
|||
|
||||
bool CSandMan::CheckCertificate(QWidget* pWidget)
|
||||
{
|
||||
if (g_CertInfo.valid)
|
||||
if (g_CertInfo.active)
|
||||
return true;
|
||||
|
||||
//if ((g_FeatureFlags & CSbieAPI::eSbieFeatureCert) == 0) {
|
||||
|
@ -2572,13 +2572,8 @@ bool CSandMan::CheckCertificate(QWidget* pWidget)
|
|||
void CSandMan::UpdateCertState()
|
||||
{
|
||||
g_CertInfo.State = theAPI->GetCertState();
|
||||
if (g_CertInfo.valid)
|
||||
if (g_CertInfo.active)
|
||||
{
|
||||
auto Args = GetArguments(g_Certificate, L'\n', L':');
|
||||
QString Type = Args.value("TYPE").toUpper();
|
||||
if (Type.contains("CONTRIBUTOR") || Type.contains("GREAT_PATREON") || Type.contains("HUGE"))
|
||||
g_CertInfo.insider = true;
|
||||
|
||||
// behave as if there would be no certificate at all
|
||||
if (theConf->GetBool("Debug/IgnoreCertificate", false))
|
||||
g_CertInfo.State = 0;
|
||||
|
@ -2594,7 +2589,7 @@ void CSandMan::UpdateCertState()
|
|||
|
||||
// simulate a subscription type certificate having expired
|
||||
if (theConf->GetBool("Debug/CertFakeOld", false)) {
|
||||
g_CertInfo.valid = 0;
|
||||
g_CertInfo.active = 0;
|
||||
g_CertInfo.expired = 1;
|
||||
}
|
||||
|
||||
|
@ -2607,22 +2602,22 @@ void CSandMan::UpdateCertState()
|
|||
// simulate a perpetual use certificate being outside the update window
|
||||
// and having been applied to a version built after the update window has ended
|
||||
if (theConf->GetBool("Debug/CertFakeOutdated", false)) {
|
||||
g_CertInfo.valid = 0;
|
||||
g_CertInfo.active = 0;
|
||||
g_CertInfo.expired = 1;
|
||||
g_CertInfo.outdated = 1;
|
||||
}
|
||||
|
||||
// simulate this being a business certificate - only contributors and other insiders
|
||||
if (g_CertInfo.insider && theConf->GetBool("Debug/CertFakeBusiness", false))
|
||||
g_CertInfo.business = 1;
|
||||
if (CERT_IS_INSIDER(g_CertInfo) && theConf->GetBool("Debug/CertFakeBusiness", false))
|
||||
g_CertInfo.type = eCertBusiness;
|
||||
|
||||
// simulate this being a evaluation certificate
|
||||
if (theConf->GetBool("Debug/CertFakeEvaluation", false))
|
||||
g_CertInfo.evaluation = 1;
|
||||
g_CertInfo.type = eCertBusiness;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_CertInfo.evaluation)
|
||||
if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation))
|
||||
{
|
||||
if (g_CertInfo.expired)
|
||||
OnLogMessage(tr("The evaluation period has expired!!!"));
|
||||
|
|
|
@ -15,8 +15,8 @@ public:
|
|||
CCertBadge(QWidget* parent = NULL): QLabel(parent)
|
||||
{
|
||||
setPixmap(QPixmap(":/Actions/Cert.png").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
if (!g_CertInfo.valid) {
|
||||
setToolTip(COptionsWindow::tr("This option requires a valid supporter certificate"));
|
||||
if (!g_CertInfo.active) {
|
||||
setToolTip(COptionsWindow::tr("This option requires an active supporter certificate"));
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
} else {
|
||||
setToolTip(COptionsWindow::tr("Supporter exclusive option"));
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
protected:
|
||||
void mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
if(!g_CertInfo.valid)
|
||||
if(!g_CertInfo.active)
|
||||
theGUI->OpenUrl(QUrl("https://sandboxie-plus.com/go.php?to=sbie-get-cert"));
|
||||
}
|
||||
};
|
||||
|
@ -38,6 +38,7 @@ void COptionsWindow__AddCertIcon(QWidget* pOriginalWidget)
|
|||
pLayout->setContentsMargins(0, 0, 0, 0);
|
||||
pLayout->setSpacing(0);
|
||||
pLayout->addWidget(new CCertBadge());
|
||||
pLayout->setAlignment(Qt::AlignLeft);
|
||||
pOriginalWidget->parentWidget()->layout()->replaceWidget(pOriginalWidget, pWidget);
|
||||
pLayout->insertWidget(0, pOriginalWidget);
|
||||
}
|
||||
|
@ -64,7 +65,7 @@ void COptionsWindow::CreateGeneral()
|
|||
connect(ui.lblBoxInfo, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
|
||||
ui.lblSupportCert->setVisible(false);
|
||||
if (!g_CertInfo.valid)
|
||||
if (!g_CertInfo.active)
|
||||
{
|
||||
ui.lblSupportCert->setVisible(true);
|
||||
connect(ui.lblSupportCert, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
|
|
|
@ -1025,8 +1025,8 @@ void CSettingsWindow::LoadSettings()
|
|||
ui.chkUpdateAddons->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForAddons", 2)));
|
||||
ui.chkUpdateIssues->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForIssues", 2)));
|
||||
|
||||
//ui.chkUpdateTemplates->setEnabled(g_CertInfo.valid && !g_CertInfo.expired);
|
||||
ui.chkUpdateIssues->setEnabled(g_CertInfo.valid && !g_CertInfo.expired);
|
||||
//ui.chkUpdateTemplates->setEnabled(g_CertInfo.active && !g_CertInfo.expired);
|
||||
ui.chkUpdateIssues->setEnabled(g_CertInfo.active && !g_CertInfo.expired);
|
||||
}
|
||||
|
||||
void CSettingsWindow::UpdateCert()
|
||||
|
@ -1043,7 +1043,7 @@ void CSettingsWindow::UpdateCert()
|
|||
if (g_CertInfo.expired) {
|
||||
palette.setColor(QPalette::Base, QColor(255, 255, 192));
|
||||
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.active) {
|
||||
if (g_CertInfo.grace_period)
|
||||
infoMsg.append(tr("<br /><font color='red'>Plus features will be disabled in %1 days.</font>").arg((g_CertInfo.expirers_in_sec + 30*60*60*24) / (60*60*24)));
|
||||
else if (!g_CertInfo.outdated) // must be an expiren medium or large cert on an old build
|
||||
|
@ -1069,7 +1069,7 @@ void CSettingsWindow::UpdateCert()
|
|||
ui.txtCertificate->setPalette(palette);
|
||||
}
|
||||
|
||||
ui.radInsider->setEnabled(g_CertInfo.insider);
|
||||
ui.radInsider->setEnabled(CERT_IS_INSIDER(g_CertInfo));
|
||||
}
|
||||
|
||||
void CSettingsWindow::UpdateUpdater()
|
||||
|
@ -1083,7 +1083,7 @@ void CSettingsWindow::UpdateUpdater()
|
|||
}
|
||||
else {
|
||||
ui.cmbInterval->setEnabled(true);
|
||||
if (ui.radStable->isChecked() && (!g_CertInfo.valid || g_CertInfo.expired)) {
|
||||
if (ui.radStable->isChecked() && (!g_CertInfo.active || g_CertInfo.expired)) {
|
||||
ui.cmbUpdate->setEnabled(false);
|
||||
ui.cmbUpdate->setCurrentIndex(ui.cmbUpdate->findData("ignore"));
|
||||
ui.lblRevision->setText(tr("Supporter certificate required"));
|
||||
|
@ -1481,7 +1481,7 @@ bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* w
|
|||
if (g_CertInfo.expired || g_CertInfo.outdated) {
|
||||
if(g_CertInfo.outdated)
|
||||
QMessageBox::information(widget, "Sandboxie-Plus", tr("This certificate is unfortunately not valid for the current build, you need to get a new certificate or downgrade to an earlier build."));
|
||||
else if(g_CertInfo.valid && !g_CertInfo.grace_period)
|
||||
else if(g_CertInfo.active && !g_CertInfo.grace_period)
|
||||
QMessageBox::information(widget, "Sandboxie-Plus", tr("Although this certificate has expired, for the currently installed version plus features remain enabled. However, you will no longer have access to Sandboxie-Live services, including compatibility updates and the online troubleshooting database."));
|
||||
else
|
||||
QMessageBox::information(widget, "Sandboxie-Plus", tr("This certificate has unfortunately expired, you need to get a new certificate."));
|
||||
|
|
|
@ -192,22 +192,7 @@ void WindowsMoveFile(const QString& from, const QString& to);
|
|||
extern quint32 g_FeatureFlags;
|
||||
|
||||
extern QByteArray g_Certificate;
|
||||
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
|
||||
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 : 7,
|
||||
insider : 1;
|
||||
qint32 expirers_in_sec;
|
||||
};
|
||||
};
|
||||
|
||||
#include "..\..\Sandboxie\core\drv\verify.h"
|
||||
|
||||
extern SCertInfo g_CertInfo;
|
||||
|
|
|
@ -24,7 +24,7 @@ QDateTime GetSbieInstallationDate()
|
|||
|
||||
bool CSupportDialog::IsBusinessUse()
|
||||
{
|
||||
if (g_CertInfo.business)
|
||||
if (CERT_IS_TYPE(g_CertInfo, eCertBusiness))
|
||||
return true;
|
||||
uchar UsageFlags = 0;
|
||||
theAPI->GetSecureParam("UsageFlags", &UsageFlags, sizeof(UsageFlags));
|
||||
|
@ -36,14 +36,14 @@ bool CSupportDialog::CheckSupport(bool bOnRun)
|
|||
bool NoGo = false;
|
||||
|
||||
#ifdef INSIDER_BUILD
|
||||
if (g_CertInfo.valid) {
|
||||
if (!g_CertInfo.insider) {
|
||||
if (g_CertInfo.active) {
|
||||
if (!CERT_IS_INSIDER(g_CertInfo)) {
|
||||
TArguments args = GetArguments(g_Certificate, L'\n', L':');
|
||||
if (args.value("TYPE").contains("PATREON")) {
|
||||
if (QMessageBox::question(NULL, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR.\n"
|
||||
"If you are a Great Supporter on Patreon already, Sandboxie can check online for an update of your certificate."), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok) {
|
||||
theGUI->m_pUpdater->UpdateCert(true);
|
||||
if (g_CertInfo.insider)
|
||||
if (CERT_IS_INSIDER(g_CertInfo))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ bool CSupportDialog::CheckSupport(bool bOnRun)
|
|||
|
||||
NoGo = true;
|
||||
#else
|
||||
if (g_CertInfo.valid)
|
||||
if (g_CertInfo.active)
|
||||
return false;
|
||||
|
||||
QDateTime InstallDate = GetSbieInstallationDate();
|
||||
|
@ -131,7 +131,7 @@ bool CSupportDialog::ShowDialog(bool NoGo, int Wait)
|
|||
QString Message;
|
||||
|
||||
#ifdef INSIDER_BUILD
|
||||
if (!g_CertInfo.insider)
|
||||
if (!CERT_IS_INSIDER(g_CertInfo))
|
||||
{
|
||||
Message += tr("This is a <a href=\"https://sandboxie-plus.com/go.php?to=sbie-insider\">exclusive Insider build</a> of Sandboxie-Plus it is only available to <a href=\"https://sandboxie-plus.com/go.php?to=patreon\">Patreon Supporters</a> on higher tiers as well as to project contributors and owners of a HUGE supporter certificate.");
|
||||
}
|
||||
|
@ -303,11 +303,11 @@ void CSupportDialog::OnButton()
|
|||
pSettingsWindow->showTab("Support", true);
|
||||
connect(pSettingsWindow, &CSettingsWindow::Closed, [this]() {
|
||||
#ifdef INSIDER_BUILD
|
||||
if (g_CertInfo.valid && !g_CertInfo.insider) {
|
||||
if (g_CertInfo.active && !CERT_IS_INSIDER(g_CertInfo)) {
|
||||
TArguments args = GetArguments(g_Certificate, L'\n', L':');
|
||||
if (args.value("TYPE").contains("PATREON")) {
|
||||
theGUI->m_pUpdater->UpdateCert(true);
|
||||
if (g_CertInfo.insider) {
|
||||
if (CERT_IS_INSIDER(g_CertInfo)) {
|
||||
accept();
|
||||
return;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ void CSupportDialog::OnButton()
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
if (g_CertInfo.valid)
|
||||
if (g_CertInfo.active)
|
||||
accept();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ void CBeginPage::initializePage()
|
|||
|
||||
m_pLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding), row++, 0);
|
||||
|
||||
if (!g_CertInfo.valid || g_CertInfo.expired) {
|
||||
if (!g_CertInfo.active || g_CertInfo.expired) {
|
||||
QLabel* pBottomLabel = new QLabel(tr("With a valid <a href=\"https://sandboxie-plus.com/go.php?to=sbie-cert\">supporter certificate</a> the wizard would be even more powerful. "
|
||||
"It could access the <a href=\"https://sandboxie-plus.com/go.php?to=sbie-issue-db\">online solution database</a> to retrieve the latest troubleshooting instructions."));
|
||||
connect(pBottomLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
|
|
|
@ -486,7 +486,7 @@ CAdvancedPage::CAdvancedPage(QWidget *parent)
|
|||
QCheckBox* pImageProtection = new QCheckBox(tr("Prevent sandboxes programs installed on host from loading dll's from the sandbox"));
|
||||
pImageProtection->setToolTip(tr("This feature may reduce compatibility as it also prevents box located processes from writing to host located ones and even starting them."));
|
||||
pImageProtection->setChecked(theConf->GetBool("BoxDefaults/ImagesProtection", false));
|
||||
pImageProtection->setEnabled(g_CertInfo.valid);
|
||||
pImageProtection->setEnabled(g_CertInfo.active);
|
||||
layout->addWidget(pImageProtection, row++, 1, 1, 3);
|
||||
registerField("imagesProtection", pImageProtection);
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ CIntroPage::CIntroPage(QWidget *parent)
|
|||
|
||||
uchar BusinessUse = 2;
|
||||
if (!g_Certificate.isEmpty())
|
||||
BusinessUse = g_CertInfo.business ? 1 : 0;
|
||||
BusinessUse = CERT_IS_TYPE(g_CertInfo, eCertBusiness) ? 1 : 0;
|
||||
else {
|
||||
uchar UsageFlags = 0;
|
||||
if (theAPI->GetSecureParam("UsageFlags", &UsageFlags, sizeof(UsageFlags)))
|
||||
|
@ -256,7 +256,7 @@ CCertificatePage::CCertificatePage(QWidget *parent)
|
|||
registerField("useCertificate", m_pCertificate, "plainText");
|
||||
|
||||
m_pEvaluate = new QCheckBox(tr("Start evaluation without a certificate for a limited period of time."));
|
||||
if (g_CertInfo.evaluation) {
|
||||
if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation)) {
|
||||
m_pEvaluate->setEnabled(false);
|
||||
m_pEvaluate->setChecked(true);
|
||||
}
|
||||
|
@ -627,7 +627,7 @@ void CSBUpdate::initializePage()
|
|||
m_pUpdate->setChecked(true);
|
||||
m_pStable->setChecked(true);
|
||||
|
||||
m_pBottomLabel->setVisible(!g_CertInfo.valid || g_CertInfo.expired);
|
||||
m_pBottomLabel->setVisible(!g_CertInfo.active || g_CertInfo.expired);
|
||||
|
||||
UpdateOptions();
|
||||
}
|
||||
|
@ -651,7 +651,7 @@ void CSBUpdate::UpdateOptions()
|
|||
|
||||
m_pStable->setEnabled(m_pVersion->isChecked());
|
||||
m_pPreview->setEnabled(m_pVersion->isChecked());
|
||||
m_pInsider->setEnabled(g_CertInfo.insider && m_pVersion->isChecked());
|
||||
m_pInsider->setEnabled(CERT_IS_INSIDER(g_CertInfo) && m_pVersion->isChecked());
|
||||
|
||||
m_pHotfixes->setEnabled(m_pVersion->isChecked());
|
||||
}
|
||||
|
|
|
@ -22,17 +22,15 @@ int main(int argc, char *argv[])
|
|||
*wcsrchr(szPath, L'\\') = L'\0';
|
||||
QString AppDir = QString::fromWCharArray(szPath);
|
||||
|
||||
if (QFile::exists(AppDir + "\\Certificate.dat")) {
|
||||
if (QFile::exists(AppDir + "\\Certificate.dat"))
|
||||
CSettingsWindow::LoadCertificate(AppDir + "\\Certificate.dat");
|
||||
g_CertInfo.business = GetArguments(g_Certificate, L'\n', L':').value("TYPE").toUpper().contains("BUSINESS");
|
||||
}
|
||||
|
||||
// use AppFolder/PlusData when present, else fallback to AppFolder
|
||||
QString ConfDir = AppDir + "\\PlusData";
|
||||
if(!QFile::exists(ConfDir))
|
||||
ConfDir = AppDir;
|
||||
// use a shared setting location when used in a business environment for easier administration
|
||||
theConf = new CSettings(ConfDir, "Sandboxie-Plus", g_CertInfo.business);
|
||||
theConf = new CSettings(ConfDir, "Sandboxie-Plus");
|
||||
|
||||
#ifndef _DEBUG
|
||||
InitMiniDumpWriter(QString("SandMan-v%1").arg(CSandMan::GetVersion()).toStdWString().c_str() , QString(theConf->GetConfigDir()).replace("/", "\\").toStdWString().c_str());
|
||||
|
|
Loading…
Reference in New Issue