This commit is contained in:
DavidXanatos 2023-08-15 09:49:03 +02:00
parent d5af62447e
commit 0d7f76a603
16 changed files with 734 additions and 468 deletions

View File

@ -4,6 +4,21 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.11.0 / 5.66.0] - 2023-08-??
### Added
- added certificate info to the about dialog
- added support for new more flexible certificate style
- added option for business customers to retrive hardware bound certificates from a serial number
- added option to upgrade existing certificates using a upgrade serial number
### Changed
- Improved online updater code
### Fixed
- fixed Symbolic links created inside of sandbox dont work properly [#3181](https://github.com/sandboxie-plus/Sandboxie/issues/3181)
## [1.10.5 / 5.65.5] - 2023-08-12

View File

@ -21,8 +21,8 @@
#ifndef _MY_VERSION_H
#define _MY_VERSION_H
#define MY_VERSION_BINARY 5,65,5
#define MY_VERSION_STRING "5.65.5"
#define MY_VERSION_BINARY 5,66,0
#define MY_VERSION_STRING "5.66.0"
#define MY_ABI_VERSION 0x56500
// These #defines are used by either Resource Compiler or NSIS installer

View File

@ -2065,24 +2065,29 @@ void CSbieAPI::ClearPassword()
m->Password.clear();
}
quint32 CSbieAPI::GetFeatureFlags()
bool CSbieAPI::GetDriverInfo(quint32 InfoClass, void* pBuffer, size_t Size)
{
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
API_QUERY_DRIVER_INFO_ARGS *args = (API_QUERY_DRIVER_INFO_ARGS*)parms;
ULONG flags = 0;
//ULONG len = sizeof(flags);
memset(parms, 0, sizeof(parms));
args->func_code = API_QUERY_DRIVER_INFO;
args->info_class.val = 0;
args->info_data.val = &flags;
//args->info_len.val = &len;
args->info_class.val = InfoClass;
args->info_data.val = pBuffer;
args->info_len.val = Size;
NTSTATUS status = m->IoControl(parms);
if (!NT_SUCCESS(status))
return 0;
if (!NT_SUCCESS(status)) {
memset(pBuffer, 0, Size);
return false;
}
return true;
}
quint32 CSbieAPI::GetFeatureFlags()
{
quint32 flags = 0;
GetDriverInfo(0, &flags, sizeof(flags));
return flags;
}
@ -2109,27 +2114,6 @@ QString CSbieAPI::GetFeatureStr()
return str.join(",");
}
quint64 CSbieAPI::GetCertState()
{
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
API_QUERY_DRIVER_INFO_ARGS *args = (API_QUERY_DRIVER_INFO_ARGS*)parms;
ULONGLONG state = 0;
ULONG len = sizeof(state);
memset(parms, 0, sizeof(parms));
args->func_code = API_QUERY_DRIVER_INFO;
args->info_class.val = -1;
args->info_data.val = &state;
args->info_len.val = len;
NTSTATUS status = m->IoControl(parms);
if (!NT_SUCCESS(status))
return 0;
return state;
}
SB_STATUS CSbieAPI::SetSecureParam(const QString& Name, const void* data, size_t size)
{
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];

View File

@ -107,6 +107,8 @@ public:
virtual SB_STATUS LockConfig(const QString& NewPassword);
virtual void ClearPassword();
virtual bool GetDriverInfo(quint32 InfoClass, void* pBuffer, size_t Size);
enum EFeatureFlags
{
eSbieFeatureWFP = 0x00000001,
@ -121,7 +123,6 @@ public:
virtual quint32 GetFeatureFlags();
virtual QString GetFeatureStr();
virtual quint64 GetCertState();
// Forced Processes
virtual SB_STATUS DisableForceProcess(bool Set, int Seconds = 0);

View File

@ -1272,7 +1272,7 @@
<item row="0" column="1">
<widget class="QTabWidget" name="tabsSupport">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabCert">
<attribute name="title">
@ -1284,28 +1284,43 @@
<property name="leftMargin">
<number>0</number>
</property>
<item row="7" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="5" column="1" colspan="3">
<widget class="QLabel" name="lblCertExp">
<property name="font">
<font>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="0" colspan="4">
<widget class="QCheckBox" name="chkNoCheck">
<property name="text">
<string>In the future, don't notify about certificate expiration</string>
<string>This supporter certificate has expired, please &lt;a href=&quot;https://sandboxie-plus.com/go.php?to=sbie-renew-cert&quot;&gt;get an updated certificate&lt;/a&gt;.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="5" colspan="2">
<item row="4" column="1" colspan="3">
<widget class="QPlainTextEdit" name="txtCertificate">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>73</height>
</size>
</property>
<property name="placeholderText">
<string>Enter the support certificate here</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="3">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@ -1317,50 +1332,7 @@
</property>
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QLabel" name="lblCertExp">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>This supporter certificate has expired, please &lt;a href=&quot;sbie://update/cert&quot;&gt;get an updated certificate&lt;/a&gt;.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_38">
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="2">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2" colspan="2">
<item row="3" column="1" colspan="3">
<widget class="QLabel" name="lblSupportCert">
<property name="text">
<string>Supporters of the Sandboxie-Plus project can receive a &lt;a href=&quot;https://sandboxie-plus.com/go.php?to=sbie-cert&quot;&gt;supporter certificate&lt;/a&gt;. It's like a license key but for awesome people using open source software. :-)</string>
@ -1370,7 +1342,24 @@
</property>
</widget>
</item>
<item row="1" column="2" rowspan="2" colspan="2">
<item row="7" column="2">
<widget class="QToolButton" name="btnGetCert">
<property name="text">
<string>Get</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QLabel" name="lblSerial">
<property name="text">
<string>Retrieve/Upgrade/Renew certificate using Serial Number</string>
</property>
<property name="openExternalLinks">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1" rowspan="2" colspan="3">
<widget class="QLabel" name="lblSupport">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
@ -1389,19 +1378,58 @@
</property>
</widget>
</item>
<item row="4" column="2" colspan="2">
<widget class="QPlainTextEdit" name="txtCertificate">
<item row="7" column="1">
<widget class="QLineEdit" name="txtSerial">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>73</height>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="placeholderText">
<string>Enter the support certificate here</string>
<string>SBIE_-_____-_____-_____-_____</string>
</property>
</widget>
</item>
<item row="7" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="0" colspan="3">
<widget class="QCheckBox" name="chkNoCheck">
<property name="text">
<string>In the future, don't notify about certificate expiration</string>
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>

View File

@ -24,7 +24,7 @@
#undef VERSION_MIN
#define VERSION_MIN 9
#undef VERSION_REV
#define VERSION_REV 8
#define VERSION_REV 7
#undef VERSION_UPD
#define VERSION_UPD 0
@ -38,13 +38,216 @@ DWORD GetIdleTime() // in seconds
return (GetTickCount() - lastInPut.dwTime) / 1000;
}
COnlineUpdater::COnlineUpdater(QObject *parent) : QObject(parent)
COnlineUpdater::COnlineUpdater(QObject* parent) : QObject(parent)
{
m_IgnoredUpdates = theConf->GetStringList("Options/IgnoredUpdates");
m_RequestManager = NULL;
m_pUpdaterUtil = NULL;
LoadState();
}
void COnlineUpdater::StartJob(CUpdatesJob* pJob, const QUrl& Url)
{
if (m_RequestManager == NULL)
m_RequestManager = new CNetworkAccessManager(30 * 1000, this);
QNetworkRequest Request = QNetworkRequest(Url);
//Request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
Request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
//Request.setRawHeader("Accept-Encoding", "gzip");
QNetworkReply* pReply = m_RequestManager->get(Request);
connect(pReply, SIGNAL(finished()), this, SLOT(OnRequestFinished()));
connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), pJob, SLOT(OnDownloadProgress(qint64, qint64)));
connect(pJob->m_pProgress.data(), &CSbieProgress::Canceled, pReply, &QNetworkReply::abort);
m_JobQueue.insert(pReply, pJob);
}
void COnlineUpdater::OnRequestFinished()
{
QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());
CUpdatesJob* pJob = m_JobQueue.take(pReply);
if (pJob) {
pJob->Finish(pReply);
pJob->deleteLater();
}
pReply->deleteLater();
}
SB_PROGRESS COnlineUpdater::GetUpdates(QObject* receiver, const char* member, const QVariantMap& Params)
{
QUrlQuery Query;
Query.addQueryItem("action", "update");
Query.addQueryItem("software", "sandboxie-plus");
//QString Branch = theConf->GetString("Options/ReleaseBranch");
//if (!Branch.isEmpty())
// Query.addQueryItem("branch", Branch);
//Query.addQueryItem("version", theGUI->GetVersion());
//Query.addQueryItem("version", QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV) + "." + QString::number(VERSION_UPD));
#ifdef INSIDER_BUILD
Query.addQueryItem("version", QString(__DATE__));
#else
Query.addQueryItem("version", QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV));
#endif
Query.addQueryItem("system", "windows-" + QSysInfo::kernelVersion() + "-" + QSysInfo::currentCpuArchitecture());
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 = "00000000000000000000000000000000";
if (!UpdateKey.isEmpty())
UpdateKey += "-";
quint64 RandID = 0;
theAPI->GetSecureParam("RandID", &RandID, sizeof(RandID));
if (!RandID) {
RandID = QRandomGenerator64::global()->generate();
theAPI->SetSecureParam("RandID", &RandID, sizeof(RandID));
}
quint32 Hash = theAPI->GetUserSettings()->GetName().mid(13).toInt(NULL, 16);
quint64 HashID = RandID ^ (quint64((Hash & 0xFFFF) ^ ((Hash >> 16) & 0xFFFF)) << 48); // fold the hash in half and xor it with the first 16 bit of RandID
UpdateKey += QString::number(HashID, 16).rightJustified(16, '0').toUpper();
Query.addQueryItem("update_key", UpdateKey);
if (Params.contains("channel"))
Query.addQueryItem("channel", Params["channel"].toString());
else {
QString ReleaseChannel = theConf->GetString("Options/ReleaseChannel", "stable");
Query.addQueryItem("channel", ReleaseChannel);
}
Query.addQueryItem("auto", Params["manual"].toBool() ? "0" : "1");
if (!Params["manual"].toBool()) {
int UpdateInterval = theConf->GetInt("Options/UpdateInterval", UPDATE_INTERVAL); // in seconds
Query.addQueryItem("interval", QString::number(UpdateInterval));
}
#ifdef _DEBUG
QString Test = Query.toString();
#endif
QUrl Url("https://sandboxie-plus.com/update.php");
Url.setQuery(Query);
CUpdatesJob* pJob = new CGetUpdatesJob(Params, this);
StartJob(pJob, Url);
QObject::connect(pJob, SIGNAL(UpdateData(const QVariantMap&, const QVariantMap&)), receiver, member, Qt::QueuedConnection);
return SB_PROGRESS(OP_ASYNC, pJob->m_pProgress);
}
void CGetUpdatesJob::Finish(QNetworkReply* pReply)
{
QByteArray Reply = pReply->readAll();
m_pProgress->Finish(SB_OK);
QVariantMap Data = QJsonDocument::fromJson(Reply).toVariant().toMap();
emit UpdateData(Data, m_Params);
}
SB_PROGRESS COnlineUpdater::DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params)
{
CUpdatesJob* pJob = new CGetFileJob(Params, this);
StartJob(pJob, Url);
QObject::connect(pJob, SIGNAL(Download(const QString&, const QVariantMap&)), receiver, member, Qt::QueuedConnection);
return SB_PROGRESS(OP_ASYNC, pJob->m_pProgress);
}
void CGetFileJob::Finish(QNetworkReply* pReply)
{
quint64 Size = pReply->bytesAvailable();
m_pProgress->SetProgress(-1);
QString FilePath = m_Params["path"].toString();
if (FilePath.isEmpty()) {
QString Name = pReply->request().url().fileName();
if (Name.isEmpty())
Name = "unnamed_download.tmp";
FilePath = ((COnlineUpdater*)parent())->GetUpdateDir(true) + "/" + Name;
}
QFile File(FilePath);
if (File.open(QFile::WriteOnly)) {
while (pReply->bytesAvailable() > 0)
File.write(pReply->read(4096));
File.flush();
QDateTime Date = m_Params["setDate"].toDateTime();
if(Date.isValid())
File.setFileTime(Date, QFileDevice::FileModificationTime);
File.close();
}
m_pProgress->Finish(SB_OK);
if (File.size() != Size) {
QMessageBox::critical(theGUI, "Sandboxie-Plus", tr("Failed to download file from: %1").arg(pReply->request().url().toString()));
return;
}
emit Download(FilePath, m_Params);
}
SB_PROGRESS COnlineUpdater::GetSupportCert(const QString& Serial, QObject* receiver, const char* member, const QVariantMap& Params)
{
QString UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY");
QUrlQuery Query;
if (!Serial.isEmpty()) {
Query.addQueryItem("SN", Serial);
if (Serial.length() > 5 && Serial.at(4).toUpper() == 'N') { // node locked business use
wchar_t uuid_str[40];
theAPI->GetDriverInfo(-2, uuid_str, sizeof(uuid_str));
Query.addQueryItem("HwId", QString::fromWCharArray(uuid_str));
}
}
if(!UpdateKey.isEmpty())
Query.addQueryItem("UpdateKey", UpdateKey);
#ifdef _DEBUG
QString Test = Query.toString();
#endif
QUrl Url("https://sandboxie-plus.com/get_cert.php");
Url.setQuery(Query);
CUpdatesJob* pJob = new CGetCertJob(Params, this);
StartJob(pJob, Url);
QObject::connect(pJob, SIGNAL(Certificate(const QByteArray&, const QVariantMap&)), receiver, member, Qt::QueuedConnection);
return SB_PROGRESS(OP_ASYNC, pJob->m_pProgress);
}
void CGetCertJob::Finish(QNetworkReply* pReply)
{
QByteArray Reply = pReply->readAll();
m_pProgress->Finish(SB_OK);
if (Reply.left(1) == "{") { // error
QVariantMap Data = QJsonDocument::fromJson(Reply).toVariant().toMap();
Reply.clear();
m_Params["error"] = Data["errorMsg"].toString();
}
emit Certificate(Reply, m_Params);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Update Handling
//
void COnlineUpdater::LoadState()
{
m_CheckMode = eInit;
int iUpdate = 0;
@ -116,18 +319,6 @@ void COnlineUpdater::Process()
}
}
if (!m_pUpdateProgress.isNull() && m_RequestManager != NULL) {
if (m_pUpdateProgress->IsCanceled()) {
m_pUpdateProgress->Finish(SB_OK);
m_pUpdateProgress.clear();
m_RequestManager->AbortAll();
if (m_pUpdaterUtil && m_pUpdaterUtil->state() == QProcess::Running)
m_pUpdaterUtil->terminate();
}
}
if (m_CheckMode == ePendingUpdate || m_CheckMode == ePendingInstall)
{
// When auto install/apply is active wait for the user to be idle
@ -146,139 +337,37 @@ void COnlineUpdater::Process()
}
}
void COnlineUpdater::GetUpdates(QObject* receiver, const char* member, const QVariantMap& Params)
{
CGetUpdatesJob* pJob = new CGetUpdatesJob(Params, this);
QObject::connect(pJob, SIGNAL(UpdateData(const QVariantMap&, const QVariantMap&)), receiver, member, Qt::QueuedConnection);
if (m_RequestManager == NULL)
m_RequestManager = new CNetworkAccessManager(30 * 1000, this);
QUrlQuery Query;
Query.addQueryItem("action", "update");
Query.addQueryItem("software", "sandboxie-plus");
//QString Branch = theConf->GetString("Options/ReleaseBranch");
//if (!Branch.isEmpty())
// Query.addQueryItem("branch", Branch);
//Query.addQueryItem("version", theGUI->GetVersion());
//Query.addQueryItem("version", QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV) + "." + QString::number(VERSION_UPD));
#ifdef INSIDER_BUILD
Query.addQueryItem("version", QString(__DATE__));
#else
Query.addQueryItem("version", QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV));
#endif
Query.addQueryItem("system", "windows-" + QSysInfo::kernelVersion() + "-" + QSysInfo::currentCpuArchitecture());
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 = "00000000000000000000000000000000";
if (!UpdateKey.isEmpty())
UpdateKey += "-";
quint64 RandID = 0;
theAPI->GetSecureParam("RandID", &RandID, sizeof(RandID));
if (!RandID) {
RandID = QRandomGenerator64::global()->generate();
theAPI->SetSecureParam("RandID", &RandID, sizeof(RandID));
}
quint32 Hash = theAPI->GetUserSettings()->GetName().mid(13).toInt(NULL, 16);
quint64 HashID = RandID ^ (quint64((Hash & 0xFFFF) ^ ((Hash >> 16) & 0xFFFF)) << 48); // fold the hash in half and xor it with the first 16 bit of RandID
UpdateKey += QString::number(HashID, 16).rightJustified(16, '0').toUpper();
Query.addQueryItem("update_key", UpdateKey);
if (Params.contains("channel"))
Query.addQueryItem("channel", Params["channel"].toString());
else {
QString ReleaseChannel = theConf->GetString("Options/ReleaseChannel", "stable");
Query.addQueryItem("channel", ReleaseChannel);
}
Query.addQueryItem("auto", Params["manual"].toBool() ? "0" : "1");
if (!Params["manual"].toBool()) {
int UpdateInterval = theConf->GetInt("Options/UpdateInterval", UPDATE_INTERVAL); // in seconds
Query.addQueryItem("interval", QString::number(UpdateInterval));
}
#ifdef _DEBUG
QString Test = Query.toString();
#endif
QUrl Url("https://sandboxie-plus.com/update.php");
Url.setQuery(Query);
QNetworkRequest Request = QNetworkRequest(Url);
//Request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
Request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
//Request.setRawHeader("Accept-Encoding", "gzip");
QNetworkReply* pReply = m_RequestManager->get(Request);
connect(pReply, SIGNAL(finished()), this, SLOT(OnUpdateCheck()));
m_JobQueue.insert(pReply, pJob);
}
void COnlineUpdater::CheckForUpdates(bool bManual)
{
if (!m_pUpdateProgress.isNull())
return;
if (m_CheckMode == eManual || m_CheckMode == eAuto)
return; // already in progress
#ifdef _DEBUG
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
bManual = false;
#endif
if (bManual) {
m_pUpdateProgress = CSbieProgressPtr(new CSbieProgress());
theGUI->AddAsyncOp(m_pUpdateProgress);
m_pUpdateProgress->ShowMessage(tr("Checking for updates..."));
}
// clean up old check result
m_UpdateData.clear();
m_CheckMode = bManual ? eManual : eAuto;
GetUpdates(this, SLOT(OnUpdateData(const QVariantMap&, const QVariantMap&)));
}
void COnlineUpdater::OnUpdateCheck()
{
QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());
QByteArray Reply = pReply->readAll();
pReply->deleteLater();
CGetUpdatesJob* pJob = m_JobQueue.take(pReply);
if (!pJob)
return;
QVariantMap Data = QJsonDocument::fromJson(Reply).toVariant().toMap();
emit pJob->UpdateData(Data, pJob->m_Params);
pJob->deleteLater();
}
void COnlineUpdater::OnDownloadProgress(qint64 bytes, qint64 bytesTotal)
{
if (bytesTotal != 0 && !m_pUpdateProgress.isNull())
m_pUpdateProgress->Progress(100 * bytes / bytesTotal);
QVariantMap Params;
SB_PROGRESS Status = GetUpdates(this, SLOT(OnUpdateData(const QVariantMap&, const QVariantMap&)), Params);
if (bManual && Status.GetStatus() == OP_ASYNC) {
theGUI->AddAsyncOp(Status.GetValue());
Status.GetValue()->ShowMessage(tr("Checking for updates..."));
}
}
void COnlineUpdater::OnUpdateData(const QVariantMap& Data, const QVariantMap& Params)
{
if (!m_pUpdateProgress.isNull()) {
m_pUpdateProgress->Finish(SB_OK);
m_pUpdateProgress.clear();
}
if (Data.isEmpty() || Data["error"].toBool()) {
QString Error = Data.isEmpty() ? tr("server not reachable") : Data["errorMsg"].toString();
theGUI->OnLogMessage(tr("Failed to check for updates, error: %1").arg(Error), m_CheckMode != eManual);
if (m_CheckMode == eManual)
QMessageBox::critical(theGUI, "Sandboxie-Plus", tr("Failed to check for updates, error: %1").arg(Error));
m_CheckMode = eInit;
return;
}
@ -414,6 +503,9 @@ bool COnlineUpdater::HandleUpdate()
m_CheckMode = ePendingInstall;
}
if (m_CheckMode != ePendingUpdate && m_CheckMode != ePendingInstall)
m_CheckMode = eInit;
return bNewRelease || bNewUpdate;
}
@ -560,6 +652,10 @@ bool COnlineUpdater::DownloadUpdate(const QVariantMap& Update, bool bAndApply)
return false;
m_pUpdateProgress = CSbieProgressPtr(new CSbieProgress());
connect(m_pUpdateProgress.data(), &CSbieProgress::Canceled, this, [&]() {
if (m_pUpdaterUtil && m_pUpdaterUtil->state() == QProcess::Running)
m_pUpdaterUtil->terminate();
});
theGUI->AddAsyncOp(m_pUpdateProgress);
m_pUpdateProgress->ShowMessage(tr("Downloading updates..."));
@ -715,72 +811,6 @@ SB_RESULT(int) COnlineUpdater::RunUpdater(const QStringList& Params, bool bSilen
return CSbieResult<int>(ExitCode);
}
void COnlineUpdater::DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params)
{
CGetUpdatesJob* pJob = new CGetUpdatesJob(Params, this);
QObject::connect(pJob, SIGNAL(Download(const QString&, const QVariantMap&)), receiver, member, Qt::QueuedConnection);
if (m_RequestManager == NULL)
m_RequestManager = new CNetworkAccessManager(30 * 1000, this);
QNetworkRequest Request = QNetworkRequest(Url);
//Request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
Request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
//Request.setRawHeader("Accept-Encoding", "gzip");
QNetworkReply* pReply = m_RequestManager->get(Request);
connect(pReply, SIGNAL(finished()), this, SLOT(OnFileDownload()));
connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(OnDownloadProgress(qint64, qint64)));
m_JobQueue.insert(pReply, pJob);
}
void COnlineUpdater::OnFileDownload()
{
if(!m_pUpdateProgress.isNull())
m_pUpdateProgress->Progress(-1);
QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());
quint64 Size = pReply->bytesAvailable();
CGetUpdatesJob* pJob = m_JobQueue.take(pReply);
if (!pJob)
return;
QString FilePath = pJob->m_Params["path"].toString();
if (FilePath.isEmpty()) {
QString Name = pReply->request().url().fileName();
if (Name.isEmpty() || Name.right(4).compare(".exe", Qt::CaseInsensitive) != 0)
Name = "Sandboxie-Plus-Install.exe";
FilePath = GetUpdateDir(true) + "/" + Name;
}
QFile File(FilePath);
if (File.open(QFile::WriteOnly)) {
while (pReply->bytesAvailable() > 0)
File.write(pReply->read(4096));
File.flush();
QDateTime Date = pJob->m_Params["setDate"].toDateTime();
if(Date.isValid())
File.setFileTime(Date, QFileDevice::FileModificationTime);
File.close();
}
pReply->deleteLater();
if (!m_pUpdateProgress.isNull()) {
m_pUpdateProgress->Finish(SB_OK);
m_pUpdateProgress.clear();
}
if (File.size() != Size) {
QMessageBox::critical(theGUI, "Sandboxie-Plus", tr("Failed to download file from: %1").arg(pReply->request().url().toString()));
return;
}
emit pJob->Download(FilePath, pJob->m_Params);
pJob->deleteLater();
}
bool COnlineUpdater::DownloadInstaller(const QVariantMap& Release, bool bAndRun)
{
if (m_RequestManager == NULL)
@ -803,11 +833,11 @@ bool COnlineUpdater::DownloadInstaller(const QVariantMap& Release, bool bAndRun)
Params["run"] = bAndRun;
Params["version"] = MakeVersionStr(Release);
Params["signature"] = Installer["signature"];
DownloadFile(DownloadUrl, this, SLOT(OnInstallerDownload(const QString&, const QVariantMap&)), Params);
m_pUpdateProgress = CSbieProgressPtr(new CSbieProgress());
theGUI->AddAsyncOp(m_pUpdateProgress);
m_pUpdateProgress->ShowMessage(tr("Downloading installer..."));
SB_PROGRESS Status = DownloadFile(DownloadUrl, this, SLOT(OnInstallerDownload(const QString&, const QVariantMap&)), Params);
if (Status.GetStatus() == OP_ASYNC) {
theGUI->AddAsyncOp(Status.GetValue());
Status.GetValue()->ShowMessage(tr("Downloading installer..."));
}
return true;
}
@ -1027,89 +1057,3 @@ bool COnlineUpdater::IsVersionNewer(const QString& VersionStr)
return VersionToInt(VersionStr) > CurrentVersion();
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// cert stuf
void COnlineUpdater::UpdateCert(bool bWait)
{
// 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;
}
if (!m_pUpdateProgress.isNull())
return;
m_pUpdateProgress = CSbieProgressPtr(new CSbieProgress());
theGUI->AddAsyncOp(m_pUpdateProgress);
m_pUpdateProgress->ShowMessage(tr("Checking for certificate..."));
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);
QUrl Url("https://sandboxie-plus.com/get_cert.php");
Url.setQuery(Query);
QNetworkRequest Request = QNetworkRequest(Url);
//Request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
Request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
//Request.setRawHeader("Accept-Encoding", "gzip");
QNetworkReply* pReply = m_RequestManager->get(Request);
connect(pReply, SIGNAL(finished()), this, SLOT(OnCertCheck()));
if (bWait) {
while (!pReply->isFinished()) {
QCoreApplication::processEvents(); // keep UI responsive
}
}
}
void COnlineUpdater::OnCertCheck()
{
if (m_pUpdateProgress.isNull())
return;
QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());
QByteArray Reply = pReply->readAll();
int Code = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
pReply->deleteLater();
m_pUpdateProgress->Finish(SB_OK);
m_pUpdateProgress.clear();
if (Code > 299 || Code < 200) {
QMessageBox::critical(theGUI, "Sandboxie-Plus", tr("No certificate found on server!"));
return;
}
if (Reply.replace("\r\n","\n").compare(g_Certificate.replace("\r\n","\n"), Qt::CaseInsensitive) == 0){
QMessageBox::information(theGUI, "Sandboxie-Plus", tr("There is no updated certificate available."));
return;
}
QString CertPath = theAPI->GetSbiePath() + "\\Certificate.dat";
QString TempPath = QDir::tempPath() + "/Sbie+Certificate.dat";
QFile CertFile(TempPath);
if (CertFile.open(QFile::WriteOnly)) {
CertFile.write(Reply);
CertFile.close();
}
WindowsMoveFile(TempPath.replace("/", "\\"), CertPath.replace("/", "\\"));
if (!theAPI->ReloadCert().IsError()) {
CSettingsWindow::LoadCertificate();
theGUI->UpdateCertState();
}
else { // this should not happen
g_Certificate.clear();
g_CertInfo.State = 0;
}
}

View File

@ -7,23 +7,77 @@
#define UPDATE_INTERVAL (7 * 24 * 60 * 60)
class CGetUpdatesJob : public QObject
class CUpdatesJob : public QObject
{
Q_OBJECT
protected:
friend class COnlineUpdater;
CGetUpdatesJob(const QVariantMap& Params, QObject* parent = nullptr) : QObject(parent) { m_Params = Params; }
virtual ~CGetUpdatesJob() {}
CUpdatesJob(const QVariantMap& Params, QObject* parent = nullptr) : QObject(parent)
{
m_Params = Params;
m_pProgress = CSbieProgressPtr(new CSbieProgress());
}
virtual ~CUpdatesJob() {}
QVariantMap m_Params;
virtual void Finish(QNetworkReply* pReply) = 0;
QVariantMap m_Params;
CSbieProgressPtr m_pProgress;
private slots:
void OnDownloadProgress(qint64 bytes, qint64 bytesTotal)
{
if (bytesTotal != 0 && !m_pProgress.isNull())
m_pProgress->Progress(100 * bytes / bytesTotal);
}
};
class CGetUpdatesJob : public CUpdatesJob
{
Q_OBJECT
protected:
friend class COnlineUpdater;
CGetUpdatesJob(const QVariantMap& Params, QObject* parent = nullptr) : CUpdatesJob(Params, parent) {}
virtual void Finish(QNetworkReply* pReply);
signals:
void UpdateData(const QVariantMap& Data, const QVariantMap& Params);
};
class CGetFileJob : public CUpdatesJob
{
Q_OBJECT
protected:
friend class COnlineUpdater;
CGetFileJob(const QVariantMap& Params, QObject* parent = nullptr) : CUpdatesJob(Params, parent) {}
virtual void Finish(QNetworkReply* pReply);
signals:
void Download(const QString& Path, const QVariantMap& Params);
};
class CGetCertJob : public CUpdatesJob
{
Q_OBJECT
protected:
friend class COnlineUpdater;
CGetCertJob(const QVariantMap& Params, QObject* parent = nullptr) : CUpdatesJob(Params, parent) {}
virtual void Finish(QNetworkReply* pReply);
signals:
void Certificate(const QByteArray& Certificate, const QVariantMap& Params);
};
class COnlineUpdater : public QObject
{
@ -31,16 +85,17 @@ class COnlineUpdater : public QObject
public:
COnlineUpdater(QObject* parent);
void Process();
SB_PROGRESS GetUpdates(QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
SB_PROGRESS DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
SB_PROGRESS GetSupportCert(const QString& Serial, QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
void GetUpdates(QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
void DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
static SB_RESULT(int) RunUpdater(const QStringList& Params, bool bSilent, bool Wait = false);
void Process();
QVariantMap GetUpdateData() { return m_UpdateData; }
QDateTime GetLastUpdateTime() { return m_LastUpdate; }
void UpdateCert(bool bWait = false);
void CheckForUpdates(bool bManual = false);
bool DownloadUpdate(const QVariantMap& Update, bool bAndApply = false);
@ -55,17 +110,14 @@ public:
static int GetCurrentUpdate();
static bool IsVersionNewer(const QString& VersionStr);
QString GetUpdateDir(bool bCreate = false);
static QString GetUpdateDir(bool bCreate = false);
static quint32 CurrentVersion();
static quint32 VersionToInt(const QString& VersionStr);
private slots:
void OnUpdateCheck();
void OnRequestFinished();
void OnFileDownload();
void OnDownloadProgress(qint64 bytes, qint64 bytesTotal);
void OnInstallerDownload(const QString& Path, const QVariantMap& Params);
void OnUpdateData(const QVariantMap& Data, const QVariantMap& Params);
@ -74,9 +126,12 @@ private slots:
void OnPrepareError();
void OnPrepareFinished(int exitCode, QProcess::ExitStatus exitStatus);
void OnCertCheck();
protected:
void StartJob(CUpdatesJob* pJob, const QUrl& Url);
void LoadState();
bool HandleUserMessage(const QVariantMap& Data);
bool HandleUpdate();
@ -91,15 +146,11 @@ protected:
EUpdateScope GetFileScope(const QString& Path);
bool AskDownload(const QVariantMap& Update);
friend class CAddonManager;
static SB_RESULT(int) RunUpdater(const QStringList& Params, bool bSilent, bool Wait = false);
static bool RunInstaller2(const QString& FilePath, bool bSilent);
CNetworkAccessManager* m_RequestManager;
CSbieProgressPtr m_pUpdateProgress;
QMap<QNetworkReply*, CGetUpdatesJob*> m_JobQueue;
QMap<QNetworkReply*, CUpdatesJob*> m_JobQueue;
QStringList m_IgnoredUpdates;
enum ECHeckMode
@ -112,5 +163,7 @@ protected:
} m_CheckMode;
QVariantMap m_UpdateData;
QDateTime m_LastUpdate;
QProcess* m_pUpdaterUtil;
CSbieProgressPtr m_pUpdateProgress;
};

View File

@ -2132,7 +2132,7 @@ void CSandMan::OnStatusChanged()
theAPI->WatchIni(true, theConf->GetBool("Options/WatchIni", true));
if (!theAPI->ReloadCert().IsError())
if (!ReloadCert().IsError())
CSettingsWindow::LoadCertificate();
else {
g_Certificate.clear();
@ -2392,6 +2392,10 @@ void CSandMan::AddLogMessage(const QString& Message)
void CSandMan::AddLogMessage(const QDateTime& TimeStamp, const QString& Message, const QString& Link)
{
QRegularExpression tagExp("<[^>]*>");
QString TextMessage = Message;
TextMessage.remove(tagExp);
int last = m_pMessageLog->GetTree()->topLevelItemCount();
if (last > 0) {
QTreeWidgetItem* pItem = m_pMessageLog->GetTree()->topLevelItem(last-1);
@ -2401,11 +2405,15 @@ void CSandMan::AddLogMessage(const QDateTime& TimeStamp, const QString& Message,
Count = 1;
Count++;
pItem->setData(0, Qt::UserRole, Count);
#ifdef _DEBUG
pItem->setText(1, TextMessage + tr(" (%1)").arg(Count));
#else
QLabel* pLabel = (QLabel*)m_pMessageLog->GetTree()->itemWidget(pItem, 1);
if(pLabel)
pLabel->setText(Message + tr(" (%1)").arg(Count));
else
pItem->setText(1, Message + tr(" (%1)").arg(Count));
#endif
return;
}
}
@ -2414,6 +2422,9 @@ void CSandMan::AddLogMessage(const QDateTime& TimeStamp, const QString& Message,
pItem->setText(0, TimeStamp.toString("hh:mm:ss.zzz"));
pItem->setData(1, Qt::UserRole, Message);
m_pMessageLog->GetTree()->addTopLevelItem(pItem);
#ifdef _DEBUG
pItem->setText(1, TextMessage);
#else
if (!Link.isEmpty()) {
QLabel* pLabel = new QLabel(Message);
pLabel->setContentsMargins(3, 0, 0, 0);
@ -2422,13 +2433,11 @@ void CSandMan::AddLogMessage(const QDateTime& TimeStamp, const QString& Message,
connect(pLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
m_pMessageLog->GetTree()->setItemWidget(pItem, 1, pLabel);
QRegularExpression tagExp("<[^>]*>");
QString TextMessage = Message;
TextMessage.remove(tagExp);
pItem->setText(1, TextMessage);
}
else
pItem->setText(1, Message);
#endif
m_pMessageLog->GetView()->verticalScrollBar()->setValue(m_pMessageLog->GetView()->verticalScrollBar()->maximum());
@ -2575,11 +2584,45 @@ bool CSandMan::CheckCertificate(QWidget* pWidget)
return false;
}
SB_STATUS CSandMan::ReloadCert(QWidget* pWidget)
{
SB_STATUS Status = theAPI->ReloadCert();
if (Status.IsError() && Status.GetStatus() != 0xC0000225 /*STATUS_NOT_FOUND*/)
{
QString Info;
switch (Status.GetStatus())
{
case 0xC000000DL: /*STATUS_INVALID_PARAMETER*/
case 0xC0000079L: /*STATUS_INVALID_SECURITY_DESCR:*/
case 0xC000A000L: /*STATUS_INVALID_SIGNATURE:*/ Info = tr("The Certificate Signature is invalid!"); break;
case 0xC0000024L: /*STATUS_OBJECT_TYPE_MISMATCH:*/ Info = tr("The Certificate is not suitable for this product."); break;
case 0xC0000485L: /*STATUS_FIRMWARE_IMAGE_INVALID:*/ Info = tr("The Certificate is node locked."); break;
default: Info = QString("0x%1").arg((quint32)Status.GetStatus(), 8, 16, QChar('0'));
}
QMessageBox::critical(pWidget ? pWidget : this, "Sandboxie-Plus", tr("The support certificate is not valid.\nError: %1").arg(Info));
}
return Status;
}
void InitCertSlot();
void CSandMan::UpdateCertState()
{
g_CertInfo.State = theAPI->GetCertState();
theAPI->GetDriverInfo(-1, &g_CertInfo.State, sizeof(g_CertInfo.State));
#ifdef _DEBUG
qDebug() << "g_CertInfo" << g_CertInfo.State;
qDebug() << "g_CertInfo.active" << g_CertInfo.active;
qDebug() << "g_CertInfo.expired" << g_CertInfo.expired;
qDebug() << "g_CertInfo.outdated" << g_CertInfo.outdated;
qDebug() << "g_CertInfo.grace_period" << g_CertInfo.grace_period;
qDebug() << "g_CertInfo.type" << CSettingsWindow::GetCertType();
qDebug() << "g_CertInfo.level" << CSettingsWindow::GetCertLevel();
#endif
if (g_CertInfo.active)
{
// behave as if there would be no certificate at all
@ -2615,13 +2658,13 @@ void CSandMan::UpdateCertState()
g_CertInfo.outdated = 1;
}
// simulate this being a business certificate - only contributors and other insiders
if (CERT_IS_INSIDER(g_CertInfo) && theConf->GetBool("Debug/CertFakeBusiness", false))
g_CertInfo.type = eCertBusiness;
int Type = theConf->GetInt("Debug/CertFakeType", -1);
if (Type != -1)
g_CertInfo.type = Type << 2;
// simulate this being a evaluation certificate
if (theConf->GetBool("Debug/CertFakeEvaluation", false))
g_CertInfo.type = eCertBusiness;
int Level = theConf->GetInt("Debug/CertFakeLevel", -1);
if (Level != -1)
g_CertInfo.level = Level;
}
}
@ -3548,8 +3591,6 @@ void CSandMan::OpenUrl(const QUrl& url)
m_pUpdater->RunInstaller(false);
else if (path == "/apply")
m_pUpdater->ApplyUpdate(false);
else if (path == "/cert")
m_pUpdater->UpdateCert();
else
OpenUrl("https://sandboxie-plus.com/sandboxie" + path);
return;
@ -3801,7 +3842,43 @@ void CSandMan::OnAbout()
msgBox->setInformativeText(AboutText);
QIcon ico(QLatin1String(":/SandMan.png"));
msgBox->setIconPixmap(ico.pixmap(128, 128));
QPixmap pix(128, 160);
pix.fill(Qt::transparent);
QPainter painter(&pix);
painter.drawPixmap(0, 0, ico.pixmap(128, 128));
if (g_CertInfo.active)
{
//painter.setPen(Qt::blue);
//painter.drawRect(0, 0, 127, 159);
QFont font;
font.fromString("Cooper Black");
//font.setItalic(true);
font.setPointSize(12);
painter.setFont(font);
painter.setPen(CSettingsWindow::GetCertColor());
QString Type = CSettingsWindow::GetCertType();
//QSize TypeSize = QFontMetrics(painter.font()).size(Qt::TextSingleLine, Type);
//painter.drawText((128 - TypeSize.width()) / 2, 128, TypeSize.width(), TypeSize.height(), 0, Type);
painter.drawText(0, 128 - 8, 128, 16, Qt::AlignHCenter, Type);
if (g_CertInfo.level != eCertMaxLevel && g_CertInfo.level != eCertStandard) {
font.setPointSize(10);
painter.setFont(font);
painter.setPen(Qt::black);
QString Level = CSettingsWindow::GetCertLevel();
painter.drawText(0, 128 + 8, 120, 16, Qt::AlignRight, Level);
}
}
msgBox->setIconPixmap(pix);
SafeExec(msgBox);
}

View File

@ -6,7 +6,6 @@
#include "../MiscHelpers/Common/TreeViewEx.h"
#include "../MiscHelpers/Common/PanelView.h"
#include "../MiscHelpers/Common/ProgressDialog.h"
#include "../MiscHelpers/Common/NetworkAccessManager.h"
#include <QTranslator>
#include "../version.h"
@ -105,6 +104,7 @@ public:
void UpdateTheme();
void UpdateTitleTheme(const HWND& hwnd);
SB_STATUS ReloadCert(QWidget* pWidget = NULL);
void UpdateCertState();
void SaveMessageLog(QIODevice* pFile);
@ -142,6 +142,7 @@ protected:
bool m_bStopPending;
CBoxBorder* m_pBoxBorder;
CSbieTemplatesEx* m_SbieTemplates;
CScriptManager* m_SbieScripts;
CAddonManager* m_AddonManager;

View File

@ -1105,7 +1105,7 @@ QString CSandBoxPlus::GetFullCommand(const QString& Command)
// CSbieTemplatesEx
//
#include <ntstatus.h>
//#include <ntstatus.h>
#define WIN32_NO_STATUS
typedef long NTSTATUS;
#include <Windows.h>

View File

@ -272,7 +272,6 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
LoadSettings();
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
connect(theGUI, SIGNAL(DrivesChanged()), this, SLOT(UpdateDrives()));
@ -442,12 +441,26 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
ui.txtCertificate->setPlaceholderText(
"NAME: User Name\n"
"LEVEL: ULTIMATE\n"
"TYPE: ULTIMATE\n"
"DATE: dd.mm.yyyy\n"
"UPDATEKEY: 00000000000000000000000000000000\n"
"SIGNATURE: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
);
if (g_CertInfo.active) {
QString Text = ui.lblSerial->text();
ui.lblSerial->setText(QString("<a href=\"_\">%1</a>").arg(Text));
ui.txtSerial->setVisible(false);
ui.btnGetCert->setVisible(false);
connect(ui.lblSerial, &QLabel::linkActivated, this, [=]() {
ui.lblSerial->setText(Text);
ui.txtSerial->setVisible(true);
ui.btnGetCert->setVisible(true);
});
}
connect(ui.btnGetCert, SIGNAL(clicked(bool)), this, SLOT(OnGetCert()));
connect(ui.chkNoCheck, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged()));
//
@ -1008,7 +1021,8 @@ void CSettingsWindow::LoadSettings()
void CSettingsWindow::UpdateCert()
{
ui.lblCertExp->setVisible(false);
if (!g_Certificate.isEmpty())
//ui.lblCertLevel->setVisible(!g_Certificate.isEmpty());
if (!g_Certificate.isEmpty())
{
ui.txtCertificate->setPlainText(g_Certificate);
//ui.lblSupport->setVisible(false);
@ -1018,36 +1032,162 @@ void CSettingsWindow::UpdateCert()
palette.setColor(QPalette::Text, Qt::black);
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>.");
QString infoMsg = tr("This supporter certificate has expired, please <a href=\"https://sandboxie-plus.com/go.php?to=sbie-renew-cert\">get an updated certificate</a>.");
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)));
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
infoMsg.append(tr("<br /><font color='red'>For the current build Plus features remain enabled</font>, but you no longer have access to Sandboxie-Live services, including compatibility updates and the troubleshooting database."));
} else
}
else
infoMsg.append(tr("<br />Plus features are no longer enabled."));
ui.lblCertExp->setText(infoMsg);
ui.lblCertExp->setVisible(true);
}
else {
if (g_CertInfo.expirers_in_sec > 0 && g_CertInfo.expirers_in_sec < (60 * 60 * 24 * 30)) {
ui.lblCertExp->setText(tr("This supporter certificate will <font color='red'>expire in %1 days</font>, please <a href=\"sbie://update/cert\">get an updated certificate</a>.").arg(g_CertInfo.expirers_in_sec / (60*60*24)));
ui.lblCertExp->setText(tr("This supporter certificate will <font color='red'>expire in %1 days</font>, please <a href=\"https://sandboxie-plus.com/go.php?to=sbie-renew-cert\">get an updated certificate</a>.").arg(g_CertInfo.expirers_in_sec / (60 * 60 * 24)));
ui.lblCertExp->setVisible(true);
}
/*#ifdef _DEBUG
else {
ui.lblCertExp->setText(tr("This supporter certificate is valid, <a href=\"sbie://update/cert\">check for an updated certificate</a>."));
ui.lblCertExp->setVisible(true);
}
#endif*/
/*#ifdef _DEBUG
else {
ui.lblCertExp->setText(tr("This supporter certificate is valid, <a href=\"https://sandboxie-plus.com/go.php?to=sbie-renew-cert\">check for an updated certificate</a>."));
ui.lblCertExp->setVisible(true);
}
#endif*/
palette.setColor(QPalette::Base, QColor(192, 255, 192));
}
ui.txtCertificate->setPalette(palette);
//ui.lblCertLevel->setText(tr("Feature Level: %1").arg(GetCertLevel()));
//
//QStringList Infos;
//Infos += tr("Type: %1").arg(GetCertType());
//if (CERT_IS_INSIDER(g_CertInfo))
// Infos += tr("Insider release capable");
//ui.lblCertLevel->setToolTip(Infos.join("\n"));
//if (CERT_IS_TYPE(g_CertInfo, eCertBusiness)) {
// ScanForSeats();
// QTimer::singleShot(1000, this, [=]() {
// QString CntInfo = QString::number(CountSeats());
// QString Amount = GetArguments(g_Certificate, L'\n', L':').value("AMOUNT");
// if (!Amount.isEmpty())
// CntInfo += "/" + Amount;
// ui.lblCertCount->setText(CntInfo);
// ui.lblCertCount->setToolTip(tr("Count of certificates in use"));
// });
//}
}
ui.radInsider->setEnabled(CERT_IS_INSIDER(g_CertInfo));
}
void CSettingsWindow::OnGetCert()
{
SB_PROGRESS Status = theGUI->m_pUpdater->GetSupportCert(ui.txtSerial->text(), this, SLOT(OnCertData(const QByteArray&, const QVariantMap&)));
if (Status.GetStatus() == OP_ASYNC) {
theGUI->AddAsyncOp(Status.GetValue());
Status.GetValue()->ShowMessage(tr("Retreiving certificate..."));
}
}
void CSettingsWindow::OnCertData(const QByteArray& Certificate, const QVariantMap& Params)
{
ui.txtCertificate->setPlainText(Certificate);
ApplyCert();
}
void CSettingsWindow::ApplyCert()
{
if (!theAPI->IsConnected())
return;
QByteArray Certificate = ui.txtCertificate->toPlainText().toUtf8();
if (g_Certificate != Certificate) {
QPalette palette = QApplication::palette();
if (theGUI->m_DarkTheme)
palette.setColor(QPalette::Text, Qt::black);
ui.lblCertExp->setVisible(false);
bool bRet = ApplyCertificate(Certificate, this);
if (Certificate.isEmpty())
palette.setColor(QPalette::Base, Qt::white);
else if (!bRet)
palette.setColor(QPalette::Base, QColor(255, 192, 192));
else
palette.setColor(QPalette::Base, QColor(192, 255, 192));
ui.txtCertificate->setPalette(palette);
}
m_CertChanged = false;
}
QString CSettingsWindow::GetCertType()
{
QString CertType;
if (CERT_IS_TYPE(g_CertInfo, eCertContributor))
CertType = tr("Contributor");
else if (CERT_IS_TYPE(g_CertInfo, eCertEternal))
CertType = tr("Eternal");
else if (CERT_IS_TYPE(g_CertInfo, eCertBusiness))
CertType = tr("Business");
else if (CERT_IS_TYPE(g_CertInfo, eCertPersonal))
CertType = tr("Personal");
else if (g_CertInfo.type == eCertGreatPatreon)
CertType = tr("Great Patreon");
else if (CERT_IS_TYPE(g_CertInfo, eCertPatreon))
CertType = tr("Patreon");
else if (g_CertInfo.type == eCertFamily)
CertType = tr("Family");
else if (CERT_IS_TYPE(g_CertInfo, eCertSubscription))
CertType = tr("Subscription");
else if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation))
CertType = tr("Evaluation");
else
CertType = tr("Type %1").arg(g_CertInfo.type);
return CertType;
}
QColor CSettingsWindow::GetCertColor()
{
if (CERT_IS_TYPE(g_CertInfo, eCertEternal))
return QColor(135, 0, 255, 255);
else if (CERT_IS_TYPE(g_CertInfo, eCertBusiness))
return QColor(211, 0, 0, 255);
else if (CERT_IS_TYPE(g_CertInfo, eCertPersonal))
return QColor(38, 127, 0, 255);
else if (CERT_IS_TYPE(g_CertInfo, eCertPatreon))
return QColor(38, 127, 0, 255);
else if (g_CertInfo.type == eCertFamily)
return QColor(0, 38, 255, 255);
else if (CERT_IS_TYPE(g_CertInfo, eCertSubscription))
return QColor(255, 106, 0, 255);
else if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation))
return Qt::gray;
else
return Qt::black;
}
QString CSettingsWindow::GetCertLevel()
{
QString CertLevel;
if (g_CertInfo.level == eCertStandard)
CertLevel = tr("Standard");
else if (g_CertInfo.level == eCertAdvanced)
CertLevel = tr("Advanced");
else if (g_CertInfo.level == eCertMaxLevel)
CertLevel = tr("Max Level");
else
CertLevel = tr("Level %1").arg(g_CertInfo.level);
return CertLevel;
}
void CSettingsWindow::UpdateUpdater()
{
//ui.radLive->setEnabled(false);
@ -1352,32 +1492,8 @@ void CSettingsWindow::SaveSettings()
theConf->SetValue("Options/AutoRunSoftCompat", !ui.chkNoCompat->isChecked());
if (m_CertChanged && theAPI->IsConnected())
{
QByteArray Certificate = ui.txtCertificate->toPlainText().toUtf8();
if (g_Certificate != Certificate) {
QPalette palette = QApplication::palette();
if (theGUI->m_DarkTheme)
palette.setColor(QPalette::Text, Qt::black);
ui.lblCertExp->setVisible(false);
bool bRet = ApplyCertificate(Certificate, this);
if (Certificate.isEmpty())
palette.setColor(QPalette::Base, Qt::white);
else if (!bRet)
palette.setColor(QPalette::Base, QColor(255, 192, 192));
else
palette.setColor(QPalette::Base, QColor(192, 255, 192));
ui.txtCertificate->setPalette(palette);
}
m_CertChanged = false;
}
if(m_CertChanged)
ApplyCert();
theConf->SetValue("Options/NoSupportCheck", ui.chkNoCheck->isChecked());
@ -1440,13 +1556,14 @@ bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* w
}
}
else if(!g_Certificate.isEmpty()){
g_Certificate.clear();
WindowsMoveFile(CertPath.replace("/", "\\"), "");
}
if (Certificate.isEmpty())
return false;
if (!theAPI->ReloadCert().IsError())
if (!theGUI->ReloadCert(widget).IsError())
{
g_FeatureFlags = theAPI->GetFeatureFlags();
g_Certificate = Certificate;
@ -1468,8 +1585,6 @@ bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* w
}
else
{
QMessageBox::critical(widget, "Sandboxie-Plus", tr("This support certificate is not valid."));
g_CertInfo.State = 0;
g_Certificate.clear();
return false;

View File

@ -55,6 +55,10 @@ public:
static void LoadCertificate(QString CertPath = QString());
static QString GetCertType();
static QColor GetCertColor();
static QString GetCertLevel();
signals:
void OptionsChanged(bool bRebuildUI = false);
void Closed();
@ -122,6 +126,9 @@ private slots:
void CertChanged();
void UpdateCert();
void OnGetCert();
void OnCertData(const QByteArray& Certificate, const QVariantMap& Params);
void ApplyCert();
void UpdateUpdater();
void GetUpdates();

View File

@ -20,7 +20,7 @@
#include <QHttpMultiPart>
#include "../Views/TraceView.h"
#include "../AddonManager.h"
#include "../MiscHelpers/Common/NetworkAccessManager.h"
#include "../CustomStyles.h"
CBoxAssistant::CBoxAssistant(QWidget *parent)

View File

@ -7,6 +7,7 @@
#include "Helpers/WinAdmin.h"
#include <QButtonGroup>
#include "../QSbieAPI/SbieUtils.h"
#include "../OnlineUpdater.h"
CSetupWizard::CSetupWizard(int iOldLevel, QWidget *parent)
: QWizard(parent)
@ -246,7 +247,7 @@ CCertificatePage::CCertificatePage(QWidget *parent)
m_pCertificate->setMaximumSize(QSize(16777215, 73));
m_pCertificate->setPlaceholderText(
"NAME: User Name\n"
"LEVEL: ULTIMATE\n"
"TYPE: ULTIMATE\n"
"DATE: dd.mm.yyyy\n"
"UPDATEKEY: 00000000000000000000000000000000\n"
"SIGNATURE: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
@ -255,6 +256,12 @@ CCertificatePage::CCertificatePage(QWidget *parent)
connect(m_pCertificate, SIGNAL(textChanged()), this, SIGNAL(completeChanged()));
registerField("useCertificate", m_pCertificate, "plainText");
layout->addWidget(new QLabel(tr("Retrieve certificate using Serial Number:")));
m_pSerial = new QLineEdit();
m_pSerial->setPlaceholderText("SBIE_-_____-_____-_____-_____");
layout->addWidget(m_pSerial);
m_pEvaluate = new QCheckBox(tr("Start evaluation without a certificate for a limited period of time."));
if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation)) {
m_pEvaluate->setEnabled(false);
@ -305,6 +312,9 @@ void CCertificatePage::initializePage()
m_pEvaluate->setVisible(false);
}
m_pSerial->setVisible(true);
m_pSerial->clear();
}
int CCertificatePage::nextId() const
@ -323,12 +333,39 @@ bool CCertificatePage::isComplete() const
return QWizardPage::isComplete();
}
void CCertificatePage::OnCertData(const QByteArray& Certificate, const QVariantMap& Params)
{
if (!Certificate.isEmpty()) {
m_pSerial->clear();
m_pCertificate->setPlainText(Certificate);
wizard()->next();
}
else {
QString Message = tr("Failed to retrive the certificate.");
Message += tr("\nError: %1").arg(Params["error"].toString());
QMessageBox::critical(this, "Sandboxie-Plus", Message);
}
}
bool CCertificatePage::validatePage()
{
QByteArray Certificate = m_pCertificate->toPlainText().toUtf8();
if (!m_pEvaluate->isChecked() && !Certificate.isEmpty() && g_Certificate != Certificate) {
return CSettingsWindow::ApplyCertificate(Certificate, this);
if (m_pEvaluate->isChecked())
return true;
QString Serial = m_pSerial->text();
if (!Serial.isEmpty()) {
SB_PROGRESS Status = theGUI->m_pUpdater->GetSupportCert(Serial, this, SLOT(OnCertData(const QByteArray&, const QVariantMap&)));
if (Status.GetStatus() == OP_ASYNC) {
theGUI->AddAsyncOp(Status.GetValue());
Status.GetValue()->ShowMessage(tr("Retreiving certificate..."));
}
return false;
}
QByteArray Certificate = m_pCertificate->toPlainText().toUtf8();
if (!Certificate.isEmpty() && Certificate != g_Certificate)
return CSettingsWindow::ApplyCertificate(Certificate, this);
return true;
}

View File

@ -66,9 +66,13 @@ public:
bool isComplete() const override;
bool validatePage() override;
private slots:
void OnCertData(const QByteArray& Certificate, const QVariantMap& Params);
private:
QLabel* m_pTopLabel;
QPlainTextEdit* m_pCertificate;
QLineEdit* m_pSerial;
QCheckBox* m_pEvaluate;
};

View File

@ -1,8 +1,8 @@
#pragma once
#define VERSION_MJR 1
#define VERSION_MIN 10
#define VERSION_REV 5
#define VERSION_MIN 11
#define VERSION_REV 0
#define VERSION_UPD 0
#ifndef STR