Add trusted provider feature 75/187575/8
authorjusung son <jusung07.son@samsung.com>
Fri, 24 Aug 2018 09:08:31 +0000 (18:08 +0900)
committerjusung son <jusung07.son@samsung.com>
Mon, 3 Sep 2018 06:35:21 +0000 (06:35 +0000)
Change-Id: I69d8dc4a924aeedde2060a2f8c0954ebd6e56a51
Signed-off-by: jusung son <jusung07.son@samsung.com>
parser/complication_parser_plugin.cc
parser/complication_parser_plugin_internal.cc
watchface-common/watchface-util.cc
watchface-common/watchface-util.h
watchface-complication-provider/complication-provider-implementation.h
watchface-complication-provider/complication-provider.cc
watchface-complication/complication.cc
watchface-complication/db-manager.cc
watchface-complication/db-manager.h

index 442aefc..64381ab 100644 (file)
@@ -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);
     }
   }
 
index ca81868..5dd2a67 100644 (file)
@@ -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, \
index 95ba5c5..bb5c75f 100644 (file)
 #include <cynara-client.h>
 #include <cynara-creds-gdbus.h>
 #include <cynara-session.h>
+#include <pkgmgr-info.h>
 #include <system_info.h>
 
 #include <string>
+#include <map>
 
 #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<std::string, bool> 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
index 0bf2c0b..596e502 100644 (file)
@@ -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
 
index 1212b3f..7c73643 100644 (file)
@@ -74,6 +74,7 @@ class ComplicationProvider::Impl : ComplicationConnector::IEventListener {
   int supported_types_;
   std::map<std::string, SenderInfo*> sender_info_;
   std::list<std::string> required_privileges_;
+  bool trusted_;
 };
 
 }  // namespace watchface_complication
index aa9fcaf..2473b3a 100644 (file)
@@ -49,15 +49,19 @@ ComplicationProvider::Impl::Impl(ComplicationProvider* parent,
     throw;
   }
 
-  std::list<std::string> privlege_list;
+  std::list<std::string> 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");
index 6e8e31c..e37240c 100644 (file)
@@ -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;
     }
   }
 
index 9c48c37..2382f8a 100644 (file)
@@ -23,6 +23,7 @@
 #include <vconf.h>
 
 #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<Bundle> 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<Bundle> DBManager::GetDefaultData(const char* provider_id,
   sqlite3_bind_int(stmt, 2, support_type);
 
   if (sqlite3_step(stmt) == SQLITE_ROW) {
-    raw_data = reinterpret_cast<const 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) {
+      sqlite3_finalize(stmt);
+      CloseDB(db);
+      return nullptr;
+    }
+    raw_data = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
     default_data = std::unique_ptr<Bundle>(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<std::unique_ptr<DBManager::ProviderInfo>>
 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<std::unique_ptr<DBManager::ProviderInfo>> 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<ProviderInfo>(new ProviderInfo(provider_id, types)));
+        std::unique_ptr<ProviderInfo>(new ProviderInfo(provider_id, type)));
   }
 
   if (stmt)
@@ -265,9 +300,11 @@ std::list<std::string> DBManager::GetProviderList(int support_type) {
   sqlite3_stmt* stmt;
   sqlite3* db;
   std::list<std::string> 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<std::string> 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<std::string> DBManager::GetProviderList(int support_type) {
 }
 
 std::list<std::string> 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<std::string> 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
index c513f6d..b19d446 100644 (file)
@@ -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<Bundle> 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<std::string> GetProviderListWithAppId(const char* provider_id);
+  static int GetTrustedInfo(std::string& provider_id, bool* trusted);
 
  private:
   DBManager();