update_engine: Process Omaha response for rollback images

Omaha returns whether the image returned is a rollback in the
_rollback="true" argument. If this is set, the client has to check
whether it's OK to apply the rollback image (policy is specifically
requesting a rollback and verified boot will accept the image based
on its kernel and firmware key versions).

In addition to this, the device has to do a safe powerwash if the
image is a rollback. (We're not supporting rollbacks with partial
or no powerwash yet.)

We're also setting the rollback_happened preference to avoid force
updates happening before the policy is available again.

Chromium CL adding the error code: http://crrev.com/c/1047866

BUG=chromium:840432
TEST='cros_run_unit_tests --board=caroline --packages update_engine'

Change-Id: I1436ca96211b2a8523e78bf83602ef8b6b525570
Reviewed-on: https://chromium-review.googlesource.com/1047610
Commit-Ready: Marton Hunyady <hunyadym@chromium.org>
Tested-by: Marton Hunyady <hunyadym@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 6809979..9021e3f 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -88,6 +88,9 @@
 
 // updatecheck attributes (without the underscore prefix).
 static const char* kEolAttr = "eol";
+static const char* kRollback = "rollback";
+static const char* kFirmwareVersion = "firmware_version";
+static const char* kKernelVersion = "kernel_version";
 
 namespace {
 
@@ -996,6 +999,18 @@
 
   // Parse the updatecheck attributes.
   PersistEolStatus(parser_data->updatecheck_attrs);
+  // Rollback-related updatecheck attributes.
+  // Defaults to false if attribute is not present.
+  output_object->is_rollback =
+      ParseBool(parser_data->updatecheck_attrs[kRollback]);
+  // Defaults to 0 if attribute is not present. This is fine for these values,
+  // because it's the lowest possible value, and the rollback image won't be
+  // installed, if the values in the TPM are larger than these, and in case the
+  // values in the TPM are 0, all images will be able to boot up.
+  output_object->firmware_version = static_cast<uint32_t>(
+      ParseInt(parser_data->updatecheck_attrs[kFirmwareVersion]));
+  output_object->kernel_version = static_cast<uint32_t>(
+      ParseInt(parser_data->updatecheck_attrs[kKernelVersion]));
 
   if (!ParseStatus(parser_data, output_object, completer))
     return false;