Merge lp:~tj/ubuntu/trusty/kde-workspace/lp-1264821 into lp:ubuntu/trusty/kde-workspace

Proposed by TJ on 2014-01-03
Status: Work in progress
Proposed branch: lp:~tj/ubuntu/trusty/kde-workspace/lp-1264821
Merge into: lp:ubuntu/trusty/kde-workspace
Diff against target: 596 lines (+545/-2)
6 files modified
.pc/applied-patches (+1/-0)
.pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver/screenlocker/greeter/greeterapp.cpp (+513/-0)
debian/changelog (+7/-0)
debian/patches/kubuntu_greeters_on_correct_X_screen.diff (+21/-0)
debian/patches/series (+1/-0)
ksmserver/screenlocker/greeter/greeterapp.cpp (+2/-2)
To merge this branch: bzr merge lp:~tj/ubuntu/trusty/kde-workspace/lp-1264821
Reviewer Review Type Date Requested Status
Dmitry Shachnev Resubmit on 2014-01-15
Ubuntu branches 2014-01-03 Pending
Review via email: mp+200397@code.launchpad.net

Description of the change

Confirmed fix for insecure greeters and locking with multiple X-screens. Should also be backported via SRU to previous releases.

To post a comment you must log in.
Dmitry Shachnev (mitya57) wrote :

Thanks for your work here. Quoting upstream review:

------
From a quick look at the patch looks wrong to me, because you use "i" as an index in QDesktopWindow::screen(). This looks crashy to me and potentially wrong. In fact in your case I expect that it's always just 0. There should be three processes with one screen each. While on a more regular setup there is just one process with three screens attached.
------

Please get an agreement with upstream on this patch before it can be included.

Also, please submit future merge proposals against lp:~kubuntu-packagers/kubuntu-packaging/kde-workspace and similar branches. I am rejecting it for now.

review: Resubmit

Unmerged revisions

110. By TJ on 2014-01-03

Add patch kubuntu_greeters_on_correct_X_screen.diff to fix insecure
screen locking (LP: #1264821)

  When using multiple X-screens the greeters for X-screens other than 0 were rendered
  on screen 0 instead of the correct screen. When the session is locked this leaves the
  contents of screens other than 0 on display, which is a security issue.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.pc/applied-patches'
2--- .pc/applied-patches 2013-12-06 10:21:29 +0000
3+++ .pc/applied-patches 2014-01-03 12:32:44 +0000
4@@ -33,3 +33,4 @@
5 kubuntu_screensaver_restricted_install.diff
6 kubuntu_upstart_session_events.diff
7 kubuntu_avoid_zic_and_deep_copy_timezone_data.diff
8+kubuntu_greeters_on_correct_X_screen.diff
9
10=== added directory '.pc/kubuntu_greeters_on_correct_X_screen.diff'
11=== added file '.pc/kubuntu_greeters_on_correct_X_screen.diff/.timestamp'
12=== added directory '.pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver'
13=== added directory '.pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver/screenlocker'
14=== added directory '.pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver/screenlocker/greeter'
15=== added file '.pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver/screenlocker/greeter/greeterapp.cpp'
16--- .pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver/screenlocker/greeter/greeterapp.cpp 1970-01-01 00:00:00 +0000
17+++ .pc/kubuntu_greeters_on_correct_X_screen.diff/ksmserver/screenlocker/greeter/greeterapp.cpp 2014-01-03 12:32:44 +0000
18@@ -0,0 +1,513 @@
19+/********************************************************************
20+ KSld - the KDE Screenlocker Daemon
21+ This file is part of the KDE project.
22+
23+Copyright (C) 2004 Chris Howells <howells@kde.org>
24+Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
25+
26+This program is free software; you can redistribute it and/or modify
27+it under the terms of the GNU General Public License as published by
28+the Free Software Foundation; either version 2 of the License, or
29+(at your option) any later version.
30+
31+This program is distributed in the hope that it will be useful,
32+but WITHOUT ANY WARRANTY; without even the implied warranty of
33+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34+GNU General Public License for more details.
35+
36+You should have received a copy of the GNU General Public License
37+along with this program. If not, see <http://www.gnu.org/licenses/>.
38+*********************************************************************/
39+#include "greeterapp.h"
40+#include "kscreensaversettings.h"
41+#include "greeter.h"
42+#include "sessions.h"
43+#include "screensaverwindow.h"
44+
45+// workspace
46+#include <kworkspace/kworkspace.h>
47+// KDE
48+#include <KDE/KAuthorized>
49+#include <KDE/KCrash>
50+#include <KDE/KDebug>
51+#include <KDE/KStandardDirs>
52+#include <KDE/KUser>
53+#include <KDE/KWindowSystem>
54+#include <Solid/PowerManagement>
55+#include <kdeclarative.h>
56+//Plasma
57+#include <Plasma/Package>
58+#include <Plasma/PackageMetadata>
59+// Qt
60+#include <QtCore/QTimer>
61+#include <QtDeclarative/QDeclarativeContext>
62+#include <QtDeclarative/QDeclarativeEngine>
63+#include <QtDeclarative/QDeclarativeItem>
64+#include <QtDeclarative/QDeclarativeProperty>
65+#include <QtDeclarative/QDeclarativeView>
66+#include <QtDeclarative/qdeclarative.h>
67+#include <QtGui/QKeyEvent>
68+#include <QDesktopWidget>
69+// X11
70+#include <X11/Xatom.h>
71+#include <X11/Xlib.h>
72+#include <fixx11h.h>
73+
74+// this is usable to fake a "screensaver" installation for testing
75+// *must* be "0" for every public commit!
76+#define TEST_SCREENSAVER 0
77+
78+namespace ScreenLocker
79+{
80+
81+static const char *DEFAULT_MAIN_PACKAGE = "org.kde.passworddialog";
82+
83+// App
84+UnlockApp::UnlockApp()
85+ : KApplication()
86+ , m_resetRequestIgnoreTimer(new QTimer(this))
87+ , m_delayedLockTimer(0)
88+ , m_testing(false)
89+ , m_capsLocked(false)
90+ , m_ignoreRequests(false)
91+ , m_showScreenSaver(false)
92+ , m_immediateLock(false)
93+ , m_runtimeInitialized(false)
94+{
95+ initialize();
96+ connect(desktop(), SIGNAL(resized(int)), SLOT(desktopResized()));
97+ connect(desktop(), SIGNAL(screenCountChanged(int)), SLOT(desktopResized()));
98+}
99+
100+UnlockApp::~UnlockApp()
101+{
102+ qDeleteAll(m_views);
103+ qDeleteAll(m_screensaverWindows);
104+}
105+
106+void UnlockApp::initialize()
107+{
108+ const char *uri = "org.kde.kscreenlocker";
109+ qmlRegisterType<GreeterItem>(uri, 1, 0, "GreeterItem");
110+ qmlRegisterType<KeyboardItem>(uri, 1, 0, "KeyboardItem");
111+ qmlRegisterType<SessionSwitching>(uri, 1, 0, "Sessions");
112+ qmlRegisterType<QAbstractItemModel>();
113+
114+ // set up the request ignore timeout, so that multiple requests to sleep/suspend/shutdown
115+ // are not processed in quick (and confusing) succession)
116+ m_resetRequestIgnoreTimer->setSingleShot(true);
117+ m_resetRequestIgnoreTimer->setInterval(2000);
118+ connect(m_resetRequestIgnoreTimer, SIGNAL(timeout()), this, SLOT(resetRequestIgnore()));
119+
120+ // disable DrKonqi as the crash dialog blocks the restart of the locker
121+ KCrash::setDrKonqiEnabled(false);
122+
123+ KScreenSaverSettings::self()->readConfig();
124+#if TEST_SCREENSAVER
125+ m_showScreenSaver = true;
126+#else
127+ m_showScreenSaver = KScreenSaverSettings::legacySaverEnabled();
128+#endif
129+
130+ m_structure = Plasma::PackageStructure::load("Plasma/Generic");
131+ m_package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), KScreenSaverSettings::greeterQML(), m_structure);
132+ m_mainQmlPath = m_package->filePath("mainscript");
133+ if (m_mainQmlPath.isEmpty()) {
134+ delete m_package;
135+ m_package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), DEFAULT_MAIN_PACKAGE, m_structure);
136+ m_mainQmlPath = m_package->filePath("mainscript");
137+ }
138+
139+ installEventFilter(this);
140+}
141+
142+void UnlockApp::viewStatusChanged(const QDeclarativeView::Status &status)
143+{
144+ // on error, if we did not load the default qml, try to do so now.
145+ if (status == QDeclarativeView::Error &&
146+ m_package->metadata().pluginName() != DEFAULT_MAIN_PACKAGE) {
147+ if (QDeclarativeView *view = qobject_cast<QDeclarativeView *>(sender())) {
148+ m_package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), DEFAULT_MAIN_PACKAGE, m_structure);
149+ m_mainQmlPath = m_package->filePath("mainscript");
150+ view->setSource(QUrl::fromLocalFile(m_mainQmlPath));
151+ }
152+ }
153+}
154+
155+void UnlockApp::desktopResized()
156+{
157+ const int nScreens = desktop()->screenCount();
158+ // remove useless views and savers
159+ while (m_views.count() > nScreens) {
160+ m_views.takeLast()->deleteLater();
161+ }
162+ while (m_screensaverWindows.count() > nScreens) {
163+ m_screensaverWindows.takeLast()->deleteLater();
164+ }
165+
166+ Q_ASSERT((!m_showScreenSaver || m_views.count() == m_screensaverWindows.count()));
167+
168+ // extend views and savers to current demand
169+ const bool canLogout = KAuthorized::authorizeKAction("logout") && KAuthorized::authorize("logout");
170+ const QSet<Solid::PowerManagement::SleepState> spdMethods = Solid::PowerManagement::supportedSleepStates();
171+ for (int i = m_views.count(); i < nScreens; ++i) {
172+ // create the view
173+ QDeclarativeView *view = new QDeclarativeView();
174+ connect(view, SIGNAL(statusChanged(QDeclarativeView::Status)),
175+ this, SLOT(viewStatusChanged(QDeclarativeView::Status)));
176+ view->setWindowFlags(Qt::X11BypassWindowManagerHint);
177+ view->setFrameStyle(QFrame::NoFrame);
178+
179+ // engine stuff
180+ KDeclarative kdeclarative;
181+ kdeclarative.setDeclarativeEngine(view->engine());
182+ kdeclarative.initialize();
183+ kdeclarative.setupBindings();
184+ QDeclarativeContext *context = view->engine()->rootContext();
185+ const KUser user;
186+ const QString fullName = user.property(KUser::FullName).toString();
187+ context->setContextProperty("kscreenlocker_userName", fullName.isEmpty() ? user.loginName() : fullName);
188+
189+ view->setSource(QUrl::fromLocalFile(m_mainQmlPath));
190+ view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
191+
192+ connect(view->rootObject(), SIGNAL(unlockRequested()), SLOT(quit()));
193+
194+ QDeclarativeProperty lockProperty(view->rootObject(), "locked");
195+ if (m_immediateLock) {
196+ lockProperty.write(true);
197+ } else if (KScreenSaverSettings::lock()) {
198+ if (KScreenSaverSettings::lockGrace() < 1) {
199+ lockProperty.write(true);
200+ } else if (m_runtimeInitialized) {
201+ // if we have new views and we are waiting on the
202+ // delayed lock timer still, we don't want to show
203+ // the lock UI just yet
204+ lockProperty.write(!m_delayedLockTimer);
205+ } else {
206+ if (!m_delayedLockTimer) {
207+ m_delayedLockTimer = new QTimer(this);
208+ m_delayedLockTimer->setSingleShot(true);
209+ connect(m_delayedLockTimer, SIGNAL(timeout()), this, SLOT(setLockedPropertyOnViews()));
210+ }
211+ m_delayedLockTimer->start(KScreenSaverSettings::lockGrace());
212+ }
213+ } else {
214+ lockProperty.write(false);
215+ }
216+
217+ QDeclarativeProperty sleepProperty(view->rootObject(), "suspendToRamSupported");
218+ sleepProperty.write(spdMethods.contains(Solid::PowerManagement::SuspendState));
219+ if (spdMethods.contains(Solid::PowerManagement::SuspendState) &&
220+ view->rootObject()->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("suspendToRam()")) != -1) {
221+ connect(view->rootObject(), SIGNAL(suspendToRam()), SLOT(suspendToRam()));
222+ }
223+
224+ QDeclarativeProperty hibernateProperty(view->rootObject(), "suspendToDiskSupported");
225+ hibernateProperty.write(spdMethods.contains(Solid::PowerManagement::SuspendState));
226+ if (spdMethods.contains(Solid::PowerManagement::SuspendState) &&
227+ view->rootObject()->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("suspendToDisk()")) != -1) {
228+ connect(view->rootObject(), SIGNAL(suspendToDisk()), SLOT(suspendToDisk()));
229+ }
230+
231+ QDeclarativeProperty shutdownProperty(view->rootObject(), "shutdownSupported");
232+ shutdownProperty.write(canLogout);
233+ if (canLogout &&
234+ view->rootObject()->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("shutdown()")) != -1) {
235+ connect(view->rootObject(), SIGNAL(shutdown()), SLOT(shutdown()));
236+ }
237+
238+ m_views << view;
239+
240+ if (m_showScreenSaver) {
241+ ScreenSaverWindow *screensaverWindow = new ScreenSaverWindow;
242+ screensaverWindow->setWindowFlags(Qt::X11BypassWindowManagerHint);
243+ m_screensaverWindows << screensaverWindow;
244+ }
245+ }
246+
247+ m_runtimeInitialized = true;
248+
249+ // update geometry of all views and savers
250+ for (int i = 0; i < nScreens; ++i) {
251+ QDeclarativeView *view = m_views.at(i);
252+
253+ view->setGeometry(desktop()->screenGeometry(i));
254+ view->show();
255+ view->raise();
256+
257+ if (m_showScreenSaver) {
258+ ScreenSaverWindow *screensaverWindow = m_screensaverWindows.at(i);
259+ screensaverWindow->setGeometry(view->geometry());
260+
261+#if TEST_SCREENSAVER
262+ screensaverWindow->setAutoFillBackground(true);
263+#else
264+ QPixmap backgroundPix(screensaverWindow->size());
265+ QPainter p(&backgroundPix);
266+ view->render(&p);
267+ p.end();
268+ screensaverWindow->setBackground(backgroundPix);
269+#endif
270+ screensaverWindow->show();
271+ screensaverWindow->activateWindow();
272+ connect(screensaverWindow, SIGNAL(hidden()), this, SLOT(getFocus()));
273+ }
274+ }
275+ // random state update, actually rather required on init only
276+ QMetaObject::invokeMethod(this, "getFocus", Qt::QueuedConnection);
277+ // getFocus on the next event cycle does not work as expected for multiple views
278+ // if there's no screensaver, hiding it won't happen and thus not trigger getFocus either
279+ // so we call it again in a few miliseconds - the value is nearly random but "must cross some event cycles"
280+ // while 150ms worked for me, 250ms gets us a bit more padding without being notable to a human user
281+ if (nScreens > 1 && m_screensaverWindows.isEmpty()) {
282+ QTimer::singleShot(250, this, SLOT(getFocus()));
283+ }
284+ capsLocked();
285+}
286+
287+void UnlockApp::getFocus()
288+{
289+ if (m_views.isEmpty()) {
290+ return;
291+ }
292+ QWidget *w = 0;
293+ // this loop is required to make the qml/graphicsscene properly handle the shared keyboard input
294+ // ie. "type something into the box of every greeter"
295+ foreach (QDeclarativeView *view, m_views) {
296+ view->activateWindow();
297+ view->grabKeyboard();
298+ view->setFocus(Qt::OtherFocusReason);
299+ }
300+ // determine which window should actually be active and have the real input focus/grab
301+ foreach (QDeclarativeView *view, m_views) {
302+ if (view->underMouse()) {
303+ w = view;
304+ break;
305+ }
306+ }
307+ if (!w) { // try harder
308+ foreach (QDeclarativeView *view, m_views) {
309+ if (view->geometry().contains(QCursor::pos())) {
310+ w = view;
311+ break;
312+ }
313+ }
314+ }
315+ if (!w) { // fallback solution
316+ w = m_views.first();
317+ }
318+ // activate window and grab input to be sure it really ends up there.
319+ // focus setting is still required for proper internal QWidget state (and eg. visual reflection)
320+ w->grabKeyboard();
321+ w->activateWindow();
322+ w->setFocus(Qt::OtherFocusReason);
323+}
324+
325+void UnlockApp::setLockedPropertyOnViews()
326+{
327+ delete m_delayedLockTimer;
328+ m_delayedLockTimer = 0;
329+
330+ foreach (QDeclarativeView *view, m_views) {
331+ QDeclarativeProperty lockProperty(view->rootObject(), "locked");
332+ lockProperty.write(true);
333+ }
334+}
335+
336+void UnlockApp::resetRequestIgnore()
337+{
338+ m_ignoreRequests = false;
339+}
340+
341+void UnlockApp::suspendToRam()
342+{
343+ if (m_ignoreRequests) {
344+ return;
345+ }
346+
347+ m_ignoreRequests = true;
348+ m_resetRequestIgnoreTimer->start();
349+
350+ Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState, 0, 0);
351+
352+}
353+
354+void UnlockApp::suspendToDisk()
355+{
356+ if (m_ignoreRequests) {
357+ return;
358+ }
359+
360+ m_ignoreRequests = true;
361+ m_resetRequestIgnoreTimer->start();
362+
363+ Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState, 0, 0);
364+}
365+
366+void UnlockApp::shutdown()
367+{
368+ if (m_ignoreRequests) {
369+ return;
370+ }
371+
372+ m_ignoreRequests = true;
373+ m_resetRequestIgnoreTimer->start();
374+
375+ const KWorkSpace::ShutdownConfirm confirm = KWorkSpace::ShutdownConfirmNo;
376+ const KWorkSpace::ShutdownType type = KWorkSpace::ShutdownTypeHalt;
377+
378+ KWorkSpace::requestShutDown(confirm, type);
379+}
380+
381+void UnlockApp::setTesting(bool enable)
382+{
383+ m_testing = enable;
384+ if (m_views.isEmpty()) {
385+ return;
386+ }
387+ if (enable) {
388+ // remove bypass window manager hint
389+ foreach (QDeclarativeView * view, m_views) {
390+ view->setWindowFlags(view->windowFlags() & ~Qt::X11BypassWindowManagerHint);
391+ }
392+ } else {
393+ foreach (QDeclarativeView * view, m_views) {
394+ view->setWindowFlags(view->windowFlags() | Qt::X11BypassWindowManagerHint);
395+ }
396+ }
397+}
398+
399+void UnlockApp::setImmediateLock(bool immediate)
400+{
401+ m_immediateLock = immediate;
402+}
403+
404+bool UnlockApp::eventFilter(QObject *obj, QEvent *event)
405+{
406+ if (obj != this && event->type() == QEvent::Show) {
407+ QDeclarativeView *view(0);
408+ foreach (QDeclarativeView *v, m_views) {
409+ if (v == obj) {
410+ view = v;
411+ break;
412+ }
413+ }
414+ if (view && view->testAttribute(Qt::WA_WState_Created) && view->internalWinId()) {
415+ // showing greeter view window, set property
416+ static Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False);
417+ XChangeProperty(QX11Info::display(), view->winId(), tag, tag, 32, PropModeReplace, 0, 0);
418+ }
419+ // no further processing
420+ return false;
421+ }
422+
423+ static bool ignoreNextEscape = false;
424+ if (event->type() == QEvent::KeyPress) { // react if saver is visible
425+ bool saverVisible = !m_screensaverWindows.isEmpty();
426+ foreach (ScreenSaverWindow *screensaverWindow, m_screensaverWindows) {
427+ if (!screensaverWindow->isVisible()) {
428+ saverVisible = false;
429+ break;
430+ }
431+ }
432+ if (!saverVisible) {
433+ shareEvent(event, qobject_cast<QDeclarativeView*>(obj));
434+ return false; // we don't care
435+ }
436+ ignoreNextEscape = bool(static_cast<QKeyEvent *>(event)->key() == Qt::Key_Escape);
437+ capsLocked();
438+ foreach (ScreenSaverWindow *screensaverWindow, m_screensaverWindows) {
439+ screensaverWindow->hide();
440+ }
441+ getFocus();
442+ return true; // do not pass the key
443+ } else if (event->type() == QEvent::KeyRelease) { // conditionally reshow the saver
444+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
445+ if (ke->key() == Qt::Key_CapsLock) {
446+ capsLocked();
447+ return false;
448+ }
449+ if (ke->key() != Qt::Key_Escape) {
450+ shareEvent(event, qobject_cast<QDeclarativeView*>(obj));
451+ return false; // irrelevant
452+ }
453+ if (ignoreNextEscape) {
454+ ignoreNextEscape = false;
455+ return true; // it's Qt::Key_Escape;
456+ }
457+ bool saverVisible = true;
458+ foreach (ScreenSaverWindow *screensaverWindow, m_screensaverWindows) {
459+ if (!screensaverWindow->isVisible()) {
460+ saverVisible = false;
461+ break;
462+ }
463+ }
464+ if (saverVisible) {
465+ return false; // we don't care
466+ }
467+ foreach (ScreenSaverWindow *screensaverWindow, m_screensaverWindows) {
468+ screensaverWindow->show();
469+ }
470+ return true; // don't pass
471+ } else if (event->type() == QEvent::GraphicsSceneMousePress) {
472+ QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(event);
473+
474+ foreach (QDeclarativeView *view, m_views) {
475+ if (view->geometry().contains(me->screenPos())) {
476+ view->activateWindow();
477+ view->grabKeyboard();
478+ break;
479+ }
480+ }
481+ }
482+
483+ return false;
484+}
485+
486+void UnlockApp::capsLocked()
487+{
488+ unsigned int lmask;
489+ Window dummy1, dummy2;
490+ int dummy3, dummy4, dummy5, dummy6;
491+ XQueryPointer(QX11Info::display(), DefaultRootWindow( QX11Info::display() ), &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &lmask);
492+ const bool before = m_capsLocked;
493+ m_capsLocked = lmask & LockMask;
494+ if (before != m_capsLocked) {
495+ foreach (QDeclarativeView *view, m_views) {
496+ view->rootObject()->setProperty("capsLockOn", m_capsLocked);
497+ }
498+ }
499+}
500+
501+/*
502+ * This function forwards an event from one greeter window to all others
503+ * It's used to have the keyboard operate on all greeter windows (on every screen)
504+ * at once so that the user gets visual feedback on the screen he's looking at -
505+ * even if the focus is actually on a powered off screen.
506+ */
507+
508+void UnlockApp::shareEvent(QEvent *e, QDeclarativeView *from)
509+{
510+ // from can be NULL any time (because the parameter is passed as qobject_cast)
511+ // m_views.contains(from) is atm. supposed to be true but required if any further
512+ // QDeclarativeViews are added (which are not part of m_views)
513+ // this makes "from" an optimization (nullptr check aversion)
514+ if (from && m_views.contains(from)) {
515+ // NOTICE any recursion in the event sharing will prevent authentication on multiscreen setups!
516+ // Any change in regarded event processing shall be tested thoroughly!
517+ removeEventFilter(this); // prevent recursion!
518+ const bool accepted = e->isAccepted(); // store state
519+ foreach (QDeclarativeView *view, m_views) {
520+ if (view != from) {
521+ QApplication::sendEvent(view, e);
522+ e->setAccepted(accepted);
523+ }
524+ }
525+ installEventFilter(this);
526+ }
527+}
528+
529+} // namespace
530+
531+#include "greeterapp.moc"
532
533=== modified file 'debian/changelog'
534--- debian/changelog 2013-12-06 10:21:29 +0000
535+++ debian/changelog 2014-01-03 12:32:44 +0000
536@@ -1,3 +1,10 @@
537+kde-workspace (4:4.11.4-0ubuntu2~tj1) trusty; urgency=medium
538+
539+ * Add patch kubuntu_greeters_on_correct_X_screen.diff to fix insecure
540+ screen locking (LP: #1264821)
541+
542+ -- TJ <ubuntu@iam.tj> Fri, 03 Jan 2014 04:20:36 +0000
543+
544 kde-workspace (4:4.11.4-0ubuntu1) trusty; urgency=low
545
546 [ Harald Sitter ]
547
548=== added file 'debian/patches/kubuntu_greeters_on_correct_X_screen.diff'
549--- debian/patches/kubuntu_greeters_on_correct_X_screen.diff 1970-01-01 00:00:00 +0000
550+++ debian/patches/kubuntu_greeters_on_correct_X_screen.diff 2014-01-03 12:32:44 +0000
551@@ -0,0 +1,21 @@
552+Description: Render greeters on correct X screens
553+Author: TJ <ubuntu@ima.tj>
554+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+bug/1264821
555+Bug: https://bugs.kde.org/show_bug.cgi?id=329375
556+Forwarded: yes
557+Last-Update: 2014-01-02
558+Index: kde-workspace/ksmserver/screenlocker/greeter/greeterapp.cpp
559+===================================================================
560+--- kde-workspace.orig/ksmserver/screenlocker/greeter/greeterapp.cpp 2014-01-03 04:09:52.712713000 +0000
561++++ kde-workspace/ksmserver/screenlocker/greeter/greeterapp.cpp 2014-01-03 04:11:17.338852937 +0000
562+@@ -151,8 +151,8 @@
563+ const bool canLogout = KAuthorized::authorizeKAction("logout") && KAuthorized::authorize("logout");
564+ const QSet<Solid::PowerManagement::SleepState> spdMethods = Solid::PowerManagement::supportedSleepStates();
565+ for (int i = m_views.count(); i < nScreens; ++i) {
566+- // create the view
567+- QDeclarativeView *view = new QDeclarativeView();
568++ // create the view, setting parent to the correct X screen
569++ QDeclarativeView *view = new QDeclarativeView(desktop()->screen(i));
570+ connect(view, SIGNAL(statusChanged(QDeclarativeView::Status)),
571+ this, SLOT(viewStatusChanged(QDeclarativeView::Status)));
572+ view->setWindowFlags(Qt::X11BypassWindowManagerHint);
573
574=== modified file 'debian/patches/series'
575--- debian/patches/series 2013-12-06 10:21:29 +0000
576+++ debian/patches/series 2014-01-03 12:32:44 +0000
577@@ -36,3 +36,4 @@
578 kubuntu_screensaver_restricted_install.diff
579 kubuntu_upstart_session_events.diff
580 kubuntu_avoid_zic_and_deep_copy_timezone_data.diff
581+kubuntu_greeters_on_correct_X_screen.diff
582
583=== modified file 'ksmserver/screenlocker/greeter/greeterapp.cpp'
584--- ksmserver/screenlocker/greeter/greeterapp.cpp 2013-12-06 10:21:29 +0000
585+++ ksmserver/screenlocker/greeter/greeterapp.cpp 2014-01-03 12:32:44 +0000
586@@ -151,8 +151,8 @@
587 const bool canLogout = KAuthorized::authorizeKAction("logout") && KAuthorized::authorize("logout");
588 const QSet<Solid::PowerManagement::SleepState> spdMethods = Solid::PowerManagement::supportedSleepStates();
589 for (int i = m_views.count(); i < nScreens; ++i) {
590- // create the view
591- QDeclarativeView *view = new QDeclarativeView();
592+ // create the view, setting parent to the correct X screen
593+ QDeclarativeView *view = new QDeclarativeView(desktop()->screen(i));
594 connect(view, SIGNAL(statusChanged(QDeclarativeView::Status)),
595 this, SLOT(viewStatusChanged(QDeclarativeView::Status)));
596 view->setWindowFlags(Qt::X11BypassWindowManagerHint);

Subscribers

People subscribed via source and target branches

to all changes: