Name: app-installers
Summary: Application installers
-Version: 1.11
+Version: 1.12
Release: 1
Group: Application Framework/Package Management
License: Apache-2.0
move_type_ = APP2EXT_MOVE_TO_PHONE;
}
+ExternalStorage::ExternalStorage(RequestType type,
+ const std::string& pkgid, uid_t uid)
+ : type_(type),
+ pkgid_(pkgid),
+ uid_(uid),
+ handle_(nullptr) {
+}
+
ExternalStorage::~ExternalStorage() {
if (handle_)
app2ext_deinit(handle_);
static_cast<app2ext_move_type_t>(move_type_),
uid_);
break;
+ case RequestType::MigrateExtImg:
+ ret = handle_->interface.client_usr_post_migrate_legacy(pkgid_.c_str(),
+ uid_);
+ break;
default:
assert(false && "Not supported installation mode");
}
case RequestType::Uninstall:
ret = handle_->interface.client_usr_pre_uninstall(pkgid_.c_str(), uid_);
break;
+ case RequestType::MigrateExtImg:
+ ret = handle_->interface.client_usr_pre_migrate_legacy(pkgid_.c_str(),
+ uid_);
+ break;
case RequestType::Reinstall:
case RequestType::Recovery:
case RequestType::ManifestDirectInstall:
return external_storage;
}
+std::unique_ptr<ExternalStorage> ExternalStorage::MigrateExternalStorage(
+ RequestType type, const std::string& pkgid, uid_t uid) {
+ std::unique_ptr<ExternalStorage> external_storage(
+ new ExternalStorage(type, pkgid, uid));
+ bf::path empty_path("");
+ if (!external_storage->Initialize(empty_path)) {
+ LOG(WARNING) << "Cannot initialize external storage for request";
+ return nullptr;
+ }
+ return external_storage;
+}
+
} // namespace common_installer
const std::string& pkgid, const std::string& package_type,
const boost::filesystem::path& space_requirement, uid_t uid);
+ static std::unique_ptr<ExternalStorage> MigrateExternalStorage(
+ RequestType type, const std::string& pkgid, uid_t uid);
+
ExternalStorage(RequestType type, const std::string& pkgid,
const std::string& package_type,
const boost::filesystem::path& application_root, uid_t uid);
const std::string& package_type,
const boost::filesystem::path& application_root, uid_t uid,
bool is_external_move);
+ ExternalStorage(RequestType type, const std::string& pkgid, uid_t uid);
~ExternalStorage();
bool Commit();
return RequestType::DisablePkg;
case PKGMGR_REQ_ENABLE_PKG:
return RequestType::EnablePkg;
+ case PKGMGR_REQ_MIGRATE_EXTIMG:
+ return RequestType::MigrateExtImg;
default:
return RequestType::Unknown;
}
{ci::RequestType::ManifestPartialUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::DisablePkg, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
{ci::RequestType::EnablePkg, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
+ {ci::RequestType::MigrateExtImg, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::Unknown, PKGMGR_INSTALLER_UNKNOWN_EVENT_STR}
};
ReadonlyUpdateInstall,
ReadonlyUpdateUninstall,
DisablePkg,
- EnablePkg
+ EnablePkg,
+ MigrateExtImg
};
/** Request mode (USER vs GLOBAL) */
{".mmc", SECURITY_MANAGER_PATH_RO}
};
+const std::vector<std::pair<const char*,
+ app_install_path_type>> kSecurityPoliciesExternalOnly = {
+ {"bin", SECURITY_MANAGER_PATH_RO},
+ {"lib", SECURITY_MANAGER_PATH_RO},
+ {"res", SECURITY_MANAGER_PATH_RO},
+ {".mmc", SECURITY_MANAGER_PATH_RO}
+};
+
const std::vector<std::pair<const char*, app_install_type>> kPathPolicies = {
{tzplatform_getenv(TZ_SYS_HOME), SM_APP_INSTALL_LOCAL},
{tzplatform_getenv(TZ_SYS_RW_APP), SM_APP_INSTALL_GLOBAL},
return true;
}
-bool PreparePathRequest(const std::string& pkg_id,
- const boost::filesystem::path& path, uid_t uid, path_req* req,
- bool is_readonly_pkg, std::string* error_message) {
+bool PreparePathRequest(path_req* req, const std::string& pkg_id,
+ const std::string& pkg_type, const boost::filesystem::path& path,
+ uid_t uid, bool is_readonly_pkg, bool is_extonly,
+ std::string* error_message) {
if (pkg_id.empty() || path.empty()) {
LOG(ERROR) << "Pkgid or path is empty. Both values must be set";
return false;
return false;
}
- for (auto& policy : kSecurityPolicies) {
+ std::vector<std::pair<const char*, app_install_path_type>> policies;
+ if (is_extonly)
+ policies = kSecurityPoliciesExternalOnly;
+ else
+ policies = kSecurityPolicies;
+ for (auto& policy : policies) {
bf::path subpath = path / policy.first;
- if (bf::exists(subpath)) {
+ if (is_extonly) {
+ // Now, this is for legacy migraton.
+ // do not try to access any file before changing label,
+ // this wil cause a exception from smack denial.
+ std::string subdir(policy.first);
+ if (pkg_type == "wgt" && (subdir == "bin" || subdir == "lib"))
+ continue;
+ } else {
+ if (!bf::exists(subpath))
+ continue;
if (bf::is_symlink(symlink_status(subpath))) {
LOG(DEBUG) << "Path " << subpath << " is a symlink."
<< "Path will not be registered";
continue;
}
- error = security_manager_path_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;
- }
+ }
+ error = security_manager_path_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 RegisterSecurityContextForPath(const std::string &pkg_id,
- const boost::filesystem::path& path, uid_t uid,
- bool is_readonly_pkg, std::string* error_message) {
+ const boost::filesystem::path& path, uid_t uid, bool is_readonly_pkg,
+ std::string* error_message) {
path_req* req;
int error = security_manager_path_req_new(&req);
if (error != SECURITY_MANAGER_SUCCESS) {
return false;
}
- if (!PreparePathRequest(pkg_id, path, uid, req, is_readonly_pkg,
+ if (!PreparePathRequest(req, pkg_id, {}, path, uid, is_readonly_pkg, false,
error_message)) {
- LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
+ LOG(ERROR) << "Failed while preparing security_manager_path_req";
+ security_manager_path_req_free(req);
+ return false;
+ }
+
+ error = security_manager_paths_register(req);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ LOG(ERROR) << "Failed while calling security_manager_paths_register 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_path_req_free(req);
+ return false;
+ }
+
+ security_manager_path_req_free(req);
+
+ return true;
+}
+
+bool RegisterSecurityContextForPathExternalOnly(const std::string &pkg_id,
+ const std::string &pkg_type, const boost::filesystem::path& path,
+ uid_t uid, std::string* error_message) {
+ path_req* req;
+ int error = security_manager_path_req_new(&req);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ LOG(ERROR)
+ << "Failed while calling security_manager_path_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 (!PreparePathRequest(req, pkg_id, pkg_type, path, uid, false, true,
+ error_message)) {
+ LOG(ERROR) << "Failed while preparing security_manager_path_req";
security_manager_path_req_free(req);
return false;
}
const boost::filesystem::path& path, uid_t uid,
bool is_readonly_pkg, std::string* error_message);
+/**
+ * Adapter interface for external Security module.
+ *
+ * Adapter interface for external Security module used for registering
+ * package external paths to security context
+ *
+ * \param pkg_id pkgid of given package
+ * \param pkg_type pkg type of given package
+ * \param path path for registering
+ * \param uid uid
+ * \param error_message extra/detailed error message
+ *
+ * \return true if success
+ */
+bool RegisterSecurityContextForPathExternalOnly(const std::string &pkg_id,
+ const std::string &pkg_type, const boost::filesystem::path& path,
+ uid_t uid, std::string* error_message);
+
} // namespace common_installer
#endif // COMMON_SECURITY_REGISTRATION_H_
case RequestType::EnablePkg:
context_->pkgid.set(pkgmgr_->GetRequestInfo());
break;
+ case RequestType::MigrateExtImg: {
+ context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ bf::path package_directory =
+ context_->root_application_path.get() / context_->pkgid.get();
+ context_->pkg_path.set(package_directory);
+ break;
+ }
default:
LOG(ERROR) <<
"Only installation, update and uninstallation is now supported";
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_migrate_legacy_external_image.h"
+
+#include <boost/filesystem.hpp>
+#include <app2ext_interface.h>
+#include <tzplatform_config.h>
+
+#include <string>
+
+#include "common/security_registration.h"
+#include "common/pkgmgr_query.h"
+
+namespace bf = boost::filesystem;
+
+namespace {
+
+const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+const char kInstalledExternally[] = "installed_external";
+
+} // namespace
+
+namespace common_installer {
+namespace security {
+
+Step::Status StepMigrateLegacyExtImage::precheck() {
+ // Policy : migration target user is 'default' user.
+ uid_t uid = context_->uid.get();
+ if (uid != kDefaultUserUid && uid != kGlobalUserUid) {
+ LOG(ERROR) << "current target uid (" << uid <<") is not allowed";
+ return Step::Status::INVALID_VALUE;
+ }
+
+ if (context_->pkg_path.get().empty()) {
+ LOG(ERROR) << "pkg_path attribute is empty";
+ return Step::Status::INVALID_VALUE;
+ }
+ if (!boost::filesystem::exists(context_->pkg_path.get())) {
+ LOG(ERROR) << "pkg_path ("
+ << context_->pkg_path.get()
+ << ") path does not exist";
+ return Step::Status::INVALID_VALUE;
+ }
+
+ if (context_->pkgid.get().empty()) {
+ LOG(ERROR) << "pkgid attribute is empty";
+ return Step::Status::INVALID_VALUE;
+ }
+
+ return Status::OK;
+}
+
+Step::Status StepMigrateLegacyExtImage::process() {
+ std::string pkgid = context_->pkgid.get();
+ uid_t uid = context_->uid.get();
+ if (QueryIsGlobalPackage(pkgid, uid))
+ context_->uid.set(kGlobalUserUid);
+
+ std::string storage_str = QueryStorageForPkgId(context_->pkgid.get(),
+ context_->uid.get());
+ if (strcmp(storage_str.c_str(), kInstalledExternally)) {
+ LOG(ERROR) << "Pkg not installed at external storage";
+ return Step::Status::ERROR;
+ }
+
+ context_->external_storage =
+ ExternalStorage::MigrateExternalStorage(context_->request_type.get(),
+ context_->pkgid.get(),
+ context_->uid.get());
+ if (!context_->external_storage) {
+ LOG(ERROR) << "Can not initialize external storage";
+ return Step::Status::ERROR;
+ }
+
+ std::string error_message;
+ if (!RegisterSecurityContextForPathExternalOnly(pkgid,
+ context_->pkg_type.get(), context_->pkg_path.get(),
+ uid, &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 StepMigrateLegacyExtImage::undo() {
+ if (context_->external_storage)
+ context_->external_storage->Abort();
+ return Status::OK;
+}
+
+Step::Status StepMigrateLegacyExtImage::clean() {
+ if (context_->external_storage)
+ context_->external_storage->Commit();
+ return Status::OK;
+}
+
+} // namespace security
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_MIGRATE_LEGACY_EXTERNAL_IMAGE_H_
+#define COMMON_STEP_FILESYSTEM_STEP_MIGRATE_LEGACY_EXTERNAL_IMAGE_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace security {
+
+class StepMigrateLegacyExtImage : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status undo() override;
+ Status clean() override;
+ Status precheck() override;
+
+ STEP_NAME(MigrateLegacyExtImage)
+};
+
+} // namespace security
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_MIGRATE_LEGACY_EXTERNAL_IMAGE_H_