15#include <QTemporaryFile>
17#include "KWayland/Client/connection_thread.h"
18#include "KWayland/Client/registry.h"
20#include <sys/socket.h>
27static const QString s_socketName = QStringLiteral(
"wayland_test_security_context-0");
37 void testSecurityContext();
38 void testClosedCloseFdOnStartup();
41void SecurityContextTest::initTestCase()
46 QVERIFY(applicationStartedSpy.wait());
49void SecurityContextTest::init()
54void SecurityContextTest::cleanup()
59void SecurityContextTest::testSecurityContext()
65 QVERIFY(securityContextManager);
67 int listenFd = socket(AF_UNIX, SOCK_STREAM, 0);
68 QVERIFY(listenFd != 0);
70 QTemporaryDir tempDir;
73 sockaddr.sun_family = AF_UNIX;
74 snprintf(sockaddr.sun_path,
sizeof(sockaddr.sun_path),
"%s", tempDir.filePath(
"socket").toUtf8().constData());
75 qDebug() <<
"listening socket:" << sockaddr.sun_path;
76 QVERIFY(bind(listenFd, (
struct sockaddr *)&sockaddr,
sizeof(sockaddr)) == 0);
77 QVERIFY(listen(listenFd, 0) == 0);
80 QVERIFY(pipe(syncFds) >= 0);
81 int closeFdForClientToKeep = syncFds[0];
82 int closeFdToGiveToKwin = syncFds[1];
84 auto securityContext =
new QtWayland::wp_security_context_v1(securityContextManager->create_listener(listenFd, closeFdToGiveToKwin));
85 close(closeFdToGiveToKwin);
87 securityContext->set_instance_id(
"kde.unitest.instance_id");
88 securityContext->set_app_id(
"kde.unittest.app_id");
89 securityContext->set_sandbox_engine(
"test_sandbox_engine");
90 securityContext->commit();
91 securityContext->destroy();
92 delete securityContext;
94 qputenv(
"WAYLAND_DISPLAY", tempDir.filePath(
"socket").toUtf8());
95 QSignalSpy clientConnectedspy(
waylandServer()->display(), &Display::clientConnected);
98 KWayland::Client::ConnectionThread restrictedClientConnection;
99 QSignalSpy connectedSpy(&restrictedClientConnection, &KWayland::Client::ConnectionThread::connected);
100 QThread restictedClientThread;
101 auto restictedClientThreadQuitter = qScopeGuard([&restictedClientThread]() {
102 restictedClientThread.quit();
103 restictedClientThread.wait();
105 restrictedClientConnection.moveToThread(&restictedClientThread);
106 restictedClientThread.start();
107 restrictedClientConnection.initConnection();
108 QVERIFY(connectedSpy.wait());
111 QVERIFY(clientConnectedspy.count());
115 KWayland::Client::Registry
registry;
116 registry.create(&restrictedClientConnection);
117 QSignalSpy interfaceAnnounced(®istry, &KWayland::Client::Registry::interfaceAnnounced);
118 QSignalSpy allAnnouncedSpy(®istry, &KWayland::Client::Registry::interfacesAnnounced);
120 QVERIFY(allAnnouncedSpy.wait());
121 for (
auto interfaceSignal : interfaceAnnounced) {
122 QVERIFY(interfaceSignal.first().toString() !=
"wp_security_context_manager_v1");
126 close(closeFdForClientToKeep);
133 KWayland::Client::ConnectionThread restrictedClientConnection2;
134 QSignalSpy connectedSpy2(&restrictedClientConnection2, &KWayland::Client::ConnectionThread::connected);
135 QSignalSpy failedSpy2(&restrictedClientConnection2, &KWayland::Client::ConnectionThread::failed);
136 QThread restictedClientThread2;
137 auto restictedClientThreadQuitter2 = qScopeGuard([&restictedClientThread2]() {
138 restictedClientThread2.quit();
139 restictedClientThread2.wait();
141 restrictedClientConnection2.moveToThread(&restictedClientThread2);
142 restictedClientThread2.start();
143 restrictedClientConnection2.initConnection();
144 QVERIFY(failedSpy2.wait());
145 QVERIFY(connectedSpy2.isEmpty());
148void SecurityContextTest::testClosedCloseFdOnStartup()
152 QVERIFY(securityContextManager);
154 int listenFd = socket(AF_UNIX, SOCK_STREAM, 0);
155 QVERIFY(listenFd != 0);
157 QTemporaryDir tempDir;
159 sockaddr_un sockaddr;
160 sockaddr.sun_family = AF_UNIX;
161 snprintf(sockaddr.sun_path,
sizeof(sockaddr.sun_path),
"%s", tempDir.filePath(
"socket").toUtf8().constData());
162 qDebug() <<
"listening socket:" << sockaddr.sun_path;
163 QVERIFY(bind(listenFd, (
struct sockaddr *)&sockaddr,
sizeof(sockaddr)) == 0);
164 QVERIFY(listen(listenFd, 0) == 0);
167 QVERIFY(pipe(syncFds) >= 0);
168 int closeFdForClientToKeep = syncFds[0];
169 int closeFdToGiveToKwin = syncFds[1];
171 close(closeFdForClientToKeep);
173 auto securityContext =
new QtWayland::wp_security_context_v1(securityContextManager->create_listener(listenFd, closeFdToGiveToKwin));
174 close(closeFdToGiveToKwin);
176 securityContext->set_instance_id(
"kde.unitest.instance_id");
177 securityContext->set_app_id(
"kde.unittest.app_id");
178 securityContext->set_sandbox_engine(
"test_sandbox_engine");
179 securityContext->commit();
180 securityContext->destroy();
181 delete securityContext;
185 qputenv(
"WAYLAND_DISPLAY", tempDir.filePath(
"socket").toUtf8());
186 QSignalSpy clientConnectedspy(
waylandServer()->display(), &Display::clientConnected);
189 KWayland::Client::ConnectionThread restrictedClientConnection;
190 QSignalSpy connectedSpy(&restrictedClientConnection, &KWayland::Client::ConnectionThread::connected);
191 QSignalSpy failedSpy(&restrictedClientConnection, &KWayland::Client::ConnectionThread::failed);
192 QThread restictedClientThread;
193 auto restictedClientThreadQuitter = qScopeGuard([&restictedClientThread]() {
194 restictedClientThread.quit();
195 restictedClientThread.wait();
197 restrictedClientConnection.moveToThread(&restictedClientThread);
198 restictedClientThread.start();
199 restrictedClientConnection.initConnection();
200 QVERIFY(failedSpy.wait());
201 QVERIFY(connectedSpy.isEmpty());
202 QVERIFY(clientConnectedspy.isEmpty());
207#include "security_context_test.moc"
Convenient Class which represents a wl_client.
QString securityContextAppId() const
#define WAYLANDTEST_MAIN(TestObject)
void destroyWaylandConnection()
bool setupWaylandConnection(AdditionalWaylandInterfaces flags=AdditionalWaylandInterfaces())
SecurityContextManagerV1 * waylandSecurityContextManagerV1()
KWayland::Client::Registry * registry
@ SecurityContextManagerV1
WaylandServer * waylandServer()