#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"
{"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},
bool IsValid() const {
return req_ != NULL;
}
- bool PrepareBasic(const std::string& pkg_id, uid_t uid) {
- if (pkg_id.empty()) {
- LOG(ERROR) << "Pkgid is empty";
+ 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());
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;
+
+ error = security_manager_app_inst_req_set_pkg_type(req_, pkgtype);
+ if (error != SECURITY_MANAGER_SUCCESS) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
return true;
}
return true;
}
+ 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) {
+ SetErrorMessage(&error_message_, error);
+ return false;
+ }
+ return true;
+ }
+
bool PrepareAppWithPrivileges(const std::string& app_id,
const std::vector<std::string>& privileges,
const AppDefinedPrivInfo& appdef_privileges,
int error = security_manager_path_req_new(&req_);
if (error != SECURITY_MANAGER_SUCCESS) {
LOG(ERROR)
- << "Failed while calling security_manager_app_inst_req_new failed "
+ << "Failed while calling security_manager_path_req_new failed "
<< "(error code: " << error << ")";
SetErrorMessage(&error_message_, error);
req_ = NULL;
} else {
if (!bf::exists(subpath))
continue;
- if (bf::is_symlink(symlink_status(subpath))) {
+ if (bf::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;
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 (bf::directory_iterator iter(subpath);
+ iter != bf::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;
}
bool Register() {
int error = security_manager_paths_register(req_);
if (error != SECURITY_MANAGER_SUCCESS) {
- LOG(ERROR) << "Failed while calling security_manager_app_install failed "
- << "(error code: " << error << ")";
+ LOG(ERROR) << "Failed while calling security_manager_paths_register "
+ << "failed (error code: " << error << ")";
SetErrorMessage(&error_message_, error);
return false;
}
}
}
-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();
+ bf::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
*error_message = req.ErrorMessage();
return false;
}
- if (!req.PrepareBasic(pkg_id, uid)) {
+ if (!req.PrepareBasic(pkg_id, uid, pkg_type)) {
*error_message = req.ErrorMessage();
return false;
}
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;
return result;
}
-static bool UnregisterSecurityContext(const std::string& pkg_id, uid_t uid,
+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)) {
+ if (!req.PrepareBasic(pkg_id, uid, pkg_type)) {
*error_message = req.ErrorMessage();
return false;
}
}
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) {
}
appids.emplace_back(app->appid);
}
- return UnregisterSecurityContext(pkg_id, uid, appids, error_message);
+ return UnregisterSecurityContext(pkg_id, pkg_type, uid,
+ appids, error_message);
}
bool UnregisterSecurityContextForPkgId(const std::string &pkg_id,
- uid_t uid, std::string* error_message, bool ignore_data_absence) {
+ const std::string& pkg_type, uid_t uid,
+ std::string* error_message, bool ignore_data_absence) {
std::vector<std::string> appids;
ci::PkgQueryInterface pkg_query(pkg_id, uid);
if (!pkg_query.AppidsForPkgId(&appids))
return ignore_data_absence;
- return UnregisterSecurityContext(pkg_id, uid, appids, error_message);
+ 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) {
+ const std::string& pkg_type, const boost::filesystem::path& path,
+ uid_t uid, bool is_readonly_pkg, std::string* error_message) {
SecurityContextPathRequest req;
if (!req.IsValid()) {
*error_message = req.ErrorMessage();
*error_message = req.ErrorMessage();
return false;
}
- if (!req.PreparePath({}, path, is_readonly_pkg, false)) {
+ if (!req.PreparePath(pkg_type, path, is_readonly_pkg, false)) {
*error_message = req.ErrorMessage();
return false;
}
return result;
}
+bool HasOwnerRwOtherRoPaths(const boost::filesystem::path& path) {
+ for (auto& policy : kSecurityPolicies) {
+ if (policy.second != SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO)
+ continue;
+
+ bf::path subpath = path / policy.first;
+ LOG(ERROR) << "subpath : " << subpath;
+ if (bf::exists(subpath))
+ return true;
+ }
+
+ return false;
+}
+
} // namespace common_installer