Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / security_registration.cc
index 164b59b..1204e3d 100644 (file)
@@ -4,9 +4,6 @@
 
 #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 <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 {
@@ -32,12 +29,14 @@ 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},
@@ -88,9 +87,10 @@ class SecurityContextRequest {
   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());
@@ -103,12 +103,24 @@ class SecurityContextRequest {
       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;
   }
 
   bool PrepareAdditional(const std::string& author_id,
       const std::string& api_version,
-      const boost::filesystem::path& path,
+      const std::filesystem::path& path,
       bool cross_app_rules) {
     if (cross_app_rules) {
       int error = security_manager_app_inst_req_set_hybrid(req_);
@@ -136,7 +148,7 @@ class SecurityContextRequest {
     if (!path.empty()) {
       app_install_type type = SM_APP_INSTALL_NONE;
       for (auto& policy : kPathPolicies) {
-        bf::path root = bf::path(policy.first);
+        fs::path root = fs::path(policy.first);
         if (ci::IsSubDir(path, root)) {
           type = policy.second;
           break;
@@ -157,6 +169,17 @@ class SecurityContextRequest {
     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,
@@ -264,7 +287,7 @@ class SecurityContextPathRequest {
     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;
@@ -299,7 +322,7 @@ class SecurityContextPathRequest {
   }
 
   bool PreparePath(const std::string& pkg_type,
-      const boost::filesystem::path& path, bool is_readonly_pkg,
+      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";
@@ -307,7 +330,7 @@ class SecurityContextPathRequest {
     }
     app_install_type type = SM_APP_INSTALL_NONE;
     for (auto& policy : kPathPolicies) {
-      bf::path root = bf::path(policy.first);
+      fs::path root = fs::path(policy.first);
       if (ci::IsSubDir(path, root)) {
         type = policy.second;
         break;
@@ -332,7 +355,7 @@ class SecurityContextPathRequest {
     else
       policies = kSecurityPolicies;
     for (auto& policy : policies) {
-      bf::path subpath = path / policy.first;
+      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,
@@ -341,9 +364,10 @@ class SecurityContextPathRequest {
         if (pkg_type == "wgt" && (subdir == "bin" || subdir == "lib"))
           continue;
       } else {
-        if (!bf::exists(subpath))
+        if (!fs::exists(subpath))
           continue;
-        if (bf::is_symlink(symlink_status(subpath))) {
+        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;
@@ -355,6 +379,19 @@ class SecurityContextPathRequest {
         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;
   }
@@ -362,8 +399,8 @@ class SecurityContextPathRequest {
   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;
     }
@@ -396,10 +433,16 @@ void PrepareAppDefinedPrivilegeData(GList *privileges,
   }
 }
 
-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
@@ -425,7 +468,7 @@ bool RegisterSecurityContextForManifest(
     *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;
   }
@@ -435,6 +478,11 @@ bool RegisterSecurityContextForManifest(
     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;
@@ -450,19 +498,23 @@ bool RegisterSecurityContextForManifest(
     }
   }
 
+  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, 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;
   }
@@ -473,13 +525,17 @@ static bool UnregisterSecurityContext(const std::string& pkg_id, uid_t uid,
     }
   }
 
+  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) {
@@ -487,21 +543,24 @@ bool UnregisterSecurityContextForManifest(const std::string& pkg_id,
     }
     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 std::filesystem::path& path,
+    uid_t uid, bool is_readonly_pkg, std::string* error_message) {
   SecurityContextPathRequest req;
   if (!req.IsValid()) {
     *error_message = req.ErrorMessage();
@@ -511,7 +570,7 @@ bool RegisterSecurityContextForPath(const std::string &pkg_id,
     *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;
   }
@@ -521,7 +580,7 @@ bool RegisterSecurityContextForPath(const std::string &pkg_id,
 }
 
 bool RegisterSecurityContextForPathExternalOnly(const std::string &pkg_id,
-    const std::string &pkg_type, const boost::filesystem::path& path,
+    const std::string &pkg_type, const std::filesystem::path& path,
     uid_t uid, std::string* error_message) {
   SecurityContextPathRequest req;
   if (!req.IsValid()) {
@@ -541,4 +600,18 @@ bool RegisterSecurityContextForPathExternalOnly(const std::string &pkg_id,
   return result;
 }
 
+bool HasOwnerRwOtherRoPaths(const std::filesystem::path& path) {
+  for (auto& policy : kSecurityPolicies) {
+    if (policy.second != SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO)
+      continue;
+
+    fs::path subpath = path / policy.first;
+    LOG(ERROR) << "subpath : " << subpath;
+    if (fs::exists(subpath))
+      return true;
+  }
+
+  return false;
+}
+
 }  // namespace common_installer