on xenial help sign in
Drop check-clock-every-tick logic, we don't need it
fc3f23eMichael Terry
qml/Greeter/Greeter.qml+19−20
@@ -216,38 +216,37 @@ Showable {
216 }
216 }
217
217
218 onTriggered: {
218 onTriggered: {
219− var now = new Date();
219+ var diff = delayTarget - new Date();
220+ if (diff > 0) {
221+ delayMinutes = Math.ceil(diff / 60000);
222+ start(); // go again
223+ } else {
224+ delayMinutes = 0;
225+ }
226+ }
227+
228+ function checkForForcedDelay() {
229+ if (greeterSettings.lockedOutTime === 0) {
230+ return;
231+ }
220
232
221− // We're going to compare stored time to system time here.
233+ var now = new Date();
222− // - We do this every tick (rather than just once at the start)
234+ delayTarget = new Date(greeterSettings.lockedOutTime + failedLoginsDelayMinutes * 60000);
223− // because clock time can change while we're running. For example,
224− // ntpdate runs as an ifupdown script.
225− // - And we trust this check because if a malicious actor is able
226− // to manipulate time to avoid our lockout, there's not much we
227− // can do to stop them.
228
235
229 // If tooEarly is true, something went very wrong. Bug or NTP
236 // If tooEarly is true, something went very wrong. Bug or NTP
230 // misconfiguration maybe?
237 // misconfiguration maybe?
231 var tooEarly = now.getTime() < greeterSettings.lockedOutTime;
238 var tooEarly = now.getTime() < greeterSettings.lockedOutTime;
232 var tooLate = now >= delayTarget;
239 var tooLate = now >= delayTarget;
233
240
241+ // Compare stored time to system time. If a malicious actor is
242+ // able to manipulate time to avoid our lockout, they already have
243+ // enough access to cause damage. So we choose to trust this check.
234 if (tooEarly || tooLate) {
244 if (tooEarly || tooLate) {
235 stop();
245 stop();
236 delayMinutes = 0;
246 delayMinutes = 0;
237 } else {
247 } else {
238− var diff = delayTarget - now;
248+ triggered();
239− delayMinutes = Math.ceil(diff / 60000);
240− start(); // go again
241− }
242− }
243−
244− function checkForForcedDelay() {
245− if (greeterSettings.lockedOutTime === 0) {
246− return;
247 }
249 }
248−
249− delayTarget = new Date(greeterSettings.lockedOutTime + failedLoginsDelayMinutes * 60000);
250− triggered();
251 }
250 }
252
251
253 Component.onCompleted: checkForForcedDelay()
252 Component.onCompleted: checkForForcedDelay()
tests/qmltests/Greeter/tst_Greeter.qml−14
@@ -472,20 +472,6 @@ Item {
472 compare(view.delayMinutes, 0);
472 compare(view.delayMinutes, 0);
473 }
473 }
474
474
475− function test_forcedDelayWhileTimeChanges() {
476− greeterSettings.lockedOutTime = new Date().getTime();
477− resetLoader();
478− view = findChild(greeter, "testView");
479− verify(view.delayMinutes > 0);
480−
481− // Fake a time change by moving lockedOutTime way forward so that
482− // the greeter will think the wall clock is too early for some
483− // reason (like NTP messing up).
484− greeterSettings.lockedOutTime = new Date().getTime() + 6000000;
485− wait(1000);
486− compare(view.delayMinutes, 0);
487− }
488−
489 function test_forcedDelayRoundTrip() {
475 function test_forcedDelayRoundTrip() {
490 greeter.failedLoginsDelayAttempts = 1;
476 greeter.failedLoginsDelayAttempts = 1;
491 greeter.failedLoginsDelayMinutes = 0.001; // make delay very short
477 greeter.failedLoginsDelayMinutes = 0.001; // make delay very short