Implement lock screen security for touch events
When the screen gets locked any existing sequence gets cancelled and the focused touch surface gets reset. While screen is locked touch events are filtered to only go to lock screen or input methods. Test case is added for touch event during lock screen. Reviewed-By: Bhushan Shah
This commit is contained in:
parent
a311f9bfda
commit
c8c33ae398
3 changed files with 94 additions and 1 deletions
|
@ -38,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <KWayland/Client/seat.h>
|
#include <KWayland/Client/seat.h>
|
||||||
#include <KWayland/Client/shm_pool.h>
|
#include <KWayland/Client/shm_pool.h>
|
||||||
#include <KWayland/Client/surface.h>
|
#include <KWayland/Client/surface.h>
|
||||||
|
#include <KWayland/Client/touch.h>
|
||||||
|
|
||||||
//screenlocker
|
//screenlocker
|
||||||
#include <KScreenLocker/KsldApp>
|
#include <KScreenLocker/KsldApp>
|
||||||
|
@ -68,6 +69,7 @@ private Q_SLOTS:
|
||||||
void testAxisShortcut_data();
|
void testAxisShortcut_data();
|
||||||
void testAxisShortcut();
|
void testAxisShortcut();
|
||||||
void testKeyboardShortcut();
|
void testKeyboardShortcut();
|
||||||
|
void testTouch();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void unlock();
|
void unlock();
|
||||||
|
@ -725,6 +727,44 @@ void LockScreenTest::testKeyboardShortcut()
|
||||||
KEYRELEASE(KEY_LEFTALT);
|
KEYRELEASE(KEY_LEFTALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LockScreenTest::testTouch()
|
||||||
|
{
|
||||||
|
using namespace KWayland::Client;
|
||||||
|
auto touch = m_seat->createTouch(m_seat);
|
||||||
|
QVERIFY(touch);
|
||||||
|
QVERIFY(touch->isValid());
|
||||||
|
AbstractClient *c = showWindow();
|
||||||
|
QVERIFY(c);
|
||||||
|
QSignalSpy sequenceStartedSpy(touch, &Touch::sequenceStarted);
|
||||||
|
QVERIFY(sequenceStartedSpy.isValid());
|
||||||
|
QSignalSpy cancelSpy(touch, &Touch::sequenceCanceled);
|
||||||
|
QVERIFY(cancelSpy.isValid());
|
||||||
|
QSignalSpy pointRemovedSpy(touch, &Touch::pointRemoved);
|
||||||
|
QVERIFY(pointRemovedSpy.isValid());
|
||||||
|
|
||||||
|
quint32 timestamp = 1;
|
||||||
|
waylandServer()->backend()->touchDown(1, QPointF(25, 25), timestamp++);
|
||||||
|
QVERIFY(sequenceStartedSpy.wait());
|
||||||
|
QCOMPARE(sequenceStartedSpy.count(), 1);
|
||||||
|
|
||||||
|
LOCK
|
||||||
|
QVERIFY(cancelSpy.wait());
|
||||||
|
|
||||||
|
waylandServer()->backend()->touchUp(1, timestamp++);
|
||||||
|
QVERIFY(!pointRemovedSpy.wait(100));
|
||||||
|
waylandServer()->backend()->touchDown(1, QPointF(25, 25), timestamp++);
|
||||||
|
waylandServer()->backend()->touchMotion(1, QPointF(26, 26), timestamp++);
|
||||||
|
waylandServer()->backend()->touchUp(1, timestamp++);
|
||||||
|
|
||||||
|
UNLOCK
|
||||||
|
waylandServer()->backend()->touchDown(1, QPointF(25, 25), timestamp++);
|
||||||
|
QVERIFY(sequenceStartedSpy.wait());
|
||||||
|
QCOMPARE(sequenceStartedSpy.count(), 2);
|
||||||
|
waylandServer()->backend()->touchUp(1, timestamp++);
|
||||||
|
QVERIFY(pointRemovedSpy.wait());
|
||||||
|
QCOMPARE(pointRemovedSpy.count(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WAYLANTEST_MAIN(KWin::LockScreenTest)
|
WAYLANTEST_MAIN(KWin::LockScreenTest)
|
||||||
|
|
53
input.cpp
53
input.cpp
|
@ -403,6 +403,49 @@ public:
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool touchDown(quint32 id, const QPointF &pos, quint32 time) {
|
||||||
|
if (!waylandServer()->isScreenLocked()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto seat = waylandServer()->seat();
|
||||||
|
seat->setTimestamp(time);
|
||||||
|
if (!seat->isTouchSequence()) {
|
||||||
|
input()->updateTouchWindow(pos);
|
||||||
|
}
|
||||||
|
if (touchSurfaceAllowed()) {
|
||||||
|
input()->insertTouchId(id, seat->touchDown(pos));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool touchMotion(quint32 id, const QPointF &pos, quint32 time) {
|
||||||
|
if (!waylandServer()->isScreenLocked()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto seat = waylandServer()->seat();
|
||||||
|
seat->setTimestamp(time);
|
||||||
|
if (touchSurfaceAllowed()) {
|
||||||
|
const qint32 kwaylandId = input()->touchId(id);
|
||||||
|
if (kwaylandId != -1) {
|
||||||
|
seat->touchMove(kwaylandId, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool touchUp(quint32 id, quint32 time) {
|
||||||
|
if (!waylandServer()->isScreenLocked()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto seat = waylandServer()->seat();
|
||||||
|
seat->setTimestamp(time);
|
||||||
|
if (touchSurfaceAllowed()) {
|
||||||
|
const qint32 kwaylandId = input()->touchId(id);
|
||||||
|
if (kwaylandId != -1) {
|
||||||
|
seat->touchUp(kwaylandId);
|
||||||
|
input()->removeTouchId(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
bool surfaceAllowed(KWayland::Server::SurfaceInterface *(KWayland::Server::SeatInterface::*method)() const) const {
|
bool surfaceAllowed(KWayland::Server::SurfaceInterface *(KWayland::Server::SeatInterface::*method)() const) const {
|
||||||
if (KWayland::Server::SurfaceInterface *s = (waylandServer()->seat()->*method)()) {
|
if (KWayland::Server::SurfaceInterface *s = (waylandServer()->seat()->*method)()) {
|
||||||
|
@ -419,6 +462,9 @@ private:
|
||||||
bool keyboardSurfaceAllowed() const {
|
bool keyboardSurfaceAllowed() const {
|
||||||
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedKeyboardSurface);
|
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedKeyboardSurface);
|
||||||
}
|
}
|
||||||
|
bool touchSurfaceAllowed() const {
|
||||||
|
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedTouchSurface);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EffectsFilter : public InputEventFilter {
|
class EffectsFilter : public InputEventFilter {
|
||||||
|
@ -872,6 +918,13 @@ void InputRedirection::setupWorkspace()
|
||||||
|
|
||||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updatePointerWindow);
|
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updatePointerWindow);
|
||||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updateKeyboardWindow);
|
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updateKeyboardWindow);
|
||||||
|
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this,
|
||||||
|
[this] {
|
||||||
|
cancelTouch();
|
||||||
|
// position doesn't matter
|
||||||
|
updateTouchWindow(QPointF());
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
setupInputFilters();
|
setupInputFilters();
|
||||||
}
|
}
|
||||||
|
|
2
input.h
2
input.h
|
@ -156,6 +156,7 @@ public:
|
||||||
void removeTouchId(quint32 internalId);
|
void removeTouchId(quint32 internalId);
|
||||||
|
|
||||||
void updateKeyboardWindow();
|
void updateKeyboardWindow();
|
||||||
|
void updateTouchWindow(const QPointF &pos);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void updatePointerWindow();
|
void updatePointerWindow();
|
||||||
|
@ -209,7 +210,6 @@ private:
|
||||||
void registerShortcutForGlobalAccelTimestamp(QAction *action);
|
void registerShortcutForGlobalAccelTimestamp(QAction *action);
|
||||||
void updateFocusedPointerPosition();
|
void updateFocusedPointerPosition();
|
||||||
void updateFocusedTouchPosition();
|
void updateFocusedTouchPosition();
|
||||||
void updateTouchWindow(const QPointF &pos);
|
|
||||||
void updatePointerDecoration(Toplevel *t);
|
void updatePointerDecoration(Toplevel *t);
|
||||||
void updatePointerInternalWindow();
|
void updatePointerInternalWindow();
|
||||||
void pointerInternalWindowVisibilityChanged(bool visible);
|
void pointerInternalWindowVisibilityChanged(bool visible);
|
||||||
|
|
Loading…
Reference in a new issue