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
master
Martin Gräßlin 9 years ago
parent a311f9bfda
commit c8c33ae398

@ -38,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/seat.h>
#include <KWayland/Client/shm_pool.h>
#include <KWayland/Client/surface.h>
#include <KWayland/Client/touch.h>
//screenlocker
#include <KScreenLocker/KsldApp>
@ -68,6 +69,7 @@ private Q_SLOTS:
void testAxisShortcut_data();
void testAxisShortcut();
void testKeyboardShortcut();
void testTouch();
private:
void unlock();
@ -725,6 +727,44 @@ void LockScreenTest::testKeyboardShortcut()
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)

@ -403,6 +403,49 @@ public:
}
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:
bool surfaceAllowed(KWayland::Server::SurfaceInterface *(KWayland::Server::SeatInterface::*method)() const) const {
if (KWayland::Server::SurfaceInterface *s = (waylandServer()->seat()->*method)()) {
@ -419,6 +462,9 @@ private:
bool keyboardSurfaceAllowed() const {
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedKeyboardSurface);
}
bool touchSurfaceAllowed() const {
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedTouchSurface);
}
};
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::updateKeyboardWindow);
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this,
[this] {
cancelTouch();
// position doesn't matter
updateTouchWindow(QPointF());
}
);
}
setupInputFilters();
}

@ -156,6 +156,7 @@ public:
void removeTouchId(quint32 internalId);
void updateKeyboardWindow();
void updateTouchWindow(const QPointF &pos);
public Q_SLOTS:
void updatePointerWindow();
@ -209,7 +210,6 @@ private:
void registerShortcutForGlobalAccelTimestamp(QAction *action);
void updateFocusedPointerPosition();
void updateFocusedTouchPosition();
void updateTouchWindow(const QPointF &pos);
void updatePointerDecoration(Toplevel *t);
void updatePointerInternalWindow();
void pointerInternalWindowVisibilityChanged(bool visible);

Loading…
Cancel
Save