From: Pawel Andruszkiewicz Date: Thu, 11 Jun 2015 11:19:41 +0000 (+0200) Subject: [Common] Code of tools extracted to separate file. X-Git-Tag: submit/tizen/20150702.103311^2~2^2~57^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ecf3fdda1501e412741f6f7c8585c1fb21b94752;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Common] Code of tools extracted to separate file. Change-Id: I8246664a7485a10ce68c64de992c6b13b116a3f4 Signed-off-by: Pawel Andruszkiewicz --- diff --git a/src/common/common.gyp b/src/common/common.gyp index 24337873..aa994f24 100644 --- a/src/common/common.gyp +++ b/src/common/common.gyp @@ -31,6 +31,8 @@ 'scope_exit.h', 'task-queue.cpp', 'task-queue.h', + 'tools.cc', + 'tools.h', 'callback_user_data.cc', 'callback_user_data.h', 'optional.h', diff --git a/src/common/extension.cc b/src/common/extension.cc index 0e523a2c..c47986db 100755 --- a/src/common/extension.cc +++ b/src/common/extension.cc @@ -11,19 +11,7 @@ #include #include -#ifdef PRIVILEGE_USE_DB -#include -#elif PRIVILEGE_USE_ACE -#include -#elif PRIVILEGE_USE_CYNARA -#include - -#include -#include -#endif - #include "common/logger.h" -#include "common/scope_exit.h" // This function is hidden, because each plugin needs to have own implementation. __attribute__ ((visibility ("hidden"))) common::Extension* CreateExtension() { @@ -382,248 +370,4 @@ void ParsedInstance::HandleError(const PlatformResult& e) { SendSyncReply(result.serialize().c_str()); } -namespace tools { -void ReportSuccess(picojson::object& out) { - LoggerD("Enter"); - out.insert(std::make_pair("status", picojson::value("success"))); -} - -void ReportSuccess(const picojson::value& result, picojson::object& out) { - LoggerD("Enter"); - out.insert(std::make_pair("status", picojson::value("success"))); - out.insert(std::make_pair("result", result)); -} - -void ReportError(picojson::object& out) { - LoggerD("Enter"); - out.insert(std::make_pair("status", picojson::value("error"))); -} - -void ReportError(const PlatformException& ex, picojson::object& out) { - LoggerD("Enter"); - out.insert(std::make_pair("status", picojson::value("error"))); - out.insert(std::make_pair("error", ex.ToJSON())); -} - -void ReportError(const PlatformResult& error, picojson::object* out) { - LoggerD("Enter"); - out->insert(std::make_pair("status", picojson::value("error"))); - out->insert(std::make_pair("error", error.ToJSON())); -} - -namespace { - -#ifdef PRIVILEGE_USE_DB - -class AccessControlImpl { - public: - AccessControlImpl() - : initialized_(false) { - LoggerD("Privilege access checked using DB."); - - const char* kWrtDBPath = "/opt/dbspace/.wrt.db"; - sqlite3* db = nullptr; - - int ret = sqlite3_open(kWrtDBPath, &db); - if (SQLITE_OK != ret) { - LoggerE("Failed to access WRT database"); - return; - } - - const char* kQuery = "select name from WidgetFeature where app_id = " - "(select app_id from WidgetInfo where tizen_appid = ?)" - " and rejected = 0"; - const std::string app_id = common::GetCurrentExtension()->GetRuntimeVariable("app_id", 64); - sqlite3_stmt* stmt = nullptr; - - ret = sqlite3_prepare_v2(db, kQuery, -1, &stmt, nullptr); - ret |= sqlite3_bind_text(stmt, 1, app_id.c_str(), -1, SQLITE_TRANSIENT); - - SCOPE_EXIT { - sqlite3_finalize(stmt); - sqlite3_close(db); - }; - - if (SQLITE_OK != ret) { - LoggerE("Failed to query WRT database"); - return; - } - - while (sqlite3_step(stmt) == SQLITE_ROW) { - const char* privilege = reinterpret_cast(sqlite3_column_text(stmt, 0)); - SLoggerD("Granted: %s", privilege); - granted_privileges_.push_back(privilege); - } - - initialized_ = true; - } - - ~AccessControlImpl() {} - - bool CheckAccess(const std::vector& privileges) { - LoggerD("Enter"); - if (!initialized_) { - return false; - } - - for (const auto& privilege : privileges) { - if (std::find(granted_privileges_.begin(), granted_privileges_.end(), privilege) == granted_privileges_.end()) { - return false; - } - } - - return true; - } - - private: - bool initialized_; - std::vector granted_privileges_; -}; - -#elif PRIVILEGE_USE_ACE - -class AccessControlImpl { - public: - AccessControlImpl() { - LoggerD("Privilege access checked using ACE."); - } - - ~AccessControlImpl() { - } - - bool CheckAccess(const std::vector& privileges) { - LoggerD("Enter"); - int ret = 0; - for (size_t i = 0; i < privileges.size(); ++i) { - ret = privilege_checker_check_privilege(privileges[i].c_str()); - if (PRIVILEGE_CHECKER_ERR_NONE != ret) { - return false; - } - } - return true; - } -}; - -#elif PRIVILEGE_USE_CYNARA - -class AccessControlImpl { - public: - AccessControlImpl() : cynara_(nullptr) { - LoggerD("Privilege access checked using Cynara."); - - char* smack_label = nullptr; - int ret = smack_new_label_from_self(&smack_label); - - if (0 == ret && nullptr != smack_label) { - auto uid = getuid(); - - SLoggerD("uid: [%u]", uid); - SLoggerD("smack label: [%s]", smack_label); - - uid_ = std::to_string(uid); - smack_label_ = smack_label; - - free(smack_label); - } else { - LoggerE("Failed to get smack label"); - return; - } - - ret = cynara_initialize(&cynara_, nullptr); - if (CYNARA_API_SUCCESS != ret) { - LoggerE("Failed to initialize Cynara"); - cynara_ = nullptr; - } - } - - ~AccessControlImpl() { - if (cynara_) { - auto ret = cynara_finish(cynara_); - if (CYNARA_API_SUCCESS != ret) { - LoggerE("Failed to finalize Cynara"); - } - cynara_ = nullptr; - } - } - - bool CheckAccess(const std::vector& privileges) { - if (cynara_) { - for (const auto& privilege : privileges) { - if (CYNARA_API_ACCESS_ALLOWED != cynara_simple_check(cynara_, // p_cynara - smack_label_.c_str(), // client - "", // client_session - uid_.c_str(), // user - privilege.c_str() // privilege - )) { - return false; - } - } - return true; - } else { - return false; - } - } - - private: - cynara* cynara_; - std::string uid_; - std::string smack_label_; -}; - -#else - -class AccessControlImpl { - public: - AccessControlImpl() { - LoggerD("Privilege access - deny all."); - } - - bool CheckAccess(const std::vector& privileges) { - return false; - } -}; - -#endif - -class AccessControl { - public: - static AccessControl& GetInstance() { - static AccessControl instance; - return instance; - } - - bool CheckAccess(const std::string& privilege) { - return CheckAccess(std::vector{privilege}); - } - - bool CheckAccess(const std::vector& privileges) { - return impl_.CheckAccess(privileges); - } - - private: - AccessControl() {} - ~AccessControl() {} - AccessControlImpl impl_; -}; - -} // namespace - -PlatformResult CheckAccess(const std::string& privilege) { - return CheckAccess(std::vector{privilege}); -} - -PlatformResult CheckAccess(const std::vector& privileges) { - LoggerD("Enter"); - if (AccessControl::GetInstance().CheckAccess(privileges)) { - return PlatformResult(ErrorCode::NO_ERROR); - } else { - for (const auto& privilege : privileges) { - LoggerD("Access to privilege: %s has been denied.", privilege.c_str()); - } - return PlatformResult(ErrorCode::SECURITY_ERR, "Permission denied"); - } -} - -} // namespace tools - } // namespace common diff --git a/src/common/extension.h b/src/common/extension.h index 1a3fe412..d8c75391 100755 --- a/src/common/extension.h +++ b/src/common/extension.h @@ -25,6 +25,9 @@ #include "common/platform_exception.h" #include "common/platform_result.h" +// TODO: this include should be moved to source file +// it's here, so we don't break other modules using it implicitly +#include "common/tools.h" #include "common/XW_Extension.h" #include "common/XW_Extension_EntryPoints.h" #include "common/XW_Extension_Permissions.h" @@ -138,42 +141,6 @@ class ParsedInstance : public Instance { std::map handler_map_; }; -namespace tools { -void ReportSuccess(picojson::object& out); -void ReportSuccess(const picojson::value& result, picojson::object& out); -void ReportError(picojson::object& out); -void ReportError(const PlatformException& ex, picojson::object& out); -void ReportError(const PlatformResult& error, picojson::object* out); - -common::PlatformResult CheckAccess(const std::string& privilege); -common::PlatformResult CheckAccess(const std::vector& privileges); - -#define CHECK_PRIVILEGE_ACCESS(privilege, out) \ -do { \ - auto r = common::tools::CheckAccess(privilege); \ - if (!r) { \ - common::tools::ReportError(r, out); \ - return; \ - } \ -} while (0) - -#define CHECK_BACKWARD_COMPABILITY_PRIVILEGE_ACCESS(current_priv, prev_priv, out) \ -do { \ - auto ret = common::tools::CheckAccess(current_priv); \ - auto ret2 = common::tools::CheckAccess(prev_priv); \ -\ - if (!ret && ret2) { \ - ret = ret2; \ - } \ -\ - if (!ret) { \ - common::tools::ReportError(ret, out); \ - return; \ - } \ -} while (0) - -} // namespace tools - } // namespace common #endif // COMMON_EXTENSION_H_ diff --git a/src/common/tools.cc b/src/common/tools.cc new file mode 100644 index 00000000..711bb8f1 --- /dev/null +++ b/src/common/tools.cc @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common/tools.h" + +#ifdef PRIVILEGE_USE_DB +#include +#elif PRIVILEGE_USE_ACE +#include +#elif PRIVILEGE_USE_CYNARA +#include + +#include +#include +#endif + +#include "common/logger.h" +#include "common/scope_exit.h" + +namespace common { +namespace tools { + +void ReportSuccess(picojson::object& out) { + LoggerD("Enter"); + out.insert(std::make_pair("status", picojson::value("success"))); +} + +void ReportSuccess(const picojson::value& result, picojson::object& out) { + LoggerD("Enter"); + out.insert(std::make_pair("status", picojson::value("success"))); + out.insert(std::make_pair("result", result)); +} + +void ReportError(picojson::object& out) { + LoggerD("Enter"); + out.insert(std::make_pair("status", picojson::value("error"))); +} + +void ReportError(const PlatformException& ex, picojson::object& out) { + LoggerD("Enter"); + out.insert(std::make_pair("status", picojson::value("error"))); + out.insert(std::make_pair("error", ex.ToJSON())); +} + +void ReportError(const PlatformResult& error, picojson::object* out) { + LoggerD("Enter"); + out->insert(std::make_pair("status", picojson::value("error"))); + out->insert(std::make_pair("error", error.ToJSON())); +} + +namespace { + +#ifdef PRIVILEGE_USE_DB + +class AccessControlImpl { + public: + AccessControlImpl() + : initialized_(false) { + LoggerD("Privilege access checked using DB."); + + const char* kWrtDBPath = "/opt/dbspace/.wrt.db"; + sqlite3* db = nullptr; + + int ret = sqlite3_open(kWrtDBPath, &db); + if (SQLITE_OK != ret) { + LoggerE("Failed to access WRT database"); + return; + } + + const char* kQuery = "select name from WidgetFeature where app_id = " + "(select app_id from WidgetInfo where tizen_appid = ?)" + " and rejected = 0"; + const std::string app_id = common::GetCurrentExtension()->GetRuntimeVariable("app_id", 64); + sqlite3_stmt* stmt = nullptr; + + ret = sqlite3_prepare_v2(db, kQuery, -1, &stmt, nullptr); + ret |= sqlite3_bind_text(stmt, 1, app_id.c_str(), -1, SQLITE_TRANSIENT); + + SCOPE_EXIT { + sqlite3_finalize(stmt); + sqlite3_close(db); + }; + + if (SQLITE_OK != ret) { + LoggerE("Failed to query WRT database"); + return; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + const char* privilege = reinterpret_cast(sqlite3_column_text(stmt, 0)); + SLoggerD("Granted: %s", privilege); + granted_privileges_.push_back(privilege); + } + + initialized_ = true; + } + + ~AccessControlImpl() {} + + bool CheckAccess(const std::vector& privileges) { + LoggerD("Enter"); + if (!initialized_) { + return false; + } + + for (const auto& privilege : privileges) { + if (std::find(granted_privileges_.begin(), granted_privileges_.end(), privilege) == granted_privileges_.end()) { + return false; + } + } + + return true; + } + + private: + bool initialized_; + std::vector granted_privileges_; +}; + +#elif PRIVILEGE_USE_ACE + +class AccessControlImpl { + public: + AccessControlImpl() { + LoggerD("Privilege access checked using ACE."); + } + + ~AccessControlImpl() { + } + + bool CheckAccess(const std::vector& privileges) { + LoggerD("Enter"); + int ret = 0; + for (size_t i = 0; i < privileges.size(); ++i) { + ret = privilege_checker_check_privilege(privileges[i].c_str()); + if (PRIVILEGE_CHECKER_ERR_NONE != ret) { + return false; + } + } + return true; + } +}; + +#elif PRIVILEGE_USE_CYNARA + +class AccessControlImpl { + public: + AccessControlImpl() : cynara_(nullptr) { + LoggerD("Privilege access checked using Cynara."); + + char* smack_label = nullptr; + int ret = smack_new_label_from_self(&smack_label); + + if (0 == ret && nullptr != smack_label) { + auto uid = getuid(); + + SLoggerD("uid: [%u]", uid); + SLoggerD("smack label: [%s]", smack_label); + + uid_ = std::to_string(uid); + smack_label_ = smack_label; + + free(smack_label); + } else { + LoggerE("Failed to get smack label"); + return; + } + + ret = cynara_initialize(&cynara_, nullptr); + if (CYNARA_API_SUCCESS != ret) { + LoggerE("Failed to initialize Cynara"); + cynara_ = nullptr; + } + } + + ~AccessControlImpl() { + if (cynara_) { + auto ret = cynara_finish(cynara_); + if (CYNARA_API_SUCCESS != ret) { + LoggerE("Failed to finalize Cynara"); + } + cynara_ = nullptr; + } + } + + bool CheckAccess(const std::vector& privileges) { + if (cynara_) { + for (const auto& privilege : privileges) { + if (CYNARA_API_ACCESS_ALLOWED != cynara_simple_check(cynara_, // p_cynara + smack_label_.c_str(), // client + "", // client_session + uid_.c_str(), // user + privilege.c_str() // privilege + )) { + return false; + } + } + return true; + } else { + return false; + } + } + + private: + cynara* cynara_; + std::string uid_; + std::string smack_label_; +}; + +#else + +class AccessControlImpl { + public: + AccessControlImpl() { + LoggerD("Privilege access - deny all."); + } + + bool CheckAccess(const std::vector& privileges) { + return false; + } +}; + +#endif + +class AccessControl { + public: + static AccessControl& GetInstance() { + static AccessControl instance; + return instance; + } + + bool CheckAccess(const std::string& privilege) { + return CheckAccess(std::vector{privilege}); + } + + bool CheckAccess(const std::vector& privileges) { + return impl_.CheckAccess(privileges); + } + + private: + AccessControl() {} + ~AccessControl() {} + AccessControlImpl impl_; +}; + +} // namespace + +PlatformResult CheckAccess(const std::string& privilege) { + return CheckAccess(std::vector{privilege}); +} + +PlatformResult CheckAccess(const std::vector& privileges) { + LoggerD("Enter"); + if (AccessControl::GetInstance().CheckAccess(privileges)) { + return PlatformResult(ErrorCode::NO_ERROR); + } else { + for (const auto& privilege : privileges) { + LoggerD("Access to privilege: %s has been denied.", privilege.c_str()); + } + return PlatformResult(ErrorCode::SECURITY_ERR, "Permission denied"); + } +} + +} // namespace tools +} // namespace common diff --git a/src/common/tools.h b/src/common/tools.h new file mode 100644 index 00000000..fecdea67 --- /dev/null +++ b/src/common/tools.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_TOOLS_H_ +#define COMMON_TOOLS_H_ + +#include +#include + +#include "common/picojson.h" +#include "common/platform_exception.h" +#include "common/platform_result.h" + +namespace common { +namespace tools { + +void ReportSuccess(picojson::object& out); +void ReportSuccess(const picojson::value& result, picojson::object& out); +void ReportError(picojson::object& out); +void ReportError(const PlatformException& ex, picojson::object& out); +void ReportError(const PlatformResult& error, picojson::object* out); + +common::PlatformResult CheckAccess(const std::string& privilege); +common::PlatformResult CheckAccess(const std::vector& privileges); + +#define CHECK_PRIVILEGE_ACCESS(privilege, out) \ +do { \ + auto r = common::tools::CheckAccess(privilege); \ + if (!r) { \ + common::tools::ReportError(r, out); \ + return; \ + } \ +} while (0) + +#define CHECK_BACKWARD_COMPABILITY_PRIVILEGE_ACCESS(current_priv, prev_priv, out) \ +do { \ + auto ret = common::tools::CheckAccess(current_priv); \ + auto ret2 = common::tools::CheckAccess(prev_priv); \ +\ + if (!ret && ret2) { \ + ret = ret2; \ + } \ +\ + if (!ret) { \ + common::tools::ReportError(ret, out); \ + return; \ + } \ +} while (0) + +} // namespace tools +} // namespace common + +#endif // COMMON_TOOLS_H_