Change security code routine for performance 75/160475/1
authorJunghyun Yeon <jungh.yeon@samsung.com>
Wed, 11 Oct 2017 08:41:42 +0000 (17:41 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 16 Nov 2017 08:17:01 +0000 (17:17 +0900)
- Security-manager APIs for Security registration/unregistration logic
  has changed to send all appid at once for performance.
- So, change app-installer logic for it.

Change-Id: Ic8a9d2b98426652fec657497391458ba760d1729
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
src/common/security_registration.cc

index 2950398..4a9363a 100644 (file)
@@ -281,85 +281,6 @@ bool PreparePathRequest(path_req* req, const std::string& pkg_id,
 
 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,
-    const AppDefinedPrivInfo& appdef_privileges,
-    const AppDefinedPrivInfo& provides_appdef_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 = std::to_string(error);
-    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
-    *error_message += ":<" + errnum + ">";
-    return false;
-  }
-
-  if (!PrepareRequest(app_id, pkg_id, author_id, api_version, path, uid,
-      privileges, appdef_privileges, provides_appdef_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;
-  }
-
-  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 = std::to_string(error);
-    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
-    *error_message += ":<" + errnum + ">";
-    security_manager_app_inst_req_free(req);
-    return false;
-  }
-
-  security_manager_app_inst_req_free(req);
-  return true;
-}
-
-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 = std::to_string(error);
-    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
-    *error_message += ":<" + errnum + ">";
-    return false;
-  }
-
-  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;
-  }
-
-  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 = std::to_string(error);
-    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
-    *error_message += ":<" + errnum + ">";
-    security_manager_app_inst_req_free(req);
-    return false;
-  }
-
-  security_manager_app_inst_req_free(req);
-  return true;
-}
-
 void PrepareAppDefinedPrivilegeData(GList *privileges,
     AppDefinedPrivInfo* tpk_priv_vec, AppDefinedPrivInfo* wgt_priv_vec) {
 
@@ -381,6 +302,18 @@ bool RegisterSecurityContextForManifest(
   // 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
   // native app and web privileges should be granted only to web applications.
+  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;
+  }
+
   std::vector<std::string> tpk_priv_vec;
   std::vector<std::string> wgt_priv_vec;
   for (auto& priv : GListRange<privilege_x*>(manifest->privileges)) {
@@ -397,34 +330,102 @@ bool RegisterSecurityContextForManifest(
   PrepareAppDefinedPrivilegeData(manifest->provides_appdefined_privileges,
       &tpk_provides_appdef_vec, &wgt_provides_appdef_vec);
 
-  for (application_x* app : GListRange<application_x*>(manifest->application)) {
+  GListRange<application_x*> list(manifest->application);
+  uint list_index = 0;
+  for (GListRange<application_x*>::Iterator iter = list.begin();
+      iter != list.end(); ++iter) {
+    application_x* app = *iter;
     if (!app->appid) {
+      security_manager_app_inst_req_free(req);
       return false;
     }
-
+    list_index++;
     bool is_web_priv = strcmp(app->type, "webapp") == 0;
-    if (!RegisterSecurityContext(app->appid, pkg_id, cert_info->author_id.get(),
+    if (!PrepareRequest(app->appid, pkg_id, cert_info->author_id.get(),
         manifest->api_version, path, uid,
         is_web_priv ? wgt_priv_vec : tpk_priv_vec,
         is_web_priv ? wgt_appdef_vec : tpk_appdef_vec,
         is_web_priv ? wgt_provides_appdef_vec : tpk_provides_appdef_vec,
-        cross_app_rules, error_message)) {
+        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;
+    }
+
+    if (list_index != list.Size() &&
+        security_manager_app_inst_req_next(req) != SECURITY_MANAGER_SUCCESS) {
+      LOG(ERROR) << "Failed to call security_manager_app_inst_req_next";
+      security_manager_app_inst_req_free(req);
       return false;
     }
   }
+
+  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;
+  }
+
+  security_manager_app_inst_req_free(req);
   return true;
 }
 
 bool UnregisterSecurityContextForManifest(const std::string& pkg_id,
     uid_t uid, manifest_x* manifest, std::string* error_message) {
-  for (application_x* app : GListRange<application_x*>(manifest->application)) {
+  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 = std::to_string(error);
+    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+    *error_message += ":<" + errnum + ">";
+    return false;
+  }
+
+  GListRange<application_x*> list(manifest->application);
+  uint list_index = 0;
+  for (GListRange<application_x*>::Iterator iter = list.begin();
+      iter != list.end(); ++iter) {
+    application_x* app = *iter;
     if (!app->appid) {
+      security_manager_app_inst_req_free(req);
       return false;
     }
-    if (!UnregisterSecurityContext(app->appid, pkg_id, uid, error_message)) {
+    list_index++;
+
+    if (!PrepareRequest(app->appid, 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;
+    }
+
+    if (list_index != list.Size() &&
+        security_manager_app_inst_req_next(req) != SECURITY_MANAGER_SUCCESS) {
+      LOG(ERROR) << "Failed to call security_manager_app_inst_req_next";
+      security_manager_app_inst_req_free(req);
       return false;
     }
   }
+  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 = std::to_string(error);
+    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+    *error_message += ":<" + errnum + ">";
+    security_manager_app_inst_req_free(req);
+    return false;
+  }
+
+  security_manager_app_inst_req_free(req);
   return true;
 }
 
@@ -434,11 +435,46 @@ bool UnregisterSecurityContextForPkgId(const std::string &pkg_id,
   ci::PkgQueryInterface pkg_query(pkg_id, uid);
   if (!pkg_query.AppidsForPkgId(&appids))
     return ignore_data_absence;
+
+  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 = std::to_string(error);
+    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+    *error_message += ":<" + errnum + ">";
+    return false;
+  }
+
   for (auto& appid : appids) {
-    if (!UnregisterSecurityContext(appid, pkg_id, uid, error_message)) {
+    if (!PrepareRequest(appid, 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;
     }
+
+    if (appid.compare(appids.at(appids.size())) == 0 &&
+        security_manager_app_inst_req_next(req) != SECURITY_MANAGER_SUCCESS) {
+      LOG(ERROR) << "Failed to call security_manager_app_inst_req_next";
+      security_manager_app_inst_req_free(req);
+      return false;
+    }
+  }
+  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 = std::to_string(error);
+    *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+    *error_message += ":<" + errnum + ">";
+    security_manager_app_inst_req_free(req);
+    return false;
   }
+
+  security_manager_app_inst_req_free(req);
   return true;
 }