#include "common/security_registration.h"
-#include <boost/filesystem/operations.hpp>
-#include <boost/format.hpp>
-
#include <unistd.h>
#include <sys/types.h>
#include <manifest_parser/utils/logging.h>
#include <utility>
#include <vector>
#include <algorithm>
+#include <functional>
-#include "common/pkgmgr_query.h"
+#include "common/utils/pkgmgr_query.h"
#include "common/privileges.h"
#include "common/utils/file_util.h"
#include "common/utils/glist_range.h"
-namespace bf = boost::filesystem;
+namespace fs = std::filesystem;
namespace ci = common_installer;
namespace {
+using AppDefinedPrivInfo = std::vector<std::pair<std::string, std::string>>;
+
const std::vector<std::pair<const char*,
app_install_path_type>> kSecurityPolicies = {
- {"/", SECURITY_MANAGER_PATH_PUBLIC_RO},
+ {".", SECURITY_MANAGER_PATH_PUBLIC_RO},
{"bin", SECURITY_MANAGER_PATH_RO},
{"data", SECURITY_MANAGER_PATH_RW},
{"cache", SECURITY_MANAGER_PATH_RW},
{"lib", SECURITY_MANAGER_PATH_RO},
{"res", SECURITY_MANAGER_PATH_RO},
+ {"res/global", SECURITY_MANAGER_PATH_PUBLIC_RO},
+ {"res/allowed", SECURITY_MANAGER_PATH_PUBLIC_RO},
{"shared", SECURITY_MANAGER_PATH_PUBLIC_RO},
{"shared/data", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
{"shared/cache", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
};
const std::vector<std::pair<const char*,
- app_install_path_type>> kSecurityRWOnlyPolicies = {
- {"data", SECURITY_MANAGER_PATH_RW},
- {"cache", SECURITY_MANAGER_PATH_RW},
- {"shared", SECURITY_MANAGER_PATH_PUBLIC_RO},
- {"shared/data", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
- {"shared/cache", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
- {"shared/trusted", SECURITY_MANAGER_PATH_TRUSTED_RW}
+ 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},
{tzplatform_getenv(TZ_SYS_RO_APP), SM_APP_INSTALL_PRELOADED},
- {tzplatform_mkpath(TZ_SYS_RO_ETC, "skel"), SM_APP_INSTALL_PRELOADED},
+ {tzplatform_mkpath(TZ_SYS_ETC, "skel"), SM_APP_INSTALL_PRELOADED},
};
-bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
- const std::string& author_id, const std::string& api_version,
- const boost::filesystem::path& path,
- uid_t uid, const std::vector<std::string>& privileges,
- app_inst_req* req, bool cross_app_rules, 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;
- }
+void SetErrorMessage(std::string* error_message, int error) {
+ std::string errnum = std::to_string(error);
+ *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+ *error_message += ":<" + errnum + ">";
+}
- 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;
+class SecurityContextRequest {
+ public:
+ SecurityContextRequest(): req_(nullptr), app_idx_(0) {
+ 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 << ")";
+ SetErrorMessage(&error_message_, error);
+ req_ = NULL;
+ }
}
-
- 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;
+ ~SecurityContextRequest() {
+ if (IsValid())
+ security_manager_app_inst_req_free(req_);
}
-
- 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;
+ bool IsValid() const {
+ return req_ != NULL;
}
+ bool PrepareBasic(const std::string& pkg_id, uid_t uid,
+ const std::string& type) {
+ if (pkg_id.empty() || type.empty()) {
+ LOG(ERROR) << "Invalid parameter";
+ return false;
+ }
+ int error = security_manager_app_inst_req_set_pkg_id(req_, pkg_id.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ error = security_manager_app_inst_req_set_uid(req_, uid);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+
+ pkg_type pkgtype = SM_PKG_TYPE_NONE;
+ if (type == "tpk")
+ pkgtype = SM_PKG_TYPE_CORE;
+ else if (type == "wgt")
+ pkgtype = SM_PKG_TYPE_WRT;
- if (cross_app_rules) {
- error = security_manager_app_inst_req_set_hybrid(req);
+ error = security_manager_app_inst_req_set_pkg_type(req_, pkgtype);
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 + ">";
+ SetErrorMessage(&error_message_, error);
return false;
}
+ return true;
+ }
+
+ bool PrepareAdditional(const std::string& author_id,
+ const std::string& api_version,
+ const std::filesystem::path& path,
+ bool cross_app_rules) {
+ if (cross_app_rules) {
+ int error = security_manager_app_inst_req_set_hybrid(req_);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ if (!api_version.empty()) {
+ int error = security_manager_app_inst_req_set_target_version(req_,
+ api_version.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ if (!author_id.empty()) {
+ int error = security_manager_app_inst_req_set_author_id(req_,
+ author_id.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ if (!path.empty()) {
+ app_install_type type = SM_APP_INSTALL_NONE;
+ for (auto& policy : kPathPolicies) {
+ fs::path root = fs::path(policy.first);
+ if (ci::IsSubDir(path, root)) {
+ type = policy.second;
+ break;
+ }
+ }
+ if (type == SM_APP_INSTALL_NONE) {
+ LOG(ERROR) << "Unexpected path: " << path;
+ return false;
+ }
+
+ LOG(INFO) << "install_type(" << type << ")";
+ int error = security_manager_app_inst_req_set_install_type(req_, type);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ return true;
}
- if (!api_version.empty()) {
- error = security_manager_app_inst_req_set_target_version(req,
- api_version.c_str());
+ bool PreparePrivilegeLevel(ci::PrivilegeLevel priv_level) {
+ pkg_privilege_level level = (pkg_privilege_level)priv_level;
+ int error = security_manager_app_inst_req_set_pkg_privilege_level(
+ req_, level);
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 + ">";
+ SetErrorMessage(&error_message_, error);
return false;
}
+ return true;
}
- if (!author_id.empty()) {
- error = security_manager_app_inst_req_set_author_id(req, author_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 + ">";
+ bool PrepareAppWithPrivileges(const std::string& app_id,
+ const std::vector<std::string>& privileges,
+ const AppDefinedPrivInfo& appdef_privileges,
+ const AppDefinedPrivInfo& provides_appdef_privileges) {
+ if (!PrepareApp(app_id))
return false;
+ return PrepareAppPrivileges(privileges, appdef_privileges,
+ provides_appdef_privileges);
+ }
+
+ bool PrepareAppPrivileges(const std::vector<std::string>& privileges,
+ const AppDefinedPrivInfo& appdef_privileges,
+ const AppDefinedPrivInfo& provides_appdef_privileges) {
+ for (auto& priv : privileges) {
+ int error = security_manager_app_inst_req_add_privilege(req_,
+ priv.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ for (auto& priv : appdef_privileges) {
+ int error = security_manager_app_inst_req_add_client_privilege(
+ req_, priv.first.c_str(), priv.second.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ // only one app can provide appdefined privileges
+ if (app_idx_ > 1)
+ return true;
+ for (auto& priv : provides_appdef_privileges) {
+ auto privilege_type = !priv.second.empty() ?
+ SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED :
+ SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED;
+ int error = security_manager_app_inst_req_add_app_defined_privilege(req_,
+ priv.first.c_str(), privilege_type, priv.second.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
}
+ return true;
}
- if (!path.empty()) {
- app_install_type type = SM_APP_INSTALL_NONE;
- for (auto& policy : kPathPolicies) {
- bf::path root = bf::path(policy.first);
- if (ci::IsSubDir(path, root)) {
- type = policy.second;
- break;
+ bool PrepareApp(const std::string& app_id) {
+ if (app_id.empty()) {
+ LOG(ERROR) << "Appid is empty.";
+ return false;
+ }
+ // req_->apps.emplace_back();
+ if (app_idx_ > 0) {
+ int error = security_manager_app_inst_req_next(req_);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
}
}
- if (type == SM_APP_INSTALL_NONE) {
- LOG(ERROR) << "Unexpected path: " << path;
+ // req_->apps.back().id = ...
+ int error = security_manager_app_inst_req_set_app_id(req_, app_id.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
return false;
}
+ ++app_idx_;
+ return true;
+ }
- LOG(INFO) << "install_type(" << type << ")";
- error = security_manager_app_inst_req_set_install_type(req, type);
+ bool Install() {
+ int error = security_manager_app_update(req_);
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 + ">";
+ LOG(ERROR) << "Failed while calling security_manager_app_update failed "
+ << "(error code: " << error << ")";
+ SetErrorMessage(&error_message_, error);
return false;
}
+ return true;
}
- for (auto& priv : privileges) {
- security_manager_app_inst_req_add_privilege(req, priv.c_str());
+ bool Uninstall() {
+ int error = security_manager_app_uninstall(req_);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ LOG(ERROR) << "Failed while calling security_manager_app_uninstall "
+ << "failed (error code: " << error << ")";
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ return true;
}
- return true;
-}
-bool PreparePathRequest(const std::string& pkg_id,
- const boost::filesystem::path& path, uid_t uid, path_req* req,
- bool is_readonly_pkg, bool rwpath_only, std::string* error_message) {
- if (pkg_id.empty() || path.empty()) {
- LOG(ERROR) << "Pkgid or path is empty. Both values must be set";
- return false;
+ const std::string& ErrorMessage() const {
+ return error_message_;
}
- int error = security_manager_path_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;
- }
+ private:
+ app_inst_req* req_;
+ uint app_idx_;
+ std::string error_message_;
+};
- error = security_manager_path_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;
+class SecurityContextPathRequest {
+ public:
+ SecurityContextPathRequest() {
+ 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 << ")";
+ SetErrorMessage(&error_message_, error);
+ req_ = NULL;
+ }
}
- app_install_type type = SM_APP_INSTALL_NONE;
- for (auto& policy : kPathPolicies) {
- bf::path root = bf::path(policy.first);
- if (ci::IsSubDir(path, root)) {
- type = policy.second;
- break;
- }
+ ~SecurityContextPathRequest() {
+ if (IsValid())
+ security_manager_path_req_free(req_);
}
- if (type == SM_APP_INSTALL_NONE) {
- LOG(ERROR) << "Unexpected path: " << path;
- return false;
+
+ bool IsValid() {
+ return req_ != NULL;
}
- // When registering skel dir on global installation mode
- if (type == SM_APP_INSTALL_PRELOADED && !is_readonly_pkg)
- type = SM_APP_INSTALL_GLOBAL;
- error = security_manager_path_req_set_install_type(req, type);
- 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 Prepare(const std::string& pkg_id, uid_t uid) {
+ if (pkg_id.empty()) {
+ LOG(ERROR) << "Pkgid is empty. This value must be set";
+ return false;
+ }
+ int error = security_manager_path_req_set_pkg_id(req_, pkg_id.c_str());
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ error = security_manager_path_req_set_uid(req_, uid);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ return true;
}
- for (auto& policy : (rwpath_only? kSecurityRWOnlyPolicies :
- kSecurityPolicies)) {
- bf::path subpath = path / policy.first;
- if (bf::exists(subpath)) {
- if (bf::is_symlink(symlink_status(subpath))) {
- LOG(DEBUG) << "Path " << subpath << " is a symlink."
- << "Path will not be registered";
- continue;
+ bool PreparePath(const std::string& pkg_type,
+ const std::filesystem::path& path, bool is_readonly_pkg,
+ bool is_extonly) {
+ if (path.empty()) {
+ LOG(ERROR) << "Path is empty. This value must be set";
+ return false;
+ }
+ app_install_type type = SM_APP_INSTALL_NONE;
+ for (auto& policy : kPathPolicies) {
+ fs::path root = fs::path(policy.first);
+ if (ci::IsSubDir(path, root)) {
+ type = policy.second;
+ break;
+ }
+ }
+ if (type == SM_APP_INSTALL_NONE) {
+ LOG(ERROR) << "Unexpected path: " << path;
+ return false;
+ }
+ // When registering skel dir on global installation mode
+ if (type == SM_APP_INSTALL_PRELOADED && !is_readonly_pkg)
+ type = SM_APP_INSTALL_GLOBAL;
+
+ int error = security_manager_path_req_set_install_type(req_, type);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ std::vector<std::pair<const char*, app_install_path_type>> policies;
+ if (is_extonly)
+ policies = kSecurityPoliciesExternalOnly;
+ else
+ policies = kSecurityPolicies;
+ for (auto& policy : policies) {
+ fs::path subpath = path / policy.first;
+ 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 (!fs::exists(subpath))
+ continue;
+ if (fs::is_symlink(symlink_status(subpath)) &&
+ policy.second != SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO) {
+ LOG(DEBUG) << "Path " << subpath << " is a symlink."
+ << "Path will not be registered";
+ continue;
+ }
}
- error = security_manager_path_req_add_path(req, subpath.c_str(),
+ 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 + ">";
+ SetErrorMessage(&error_message_, error);
return false;
}
+
+ // this is for lib rpk installation. set public RO for contents only.
+ if (pkg_type == "rpk" && std::string(policy.first) == "lib") {
+ for (fs::directory_iterator iter(subpath);
+ iter != fs::directory_iterator(); ++iter) {
+ error = security_manager_path_req_add_path(req_,
+ iter->path().string().c_str(), SECURITY_MANAGER_PATH_PUBLIC_RO);
+ if (error!= SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ }
+ }
}
+ return true;
}
- return true;
-}
-
-} // namespace
-
-namespace common_installer {
-
-bool RegisterSecurityContext(const std::string& app_id,
- const std::string& pkg_id, const std::string& author_id,
- const std::string& api_version, const boost::filesystem::path& path,
- uid_t uid, const std::vector<std::string>& privileges,
- bool cross_app_rules, 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 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;
+ bool Register() {
+ int error = security_manager_paths_register(req_);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ LOG(ERROR) << "Failed while calling security_manager_paths_register "
+ << "failed (error code: " << error << ")";
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ return true;
}
- if (!PrepareRequest(app_id, pkg_id, author_id, api_version, path, uid,
- privileges, req, cross_app_rules, error_message)) {
- LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
- security_manager_app_inst_req_free(req);
- return false;
+ const std::string& ErrorMessage() const {
+ return error_message_;
}
- error = security_manager_app_install(req);
- 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;
- }
+ private:
+ path_req* req_;
+ std::string error_message_;
+};
- security_manager_app_inst_req_free(req);
- return true;
-}
+} // namespace
-bool UnregisterSecurityContext(const std::string& app_id,
- 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;
- }
+namespace common_installer {
- if (!PrepareRequest(app_id, pkg_id, std::string(), std::string(),
- bf::path(), uid, {}, req, false, error_message)) {
- LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
- security_manager_app_inst_req_free(req);
- return false;
- }
+void PrepareAppDefinedPrivilegeData(GList *privileges,
+ AppDefinedPrivInfo* tpk_priv_vec, AppDefinedPrivInfo* wgt_priv_vec) {
- error = security_manager_app_uninstall(req);
- 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;
+ for (auto& priv : GListRange<appdefined_privilege_x*>(privileges)) {
+ if (strcmp(priv->type, kWebPrivilegeType) == 0)
+ wgt_priv_vec->emplace_back(std::make_pair(priv->value, priv->license ?
+ priv->license : std::string()));
+ else
+ tpk_priv_vec->emplace_back(std::make_pair(priv->value, priv->license ?
+ priv->license : std::string()));
}
-
- security_manager_app_inst_req_free(req);
- return true;
}
-bool RegisterSecurityContextForManifest(
- const std::string& pkg_id, const boost::filesystem::path& path, uid_t uid,
- common_installer::CertificateInfo* cert_info, manifest_x* manifest,
- bool cross_app_rules, std::string* error_message) {
+bool RegisterSecurityContextForManifest(const ci::InstallerContext* context,
+ std::string* error_message) {
+ std::string pkg_id = context->pkgid.get();
+ std::string pkg_type = context->pkg_type.get();
+ fs::path path = context->GetPkgPath();
+ uid_t uid = context->uid.get();
+ const ci::CertificateInfo* cert_info = &(context->certificate_info.get());
+ manifest_x* manifest = context->manifest_data.get();
+ bool cross_app_rules = context->cross_app_rules.get();
+
// Although application framework hold list of privilege per package, there
// is situation where we need to filter privileges. This data model doesn't
// cover hybrid apps well where native privileges should be granted only to
else
tpk_priv_vec.emplace_back(priv->value);
}
+ AppDefinedPrivInfo tpk_appdef_vec, wgt_appdef_vec;
+ AppDefinedPrivInfo tpk_provides_appdef_vec, wgt_provides_appdef_vec;
+
+ PrepareAppDefinedPrivilegeData(manifest->appdefined_privileges,
+ &tpk_appdef_vec, &wgt_appdef_vec);
+ PrepareAppDefinedPrivilegeData(manifest->provides_appdefined_privileges,
+ &tpk_provides_appdef_vec, &wgt_provides_appdef_vec);
+
+ SecurityContextRequest req;
+ if (!req.IsValid()) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+ if (!req.PrepareBasic(pkg_id, uid, pkg_type)) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+ if (!req.PrepareAdditional(cert_info->author_id.get(), manifest->api_version,
+ path, cross_app_rules)) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+
+ if (!req.PreparePrivilegeLevel(context->privilege_level.get())) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+
for (application_x* app : GListRange<application_x*>(manifest->application)) {
if (!app->appid) {
return false;
}
bool is_web_priv = strcmp(app->type, "webapp") == 0;
- if (!RegisterSecurityContext(app->appid, pkg_id, cert_info->author_id.get(),
- manifest->api_version, path, uid,
+ if (!req.PrepareAppWithPrivileges(app->appid,
is_web_priv ? wgt_priv_vec : tpk_priv_vec,
- cross_app_rules, error_message)) {
+ is_web_priv ? wgt_appdef_vec : tpk_appdef_vec,
+ is_web_priv ? wgt_provides_appdef_vec : tpk_provides_appdef_vec)) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+ }
+
+ if (!manifest->application)
+ req.PrepareApp(pkg_id);
+
+ bool result = req.Install();
+ *error_message = req.ErrorMessage();
+ return result;
+}
+
+static bool UnregisterSecurityContext(const std::string& pkg_id,
+ const std::string& pkg_type, uid_t uid,
+ const std::vector<std::string>& appids, std::string* error_message) {
+ SecurityContextRequest req;
+ if (!req.IsValid()) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+ if (!req.PrepareBasic(pkg_id, uid, pkg_type)) {
+ *error_message = req.ErrorMessage();
+ return false;
+ }
+
+ for (const auto& appid : appids) {
+ if (!req.PrepareApp(appid)) {
return false;
}
}
- return true;
+
+ if (appids.empty())
+ req.PrepareApp(pkg_id);
+
+ bool result = req.Uninstall();
+ *error_message = req.ErrorMessage();
+ return result;
}
bool UnregisterSecurityContextForManifest(const std::string& pkg_id,
- uid_t uid, manifest_x* manifest, std::string* error_message) {
+ const std::string& pkg_type, uid_t uid, manifest_x* manifest,
+ std::string* error_message) {
+ std::vector<std::string> appids;
for (application_x* app : GListRange<application_x*>(manifest->application)) {
if (!app->appid) {
return false;
}
- if (!UnregisterSecurityContext(app->appid, pkg_id, uid, error_message)) {
- return false;
- }
+ appids.emplace_back(app->appid);
}
- return true;
+ return UnregisterSecurityContext(pkg_id, pkg_type, uid,
+ appids, error_message);
}
bool UnregisterSecurityContextForPkgId(const std::string &pkg_id,
- uid_t uid, std::string* error_message) {
+ const std::string& pkg_type, uid_t uid,
+ std::string* error_message, bool ignore_data_absence) {
std::vector<std::string> appids;
- if (!QueryAppidsForPkgId(pkg_id, &appids, uid))
- return false;
- for (auto& appid : appids) {
- if (!UnregisterSecurityContext(appid, pkg_id, uid, error_message)) {
- return false;
- }
- }
- return true;
+ ci::PkgQueryInterface pkg_query(pkg_id, uid);
+ if (!pkg_query.AppidsForPkgId(&appids))
+ return ignore_data_absence;
+ return UnregisterSecurityContext(pkg_id, pkg_type, uid,
+ appids, error_message);
}
bool RegisterSecurityContextForPath(const std::string &pkg_id,
- 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) {
- 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 + ">";
+ const std::string& pkg_type, const std::filesystem::path& path,
+ uid_t uid, bool is_readonly_pkg, std::string* error_message) {
+ SecurityContextPathRequest req;
+ if (!req.IsValid()) {
+ *error_message = req.ErrorMessage();
return false;
}
-
- if (!PreparePathRequest(pkg_id, path, uid, req, is_readonly_pkg,
- false, error_message)) {
- LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
- security_manager_path_req_free(req);
+ if (!req.Prepare(pkg_id, uid)) {
+ *error_message = req.ErrorMessage();
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);
+ if (!req.PreparePath(pkg_type, path, is_readonly_pkg, false)) {
+ *error_message = req.ErrorMessage();
return false;
}
-
- security_manager_path_req_free(req);
-
- return true;
+ bool result = req.Register();
+ *error_message = req.ErrorMessage();
+ return result;
}
-bool RegisterSecurityContextForRWOnlyPath(const std::string &pkg_id,
- 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) {
- 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 + ">";
+bool RegisterSecurityContextForPathExternalOnly(const std::string &pkg_id,
+ const std::string &pkg_type, const std::filesystem::path& path,
+ uid_t uid, std::string* error_message) {
+ SecurityContextPathRequest req;
+ if (!req.IsValid()) {
+ *error_message = req.ErrorMessage();
return false;
}
-
- if (!PreparePathRequest(pkg_id, path, uid, req, is_readonly_pkg,
- true, error_message)) {
- LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
- security_manager_path_req_free(req);
+ if (!req.Prepare(pkg_id, uid)) {
+ *error_message = req.ErrorMessage();
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);
+ if (!req.PreparePath(pkg_type, path, false, true)) {
+ *error_message = req.ErrorMessage();
return false;
}
+ bool result = req.Register();
+ *error_message = req.ErrorMessage();
+ return result;
+}
+
+bool HasOwnerRwOtherRoPaths(const std::filesystem::path& path) {
+ for (auto& policy : kSecurityPolicies) {
+ if (policy.second != SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO)
+ continue;
- security_manager_path_req_free(req);
+ fs::path subpath = path / policy.first;
+ LOG(ERROR) << "subpath : " << subpath;
+ if (fs::exists(subpath))
+ return true;
+ }
- return true;
+ return false;
}
} // namespace common_installer