return ret;
}
+void AppInstaller::HandleStepError(const std::string& error) {
+ pi_->SendError(error, context_->pkg_type.get(), context_->pkgid.get());
+}
+
} // namespace common_installer
#include <list>
#include <memory>
+#include <string>
+
+#include <boost/bind.hpp>
#include "common/pkgmgr_interface.h"
#include "common/pkgmgr_signal.h"
*/
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));
}
/**
// 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);
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(
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)) {
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,
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;
/**
pkgmgr_installer* pi_;
static State state_;
RequestType request_type_;
+ bool error_message_sent_;
DISALLOW_COPY_AND_ASSIGN(PkgmgrSignal);
};
#ifndef COMMON_STEP_STEP_H_
#define COMMON_STEP_STEP_H_
+#include <string>
+
+#include <boost/signals2.hpp>
+
#include "common/installer_context.h"
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 */
/** Checks the input data used during process method */
virtual Status precheck() = 0;
+ StepErrorSignal on_error;
+
protected:
InstallerContext* context_;
};
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;
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";
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());
// 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;
}
}
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);
#include <manifest_parser/utils/logging.h>
+#include <string>
+
#include "common/installer_context.h"
#include "common/step/step.h"
// 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
# 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})
"/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);
}
"/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);
}