From 70b2931e093746ead5824fd4a76da03dc0becd69 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Tue, 20 Jan 2015 15:39:20 +0100 Subject: [PATCH] StepSecurity Adds security manager API calls to apply correct security context during installation and uninstallation process. Change-Id: Ieceb1126edfe65f1f1f438e9c4dea7907e9f3e27 --- CMakeLists.txt | 1 + packaging/app-installers.spec | 1 + src/common/CMakeLists.txt | 4 + src/common/context_installer.cc | 15 +-- src/common/context_installer.h | 6 +- src/common/security_registration.cc | 174 ++++++++++++++++++++++++++++++++ src/common/security_registration.h | 25 +++++ src/common/step/step_revoke_security.cc | 38 +++++++ src/common/step/step_revoke_security.h | 26 +++++ src/common/step/step_security.cc | 38 +++++++ src/common/step/step_security.h | 25 +++++ src/wgt/wgt_backend.cc | 4 + 12 files changed, 348 insertions(+), 9 deletions(-) create mode 100644 src/common/security_registration.cc create mode 100644 src/common/security_registration.h create mode 100644 src/common/step/step_revoke_security.cc create mode 100644 src/common/step/step_revoke_security.h create mode 100644 src/common/step/step_security.cc create mode 100644 src/common/step/step_security.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12d9204..22f9180 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/packaging/app-installers.spec b/packaging/app-installers.spec index a4f00af..5568d82 100644 --- a/packaging/app-installers.spec +++ b/packaging/app-installers.spec @@ -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) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c80dfb0..9c8dea8 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -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 diff --git a/src/common/context_installer.cc b/src/common/context_installer.cc index 1773e07..a14095a 100644 --- a/src/common/context_installer.cc +++ b/src/common/context_installer.cc @@ -8,14 +8,17 @@ #include #include +#include + 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(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(); } diff --git a/src/common/context_installer.h b/src/common/context_installer.h index 46750c8..99ec0ce 100644 --- a/src/common/context_installer.h +++ b/src/common/context_installer.h @@ -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 index 0000000..2c55ba5 --- /dev/null +++ b/src/common/security_registration.cc @@ -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 + +#include + +// 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 index 0000000..4d761ef --- /dev/null +++ b/src/common/security_registration.h @@ -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 + +#include + +#include + +#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 index 0000000..e7f476c --- /dev/null +++ b/src/common/step/step_revoke_security.cc @@ -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 + +#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 index 0000000..eb981a2 --- /dev/null +++ b/src/common/step/step_revoke_security.h @@ -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 index 0000000..0216fdc --- /dev/null +++ b/src/common/step/step_security.cc @@ -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 + +#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 index 0000000..43d7422 --- /dev/null +++ b/src/common/step/step_security.h @@ -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_ diff --git a/src/wgt/wgt_backend.cc b/src/wgt/wgt_backend.cc index 2ee2a5d..f840e7a 100644 --- a/src/wgt/wgt_backend.cc +++ b/src/wgt/wgt_backend.cc @@ -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(); installer.AddStep(); installer.AddStep(); + installer.AddStep(); installer.AddStep(); installer.AddStep(); @@ -60,6 +63,7 @@ int main(int argc, char** argv) { installer.AddStep(); installer.AddStep(); + installer.AddStep(); installer.AddStep(); installer.AddStep(); -- 2.7.4