diff options
-rw-r--r-- | action_processor.h | 1 | ||||
-rw-r--r-- | delta_performer.cc | 5 | ||||
-rw-r--r-- | delta_performer.h | 2 | ||||
-rw-r--r-- | omaha_response_handler_action.cc | 10 | ||||
-rw-r--r-- | omaha_response_handler_action.h | 8 | ||||
-rw-r--r-- | omaha_response_handler_action_unittest.cc | 26 | ||||
-rw-r--r-- | update_attempter.cc | 12 |
7 files changed, 48 insertions, 16 deletions
diff --git a/action_processor.h b/action_processor.h index 124fe000..ef06181f 100644 --- a/action_processor.h +++ b/action_processor.h @@ -40,6 +40,7 @@ enum ActionExitCode { kActionCodeDownloadWriteError = 14, kActionCodeNewRootfsVerificationError = 15, kActionCodeNewKernelVerificationError = 16, + kActionCodeSignedDeltaPayloadExpectedError = 17, kActionCodeOmahaRequestEmptyResponseError = 200, kActionCodeOmahaRequestXMLParseError = 201, kActionCodeOmahaRequestNoUpdateCheckNode = 202, diff --git a/delta_performer.cc b/delta_performer.cc index 117e8f5d..1a98102f 100644 --- a/delta_performer.cc +++ b/delta_performer.cc @@ -33,12 +33,13 @@ using google::protobuf::RepeatedPtrField; namespace chromeos_update_engine { +const char DeltaPerformer::kUpdatePayloadPublicKeyPath[] = + "/usr/share/update_engine/update-payload-key.pub.pem"; + namespace { const int kDeltaVersionLength = 8; const int kDeltaProtobufLengthLength = 8; -const char kUpdatePayloadPublicKeyPath[] = - "/usr/share/update_engine/update-payload-key.pub.pem"; const int kUpdateStateOperationInvalid = -1; const int kMaxResumedUpdateFailures = 10; diff --git a/delta_performer.h b/delta_performer.h index c693333a..7cc1d9bf 100644 --- a/delta_performer.h +++ b/delta_performer.h @@ -31,6 +31,8 @@ class DeltaPerformer : public FileWriter { kMetadataParseInsufficientData, }; + static const char kUpdatePayloadPublicKeyPath[]; + DeltaPerformer(PrefsInterface* prefs) : prefs_(prefs), fd_(-1), diff --git a/omaha_response_handler_action.cc b/omaha_response_handler_action.cc index fdbd80a6..74e149f3 100644 --- a/omaha_response_handler_action.cc +++ b/omaha_response_handler_action.cc @@ -19,6 +19,11 @@ namespace chromeos_update_engine { const char OmahaResponseHandlerAction::kDeadlineFile[] = "/tmp/update-check-response-deadline"; +OmahaResponseHandlerAction::OmahaResponseHandlerAction(PrefsInterface* prefs) + : prefs_(prefs), + got_no_update_response_(false), + key_path_(DeltaPerformer::kUpdatePayloadPublicKeyPath) {} + void OmahaResponseHandlerAction::PerformAction() { CHECK(HasInputObject()); ScopedActionCompleter completer(processor_, this); @@ -49,6 +54,11 @@ void OmahaResponseHandlerAction::PerformAction() { utils::BootKernelDevice(install_plan_.install_path); install_plan_.is_full_update = !response.is_delta; + if (!response.is_delta && utils::FileExists(key_path_.c_str())) { + // Can't sign old style full payloads but signature is required so bail out. + completer.set_code(kActionCodeSignedDeltaPayloadExpectedError); + return; + } TEST_AND_RETURN(HasOutputPipe()); if (HasOutputPipe()) diff --git a/omaha_response_handler_action.h b/omaha_response_handler_action.h index 25c57e0e..17851382 100644 --- a/omaha_response_handler_action.h +++ b/omaha_response_handler_action.h @@ -29,9 +29,7 @@ class OmahaResponseHandlerAction : public Action<OmahaResponseHandlerAction> { public: static const char kDeadlineFile[]; - OmahaResponseHandlerAction(PrefsInterface* prefs) - : prefs_(prefs), - got_no_update_response_(false) {} + OmahaResponseHandlerAction(PrefsInterface* prefs); typedef ActionTraits<OmahaResponseHandlerAction>::InputObjectType InputObjectType; typedef ActionTraits<OmahaResponseHandlerAction>::OutputObjectType @@ -53,6 +51,7 @@ class OmahaResponseHandlerAction : public Action<OmahaResponseHandlerAction> { // Debugging/logging static std::string StaticType() { return "OmahaResponseHandlerAction"; } std::string Type() const { return StaticType(); } + void set_key_path(const std::string& path) { key_path_ = path; } private: // Assumes you want to install on the "other" device, where the other @@ -74,6 +73,9 @@ class OmahaResponseHandlerAction : public Action<OmahaResponseHandlerAction> { // True only if we got a response and the response said no updates bool got_no_update_response_; + // Public key path to use for payload verification. + std::string key_path_; + DISALLOW_COPY_AND_ASSIGN(OmahaResponseHandlerAction); }; diff --git a/omaha_response_handler_action_unittest.cc b/omaha_response_handler_action_unittest.cc index 7f1ee159..4a60315d 100644 --- a/omaha_response_handler_action_unittest.cc +++ b/omaha_response_handler_action_unittest.cc @@ -23,6 +23,7 @@ class OmahaResponseHandlerActionTest : public ::testing::Test { // If out is non-NULL, it's set w/ the response from the action. bool DoTest(const OmahaResponse& in, const string& boot_dev, + bool test_key, InstallPlan* out); }; @@ -58,6 +59,7 @@ const string kLongName = bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in, const string& boot_dev, + bool test_key, InstallPlan* out) { ActionProcessor processor; OmahaResponseHandlerActionProcessorDelegate delegate; @@ -71,6 +73,9 @@ bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in, .WillOnce(Return(true)); } OmahaResponseHandlerAction response_handler_action(&prefs); + if (test_key) { + response_handler_action.set_key_path("/dev/null"); + } response_handler_action.set_boot_device(boot_dev); BondActions(&feeder_action, &response_handler_action); ObjectCollectorAction<InstallPlan> collector_action; @@ -84,7 +89,9 @@ bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in, if (out) *out = collector_action.object(); EXPECT_TRUE(delegate.code_set_); - return delegate.code_ == kActionCodeSuccess; + ActionExitCode expected_code = test_key ? + kActionCodeSignedDeltaPayloadExpectedError : kActionCodeSuccess; + return delegate.code_ == expected_code; } TEST_F(OmahaResponseHandlerActionTest, SimpleTest) { @@ -103,7 +110,7 @@ TEST_F(OmahaResponseHandlerActionTest, SimpleTest) { in.is_delta = false; in.deadline = "20101020"; InstallPlan install_plan; - EXPECT_TRUE(DoTest(in, "/dev/sda3", &install_plan)); + EXPECT_TRUE(DoTest(in, "/dev/sda3", false, &install_plan)); EXPECT_TRUE(install_plan.is_full_update); EXPECT_EQ(in.codebase, install_plan.download_url); EXPECT_EQ(in.hash, install_plan.download_hash); @@ -131,7 +138,7 @@ TEST_F(OmahaResponseHandlerActionTest, SimpleTest) { in.prompt = true; in.is_delta = true; InstallPlan install_plan; - EXPECT_TRUE(DoTest(in, "/dev/sda5", &install_plan)); + EXPECT_TRUE(DoTest(in, "/dev/sda5", false, &install_plan)); EXPECT_FALSE(install_plan.is_full_update); EXPECT_EQ(in.codebase, install_plan.download_url); EXPECT_EQ(in.hash, install_plan.download_hash); @@ -154,7 +161,7 @@ TEST_F(OmahaResponseHandlerActionTest, SimpleTest) { in.is_delta = false; in.deadline = "some-deadline"; InstallPlan install_plan; - EXPECT_TRUE(DoTest(in, "/dev/sda3", &install_plan)); + EXPECT_TRUE(DoTest(in, "/dev/sda3", false, &install_plan)); EXPECT_TRUE(install_plan.is_full_update); EXPECT_EQ(in.codebase, install_plan.download_url); EXPECT_EQ(in.hash, install_plan.download_hash); @@ -167,11 +174,20 @@ TEST_F(OmahaResponseHandlerActionTest, SimpleTest) { } } +TEST_F(OmahaResponseHandlerActionTest, PublicKeyOldStyleTest) { + OmahaResponse in; + in.update_exists = true; + in.codebase = "http://foo/the_update_a.b.c.d.tgz"; + in.is_delta = false; + InstallPlan install_plan; + EXPECT_TRUE(DoTest(in, "/dev/sda3", true, &install_plan)); +} + TEST_F(OmahaResponseHandlerActionTest, NoUpdatesTest) { OmahaResponse in; in.update_exists = false; InstallPlan install_plan; - EXPECT_FALSE(DoTest(in, "/dev/sda1", &install_plan)); + EXPECT_FALSE(DoTest(in, "/dev/sda1", false, &install_plan)); EXPECT_FALSE(install_plan.is_full_update); EXPECT_EQ("", install_plan.download_url); EXPECT_EQ("", install_plan.download_hash); diff --git a/update_attempter.cc b/update_attempter.cc index 3ea1c18f..949434e8 100644 --- a/update_attempter.cc +++ b/update_attempter.cc @@ -456,12 +456,12 @@ void UpdateAttempter::CreatePendingErrorEvent(AbstractAction* action, return; } - // For now assume that Omaha response action failure means that - // there's no update so don't send an event. Also, double check that - // the failure has not occurred while sending an error event -- in - // which case don't schedule another. This shouldn't really happen - // but just in case... - if (action->Type() == OmahaResponseHandlerAction::StaticType() || + // For now assume that a generic Omaha response action failure means that + // there's no update so don't send an event. Also, double check that the + // failure has not occurred while sending an error event -- in which case + // don't schedule another. This shouldn't really happen but just in case... + if ((action->Type() == OmahaResponseHandlerAction::StaticType() && + code == kActionCodeError) || status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { return; } |