[Feature] Privilege translation for backward compatilibity 64/46564/4
authorTomasz Iwanek <t.iwanek@samsung.com>
Thu, 20 Aug 2015 13:46:05 +0000 (15:46 +0200)
committerPawel Sikorski <p.sikorski@samsung.com>
Fri, 21 Aug 2015 14:12:54 +0000 (07:12 -0700)
ConfigData class was removed because it had only one member
field and it was redundant.

API added to security-manager and used here should be implemented
in privilege-checker instead probably. Security manager and
privilege-checker holds very similar databases now.

Change-Id: I4ee1bfd7a98cf9aecbd291fda9e5c7e1f05ceb20

12 files changed:
src/common/CMakeLists.txt
src/common/context_installer.h
src/common/step/step_check_signature.cc
src/common/step/step_privilege_compatibility.cc [new file with mode: 0644]
src/common/step/step_privilege_compatibility.h [new file with mode: 0644]
src/common/utils/clist_helpers.h
src/tpk/step/step_parse.cc
src/tpk/tpk_installer.cc
src/wgt/step/step_parse.cc
src/wgt/step/step_wgt_copy_storage_directories.cc
src/wgt/step/step_wgt_create_storage_directories.cc
src/wgt/wgt_installer.cc

index 78eb24e..f965dee 100644 (file)
@@ -31,6 +31,7 @@ SET(SRCS
   step/step_old_manifest.cc
   step/step_open_recovery_file.cc
   step/step_parse.cc
+  step/step_privilege_compatibility.cc
   step/step_remove_icons.cc
   step/step_remove_files.cc
   step/step_remove_temporary_directory.cc
index 3412085..0438372 100644 (file)
@@ -55,13 +55,6 @@ class ExtraManifestData {
   Property<AccountInfo> account_info;
 };
 
-class ConfigData {
- public:
-  ConfigData() {}
-  /** version pointed in <application> tag*/
-  Property<std::string> required_api_version;
-};
-
 class BackendData {
  public:
   virtual ~BackendData() { }
@@ -137,9 +130,6 @@ class ContextInstaller {
   // uid of the user that request the operation
   Property<uid_t> uid;
 
-  // data from config.xml
-  Property<ConfigData> config_data;
-
   // path for the applications root directory
   Property<boost::filesystem::path> root_application_path;
 
index 37979bb..dca62eb 100644 (file)
@@ -204,7 +204,7 @@ Step::Status StepCheckSignature::process() {
   // TODO(t.iwanek): refactoring, move to wgt backend
   bool is_webapp = context_->pkg_type.get() == "wgt";
   if (!ValidatePrivilegeLevel(level, is_webapp,
-      context_->config_data.get().required_api_version.get().c_str(),
+      context_->manifest_data.get()->api_version,
       context_->manifest_data.get()->privileges))
     return Status::ERROR;
 
diff --git a/src/common/step/step_privilege_compatibility.cc b/src/common/step/step_privilege_compatibility.cc
new file mode 100644 (file)
index 0000000..7809eef
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/step_privilege_compatibility.h"
+
+#include <pkgmgrinfo_basic.h>
+#include <security-manager.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+
+#include "common/utils/clist_helpers.h"
+
+namespace {
+
+const char kPlatformVersion[] = "3.0";
+
+bool TranslatePrivilegesForCompatibility(manifest_x* m) {
+  if (!m->api_version) {
+    LOG(WARNING) << "Skipping privileges mapping because api-version "
+                 << "is not specified by package";
+    return true;
+  }
+  if (strcmp(m->api_version, kPlatformVersion) == 0)
+    return true;
+
+  // calculate number of privileges
+  size_t size = 0;
+  privileges_x *privileges = nullptr;
+  PKGMGR_LIST_MOVE_NODE_TO_HEAD(m->privileges, privileges);
+  for (; privileges; privileges = privileges->next) {
+    size += PKGMGR_LIST_LEN(privileges);
+  }
+
+  // prepare input structure
+  std::unique_ptr<const char*[]> input_privileges(new const char*[size]);
+  size_t input_size = 0;
+  privileges = nullptr;
+  PKGMGR_LIST_MOVE_NODE_TO_HEAD(m->privileges, privileges);
+  for (; privileges; privileges = privileges->next) {
+    privilege_x* priv = nullptr;
+    PKGMGR_LIST_MOVE_NODE_TO_HEAD(privileges->privilege, priv);
+    for (; priv; priv = priv->next) {
+      input_privileges[input_size++] = priv->text;
+    }
+  }
+
+  // get mapping
+  size_t output_size = 0;
+  char** output_privileges = nullptr;
+  if (security_manager_get_privileges_mapping(m->api_version, kPlatformVersion,
+      input_privileges.get(), input_size, &output_privileges, &output_size)
+      != SECURITY_MANAGER_SUCCESS) {
+    LOG(ERROR) << "security_manager_get_privileges_mapping failed";
+    return false;
+  }
+
+  // delete pkgmgr old list
+  privileges = nullptr;
+  privileges_x* privileges_next = nullptr;
+  PKGMGR_LIST_MOVE_NODE_TO_HEAD(m->privileges, privileges);
+  for (; privileges; privileges = privileges_next) {
+    privileges_next = privileges->next;
+    privilege_x* priv = nullptr;
+    privilege_x* next = nullptr;
+    PKGMGR_LIST_MOVE_NODE_TO_HEAD(privileges->privilege, priv);
+    for (; priv; priv = next) {
+      next = priv->next;
+      // mark as const but we actually have ownership
+      free(const_cast<char*>(priv->text));
+      free(priv);
+    }
+    free(privileges);
+  }
+
+  // set pkgmgr new list
+  m->privileges =
+      reinterpret_cast<privileges_x*>(calloc(1, sizeof(privileges_x)));
+  for (size_t i = 0; i < output_size; ++i) {
+    privilege_x* priv =
+        reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    priv->text = strdup(output_privileges[i]);
+    LISTADD(m->privileges->privilege, priv);
+  }
+
+  security_manager_privilege_mapping_free(output_privileges, output_size);
+  return true;
+}
+
+}  // namespace
+
+namespace common_installer {
+namespace security {
+
+Step::Status StepPrivilegeCompatibility::precheck() {
+  if (!context_->manifest_data.get()) {
+    LOG(ERROR) << "Manifest data is not set";
+    return Status::ERROR;
+  }
+  return Status::OK;
+}
+
+Step::Status StepPrivilegeCompatibility::process() {
+  return TranslatePrivilegesForCompatibility(context_->manifest_data.get()) ?
+      Status::OK : Status::ERROR;
+}
+
+}  // namespace security
+}  // namespace common_installer
+
diff --git a/src/common/step/step_privilege_compatibility.h b/src/common/step/step_privilege_compatibility.h
new file mode 100644 (file)
index 0000000..29ed20b
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_PRIVILEGE_COMPATIBILITY_H_
+#define COMMON_STEP_STEP_PRIVILEGE_COMPATIBILITY_H_
+
+#include "common/context_installer.h"
+#include "common/step/step.h"
+#include "common/utils/logging.h"
+
+namespace common_installer {
+namespace security {
+
+/**
+ * @brief This step converts privileges declared in package manifest to the
+ *        privileges for current platform version
+ */
+class StepPrivilegeCompatibility : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override { return Status::OK; }
+  // backward translation not needed
+  Status undo() override { return Status::OK; }
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(PrivilegeCompatibility)
+};
+
+}  // namespace security
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_STEP_PRIVILEGE_COMPATIBILITY_H_
index f0fd08d..045dd7f 100644 (file)
     if (list) {                                                                \
       LISTHEAD(list, node);                                                    \
     }                                                                          \
-  } while (0)                                                                  \
+  } while (false)                                                              \
+
+/*
+ * Calculates size of C style list from any of its point
+ */
+#define PKGMGR_LIST_LEN(list)                                                  \
+  [list]() {                                                                   \
+    size_t size = 0;                                                           \
+    auto node = list;                                                          \
+    PKGMGR_LIST_MOVE_NODE_TO_HEAD(list, node);                                 \
+    while (node) {                                                             \
+      node = node->next;                                                       \
+      ++size;                                                                  \
+    }                                                                          \
+    return size;                                                               \
+  }()                                                                          \
 
 #endif  // COMMON_UTILS_CLIST_HELPERS_H_
index 9729209..78265df 100644 (file)
@@ -2,9 +2,11 @@
 #include "tpk/step/step_parse.h"
 
 #include <boost/filesystem.hpp>
+
 #include <memory>
 #include <string>
 #include <vector>
+
 #include "common/context_installer.h"
 #include "common/step/step.h"
 
@@ -135,7 +137,7 @@ bool StepParse::SetContextByManifestParser(XmlTree* tree) {
 
   LOG(DEBUG) << "Getting manifest xml data";
   LOG(DEBUG) << "manifest: xmlns='" << manifest->attr("xmlns") <<
-                "' api_version='" << manifest->attr("api_version") <<
+                "' api-version='" << manifest->attr("api-version") <<
                 "' package='" << manifest->attr("package") <<
                 "' versionr='" << manifest->attr("version") << "'";
 
@@ -156,8 +158,6 @@ bool StepParse::SetContextByManifestParser(XmlTree* tree) {
   }
 
   // set context_
-  context_->config_data.get().required_api_version.set(
-      manifest->attr("api-version"));
   context_->pkgid.set(manifest->attr("package"));
 
   // write pkgid for recovery file
@@ -194,6 +194,7 @@ bool StepParse::SetPkgInfoManifest(manifest_x* m,
   m->type = strdup("tpk");
   m->version = string_strdup(manifest->attr("version"));
   m->installlocation = string_strdup(manifest->attr("install-location"));
+  m->api_version = string_strdup(manifest->attr("api-version"));
 
   // Choose main app among ui-application or service-application
   // NOTE: main app must have appid attribute
index 586290a..1654512 100644 (file)
@@ -13,6 +13,7 @@
 #include "common/step/step_old_manifest.h"
 #include "common/step/step_open_recovery_file.h"
 #include "common/step/step_parse.h"
+#include "common/step/step_privilege_compatibility.h"
 #include "common/step/step_recover_application.h"
 #include "common/step/step_recover_files.h"
 #include "common/step/step_recover_icons.h"
@@ -84,6 +85,7 @@ void TpkInstaller::InstallSteps() {
   AddStep<ci::filesystem::StepUnzip>();
   AddStep<tpk::parse::StepParse>();
   AddStep<ci::security::StepCheckSignature>();
+  AddStep<ci::security::StepPrivilegeCompatibility>();
   AddStep<ci::security::StepRollbackInstallationSecurity>();
   AddStep<ci::filesystem::StepCopy>();
   AddStep<ci::filesystem::StepCreateStorageDirectories>();
@@ -99,6 +101,7 @@ void TpkInstaller::UpdateSteps() {
   AddStep<ci::filesystem::StepUnzip>();
   AddStep<tpk::parse::StepParse>();
   AddStep<ci::security::StepCheckSignature>();
+  AddStep<ci::security::StepPrivilegeCompatibility>();
   AddStep<ci::security::StepCheckOldCertificate>();
   AddStep<ci::backup::StepOldManifest>();
   AddStep<ci::backup::StepBackupManifest>();
index 5eda241..3b715f2 100755 (executable)
@@ -195,14 +195,12 @@ bool StepParse::FillPrivileges(manifest_x* manifest) {
       std::static_pointer_cast<const PermissionsInfo>(parser_->GetManifestData(
           app_keys::kTizenPermissionsKey));
   std::set<std::string> privileges;
-  privileges.insert({"priv"});
-  privileges.clear();
   if (perm_info)
     privileges = ExtractPrivileges(perm_info);
 
   if (!privileges.empty()) {
     privileges_x* privileges_x_list =
-        reinterpret_cast<privileges_x*> (calloc(1, sizeof(privileges_x)));\
+        reinterpret_cast<privileges_x*>(calloc(1, sizeof(privileges_x)));
     manifest->privileges = privileges_x_list;
     for (const std::string& p : privileges) {
       privilege_x* privilege_x_node =
@@ -336,7 +334,8 @@ common_installer::Step::Status StepParse::process() {
   const std::string& package_version = wgt_info->version();
   const std::string& required_api_version = info->required_version();
 
-  context_->config_data.get().required_api_version.set(required_api_version);
+  context_->manifest_data.get()->api_version =
+      strdup(required_api_version.c_str());
   context_->pkgid.set(manifest->package);
 
   // write pkgid for recovery file
index 695fcfa..b8211f6 100644 (file)
@@ -27,8 +27,7 @@ namespace wgt {
 namespace filesystem {
 
 common_installer::Step::Status StepWgtCopyStorageDirectories::process() {
-  int version =
-      context_->config_data.get().required_api_version.get().at(0) - '0';
+  int version = context_->manifest_data.get()->api_version[0] - '0';
   if (version < 3) {
     LOG(DEBUG) << "Shared directory coping for tizen 2.x";
     return StepCopyStorageDirectories::process();
@@ -43,8 +42,7 @@ common_installer::Step::Status StepWgtCopyStorageDirectories::process() {
 }
 
 common_installer::Step::Status StepWgtCopyStorageDirectories::undo() {
-  int version =
-      context_->config_data.get().required_api_version.get().at(0) - '0';
+  int version = context_->manifest_data.get()->api_version[0] - '0';
   if (version < 3) {
     LOG(DEBUG) << "Shared directory coping for tizen 2.x";
     return StepCopyStorageDirectories::undo();
index 4b24850..358c4ed 100644 (file)
@@ -27,8 +27,7 @@ common_installer::Step::Status StepWgtCreateStorageDirectories::process() {
   if (!PrivateDir())
     return Status::ERROR;
 
-  char version =
-      context_->config_data.get().required_api_version.get().at(0);
+  char version = context_->manifest_data.get()->api_version[0];
 
   if ((version-'0') < 3) {
     LOG(DEBUG) << "Shared directory preparation for tizen 2.x";
index b56b148..a46cf25 100644 (file)
@@ -16,6 +16,7 @@
 #include "common/step/step_fail.h"
 #include "common/step/step_open_recovery_file.h"
 #include "common/step/step_parse.h"
+#include "common/step/step_privilege_compatibility.h"
 #include "common/step/step_register_app.h"
 #include "common/step/step_recover_application.h"
 #include "common/step/step_recover_files.h"
@@ -65,6 +66,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
       AddStep<ci::filesystem::StepUnzip>();
       AddStep<wgt::parse::StepParse>(true);
       AddStep<ci::security::StepCheckSignature>();
+      AddStep<ci::security::StepPrivilegeCompatibility>();
       AddStep<wgt::security::StepCheckSettingsLevel>();
       AddStep<wgt::encrypt::StepEncryptResources>();
       AddStep<wgt::filesystem::StepWgtResourceDirectory>();
@@ -83,6 +85,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
       AddStep<ci::filesystem::StepUnzip>();
       AddStep<wgt::parse::StepParse>(true);
       AddStep<ci::security::StepCheckSignature>();
+      AddStep<ci::security::StepPrivilegeCompatibility>();
       AddStep<wgt::security::StepCheckSettingsLevel>();
       AddStep<ci::security::StepCheckOldCertificate>();
       AddStep<wgt::filesystem::StepWgtResourceDirectory>();