From af04ca049e3aa62d1cd4d59814222c2854a6e30d Mon Sep 17 00:00:00 2001 From: jusung son Date: Fri, 24 Aug 2018 18:08:31 +0900 Subject: [PATCH] Add trusted provider feature Change-Id: I69d8dc4a924aeedde2060a2f8c0954ebd6e56a51 Signed-off-by: jusung son --- parser/complication_parser_plugin.cc | 24 +++- parser/complication_parser_plugin_internal.cc | 1 + watchface-common/watchface-util.cc | 52 ++++++++ watchface-common/watchface-util.h | 2 + .../complication-provider-implementation.h | 1 + .../complication-provider.cc | 16 ++- watchface-complication/complication.cc | 14 +- watchface-complication/db-manager.cc | 142 +++++++++++++++++---- watchface-complication/db-manager.h | 11 +- 9 files changed, 215 insertions(+), 48 deletions(-) diff --git a/parser/complication_parser_plugin.cc b/parser/complication_parser_plugin.cc index 442aefc..64381ab 100644 --- a/parser/complication_parser_plugin.cc +++ b/parser/complication_parser_plugin.cc @@ -304,7 +304,7 @@ static int _get_time_value(const char* time_type, const char* time_val, } static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid, - const char* appid, const char* providerid, int period) { + const char* appid, const char* providerid, int period, bool trusted) { int ret; int idx; int support_type = 0; @@ -324,9 +324,9 @@ static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid, static const char query[] = "INSERT INTO complication_provider ( " - "pkgid, appid, provider_id, period, " + "pkgid, appid, provider_id, trusted, period, " "support_type, default_data) " - "VALUES (?, ?, ?, ?, ?, ?)"; + "VALUES (?, ?, ?, ?, ?, ?, ?)"; if (node->children == NULL) return -1; @@ -404,6 +404,7 @@ static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid, sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, idx++, appid, -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT); + sqlite3_bind_int(stmt, idx++, trusted ? 1 : 0); sqlite3_bind_int(stmt, idx++, period); sqlite3_bind_int(stmt, idx++, support_type); sqlite3_bind_text(stmt, idx, (char*)raw, -1, SQLITE_TRANSIENT); @@ -620,7 +621,7 @@ out: } static int _parse_complication(xmlNode* node, sqlite3* db, const char* pkgid, - const char* appid, const char* providerid, const char* setup_appid) { + const char* appid, const char* providerid, const char* setup_appid, bool trusted) { int period = -1; xmlNode* tmp = NULL; @@ -674,7 +675,7 @@ static int _parse_complication(xmlNode* node, sqlite3* db, const char* pkgid, } if (_parse_support_type(support_type_node, db, pkgid, - appid, providerid, period)) { + appid, providerid, period, trusted)) { LOGE("parse support type fail"); return -1; } @@ -687,6 +688,8 @@ static int _parse_service_application(xmlNode* node, const char* pkgid) { char* appid; char* providerid; char* setup_appid; + char* trusted_str; + bool trusted; xmlNode* tmp; sqlite3* db; @@ -716,9 +719,14 @@ static int _parse_service_application(xmlNode* node, const char* pkgid) { } setup_appid = _get_attribute(tmp, "setup-appid"); + trusted_str = _get_attribute(tmp, "trusted"); + if (trusted_str != NULL && strcasecmp(trusted_str, "true") == 0) + trusted = true; + else + trusted = false; if (_parse_complication(tmp, db, pkgid, appid, - providerid, setup_appid)) { + providerid, setup_appid, trusted)) { LOGE("parse complication error"); sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); @@ -727,6 +735,8 @@ static int _parse_service_application(xmlNode* node, const char* pkgid) { if (setup_appid) free(setup_appid); + if (trusted_str) + free(trusted_str); goto out; } @@ -735,6 +745,8 @@ static int _parse_service_application(xmlNode* node, const char* pkgid) { if (setup_appid) free(setup_appid); + if (trusted_str) + free(trusted_str); } } diff --git a/parser/complication_parser_plugin_internal.cc b/parser/complication_parser_plugin_internal.cc index ca81868..5dd2a67 100644 --- a/parser/complication_parser_plugin_internal.cc +++ b/parser/complication_parser_plugin_internal.cc @@ -39,6 +39,7 @@ CREATE TABLE IF NOT EXISTS complication_provider ( \ pkgid TEXT NOT NULL, \ appid TEXT NOT NULL, \ provider_id TEXT NOT NULL, \ + trusted INTEGER DEFAULT 0, \ period INTEGER DEFAULT -1, \ support_type INTEGER DEFAULT 0, \ default_data TEXT NOT NULL, \ diff --git a/watchface-common/watchface-util.cc b/watchface-common/watchface-util.cc index 95ba5c5..bb5c75f 100644 --- a/watchface-common/watchface-util.cc +++ b/watchface-common/watchface-util.cc @@ -23,9 +23,11 @@ #include #include #include +#include #include #include +#include #include "watchface-common/watchface-util.h" #include "watchface-common/include/watchface-common.h" @@ -36,6 +38,7 @@ #define MAX_PACKAGE_STR_SIZE 512 #define SMACK_LABEL_LEN 255 +#define MAX_CACHE_COUNT 10 #define LOG_TAG "WATCHFACE_COMPLICATION" @@ -242,5 +245,54 @@ out: } } + bool CheckCertificate(const std::string& provider_app_id) { + static std::map cache; + bool ret; + + auto cp = cache.find(provider_app_id); + if (cp != cache.end()) + return cp->second; + + pkgmgrinfo_cert_compare_result_type_e res; + char* app_id = GetAppID(); + int cert_ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, + provider_app_id.c_str(), getuid(), &res); + if (cert_ret < 0) { + LOGE("CheckCertificate() Failed %d", cert_ret); + return false; + } + if (res == PMINFO_CERT_COMPARE_MATCH) { + ret = true; + } else { + ret = false; + LOGI("CheckCertificate() Failed : CERTIFICATE_NOT_MATCH"); + } + + if (cache.size() >= MAX_CACHE_COUNT) + cache.clear(); + + cache[provider_app_id] = ret; + + return ret; + } + + char* GetAppID() { + int pid = getpid(); + int ret = 0; + char buffer[MAX_PACKAGE_STR_SIZE] = {0, }; + static char* app_id = NULL; + + if (app_id == NULL) { + ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer)); + if (ret != AUL_R_OK) { + LOGE("Failed to get the application ID: %d", ret); + return NULL; + } + + app_id = strdup(buffer); + } + + return app_id; + } } // namespace util } // namespace watchface_complication diff --git a/watchface-common/watchface-util.h b/watchface-common/watchface-util.h index 0bf2c0b..596e502 100644 --- a/watchface-common/watchface-util.h +++ b/watchface-common/watchface-util.h @@ -44,6 +44,8 @@ namespace util { const std::string& sender_name, GDBusConnection* conn); bool CheckComplicationType(int type); + bool CheckCertificate(const std::string& provider_app_id); + char* GetAppID(); } // namespace util } // namespace watchface_complication diff --git a/watchface-complication-provider/complication-provider-implementation.h b/watchface-complication-provider/complication-provider-implementation.h index 1212b3f..7c73643 100644 --- a/watchface-complication-provider/complication-provider-implementation.h +++ b/watchface-complication-provider/complication-provider-implementation.h @@ -74,6 +74,7 @@ class ComplicationProvider::Impl : ComplicationConnector::IEventListener { int supported_types_; std::map sender_info_; std::list required_privileges_; + bool trusted_; }; } // namespace watchface_complication diff --git a/watchface-complication-provider/complication-provider.cc b/watchface-complication-provider/complication-provider.cc index aa9fcaf..2473b3a 100644 --- a/watchface-complication-provider/complication-provider.cc +++ b/watchface-complication-provider/complication-provider.cc @@ -49,15 +49,19 @@ ComplicationProvider::Impl::Impl(ComplicationProvider* parent, throw; } - std::list privlege_list; + std::list privilege_list; required_privileges_.push_back(std::string(PRIVILEGE_DATASHARING)); ret = DBManager::GetSupportTypes(provider_id_, &supported_types_); if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) THROW(ret); - privlege_list = DBManager::GetRequiredPrivilegeList(provider_id_); - for (auto& i : privlege_list) { + ret = DBManager::GetTrustedInfo(provider_id_, &trusted_); + if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) + THROW(ret); + + privilege_list = DBManager::GetRequiredPrivilegeList(provider_id_); + for (auto& i : privilege_list) { required_privileges_.push_back(i); LOGI("required_privileges %s", i.c_str()); } @@ -172,6 +176,12 @@ void ComplicationProvider::Impl::OnSignal(GDBusConnection* connection, } catch (...) { } try { + if (trusted_) { + if (util::CheckCertificate(sender_app_id) == false) { + LOGE("Permission denied"); + return; + } + } si = new SenderInfo(sender_name, sender_app_id, watcher_id); } catch (const std::bad_alloc &ba) { LOGE("SenderInfo::Exception bad_alloc"); diff --git a/watchface-complication/complication.cc b/watchface-complication/complication.cc index 6e8e31c..e37240c 100644 --- a/watchface-complication/complication.cc +++ b/watchface-complication/complication.cc @@ -1028,16 +1028,10 @@ int Complication::Impl::AddCandidates(int types) { = DBManager::GetProviderListWithTypes(types); for (auto& info : provider_list) { - std::string provider_id = info.get()->GetProviderId(); - int provider_types = info.get()->GetTypes(); - for (int type = ShortText; type <= Image; type *= 2) { - if ((type & types & provider_types) == 0) - continue; - int ret = AddCandidate(provider_id, type); - if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) { - candidates_list_.clear(); - return ret; - } + int ret = AddCandidate(info.get()->GetProviderId(), info.get()->GetType()); + if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) { + candidates_list_.clear(); + return ret; } } diff --git a/watchface-complication/db-manager.cc b/watchface-complication/db-manager.cc index 9c48c37..2382f8a 100644 --- a/watchface-complication/db-manager.cc +++ b/watchface-complication/db-manager.cc @@ -23,6 +23,7 @@ #include #include "watchface-complication/db-manager.h" +#include "watchface-common/watchface-util.h" #ifdef LOG_TAG #undef LOG_TAG @@ -73,9 +74,11 @@ std::unique_ptr DBManager::GetDefaultData(const char* provider_id, sqlite3_stmt* stmt; sqlite3* db; int ret; + int trusted; + std::string provider_app_id; static const char query[] = - "SELECT default_data FROM complication_provider " + "SELECT trusted, appid, default_data FROM complication_provider " "WHERE provider_id=? AND support_type=?"; db = OpenDB(); @@ -96,7 +99,15 @@ std::unique_ptr DBManager::GetDefaultData(const char* provider_id, sqlite3_bind_int(stmt, 2, support_type); if (sqlite3_step(stmt) == SQLITE_ROW) { - raw_data = reinterpret_cast(sqlite3_column_text(stmt, 0)); + trusted = sqlite3_column_int(stmt, 0); + provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1)); + if (trusted && + util::CheckCertificate(provider_app_id) == false) { + sqlite3_finalize(stmt); + CloseDB(db); + return nullptr; + } + raw_data = reinterpret_cast(sqlite3_column_text(stmt, 2)); default_data = std::unique_ptr(new Bundle(std::string(raw_data))); } @@ -146,13 +157,14 @@ int DBManager::GetProviderPeriod(std::string& provider_id, int* period) { bool DBManager::IsProviderExist(std::string& provider_id, int support_type) { int ret; - std::string appid; sqlite3_stmt* stmt = NULL; sqlite3* db; bool is_exist = false; + int trusted; + std::string provider_app_id; static const char query[] = - "SELECT DISTINCT appid FROM complication_provider " + "SELECT trusted, appid FROM complication_provider " "WHERE provider_id=? AND support_type=?"; db = OpenDB(); @@ -172,8 +184,15 @@ bool DBManager::IsProviderExist(std::string& provider_id, sqlite3_bind_text(stmt, 1, provider_id.c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 2, support_type); - if (sqlite3_step(stmt) == SQLITE_ROW) - is_exist = true; + if (sqlite3_step(stmt) == SQLITE_ROW) { + trusted = sqlite3_column_int(stmt, 0); + provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1)); + if (trusted && + util::CheckCertificate(provider_app_id) == false) + is_exist = false; + else + is_exist = true; + } sqlite3_finalize(stmt); CloseDB(db); @@ -183,12 +202,13 @@ bool DBManager::IsProviderExist(std::string& provider_id, std::string DBManager::GetProviderAppId(const char* provider_id) { int ret; - std::string appid; sqlite3_stmt* stmt = NULL; sqlite3* db; + int trusted; + std::string provider_app_id; static const char query[] = - "SELECT DISTINCT appid FROM complication_provider " + "SELECT trusted, appid FROM complication_provider " "WHERE provider_id=?"; db = OpenDB(); @@ -207,27 +227,37 @@ std::string DBManager::GetProviderAppId(const char* provider_id) { sqlite3_bind_text(stmt, 1, provider_id, -1, SQLITE_TRANSIENT); - if (sqlite3_step(stmt) == SQLITE_ROW) - appid = std::string((char*)sqlite3_column_text(stmt, 0)); + if (sqlite3_step(stmt) == SQLITE_ROW) { + trusted = sqlite3_column_int(stmt, 0); + provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1)); + if (trusted && + util::CheckCertificate(provider_app_id) == false) { + sqlite3_finalize(stmt); + CloseDB(db); + return std::string(); + } + } sqlite3_finalize(stmt); CloseDB(db); - return appid; + return provider_app_id; } std::list> DBManager::GetProviderListWithTypes(int supported_types) { int ret; char* provider_id = NULL; - int types = 0; + int type = 0; sqlite3_stmt* stmt; sqlite3* db = NULL; std::list> provider_list; + int trusted; + std::string provider_app_id; static const char query[] = - "SELECT provider_id, SUM(support_type) FROM complication_provider " - "WHERE (support_type & ?) > 0 GROUP BY provider_id"; + "SELECT trusted, appid, provider_id, support_type FROM complication_provider " + "WHERE (support_type & ?) > 0"; db = OpenDB(); if (db == NULL) { @@ -245,10 +275,15 @@ DBManager::GetProviderListWithTypes(int supported_types) { sqlite3_bind_int(stmt, 1, supported_types); while (sqlite3_step(stmt) == SQLITE_ROW) { - provider_id = (char*)sqlite3_column_text(stmt, 0); - types = sqlite3_column_int(stmt, 1); + trusted = sqlite3_column_int(stmt, 0); + provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1)); + if (trusted && util::CheckCertificate(provider_app_id) == false) + continue; + + provider_id = (char*)sqlite3_column_text(stmt, 2); + type = sqlite3_column_int(stmt, 3); provider_list.emplace_back( - std::unique_ptr(new ProviderInfo(provider_id, types))); + std::unique_ptr(new ProviderInfo(provider_id, type))); } if (stmt) @@ -265,9 +300,11 @@ std::list DBManager::GetProviderList(int support_type) { sqlite3_stmt* stmt; sqlite3* db; std::list provider_list; + int trusted; + std::string provider_app_id; static const char query[] = - "SELECT DISTINCT provider_id FROM complication_provider " + "SELECT trusted, appid, provider_id FROM complication_provider " "WHERE support_type=?"; db = OpenDB(); @@ -287,7 +324,12 @@ std::list DBManager::GetProviderList(int support_type) { sqlite3_bind_int(stmt, 1, support_type); while (sqlite3_step(stmt) == SQLITE_ROW) { - provider_id = (char*)sqlite3_column_text(stmt, 0); + trusted = sqlite3_column_int(stmt, 0); + provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1)); + if (trusted && util::CheckCertificate(provider_app_id) == false) + continue; + + provider_id = (char*)sqlite3_column_text(stmt, 2); provider_list.push_back(std::string(provider_id)); } @@ -298,7 +340,7 @@ std::list DBManager::GetProviderList(int support_type) { } std::list DBManager::GetProviderListWithAppId( - const char* provider_id) { + const char* provider_app_id) { int ret; char* provider = NULL; sqlite3_stmt* stmt; @@ -323,7 +365,7 @@ std::list DBManager::GetProviderListWithAppId( return provider_list; } - sqlite3_bind_text(stmt, 1, provider_id, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 1, provider_app_id, -1, SQLITE_TRANSIENT); while (sqlite3_step(stmt) == SQLITE_ROW) { provider = (char*)sqlite3_column_text(stmt, 0); @@ -341,9 +383,11 @@ int DBManager::GetSupportTypes(std::string& provider_id, int* types) { int supported_types = 0; sqlite3_stmt* stmt; sqlite3* db; + int trusted; + std::string provider_app_id; static const char query[] = - "SELECT SUM(support_type) FROM complication_provider " + "SELECT trusted, appid, SUM(support_type) FROM complication_provider " "WHERE provider_id = ?"; db = OpenDB(); @@ -362,8 +406,14 @@ int DBManager::GetSupportTypes(std::string& provider_id, int* types) { sqlite3_bind_text(stmt, 1, provider_id.c_str(), -1, SQLITE_TRANSIENT); - while (sqlite3_step(stmt) == SQLITE_ROW) - supported_types = sqlite3_column_int(stmt, 0); + if (sqlite3_step(stmt) == SQLITE_ROW) { + trusted = sqlite3_column_int(stmt, 0); + provider_app_id = std::string((char*)sqlite3_column_text(stmt, 1)); + if (trusted && util::CheckCertificate(provider_app_id) == false) + supported_types = 0; + else + supported_types = sqlite3_column_int(stmt, 2); + } sqlite3_finalize(stmt); CloseDB(db); @@ -615,4 +665,48 @@ const char* DBManager::GetParserDataPath() { return path; } +int DBManager::GetTrustedInfo(std::string& provider_id, bool* trusted) { + int ret = WATCHFACE_COMPLICATION_ERROR_NONE; + int trusted_info; + sqlite3_stmt* stmt; + sqlite3* db; + + static const char query[] = + "SELECT trusted FROM complication_provider " + "WHERE provider_id = ?"; + + db = OpenDB(); + if (db == NULL) { + LOGE("parser db not exist"); + return WATCHFACE_COMPLICATION_ERROR_DB; + } + + ret = sqlite3_prepare_v2(db, query, strlen(query), + &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + CloseDB(db); + return WATCHFACE_COMPLICATION_ERROR_DB; + } + + sqlite3_bind_text(stmt, 1, provider_id.c_str(), -1, SQLITE_TRANSIENT); + + if (sqlite3_step(stmt) == SQLITE_ROW) { + trusted_info = sqlite3_column_int(stmt, 0); + if (trusted_info == 0) + *trusted = false; + else if (trusted_info == 1) + *trusted = true; + else + ret = WATCHFACE_COMPLICATION_ERROR_DB; + } else { + ret = WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER; + } + + sqlite3_finalize(stmt); + CloseDB(db); + + return ret; +} + } // namespace watchface_complication diff --git a/watchface-complication/db-manager.h b/watchface-complication/db-manager.h index c513f6d..b19d446 100644 --- a/watchface-complication/db-manager.h +++ b/watchface-complication/db-manager.h @@ -33,16 +33,16 @@ class EXPORT_API DBManager { public: class ProviderInfo { std::string provider_id_; - int types_; + int type_; public: - ProviderInfo(std::string provider_id, int types) - : provider_id_(provider_id), types_(types) { + ProviderInfo(std::string provider_id, int type) + : provider_id_(provider_id), type_(type) { } std::string& GetProviderId() { return provider_id_; } - int GetTypes() { - return types_; + int GetType() { + return type_; } }; static std::unique_ptr GetDefaultData(const char* provider_id, @@ -60,6 +60,7 @@ class EXPORT_API DBManager { static std::string GetSetupAppId(const char* provider_id); static bool IsProviderExist(std::string& provider_id, int support_type); static std::list GetProviderListWithAppId(const char* provider_id); + static int GetTrustedInfo(std::string& provider_id, bool* trusted); private: DBManager(); -- 2.7.4