Pass error message from StepCheckSignature to AppInstaller 11/54611/10
authorArkadiusz Szulakiewicz <a.szulakiewi@partner.samsung.com>
Wed, 16 Dec 2015 12:18:46 +0000 (13:18 +0100)
committerPawel Sikorski <p.sikorski@samsung.com>
Fri, 18 Dec 2015 10:59:50 +0000 (02:59 -0800)
Change-Id: I422e111195249ac2db9668ad14013071af7dce40

src/common/app_installer.cc
src/common/app_installer.h
src/common/pkgmgr_signal.cc
src/common/pkgmgr_signal.h
src/common/step/step.h
src/common/step/step_check_signature.cc
src/common/step/step_check_signature.h
src/unit_tests/CMakeLists.txt
src/unit_tests/signature_unittest.cc

index 9c07a1c48cc5867cd509ef622e74bccd0cb82386..3376118dfe0bd1fcda7ff84d26b7cb643ea618de 100644 (file)
@@ -111,4 +111,8 @@ AppInstaller::Result AppInstaller::Run() {
   return ret;
 }
 
+void AppInstaller::HandleStepError(const std::string& error) {
+  pi_->SendError(error, context_->pkg_type.get(), context_->pkgid.get());
+}
+
 }  // namespace common_installer
index d925df10bf9709ded15ed75ddb3010e5ad43dc95..17adb5fb3c40d777ace1e67373e637802755ca94 100644 (file)
@@ -10,6 +10,9 @@
 
 #include <list>
 #include <memory>
+#include <string>
+
+#include <boost/bind.hpp>
 
 #include "common/pkgmgr_interface.h"
 #include "common/pkgmgr_signal.h"
@@ -59,8 +62,11 @@ class AppInstaller {
    */
   template<class StepT, class... Args>
   void AddStep(Args&&... args) {
-    steps_.push_back(std::unique_ptr<Step>(
-        new StepT(context_.get(), std::forward<Args>(args)...)));
+    std::unique_ptr<Step> step(
+        new StepT(context_.get(), std::forward<Args>(args)...));
+    step->on_error.connect(
+        boost::bind(&AppInstaller::HandleStepError, this, _1));
+    steps_.emplace_back(std::move(step));
   }
 
   /**
@@ -80,6 +86,8 @@ class AppInstaller {
   // data used to send signal
   std::unique_ptr<PkgmgrSignal> pi_;
 
+  void HandleStepError(const std::string& error);
+
   SCOPE_LOG_TAG(AppInstaller)
 
   DISALLOW_COPY_AND_ASSIGN(AppInstaller);
index 26d266c1c517fe2b6919bcebfe328fc640bf4f09..0e58639f89dc1a6df3bba6564018878d38bc6ae0 100644 (file)
@@ -37,7 +37,7 @@ namespace common_installer {
 PkgmgrSignal::State PkgmgrSignal::state_ = PkgmgrSignal::State::NOT_SENT;
 
 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi, RequestType req_type)
-    : pi_(pi), request_type_(req_type) {
+    : pi_(pi), request_type_(req_type), error_message_sent_(false) {
 }
 
 bool PkgmgrSignal::SendStarted(
@@ -79,7 +79,7 @@ bool PkgmgrSignal::SendFinished(
   if (state_ != State::STARTED) {
     return false;
   }
-  if (result != Step::Status::OK) {
+  if (result != Step::Status::OK && !error_message_sent_) {
     if (!SendSignal(
         PKGMGR_INSTALLER_ERROR_KEY_STR,
         std::to_string(static_cast<int>(result)).c_str(), type, pkgid)) {
@@ -94,6 +94,21 @@ bool PkgmgrSignal::SendFinished(
   return true;
 }
 
+bool PkgmgrSignal::SendError(
+    const std::string& error_message,
+    const std::string& type,
+    const std::string& pkgid) {
+  if (state_ != State::STARTED) {
+    return false;
+  }
+  error_message_sent_ = true;
+  return SendSignal(
+    PKGMGR_INSTALLER_ERROR_KEY_STR,
+    error_message.c_str(),
+    type,
+    pkgid);
+}
+
 bool PkgmgrSignal::SendSignal(
     const char* key,
     const char* value,
index 568042c729ad838ccb61b476803aad6ff6825e4f..c5d9dc71bce8dc21967b886e6831497a318762fe 100644 (file)
@@ -79,6 +79,18 @@ class PkgmgrSignal {
       Step::Status result,
       const std::string& type = std::string(),
       const std::string& pkgid = std::string());
+
+  /**
+   * "error" Signal sending
+   *
+   * \param error_message error message content
+   *
+   * \return true if success
+   */
+  bool SendError(const std::string& error_message,
+      const std::string& type = std::string(),
+      const std::string& pkgid = std::string());
+
   bool IsFinished() const;
 
   /**
@@ -100,6 +112,7 @@ class PkgmgrSignal {
   pkgmgr_installer* pi_;
   static State state_;
   RequestType request_type_;
+  bool error_message_sent_;
 
   DISALLOW_COPY_AND_ASSIGN(PkgmgrSignal);
 };
index 961a2391a0b359fe4c7e759a286637f5c83b7596..0e14de732d42ddd3c2e244360233068604105ab2 100644 (file)
 #ifndef COMMON_STEP_STEP_H_
 #define COMMON_STEP_STEP_H_
 
+#include <string>
+
+#include <boost/signals2.hpp>
+
 #include "common/installer_context.h"
 
 namespace common_installer {
@@ -38,6 +42,8 @@ namespace common_installer {
  */
 class Step {
  public:
+  using StepErrorSignal = boost::signals2::signal<void(const std::string&)>;
+
   /** Possible code returned by process, undo, clean, precheck methods. */
   enum class Status {
     OUT_OF_SPACE = -3,      /**< Out of disc space */
@@ -64,6 +70,8 @@ class Step {
   /** Checks the input data used during process method */
   virtual Status precheck() = 0;
 
+  StepErrorSignal on_error;
+
  protected:
   InstallerContext* context_;
 };
index 94bc8a2c9aa6523f2c05d50da333cea5be4fbb1c..4471eb37ccd7c6368b148fbe8c77fe56a860e76d 100644 (file)
@@ -55,7 +55,8 @@ common_installer::Step::Status ValidateSignatureFile(
     const bf::path& base_path,
     const ValidationCore::SignatureFileInfo& file_info,
     common_installer::PrivilegeLevel* level,
-    common_installer::CertificateInfo* cert_info) {
+    common_installer::CertificateInfo* cert_info,
+    std::string* error_message) {
   bf::path path = base_path / file_info.getFileName();
   LOG(INFO) << "Processing signature: " << path;
 
@@ -67,6 +68,8 @@ common_installer::Step::Status ValidateSignatureFile(
       true,                // file reference hash check flag
       data);               // output signature data
 
+  *error_message = validator.errorToString(result);
+
   switch (result) {
     case ValidationCore::E_SIG_REVOKED: {
       LOG(ERROR) << "Certificate is revoked";
@@ -137,7 +140,8 @@ namespace common_installer {
 namespace security {
 
 Step::Status ValidateSignatures(const bf::path& base_path,
-    PrivilegeLevel* level, common_installer::CertificateInfo* cert_info) {
+    PrivilegeLevel* level, common_installer::CertificateInfo* cert_info,
+    std::string* error_message) {
   // Find signature files
   ValidationCore::SignatureFileInfoSet signature_files;
   ValidationCore::SignatureFinder signature_finder(base_path.string());
@@ -150,9 +154,11 @@ Step::Status ValidateSignatures(const bf::path& base_path,
 
   // Read xml schema for signatures
   for (auto& file_info : signature_files) {
+    std::string error;
     Step::Status status = ValidateSignatureFile(base_path, file_info, level,
-                                                cert_info);
+                                                cert_info, &error);
     if (status != Step::Status::OK) {
+      *error_message = error;
       return status;
     }
   }
@@ -176,13 +182,14 @@ Step::Status StepCheckSignature::precheck() {
 
 Step::Status StepCheckSignature::process() {
   PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
+  std::string error_message;
   Status status =
       ValidateSignatures(context_->unpacked_dir_path.get(), &level,
-                         &context_->certificate_info.get());
+                         &context_->certificate_info.get(), &error_message);
   if (status != Status::OK) {
+      on_error(error_message);
     return status;
   }
-
   LOG(INFO) << "Privilege level: " << PrivilegeLevelToString(level);
   context_->privilege_level.set(level);
 
index 9f8c2e0340f269de541ac81c6c7977b7de42b395..a0305f32a5da254e6e73921ab7db426bb9bb9769 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <manifest_parser/utils/logging.h>
 
+#include <string>
+
 #include "common/installer_context.h"
 #include "common/step/step.h"
 
@@ -54,7 +56,8 @@ class StepCheckSignature : public Step {
 
 // Exposed for tests
 Step::Status ValidateSignatures(const boost::filesystem::path& base_path,
-    PrivilegeLevel* level, common_installer::CertificateInfo* cert_info);
+    PrivilegeLevel* level, common_installer::CertificateInfo* cert_info,
+    std::string* error_message);
 
 }  // namespace security
 }  // namespace common_installer
index 588c87d49066b119ca1fa9accb865ce55cfb2a7f..54f33fa0fe1cbb72dbf1eb3523b987ea29745752 100644 (file)
@@ -28,8 +28,8 @@ ENDFOREACH(test)
 # FindGTest module do not sets all needed libraries in GTEST_LIBRARIES and
 # GTest main libraries is still missing, so additional linking of
 # GTEST_MAIN_LIBRARIES is needed.
-target_link_libraries(signature_unittest PUBLIC ${TARGET_LIBNAME_COMMON} ${GTEST_MAIN_LIBRARIES})
-target_link_libraries(smoke_test PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_TPK})
+target_link_libraries(signature_unittest PUBLIC ${TARGET_LIBNAME_COMMON} ${GTEST_MAIN_LIBRARIES} pthread)
+target_link_libraries(smoke_test PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_TPK} pthread)
 
 FOREACH(test ${TESTS})
   INSTALL(TARGETS ${test} DESTINATION ${BINDIR}/${DESTINATION_DIR})
index 98485bd623a7087600fe0e8237f7ad4a69be5a8f..89b91cb75b7817d1f9ea9fdff31429d1672a22ec 100644 (file)
@@ -25,7 +25,8 @@ TEST_F(SignatureValidatorTest, HandlesInitializedSignatureDir) {
       "/usr/share/app-installers-ut/test_samples/good_signatures"));
   PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
   common_installer::CertificateInfo cert_info;
-  EXPECT_EQ(ValidateSignatures(*signature_file, &level, &cert_info),
+  std::string error;
+  EXPECT_EQ(ValidateSignatures(*signature_file, &level, &cert_info, &error),
             Step::Status::OK);
 }
 
@@ -35,7 +36,8 @@ TEST_F(SignatureValidatorTest, HandlesBadSignatureDir) {
       "/usr/share/app-installers-ut/test_samples/bad_signatures"));
   PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
   common_installer::CertificateInfo cert_info;
-  EXPECT_EQ(ValidateSignatures(*signature_file, &level, &cert_info),
+  std::string error;
+  EXPECT_EQ(ValidateSignatures(*signature_file, &level, &cert_info, &error),
             Step::Status::ERROR);
 }