StepSecurity 82/34282/7
authorTomasz Iwanek <t.iwanek@samsung.com>
Tue, 20 Jan 2015 14:39:20 +0000 (15:39 +0100)
committerTomasz Iwanek <t.iwanek@samsung.com>
Mon, 26 Jan 2015 11:31:54 +0000 (12:31 +0100)
Adds security manager API calls to apply correct security context
during installation and uninstallation process.

Change-Id: Ieceb1126edfe65f1f1f438e9c4dea7907e9f3e27

12 files changed:
CMakeLists.txt
packaging/app-installers.spec
src/common/CMakeLists.txt
src/common/context_installer.cc
src/common/context_installer.h
src/common/security_registration.cc [new file with mode: 0644]
src/common/security_registration.h [new file with mode: 0644]
src/common/step/step_revoke_security.cc [new file with mode: 0644]
src/common/step/step_revoke_security.h [new file with mode: 0644]
src/common/step/step_security.cc [new file with mode: 0644]
src/common/step/step_security.h [new file with mode: 0644]
src/wgt/wgt_backend.cc

index 12d9204..22f9180 100644 (file)
@@ -49,6 +49,7 @@ PKG_CHECK_MODULES(TZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
 PKG_CHECK_MODULES(LIBXML_DEPS REQUIRED libxml-2.0)
 PKG_CHECK_MODULES(XMLSEC1_DEPS REQUIRED xmlsec1)
 PKG_CHECK_MODULES(WIDGET_MANIFEST_PARSER_DEPS REQUIRED widget-manifest-parser)
+PKG_CHECK_MODULES(SECURITY_MANAGER_DEPS REQUIRED security-manager)
 
 FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem)
 
index a4f00af..5568d82 100644 (file)
@@ -13,6 +13,7 @@ BuildRequires:  pkgconfig(pkgmgr)
 BuildRequires:  pkgconfig(pkgmgr-parser)
 BuildRequires:  pkgconfig(pkgmgr-info)
 BuildRequires:  pkgconfig(pkgmgr-installer)
+BuildRequires:  pkgconfig(security-manager)
 BuildRequires:  pkgconfig(openssl)
 BuildRequires:  pkgconfig(libxml-2.0)
 BuildRequires:  pkgconfig(zlib)
index c80dfb0..9c8dea8 100644 (file)
@@ -2,6 +2,7 @@
 SET(SRCS
   app_installer.cc
   context_installer.cc
+  security_registration.cc
   step/step_unzip.cc
   step/step_signature.cc
   step/step_copy.cc
@@ -9,6 +10,8 @@ SET(SRCS
   step/step_record.cc
   step/step_parse.cc
   step/step_remove.cc
+  step/step_revoke_security.cc
+  step/step_security.cc
   step/step_signal.cc
   step/step_unregister.cc
   utils.cc
@@ -23,6 +26,7 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_COMMON} PUBLIC
   PKGMGR_INFO_DEPS
   PKGMGR_PARSER_DEPS
   PKGMGR_INSTALLER_DEPS
+  SECURITY_MANAGER_DEPS
   MINIZIP_DEPS
   ZLIB_DEPS
   TZPLATFORM_CONFIG_DEPS
index 1773e07..a14095a 100644 (file)
@@ -8,14 +8,17 @@
 #include <tzplatform_config.h>
 #include <unistd.h>
 
+#include <cstdlib>
+
 namespace common_installer {
 
 namespace fs = boost::filesystem;
 
-ContextInstaller::ContextInstaller() : req_(PKGMGR_REQ_INVALID),
-                                       uid_(getuid()),
-                                       manifest_(new manifest_x()),
-                                       config_data_(new ConfigData()) {
+ContextInstaller::ContextInstaller()
+    : req_(PKGMGR_REQ_INVALID),
+      manifest_(static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)))),
+      uid_(getuid()),
+      config_data_(new ConfigData()) {
 }
 
 ContextInstaller::~ContextInstaller() {
@@ -23,12 +26,12 @@ ContextInstaller::~ContextInstaller() {
     pkgmgr_parser_free_manifest_xml(manifest_);
 }
 
-const char* ContextInstaller::GetRootApplicationPath() {
+const char* ContextInstaller::GetRootApplicationPath() const {
   return uid_ != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
       ? tzplatform_getenv(TZ_USER_APP) : tzplatform_getenv(TZ_SYS_RW_APP);
 }
 
-const char* ContextInstaller::GetApplicationPath() {
+const char* ContextInstaller::GetApplicationPath() const {
   return (fs::path(GetRootApplicationPath()) / fs::path(pkgid())).c_str();
 }
 
index 46750c8..99ec0ce 100644 (file)
@@ -87,12 +87,12 @@ class ContextInstaller {
     unpack_directory_ = unpack_dir;
   }
 
-  ConfigData* config_data() { return config_data_.get(); }
+  ConfigData* config_data() const { return config_data_.get(); }
 
   pkgmgr_installer* pi() const { return pi_; }
 
-  const char* GetApplicationPath();
-  const char* GetRootApplicationPath();
+  const char* GetApplicationPath() const;
+  const char* GetRootApplicationPath() const;
 
  private :
   // request type: Install, Reinstall, Uninstall, Update.
diff --git a/src/common/security_registration.cc b/src/common/security_registration.cc
new file mode 100644 (file)
index 0000000..2c55ba5
--- /dev/null
@@ -0,0 +1,174 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/security_registration.h"
+
+#include <security-manager.h>
+
+#include <iostream>
+
+// TODO(t.iwanek): logging mechanism...
+#define DBG(msg) std::cout << "[DEBUG:SecurityContext] " << msg << std::endl;
+#define ERR(msg) std::cout << "[ERROR:SecurityContext] " << msg << std::endl;
+
+namespace bf = boost::filesystem;
+
+namespace {
+
+bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
+    const boost::filesystem::path& path, manifest_x* manifest,
+    app_inst_req* req) {
+  if (app_id.empty() || pkg_id.empty()) {
+    ERR("Appid or pkgid is empty. Both values must be set");
+    return false;
+  }
+
+  int error = security_manager_app_inst_req_set_app_id(req,
+      app_id.c_str());
+  if (error != SECURITY_MANAGER_SUCCESS) {
+    return false;
+  }
+
+  error = security_manager_app_inst_req_set_pkg_id(req,
+      pkg_id.c_str());
+  if (error != SECURITY_MANAGER_SUCCESS) {
+    return false;
+  }
+
+  if (!path.empty()) {
+    error = security_manager_app_inst_req_add_path(req, path.string().c_str(),
+        SECURITY_MANAGER_PATH_PRIVATE);
+    if (error != SECURITY_MANAGER_SUCCESS) {
+      return false;
+    }
+  }
+
+  if (manifest) {
+    for (privileges_x* privileges = manifest->privileges;
+        privileges != nullptr; privileges = privileges->next) {
+      for (privilege_x* priv = privileges->privilege;
+          priv != nullptr; priv = priv->next) {
+        security_manager_app_inst_req_add_privilege(req, priv->text);
+      }
+    }
+  }
+  return true;
+}
+
+bool RegisterSecurityContext(const std::string& app_id,
+    const std::string& pkg_id, const boost::filesystem::path& path,
+    manifest_x* manifest) {
+  app_inst_req* req;
+
+  int error = security_manager_app_inst_req_new(&req);
+  if (error != SECURITY_MANAGER_SUCCESS) {
+    ERR("Failed while calling security_manager_app_inst_req_new failed "
+        << "(error code: " << error << ")");
+    return false;
+  }
+
+  if (!PrepareRequest(app_id, pkg_id, path, manifest, req)) {
+      ERR("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) {
+    ERR("Failed while calling security_manager_app_install failed "
+        << "(error code: " << error << ")");
+    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) {
+  app_inst_req* req;
+
+  int error = security_manager_app_inst_req_new(&req);
+  if (error != SECURITY_MANAGER_SUCCESS) {
+    ERR("Failed while calling security_manager_app_inst_req_new  "
+        << "(error code: " << error << ")");
+    return false;
+  }
+
+  if (!PrepareRequest(app_id, pkg_id, bf::path(), nullptr, req)) {
+    ERR("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) {
+    ERR("Failed while calling  security_manager_app_uninstall failed "
+        << "(error code: " << error << ")");
+    security_manager_app_inst_req_free(req);
+    return false;
+  }
+
+  security_manager_app_inst_req_free(req);
+  return true;
+}
+
+}  // namespace
+
+namespace common_installer {
+
+bool RegisterSecurityContextForApps(
+    const std::string& pkg_id, const boost::filesystem::path& path,
+    manifest_x* manifest) {
+  for (uiapplication_x* ui = manifest->uiapplication;
+      ui != nullptr; ui = ui->next) {
+    if (!ui->appid) {
+      return false;
+    }
+    if (!RegisterSecurityContext(ui->appid, pkg_id, path, manifest)) {
+      return false;
+    }
+  }
+
+  for (serviceapplication_x* svc =
+      manifest->serviceapplication;
+      svc != nullptr; svc = svc->next) {
+    if (!svc->appid) {
+      return false;
+    }
+    if (!RegisterSecurityContext(svc->appid, pkg_id, path,  manifest)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool UnregisterSecurityContextForApps(
+    const std::string& pkg_id, manifest_x* manifest) {
+  for (uiapplication_x* ui = manifest->uiapplication;
+      ui != nullptr; ui = ui->next) {
+    if (!ui->appid) {
+      return false;
+    }
+    if (!UnregisterSecurityContext(ui->appid, pkg_id)) {
+      return false;
+    }
+  }
+
+  for (serviceapplication_x* svc =
+      manifest->serviceapplication;
+      svc != nullptr; svc = svc->next) {
+    if (!svc->appid) {
+      return false;
+    }
+    if (!UnregisterSecurityContext(svc->appid, pkg_id)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace common_installer
diff --git a/src/common/security_registration.h b/src/common/security_registration.h
new file mode 100644 (file)
index 0000000..4d761ef
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_SECURITY_REGISTRATION_H_
+#define COMMON_SECURITY_REGISTRATION_H_
+
+#include <boost/filesystem/path.hpp>
+
+#include <sys/types.h>
+
+#include <string>
+
+#include "common/context_installer.h"
+
+namespace common_installer {
+
+bool RegisterSecurityContextForApps(const std::string& pkg_id,
+    const boost::filesystem::path& path, manifest_x* manifest);
+bool UnregisterSecurityContextForApps(const std::string& pkg_id,
+    manifest_x* manifest);
+
+}  // namespace common_installer
+
+#endif  // COMMON_SECURITY_REGISTRATION_H_
diff --git a/src/common/step/step_revoke_security.cc b/src/common/step/step_revoke_security.cc
new file mode 100644 (file)
index 0000000..e7f476c
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/step_revoke_security.h"
+
+#include <iostream>
+
+#include "common/security_registration.h"
+
+// TODO(t.iwanek): logging mechanism...
+#define DBG(msg) std::cout << "[RevokeSecurity] " << msg << std::endl;
+#define ERR(msg) std::cout << "[ERROR:RevokeSecurity] " << msg << std::endl;
+
+namespace common_installer {
+namespace revoke_security {
+
+Step::Status StepRevokeSecurity::process() {
+  if (!UnregisterSecurityContextForApps(
+      context_->pkgid(), context_->manifest_data())) {
+    return Status::ERROR;
+  }
+  DBG("Security context uninstalled");
+  return Status::OK;
+}
+
+Step::Status StepRevokeSecurity::undo() {
+  if (!RegisterSecurityContextForApps(
+      context_->pkgid(), context_->GetRootApplicationPath(),
+      context_->manifest_data())) {
+    return Status::ERROR;
+  }
+  DBG("Security context installed");
+  return Status::OK;
+}
+
+}  // namespace revoke_security
+}  // namespace common_installer
diff --git a/src/common/step/step_revoke_security.h b/src/common/step/step_revoke_security.h
new file mode 100644 (file)
index 0000000..eb981a2
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_REVOKE_SECURITY_H_
+#define COMMON_STEP_STEP_REVOKE_SECURITY_H_
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace revoke_security {
+
+// Step that is used during uninstallation
+class StepRevokeSecurity : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status undo() override;
+  Status clean() override { return Status::OK; }
+};
+
+}  // namespace revoke_security
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_STEP_REVOKE_SECURITY_H_
diff --git a/src/common/step/step_security.cc b/src/common/step/step_security.cc
new file mode 100644 (file)
index 0000000..0216fdc
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/step_security.h"
+
+#include <iostream>
+
+#include "common/security_registration.h"
+
+// TODO(t.iwanek): logging mechanism...
+#define DBG(msg) std::cout << "[Security] " << msg << std::endl;
+#define ERR(msg) std::cout << "[ERROR:Security] " << msg << std::endl;
+
+namespace common_installer {
+namespace security {
+
+Step::Status StepSecurity::process() {
+  if (!RegisterSecurityContextForApps(
+      context_->pkgid(), context_->GetRootApplicationPath(),
+      context_->manifest_data())) {
+    return Status::ERROR;
+  }
+  DBG("Security context installed");
+  return Status::OK;
+}
+
+Step::Status StepSecurity::undo() {
+  if (!UnregisterSecurityContextForApps(
+      context_->pkgid(), context_->manifest_data())) {
+    return Status::ERROR;
+  }
+  DBG("Security context uninstalled");
+  return Status::OK;
+}
+
+}  // namespace security
+}  // namespace common_installer
diff --git a/src/common/step/step_security.h b/src/common/step/step_security.h
new file mode 100644 (file)
index 0000000..43d7422
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_SECURITY_H_
+#define COMMON_STEP_STEP_SECURITY_H_
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace security {
+
+class StepSecurity : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status undo() override;
+  Status clean() override { return Status::OK; }
+};
+
+}  // namespace security
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_STEP_SECURITY_H_
index 2ee2a5d..f840e7a 100644 (file)
@@ -18,6 +18,8 @@
 #include "common/step/step_parse.h"
 #include "common/step/step_record.h"
 #include "common/step/step_remove.h"
+#include "common/step/step_revoke_security.h"
+#include "common/step/step_security.h"
 #include "common/step/step_signal.h"
 #include "common/step/step_signature.h"
 #include "common/step/step_unregister.h"
@@ -49,6 +51,7 @@ int main(int argc, char** argv) {
       installer.AddStep<wgt::parse::StepParse>();
       installer.AddStep<ci::signal::StepSignal>();
       installer.AddStep<ci::copy::StepCopy>();
+      installer.AddStep<ci::security::StepSecurity>();
       installer.AddStep<ci::generate_xml::StepGenerateXml>();
       installer.AddStep<ci::record::StepRecord>();
 
@@ -60,6 +63,7 @@ int main(int argc, char** argv) {
 
       installer.AddStep<ci::parse::StepParse>();
       installer.AddStep<ci::signal::StepSignal>();
+      installer.AddStep<ci::revoke_security::StepRevokeSecurity>();
       installer.AddStep<ci::unregister::StepUnregister>();
       installer.AddStep<ci::remove::StepRemove>();