summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFredrik Orderud <fredrik.orderud@ge.com>2022-11-28 13:49:44 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-12-15 12:46:32 +0000
commitc28c52d418834f107c41632273dcf8fbb32b15aa (patch)
treefe116c4a6885da6b768c9279570a02e64b286fce
parent457ad21eebd41be2b225db60794c1f39964a414f (diff)
Introduce security sandboxing factory
Encapsulate the LowIntegrity sandboxing impl. behind a Sandboxing interface with a factory function. Done to make room for upcoming AppContainer sandboxing support. Task-number: QTBUG-109184 Change-Id: Iaca3b8ba37d317b9cdcde0d194ba13c8beef110b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 9f6b6ec6a51d2dccb08841d44c2f2ce5639ecdb4) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--tools/testcon/mainwindow.cpp19
-rw-r--r--tools/testcon/sandboxing.cpp73
-rw-r--r--tools/testcon/sandboxing.h17
3 files changed, 67 insertions, 42 deletions
diff --git a/tools/testcon/mainwindow.cpp b/tools/testcon/mainwindow.cpp
index e2547ff..482840e 100644
--- a/tools/testcon/mainwindow.cpp
+++ b/tools/testcon/mainwindow.cpp
@@ -95,17 +95,22 @@ bool MainWindow::addControlFromClsid(const QString &clsid, QAxSelect::Sandboxing
bool result = false;
{
- std::unique_ptr<LowIntegrity> low_integrity;
+ // RAII object for impersonating sandboxing on current thread
+ std::unique_ptr<Sandboxing> sandbox_impl;
- if (sandboxing == QAxSelect::SandboxingProcess) {
+ switch (sandboxing) {
+ case QAxSelect::SandboxingNone:
+ break; // sandboxing disabled
+ case QAxSelect::SandboxingProcess:
// require out-of-process
container->setClassContext(CLSCTX_LOCAL_SERVER);
- } else if (sandboxing == QAxSelect::SandboxingLowIntegrity) {
- // impersonate "low integrity"
- low_integrity.reset(new LowIntegrity);
- // require out-of-process and
- // propagate integrity level when calling setControl
+ break;
+ default:
+ // impersonate desired sandboxing
+ sandbox_impl = Sandboxing::Create(sandboxing);
+ // require out-of-process and activate impersonation
container->setClassContext(CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING);
+ break;
}
result = container->setControl(clsid);
diff --git a/tools/testcon/sandboxing.cpp b/tools/testcon/sandboxing.cpp
index 317bcf2..4774833 100644
--- a/tools/testcon/sandboxing.cpp
+++ b/tools/testcon/sandboxing.cpp
@@ -3,43 +3,64 @@
#include "sandboxing.h"
#include <memory>
+#include <windows.h>
#include <sddl.h>
+#include <userenv.h>
-LowIntegrity::LowIntegrity()
+/** RAII class for temporarily impersonating low-integrity level for the current thread.
+ Intended to be used together with CLSCTX_ENABLE_CLOAKING when creating COM objects.
+ Based on "Designing Applications to Run at a Low Integrity Level" https://msdn.microsoft.com/en-us/library/bb625960.aspx */
+class LowIntegrity : public Sandboxing
{
- HANDLE cur_token = nullptr;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &cur_token))
- abort();
+public:
+ LowIntegrity()
+ {
+ HANDLE cur_token = nullptr;
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &cur_token))
+ qFatal("OpenProcessToken failed");
- if (!DuplicateTokenEx(cur_token, 0, nullptr, SecurityImpersonation, TokenPrimary, &m_token))
- abort();
+ if (!DuplicateTokenEx(cur_token, 0, nullptr, SecurityImpersonation, TokenPrimary, &m_token))
+ qFatal("DuplicateTokenEx failed");
- CloseHandle(cur_token);
+ CloseHandle(cur_token);
- PSID li_sid = nullptr;
- if (!ConvertStringSidToSid(L"S-1-16-4096", &li_sid)) // low integrity SID
- abort();
+ PSID li_sid = nullptr;
+ if (!ConvertStringSidToSid(L"S-1-16-4096", &li_sid)) // low integrity SID
+ qFatal("ConvertStringSidToSid failed");
- // reduce process integrity level
- TOKEN_MANDATORY_LABEL TIL = {};
- TIL.Label.Attributes = SE_GROUP_INTEGRITY;
- TIL.Label.Sid = li_sid;
- if (!SetTokenInformation(m_token, TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(li_sid)))
- abort();
+ // reduce process integrity level
+ TOKEN_MANDATORY_LABEL TIL = {};
+ TIL.Label.Attributes = SE_GROUP_INTEGRITY;
+ TIL.Label.Sid = li_sid;
+ if (!SetTokenInformation(m_token, TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(li_sid)))
+ qFatal("SetTokenInformation failed");
- if (!ImpersonateLoggedOnUser(m_token)) // change current thread integrity
- abort();
+ if (!ImpersonateLoggedOnUser(m_token)) // change current thread integrity
+ qFatal("ImpersonateLoggedOnUser failed");
- LocalFree(li_sid);
- li_sid = nullptr;
-}
+ LocalFree(li_sid);
+ li_sid = nullptr;
+ }
+
+ ~LowIntegrity()
+ {
+ if (!RevertToSelf())
+ qFatal("RevertToSelf failed");
+
+ CloseHandle(m_token);
+ m_token = nullptr;
+ }
+
+private:
+ HANDLE m_token = nullptr;
+};
-LowIntegrity::~LowIntegrity()
+std::unique_ptr<Sandboxing> Sandboxing::Create(QAxSelect::SandboxingLevel level)
{
- if (!RevertToSelf())
- abort();
+ if (level == QAxSelect::SandboxingLowIntegrity)
+ return std::make_unique<LowIntegrity>();
- CloseHandle(m_token);
- m_token = nullptr;
+ Q_ASSERT_X(false, "Sandboxing::Create", "unknown sandboxing level");
+ return {};
}
diff --git a/tools/testcon/sandboxing.h b/tools/testcon/sandboxing.h
index ec61330..d63d746 100644
--- a/tools/testcon/sandboxing.h
+++ b/tools/testcon/sandboxing.h
@@ -3,18 +3,17 @@
#ifndef SANDBOXING_H
#define SANDBOXING_H
-#include <windows.h>
+#include <QAxSelect>
-/** RAII class for temporarily impersonating low-integrity level for the current thread.
- Intended to be used together with CLSCTX_ENABLE_CLOAKING when creating COM objects.
- Based on "Designing Applications to Run at a Low Integrity Level" https://msdn.microsoft.com/en-us/library/bb625960.aspx */
-struct LowIntegrity {
- LowIntegrity();
- ~LowIntegrity();
+class Sandboxing
+{
+public:
+ static std::unique_ptr<Sandboxing> Create(QAxSelect::SandboxingLevel level);
-private:
- HANDLE m_token = nullptr;
+ Sandboxing() {}
+
+ virtual ~Sandboxing() {}
};
#endif // SANDBOXING_H