update_engine: UM: Make DefaultPolicy::UpdateCheckAllowed stateful.

This adds an auxiliary state to DefaultPolicy, and makes
UpdateCheckAllowed use it for recording the last time an update check
was allowed. This is necessary for enforcing a minimum interval between
consecutive update checks, a necessary property in the unlikely case
that the main policy is badly screwed: with it, the update engine will
repeatedly check for updates, unnecessarily consuming local resources
and potentially DDoS-ing Omaha.

In order to track time, the DefaultPolicy now takes a ClockInterface
argument; for backward compatibility with existing unit testing code, we
allow this handle to be null, in which case time is not tracked and the
policy resorts to the previous default behavior (namely, updates are
always allowed). We do plug a clock when DefaultPolicy is used in the
UpdateManager production (backup policy) and fake (main policy)
implementations.

Note that the state is added as an external object, in order to work
around the constness of policy objects that's implied by the policy API
(const methods).

Finally, it should be noted that we use monotonic time in order to
ensure that the DefaultPolicy does not become an attack surface for
denying updates, or exhausting local resources and/or DoS-ing services.

BUG=chromium:394778
TEST=Unit tests.

Change-Id: I08628ea9b0067fa7abf6e457c55d4ffea276c463
Reviewed-on: https://chromium-review.googlesource.com/208732
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/update_manager/default_policy.cc b/update_manager/default_policy.cc
new file mode 100644
index 0000000..2c75d13
--- /dev/null
+++ b/update_manager/default_policy.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/update_manager/default_policy.h"
+
+namespace {
+
+// A fixed minimum interval between consecutive allowed update checks. This
+// needs to be long enough to prevent busywork and/or DDoS attacks on Omaha, but
+// at the same time short enough to allow the machine to update itself
+// reasonably soon.
+const int kCheckIntervalInSeconds = 15 * 60;
+
+}  // namespace
+
+namespace chromeos_update_manager {
+
+DefaultPolicy::DefaultPolicy(chromeos_update_engine::ClockInterface* clock)
+    : clock_(clock), aux_state_(new DefaultPolicyState()) {}
+
+EvalStatus DefaultPolicy::UpdateCheckAllowed(
+    EvaluationContext* ec, State* state, std::string* error,
+    UpdateCheckParams* result) const {
+  result->updates_enabled = true;
+  result->target_channel.clear();
+
+  // Ensure that the minimum interval is set. If there's no clock, this defaults
+  // to always allowing the update.
+  if (!aux_state_->IsLastCheckAllowedTimeSet() ||
+      ec->IsMonotonicTimeGreaterThan(
+          aux_state_->last_check_allowed_time() +
+          base::TimeDelta::FromSeconds(kCheckIntervalInSeconds))) {
+    if (clock_)
+      aux_state_->set_last_check_allowed_time(clock_->GetMonotonicTime());
+    return EvalStatus::kSucceeded;
+  }
+
+  return EvalStatus::kAskMeAgainLater;
+}
+
+}  // namespace chromeos_update_manager