To offer more detailed information to developer.
dependency : https://review.tizen.org/gerrit/#/c/56333/
Change-Id: Id156eaf0eb03b73f9a66fbb27d599a95da952da6
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
return ret;
}
-void AppInstaller::HandleStepError(const std::string& error) {
- pi_->SendError(error, context_->pkg_type.get(), context_->pkgid.get());
+void AppInstaller::HandleStepError(Step::Status result,
+ const std::string& error) {
+ pi_->SendError(result, error, context_->pkg_type.get(),
+ context_->pkgid.get());
}
} // namespace common_installer
std::unique_ptr<Step> step(
new StepT(context_.get(), std::forward<Args>(args)...));
step->on_error.connect(
- boost::bind(&AppInstaller::HandleStepError, this, _1));
+ boost::bind(&AppInstaller::HandleStepError, this, _1, _2));
steps_.emplace_back(std::move(step));
}
// data used to send signal
std::unique_ptr<PkgmgrSignal> pi_;
- void HandleStepError(const std::string& error);
+ void HandleStepError(Step::Status result, const std::string& error);
SCOPE_LOG_TAG(AppInstaller)
std::ifstream preload_list("/etc/package-manager/preload/preload_list.txt");
bool is_preload_app = false;
for (std::string str; std::getline(preload_list, str); ) {
- if(str.compare(directory_path.filename().string()) == 0) {
+ if (str.compare(directory_path.filename().string()) == 0) {
is_preload_app = true;
break;
}
}
bool PkgmgrSignal::SendError(
+ Step::Status result,
const std::string& error_message,
const std::string& type,
const std::string& pkgid) {
if (state_ != State::STARTED) {
return false;
}
+ std::string error_value = std::to_string(static_cast<int>(result));
+ if (!error_message.empty()) {
+ error_value = error_value + ":" + error_message;
+ }
+ LOG(ERROR) << "PkgmgrSignal error_value: (" << error_value << ")";
error_message_sent_ = true;
return SendSignal(
PKGMGR_INSTALLER_ERROR_KEY_STR,
- error_message.c_str(),
+ error_value.c_str(),
type,
pkgid);
}
*
* \return true if success
*/
- bool SendError(const std::string& error_message,
+ bool SendError(Step::Status result,
+ const std::string& error_message,
const std::string& type = std::string(),
const std::string& pkgid = std::string());
#include "common/security_registration.h"
#include <boost/filesystem/operations.hpp>
+#include <boost/format.hpp>
#include <manifest_parser/utils/logging.h>
#include <security-manager.h>
bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
const boost::filesystem::path& path, uid_t uid,
const std::vector<std::string>& privileges,
- app_inst_req* req) {
+ app_inst_req* req, std::string* error_message) {
if (app_id.empty() || pkg_id.empty()) {
LOG(ERROR) << "Appid or pkgid is empty. Both values must be set";
return false;
int error = security_manager_app_inst_req_set_app_id(req,
app_id.c_str());
if (error != SECURITY_MANAGER_SUCCESS) {
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
return false;
}
error = security_manager_app_inst_req_set_pkg_id(req,
pkg_id.c_str());
if (error != SECURITY_MANAGER_SUCCESS) {
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
return false;
}
error = security_manager_app_inst_req_set_uid(req, uid);
if (error != SECURITY_MANAGER_SUCCESS) {
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
return false;
}
error = security_manager_app_inst_req_add_path(req, subpath.c_str(),
policy.second);
if (error != SECURITY_MANAGER_SUCCESS) {
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message =
+ security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
return false;
}
}
bool RegisterSecurityContext(const std::string& app_id,
const std::string& pkg_id, const boost::filesystem::path& path, uid_t uid,
- const std::vector<std::string>& privileges) {
+ const std::vector<std::string>& privileges, std::string* error_message) {
app_inst_req* req;
int error = security_manager_app_inst_req_new(&req);
LOG(ERROR)
<< "Failed while calling security_manager_app_inst_req_new failed "
<< "(error code: " << error << ")";
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
return false;
}
- if (!PrepareRequest(app_id, pkg_id, path, uid, privileges, req)) {
+ if (!PrepareRequest(app_id, pkg_id, path, uid, privileges,
+ req, error_message)) {
LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
security_manager_app_inst_req_free(req);
return false;
if (error != SECURITY_MANAGER_SUCCESS) {
LOG(ERROR) << "Failed while calling security_manager_app_install failed "
<< "(error code: " << error << ")";
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
security_manager_app_inst_req_free(req);
return false;
}
}
bool UnregisterSecurityContext(const std::string& app_id,
- const std::string& pkg_id, uid_t uid) {
+ const std::string& pkg_id, uid_t uid, std::string* error_message) {
app_inst_req* req;
int error = security_manager_app_inst_req_new(&req);
if (error != SECURITY_MANAGER_SUCCESS) {
LOG(ERROR) << "Failed while calling security_manager_app_inst_req_new "
<< "(error code: " << error << ")";
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
return false;
}
- if (!PrepareRequest(app_id, pkg_id, bf::path(), uid, {}, req)) {
+ if (!PrepareRequest(app_id, pkg_id, bf::path(), uid, {},
+ req, error_message)) {
LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
security_manager_app_inst_req_free(req);
return false;
if (error != SECURITY_MANAGER_SUCCESS) {
LOG(ERROR) << "Failed while calling security_manager_app_uninstall failed "
<< "(error code: " << error << ")";
+ std::string errnum = boost::str(boost::format("%d") % error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
security_manager_app_inst_req_free(req);
return false;
}
bool RegisterSecurityContextForManifest(
const std::string& pkg_id, const boost::filesystem::path& path,
- uid_t uid, manifest_x* manifest) {
+ uid_t uid, manifest_x* manifest, std::string* error_message) {
std::vector<std::string> priv_vec;
for (const char* priv : GListRange<char*>(manifest->privileges)) {
priv_vec.emplace_back(priv);
return false;
}
if (!RegisterSecurityContext(app->appid, pkg_id,
- path, uid, priv_vec)) {
+ path, uid, priv_vec, error_message)) {
return false;
}
}
}
bool UnregisterSecurityContextForManifest(const std::string& pkg_id,
- uid_t uid, manifest_x* manifest) {
+ uid_t uid, manifest_x* manifest, std::string* error_message) {
for (application_x* app : GListRange<application_x*>(manifest->application)) {
if (!app->appid) {
return false;
}
- if (!UnregisterSecurityContext(app->appid, pkg_id, uid)) {
+ if (!UnregisterSecurityContext(app->appid, pkg_id, uid, error_message)) {
return false;
}
}
* \param path path of installed package
* \param uid uid
* \param privileges pointer to manifest structure
+ * \param error_message extra/detailed error message
*
* \return true if success
*/
bool RegisterSecurityContext(const std::string& app_id,
const std::string& pkg_id, const boost::filesystem::path& path, uid_t uid,
- const std::vector<std::string>& privileges);
+ const std::vector<std::string>& privileges, std::string* error_message);
/**
* Adapter interface for external Security module.
* \param app_id id of given application
* \param pkg_id id of given package
* \param uid uid
+ * \param error_message extra/detailed error message
*
* \return true if success
*/
bool UnregisterSecurityContext(const std::string& app_id,
- const std::string& pkg_id, uid_t uid);
+ const std::string& pkg_id, uid_t uid, std::string* error_message);
/**
* Adapter interface for external Security module.
* \param path path of installed package
* \param uid uid
* \param manifest pointer to manifest structure
+ * \param error_message extra/detailed error message
*
* \return true if success
*/
bool RegisterSecurityContextForManifest(const std::string& pkg_id,
- const boost::filesystem::path& path, uid_t uid, manifest_x* manifest);
+ const boost::filesystem::path& path, uid_t uid, manifest_x* manifest,
+ std::string* error_message);
/**
* Adapter interface for external Security module.
* \param pkg_id pkgid of given package
* \param uid uid
* \param manifest pointer to manifest structure
+ * \param error_message extra/detailed error message
*
* \return true if success
*/
bool UnregisterSecurityContextForManifest(const std::string& pkg_id, uid_t uid,
- manifest_x* manifest);
+ manifest_x* manifest, std::string* error_message);
} // namespace common_installer
#ifndef COMMON_STEP_STEP_H_
#define COMMON_STEP_STEP_H_
+#include <package-manager.h>
+
#include <boost/signals2.hpp>
#include <string>
*/
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 */
- INVALID_VALUE = -2, /**< Invalid argument */
- ERROR = -1, /**< General error */
- OK = 0 /**< General success */
+ UNZIP_ERROR = PKGCMD_ERRCODE_UNZIP_ERROR,
+ SECURITY_ERROR = PKGCMD_ERRCODE_SECURITY_ERROR,
+ REGISTER_ERROR = PKGCMD_ERRCODE_REGISTER_ERROR,
+ PRIVILEGE_ERROR = PKGCMD_ERRCODE_PRIVILEGE_ERROR,
+ PARSE_ERROR = PKGCMD_ERRCODE_PARSE_ERROR,
+ RECOVERY_ERROR = PKGCMD_ERRCODE_RECOVERY_ERROR,
+ DELTA_ERROR = PKGCMD_ERRCODE_DELTA_ERROR,
+ APP_DIR_ERROR = PKGCMD_ERRCODE_APP_DIR_ERROR,
+ CONFIG_ERROR = PKGCMD_ERRCODE_CONFIG_ERROR,
+ SIGNATURE_ERROR = PKGCMD_ERRCODE_SIGNATURE_ERROR,
+ SIGNATURE_INVALID = PKGCMD_ERRCODE_SIGNATURE_INVALID,
+ CERT_ERROR = PKGCMD_ERRCODE_CERT_ERROR,
+ AUTHOR_CERT_NOT_MATCH = PKGCMD_ERRCODE_AUTHOR_CERT_NOT_MATCH,
+ AUTHOR_CERT_NOT_FOUND = PKGCMD_ERRCODE_AUTHOR_CERT_NOT_FOUND,
+ ICON_ERROR = PKGCMD_ERRCODE_ICON_ERROR,
+ ICON_NOT_FOUND = PKGCMD_ERRCODE_ICON_NOT_FOUND,
+ MANIFEST_ERROR = PKGCMD_ERRCODE_MANIFEST_ERROR,
+ MANIFEST_NOT_FOUND = PKGCMD_ERRCODE_MANIFEST_NOT_FOUND,
+ PACKAGE_NOT_FOUND = PKGCMD_ERRCODE_PACKAGE_NOT_FOUND,
+ OPERATION_NOT_ALLOWED = PKGCMD_ERRCODE_OPERATION_NOT_ALLOWED,
+ OUT_OF_SPACE = PKGCMD_ERRCODE_OUT_OF_SPACE,
+ INVALID_VALUE = PKGCMD_ERRCODE_INVALID_VALUE,
+ ERROR = PKGCMD_ERRCODE_ERROR,
+ OK = PKGCMD_ERRCODE_OK
};
+ using StepErrorSignal =
+ boost::signals2::signal<void(Step::Status result, const std::string&)>;
+
/** Standard constructor */
explicit Step(InstallerContext* context) : context_(context) { }
icon_x* icon = reinterpret_cast<icon_x*>(app->icon->data);
if (!icon->text) {
LOG(ERROR) << "Icon text is not set";
- return Status::ERROR;
+ return Status::ICON_NOT_FOUND;
}
app_icon += bf::path(icon->text).extension();
} else {
for (auto& pair : icons_) {
if (!MoveFile(pair.first, pair.second)) {
LOG(ERROR) << "Cannot create backup for icon: " << pair.first;
- return Status::ERROR;
+ return Status::ICON_ERROR;
}
}
for (auto& pair : icons_) {
if (!MoveFile(pair.second, pair.first)) {
LOG(ERROR) << "Cannot revert icon from backup: " << pair.first;
- return Status::ERROR;
+ return Status::ICON_ERROR;
}
}
LOG(DEBUG) << "Icons reverted from backup";
Step::Status StepBackupManifest::precheck() {
if (!bf::exists(context_->xml_path.get())) {
LOG(ERROR) << "Xml manifest file does not exist";
- return Status::ERROR;
+ return Status::MANIFEST_NOT_FOUND;
}
return Status::OK;
}
bf::copy(context_->xml_path.get(), context_->backup_xml_path.get(), error);
if (error) {
LOG(ERROR) << "Failed to make a copy of xml manifest file";
- return Status::ERROR;
+ return Status::MANIFEST_ERROR;
}
LOG(DEBUG) << "Manifest backup created";
return Status::OK;
bf::remove(context_->backup_xml_path.get(), error);
if (error) {
LOG(WARNING) << "Cannot remove backup manifest file";
- return Status::ERROR;
+ return Status::MANIFEST_ERROR;
}
LOG(DEBUG) << "Manifest backup removed";
return Status::OK;
bf::remove(context_->xml_path.get(), error);
if (error) {
LOG(ERROR) << "Failed to remove newly generated xml file in revert";
- return Status::ERROR;
+ return Status::MANIFEST_ERROR;
}
if (!MoveFile(context_->backup_xml_path.get(),
context_->xml_path.get())) {
LOG(ERROR) << "Failed to revert a content of xml manifest file";
- return Status::ERROR;
+ return Status::MANIFEST_ERROR;
}
LOG(DEBUG) << "Manifest reverted from backup";
}
if (!cert) {
LOG(ERROR) << "Trying to update package without signature is not allowed "
<< "when the previous version of package has signature";
- return Status::ERROR;
+ return Status::AUTHOR_CERT_NOT_FOUND;
} else {
try {
if (old_author_certificate != cert->getBase64()) {
LOG(ERROR) << "Author signature doesn't match the previous one. "
<< "Update must be aborted";
- return Status::ERROR;
+ return Status::AUTHOR_CERT_NOT_MATCH;
}
} catch (const ValidationCore::Certificate::Exception::Base &e) {
LOG(ERROR) << "Exception occured on cert-svc-vcore getBase64 "
<< "Dump : " << e.DumpToString();
- return Status::ERROR;
+ return Status::CERT_ERROR;
}
}
} else {
if (cert) {
LOG(ERROR) << "Trying to update package with signature is not allowed "
<< "when the previous version of package has not signature";
- return Status::ERROR;
+ return Status::AUTHOR_CERT_NOT_MATCH;
}
}
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
+#include <boost/format.hpp>
#include <glib.h>
#include <privilege_manager.h>
true, // file reference hash check flag
data); // output signature data
+ std::string errnum =
+ boost::str(boost::format("%d") % result);
*error_message = validator.errorToString(result);
+ *error_message += ":<" + errnum + ">";
switch (result) {
case ValidationCore::E_SIG_REVOKED: {
LOG(ERROR) << "Certificate is revoked";
- return common_installer::Step::Status::ERROR;
+ return common_installer::Step::Status::SIGNATURE_INVALID;
};
case ValidationCore::E_SIG_DISREGARDED: {
if (data.isAuthorSignature()) {
LOG(ERROR) << "Author-signiture is disregarded";
- return common_installer::Step::Status::ERROR;
+ return common_installer::Step::Status::SIGNATURE_INVALID;
}
LOG(WARNING) << "Signature disregarded: " << path;
break;
default: {
LOG(ERROR) << "signature validation check failed : "
<< validator.errorToString(result);
- return common_installer::Step::Status::ERROR;
+ return common_installer::Step::Status::SIGNATURE_INVALID;
};
}
return common_installer::Step::Status::OK;
}
bool ValidatePrivilegeLevel(common_installer::PrivilegeLevel level,
- bool is_webapp, const char* api_version, GList* privileges) {
+ bool is_webapp, const char* api_version, GList* privileges,
+ std::string* error_message) {
if (level == common_installer::PrivilegeLevel::UNTRUSTED) {
if (privileges) {
LOG(ERROR) << "Untrusted application cannot declare privileges";
privileges, PrivilegeLevelToVisibility(level), &error);
}
if (status != PRVMGR_ERR_NONE) {
- LOG(ERROR) << "Error while verifing privilege level: " << error;
+ std::string errnum =
+ boost::str(boost::format("%d") % status);
+ LOG(ERROR) << "Error while verifing privilege level: "
+ << error << " <" << errnum << ">";
+ *error_message = error;
+ *error_message += ":<" + errnum + ">";
free(error);
return false;
}
ValidateSignatures(context_->unpacked_dir_path.get(), &level,
&context_->certificate_info.get(), &error_message);
if (status != Status::OK) {
- on_error(error_message);
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(status, error_message);
return status;
}
LOG(INFO) << "Privilege level: " << PrivilegeLevelToString(level);
// TODO(t.iwanek): refactoring, move to wgt backend
bool is_webapp = context_->pkg_type.get() == "wgt";
+ error_message.clear();
if (!ValidatePrivilegeLevel(level, is_webapp,
context_->manifest_data.get()->api_version,
- context_->manifest_data.get()->privileges))
- return Status::ERROR;
+ context_->manifest_data.get()->privileges, &error_message)) {
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(Status::SIGNATURE_ERROR, error_message);
+ }
+ return Status::SIGNATURE_ERROR;
+ }
LOG(INFO) << "Signature done";
return Status::OK;
SetupFileCreationMask();
if (!SetupRootAppDirectory())
- return Status::ERROR;
+ return Status::CONFIG_ERROR;
switch (pkgmgr_->GetRequestType()) {
case RequestType::Install:
if (context_->request_mode.get() != RequestMode::GLOBAL) {
LOG(ERROR) <<
"Only global user allows to use Manifest Direct Install";
- return Status::ERROR;
+ return Status::CONFIG_ERROR;
}
context_->xml_path.set(pkgmgr_->GetXMLPath());
context_->pkgid.set(context_->xml_path.get().stem().string());
context_->unpacked_dir_path.set(pkgmgr_->GetDirectoryPath());
context_->pkg_path.set(pkgmgr_->GetDirectoryPath());
context_->privilege_level.set(common_installer::PrivilegeLevel::PUBLIC);
- context_->pkg_type.set("rpm"); //temporary fix as rpm
+ context_->pkg_type.set("rpm"); // temporary fix as rpm
break;
default:
// TODO(p.sikorski): should return unsupported, and display error
LOG(ERROR) <<
"Only installation, update and uninstallation is now supported";
- return Status::ERROR;
+ return Status::CONFIG_ERROR;
break;
}
context_->root_application_path.get() / "recovery"));
if (!recovery_file) {
LOG(ERROR) << "Failed to create recovery file";
- return Status::ERROR;
+ return Status::CONFIG_ERROR;
}
recovery_file->set_type(pkgmgr_->GetRequestType());
if (!recovery_file->WriteAndCommitFileContent()) {
LOG(ERROR) << "Failed to write recovery file";
- return Status::ERROR;
+ return Status::CONFIG_ERROR;
}
context_->recovery_info.set(RecoveryInfo(std::move(recovery_file)));
}
Step::Status StepConfigure::precheck() {
if (getuid() == 0) {
LOG(ERROR) << "App-installer should not run with superuser!";
- return Status::ERROR;
+ return Status::OPERATION_NOT_ALLOWED;
}
return Status::OK;
}
if (!context_->manifest_data.get()) {
LOG(ERROR) << "manifest_data attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "pkgid attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::PACKAGE_NOT_FOUND;
}
// TODO(p.sikorski) asserts?
if (error) {
LOG(ERROR) << "Cannot create directory: "
<< install_path.parent_path().string();
- return Step::Status::ERROR;
+ return Step::Status::APP_DIR_ERROR;
}
if (!MoveDir(context_->unpacked_dir_path.get(), install_path)) {
LOG(ERROR) << "Cannot move widget directory to install path, from "
<< context_->unpacked_dir_path.get() << " to " << install_path;
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
LOG(INFO) << "Successfully move: " << context_->unpacked_dir_path.get()
<< " to: " << install_path << " directory";
Step::Status StepCopyBackup::precheck() {
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "pkgid attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::PACKAGE_NOT_FOUND;
}
if (context_->root_application_path.get().empty()) {
LOG(ERROR) << "root_application_path attribute is empty";
Step::Status StepCopyBackup::process() {
if (!Backup())
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
if (!NewContent())
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
return Status::OK;
}
Step::Status StepCopyBackup::clean() {
if (!CleanBackupDirectory()) {
LOG(DEBUG) << "Cannot remove backup directory";
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
LOG(DEBUG) << "Applications files backup directory removed";
if (bf::exists(backup_path_)) {
if (!RollbackApplicationDirectory()) {
LOG(ERROR) << "Failed to revert package directory";
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
LOG(DEBUG) << "Application files reverted from backup";
}
bs::error_code error_code;
if (!bf::exists(backup_path_, error_code)) {
LOG(DEBUG) << "Cannot restore storage directories from: " << backup_path_;
- return Status::ERROR;
+ return Status::INVALID_VALUE;
}
return Status::OK;
context_->pkg_path.get(),
kDataLocation)) {
LOG(ERROR) << "Failed to restore private directory for widget in update";
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
if (!MoveAppStorage(backup_path_,
context_->pkg_path.get(),
kSharedLocation)) {
LOG(ERROR) << "Failed to restore shared directory for widget in update";
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
if (!CacheDir())
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
return Status::OK;
}
backup_path_,
kDataLocation)) {
LOG(ERROR) << "Failed to restore private directory for package in update";
- ret = Status::ERROR;
+ ret = Status::APP_DIR_ERROR;
}
if (!MoveAppStorage(context_->pkg_path.get(),
backup_path_,
kSharedLocation)) {
LOG(ERROR) << "Failed to restore shared directory for package in update";
- ret = Status::ERROR;
+ ret = Status::APP_DIR_ERROR;
}
return ret;
if (context_->is_tep_move.get()) {
if (!MoveFile(context_->tep_path.get(), tep_path)) {
LOG(ERROR) << "Cannnot move TEP file into install path";
- return Step::Status::ERROR;
+ return Step::Status::APP_DIR_ERROR;
}
} else {
if (!CopyFile(context_->tep_path.get(), tep_path)) {
LOG(ERROR) << "Cannot copy TEP file [" << context_->tep_path.get() <<
"] into install path [" << tep_path << "]";
- return Step::Status::ERROR;
+ return Step::Status::APP_DIR_ERROR;
}
}
context_->tep_path.set(tep_path);
bf::create_directories(icons_directory, error);
if (error) {
LOG(ERROR) << "Cannot create directory of application icons";
- return Status::ERROR;
+ return Status::ICON_ERROR;
}
}
bf::copy_file(source, destination, error);
if (error) {
LOG(ERROR) << "Cannot create package icon: " << destination;
- return Status::ERROR;
+ return Status::ICON_ERROR;
}
icons_.push_back(destination);
}
common_installer::Step::Status StepCreateStorageDirectories::process() {
if (!ShareDir())
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
if (!PrivateDir())
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
if (!CacheDir())
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
return Status::OK;
}
Step::Status StepDeltaPatch::precheck() {
if (context_->unpacked_dir_path.get().empty()) {
LOG(ERROR) << "Unpacked dir is not set";
- return Status::ERROR;
+ return Status::INVALID_VALUE;
}
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "Package id is not set";
- return Status::ERROR;
+ return Status::PACKAGE_NOT_FOUND;
}
return Status::OK;
}
bf::path delta_file = context_->unpacked_dir_path.get() / kDeltaFile;
if (!bf::exists(delta_file)) {
LOG(ERROR) << "Delta file doesn't exist in package.";
- return Status::ERROR;
+ return Status::DELTA_ERROR;
}
delta::DeltaParser parser;
if (!parser.ParseManifest(delta_file)) {
LOG(ERROR) << parser.GetErrorMessage();
- return Status::ERROR;
+ return Status::DELTA_ERROR;
}
std::shared_ptr<const delta::DeltaInfo> delta_info =
std::static_pointer_cast<const delta::DeltaInfo>(
parser.GetManifestData(delta::kDeltaInfoKey));
if (!delta_info) {
LOG(ERROR) << "Failed to parse delta information";
- return Status::ERROR;
+ return Status::DELTA_ERROR;
}
// additional validation
if (!ValidateDeltaInfo(*delta_info)) {
LOG(ERROR) << "Delta info is malformed";
- return Status::ERROR;
+ return Status::DELTA_ERROR;
}
// create old content directory and patch directory
patch_dir_ += ".patch";
if (!MoveDir(context_->unpacked_dir_path.get(), patch_dir_)) {
LOG(ERROR) << "Failed to move content to patch directory";
- return Status::ERROR;
+ return Status::DELTA_ERROR;
}
if (!CopyDir(context_->root_application_path.get() / context_->pkgid.get()
/ delta_root_, context_->unpacked_dir_path.get())) {
LOG(ERROR) << "Failed to copy package files";
- return Status::ERROR;
+ return Status::DELTA_ERROR;
}
// if there is no root set, that means we need to handle files added by
// apply changes mentioned in delta
if (!ApplyPatch(*delta_info, context_->unpacked_dir_path.get(), patch_dir_))
- return Status::ERROR;
+ return Status::DELTA_ERROR;
bs::error_code error;
bf::remove_all(patch_dir_, error);
if (!bf::exists(context_->xml_path.get())) {
LOG(ERROR) << "Missing old platform manifest file";
- return Status::ERROR;
+ return Status::MANIFEST_NOT_FOUND;
}
xmlInitParser();
if (!mfx) {
LOG(ERROR) << "Failed to parse old tizen manifest xml "
<< context_->xml_path.get();
- return Step::Status::ERROR;
+ return Step::Status::MANIFEST_ERROR;
}
context_->old_manifest_data.set(mfx);
RecoveryFile::OpenRecoveryFileForPath(context_->file_path.get());
if (!recovery_file) {
LOG(ERROR) << "Failed to open recovery file";
- return Status::ERROR;
+ return Status::RECOVERY_ERROR;
}
context_->unpacked_dir_path.set(recovery_file->unpacked_dir());
context_->pkgid.set(recovery_file->pkgid());
if (!mfx) {
LOG(ERROR) << "Failed to parse tizen manifest xml "
<< context_->xml_path.get();
- return Step::Status::ERROR;
+ return Step::Status::PARSE_ERROR;
}
context_->manifest_data.set(mfx);
Step::Status StepPrivilegeCompatibility::precheck() {
if (!context_->manifest_data.get()) {
LOG(ERROR) << "Manifest data is not set";
- return Status::ERROR;
+ return Status::MANIFEST_NOT_FOUND;
}
return Status::OK;
}
}
if (!ret) {
LOG(ERROR) << "Error during adding default privileges for certificates.";
- return Status::ERROR;
+ return Status::PRIVILEGE_ERROR;
}
return TranslatePrivilegesForCompatibility(context_->manifest_data.get()) ?
- Status::OK : Status::ERROR;
+ Status::OK : Status::PRIVILEGE_ERROR;
}
} // namespace security
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Unsuccessful app registration";
- return Status::ERROR;
+ return Status::RECOVERY_ERROR;
}
return Status::OK;
}
bf::remove_all(context_->pkg_path.get(), error);
if (error) {
LOG(ERROR) << "Cannot restore widget files to its correct location";
- return Status::ERROR;
+ return Status::RECOVERY_ERROR;
}
}
(void) MoveDir(backup_path, context_->pkg_path.get());
bf::remove(pair.first, error);
if (error) {
LOG(ERROR) << "Cannot move icon to restore its correct location";
- return Status::ERROR;
+ return Status::RECOVERY_ERROR;
}
}
(void) MoveFile(pair.second, pair.first);
bf::remove(context_->xml_path.get(), error);
if (error) {
LOG(ERROR) << "Cannot move manifest file to restore its location";
- return Status::ERROR;
+ return Status::RECOVERY_ERROR;
}
}
(void) MoveFile(context_->backup_xml_path.get(), context_->xml_path.get());
#include "common/step/step_recover_security.h"
#include <boost/filesystem.hpp>
+#include <string>
#include "common/security_registration.h"
Step::Status StepRecoverSecurity::RecoveryNew() {
if (!Check())
return Status::OK;
- UnregisterSecurityContextForManifest(
+ std::string error_message;
+ if (!UnregisterSecurityContextForManifest(
context_->pkgid.get(), context_->uid.get(),
- context_->manifest_data.get());
+ context_->manifest_data.get(), &error_message)) {
+ LOG(ERROR) << "Unsuccessful install";
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(Status::RECOVERY_ERROR, error_message);
+ }
+ return Status::RECOVERY_ERROR;
+ }
return Status::OK;
}
Step::Status StepRecoverSecurity::RecoveryUpdate() {
if (!Check()) {
LOG(ERROR) << "Invalid parameters";
- return Status::ERROR;
+ return Status::INVALID_VALUE;
}
+ std::string error_message;
if (!RegisterSecurityContextForManifest(
context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
- context_->manifest_data.get())) {
+ context_->manifest_data.get(), &error_message)) {
LOG(ERROR) << "Unsuccessful update";
- return Status::ERROR;
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(Status::RECOVERY_ERROR, error_message);
+ }
+ return Status::RECOVERY_ERROR;
}
return Status::OK;
}
return RecoveryUpdate();
default:
LOG(ERROR) << "Recovery is not supported for given type of installation";
- return Status::ERROR;
+ return Status::RECOVERY_ERROR;
}
}
Step::Status StepRegisterApplication::precheck() {
if (context_->xml_path.get().empty()) {
LOG(ERROR) << "xml_path attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
if (!boost::filesystem::exists(context_->xml_path.get())) {
LOG(ERROR) << "xml_path ("
<< context_->xml_path.get()
<< ") path does not exist";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
// TODO(p.sikorski) check context_->uid.get()
context_->request_mode.get(),
context_->tep_path.get())) {
LOG(ERROR) << "Failed to register the app";
- return Step::Status::ERROR;
+ return Step::Status::REGISTER_ERROR;
}
LOG(INFO) << "Successfully registered the app";
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Application couldn't be unregistered";
- return Status::ERROR;
+ return Status::REGISTER_ERROR;
}
LOG(INFO) << "Successfuly clean database";
#include "common/step/step_register_security.h"
#include <boost/filesystem.hpp>
+#include <string>
#include "common/security_registration.h"
}
Step::Status StepRegisterSecurity::process() {
+ std::string error_message;
if (!RegisterSecurityContextForManifest(
context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
- context_->manifest_data.get())) {
- return Status::ERROR;
+ context_->manifest_data.get(), &error_message)) {
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(Status::SECURITY_ERROR, error_message);
+ }
+ return Status::SECURITY_ERROR;
}
LOG(DEBUG) << "Security context installed";
return Status::OK;
Step::Status StepRemoveFiles::precheck() {
if (!context_->manifest_data.get()) {
LOG(ERROR) << "manifest_data attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
// Even though, the below checks can fail, StepRemoveFiles should still try
bf::path backup_path = GetBackupPathForPackagePath(context_->pkg_path.get());
if (!MoveDir(context_->pkg_path.get(), backup_path)) {
LOG(ERROR) << "Cannot remove widget files from its location";
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
LOG(DEBUG) << "Removed directory: " << context_->pkg_path.get();
return Status::OK;
LOG(DEBUG) << "Restoring directory: " << context_->pkg_path.get();
if (!MoveDir(backup_path, context_->pkg_path.get())) {
LOG(ERROR) << "Cannot restore widget files";
- return Status::ERROR;
+ return Status::APP_DIR_ERROR;
}
}
Step::Status StepRemoveIcons::precheck() {
if (!context_->manifest_data.get()) {
LOG(ERROR) << "manifest_data attribute is empty";
- return Status::ERROR;
+ return Status::MANIFEST_NOT_FOUND;
}
return Status::OK;
bf::path backup_icon_file = GetBackupPathForIconFile(app_icon);
if (!MoveFile(app_icon, backup_icon_file)) {
LOG(ERROR) << "Failed to create backup for icon: " << app_icon;
- return Status::ERROR;
+ return Status::ICON_ERROR;
}
backups_.emplace_back(backup_icon_file, app_icon);
}
if (!MoveFile(pair.first, pair.second)) {
LOG(ERROR) << "Failed to restore: " << pair.second;
// We need to try to restore all icons anyway...
- ret = Status::ERROR;
+ ret = Status::ICON_ERROR;
}
}
}
#include "common/step/step_revoke_security.h"
#include <boost/filesystem.hpp>
+#include <string>
#include "common/security_registration.h"
Step::Status StepRevokeSecurity::precheck() {
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "pkgid attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::PACKAGE_NOT_FOUND;
}
if (!context_->manifest_data.get()) {
LOG(ERROR) << "manifest_data attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
return Step::Status::OK;
}
Step::Status StepRevokeSecurity::clean() {
+ std::string error_message;
if (!UnregisterSecurityContextForManifest(
context_->pkgid.get(), context_->uid.get(),
- context_->manifest_data.get())) {
+ context_->manifest_data.get(), &error_message)) {
LOG(ERROR) << "Failure on unregistering security context for app "
<< context_->pkgid.get();
- return Status::ERROR;
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(Status::SECURITY_ERROR, error_message);
+ }
+ return Status::SECURITY_ERROR;
}
LOG(DEBUG) << "Security context uninstalled";
return Status::OK;
#include "common/step/step_rollback_deinstallation_security.h"
#include <boost/filesystem.hpp>
+#include <string>
#include "common/security_registration.h"
Step::Status StepRollbackDeinstallationSecurity::precheck() {
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "pkgid attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::PACKAGE_NOT_FOUND;
}
if (!context_->manifest_data.get()) {
LOG(ERROR) << "manifest_data attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
return Step::Status::OK;
}
Step::Status StepRollbackDeinstallationSecurity::undo() {
+ std::string error_message;
if (!RegisterSecurityContextForManifest(
context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
- context_->manifest_data.get())) {
+ context_->manifest_data.get(), &error_message)) {
LOG(ERROR) << "Failure on re-installing security context for app "
<< context_->pkgid.get();
- return Status::ERROR;
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ }
+ return Status::SECURITY_ERROR;
}
LOG(DEBUG) << "Security context installed";
return Status::OK;
#include "common/step/step_rollback_installation_security.h"
#include <boost/filesystem.hpp>
+#include <string>
#include "common/security_registration.h"
Step::Status StepRollbackInstallationSecurity::precheck() {
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "pkgid attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::PACKAGE_NOT_FOUND;
}
if (!context_->manifest_data.get()) {
LOG(ERROR) << "manifest_data attribute is empty";
- return Step::Status::INVALID_VALUE;
+ return Step::Status::MANIFEST_NOT_FOUND;
}
return Step::Status::OK;
}
Step::Status StepRollbackInstallationSecurity::undo() {
+ std::string error_message;
if (!UnregisterSecurityContextForManifest(
context_->pkgid.get(), context_->uid.get(),
- context_->manifest_data.get())) {
- return Status::ERROR;
+ context_->manifest_data.get(), &error_message)) {
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ }
+ return Status::SECURITY_ERROR;
}
LOG(DEBUG) << "Security context uninstalled";
return Status::OK;
Step::Status StepUnregisterApplication::precheck() {
if (context_->pkgid.get().empty()) {
LOG(ERROR) << "pkgid attribute is empty";
- return Status::INVALID_VALUE;
+ return Status::PACKAGE_NOT_FOUND;
}
if (context_->xml_path.get().empty()) {
LOG(ERROR) << "xml_path attribute is empty";
- return Status::INVALID_VALUE;
+ return Status::MANIFEST_NOT_FOUND;
}
if (!boost::filesystem::exists(context_->xml_path.get())) {
LOG(ERROR) << "xml_path ("
<< context_->xml_path.get()
<< ") path does not exist";
- return Status::INVALID_VALUE;
+ return Status::MANIFEST_NOT_FOUND;
}
if (context_->backup_xml_path.get().empty()) {
// Prepare certificate info for rollback operations
if (!BackupCertInfo()) {
LOG(ERROR) << "Failed to backup cert info";
- return Status::ERROR;
+ return Status::CERT_ERROR;
}
if (!UnregisterAppInPkgmgr(context_->manifest_data.get(),
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Failed to unregister package into database";
- return Status::ERROR;
+ return Status::REGISTER_ERROR;
}
// remove manifest file
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Failed to restore the app registration in pkgmgr";
- return Step::Status::ERROR;
+ return Step::Status::REGISTER_ERROR;
}
LOG(INFO) << "Successfully restored the app registration in pkgmgr";
if (!CreateDir(tmp_dir)) {
LOG(ERROR) << "Failed to create temp directory: " << tmp_dir;
- return Step::Status::ERROR;
+ return Step::Status::APP_DIR_ERROR;
}
int64_t required_size =
<< context_->file_path.get();
bs::error_code error;
bf::remove_all(tmp_dir, error);
- return Step::Status::ERROR;
+ return Step::Status::APP_DIR_ERROR;
}
LOG(DEBUG) << "Required size for application: " << required_size << "B";
LOG(ERROR) << "Failed to process unpack step";
bs::error_code error;
bf::remove_all(tmp_dir, error);
- return Step::Status::ERROR;
+ return Step::Status::UNZIP_ERROR;
}
context_->unpacked_dir_path.set(tmp_dir);
Step::Status StepUpdateApplication::precheck() {
if (context_->xml_path.get().empty()) {
LOG(ERROR) << "Xml path is empty";
- return Status::ERROR;
+ return Status::MANIFEST_NOT_FOUND;
}
return Status::OK;
}
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Cannot upgrade manifest for application";
- return Status::ERROR;
+ return Status::REGISTER_ERROR;
}
LOG(INFO) << "Successfully install the application";
} catch (const ValidationCore::Certificate::Exception::Base &e) {
LOG(ERROR) << "Exception in cert-svc-vcore Certificate "
<< "Dump : " << e.DumpToString();
- return Status::ERROR;
+ return Status::CERT_ERROR;
}
}
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Cannot revert manifest for application";
- return Status::ERROR;
+ return Status::REGISTER_ERROR;
}
LOG(INFO) << "Database reverted successfully";
return Status::OK;
#include "common/step/step_update_security.h"
+#include <string>
+
#include "common/security_registration.h"
namespace common_installer {
namespace security {
Step::Status StepUpdateSecurity::process() {
+ std::string error_message;
if (!RegisterSecurityContextForManifest(
context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
- context_->manifest_data.get())) {
- return Status::ERROR;
+ context_->manifest_data.get(), &error_message)) {
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ on_error(Status::SECURITY_ERROR, error_message);
+ }
+ return Status::SECURITY_ERROR;
}
LOG(DEBUG) << "Security context updated";
return Status::OK;
}
Step::Status StepUpdateSecurity::undo() {
+ std::string error_message;
if (!RegisterSecurityContextForManifest(
context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
- context_->old_manifest_data.get())) {
- return Status::ERROR;
+ context_->old_manifest_data.get(), &error_message)) {
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ }
+ return Status::SECURITY_ERROR;
}
LOG(DEBUG) << "Security context reverted";
return Status::OK;
context_->uid.get(),
context_->request_mode.get())) {
LOG(ERROR) << "Cannot update tep info for application";
- return Status::ERROR;
+ return Status::REGISTER_ERROR;
}
LOG(INFO) << "Successfully update the tep info for application";
LOG(ERROR) << "Failed to get application ids for package id";
return false;
}
+ std::string error_message;
for (const auto& appid : appids) {
if (!common_installer::RegisterSecurityContext(appid, pkgid, base_dir,
- uid, privileges)) {
+ uid, privileges, &error_message)) {
+ LOG(ERROR) << "Failed to register security context";
+ if (!error_message.empty()) {
+ LOG(ERROR) << "error_message: " << error_message;
+ }
return false;
}
}