Add blacklist management feature 43/57543/18 accepted/tizen/mobile/20160201.042845 accepted/tizen/tv/20160201.042919 accepted/tizen/wearable/20160201.042933 submit/tizen/20160201.013807
authorSangyoon Jang <s89.jang@samsung.com>
Thu, 21 Jan 2016 04:50:02 +0000 (13:50 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Fri, 29 Jan 2016 05:58:59 +0000 (14:58 +0900)
Change-Id: I48543f21262825bd70a2508195ff4d6191233341
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
CMakeLists.txt
blacklist.sql [new file with mode: 0644]
include/pkgmgr-server.h
org.tizen.pkgmgr.conf.in
packaging/pkgmgr-server.spec
src/db.c [new file with mode: 0644]
src/pkgmgr-server.c
src/request.c

index 7accf56..0bc54d6 100644 (file)
@@ -11,13 +11,15 @@ SET(EXEC_PREFIX "\${prefix}")
 SET(LIBDIR ${LIB_INSTALL_DIR})
 SET(INCLUDEDIR "\${prefix}/include")
 
+ADD_DEFINITIONS(-DDB_DIR="${DB_DIR}")
+
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -g -Wall")
 
 INCLUDE_DIRECTORIES(include)
 INCLUDE(FindPkgConfig)
 
 SET(PKGMGR_SERVER "pkgmgr-server")
-SET(SRCS src/pkgmgr-server.c src/request.c src/pm-queue.c)
+SET(SRCS src/pkgmgr-server.c src/request.c src/pm-queue.c src/db.c)
 
 pkg_check_modules(SERVER_DEPS REQUIRED
                gio-2.0
@@ -26,6 +28,7 @@ pkg_check_modules(SERVER_DEPS REQUIRED
                pkgmgr-info
                libtzplatform-config
                drm-service-core-tizen
+               sqlite3
                pkgmgr)
 FOREACH(SERVER_FLAGS ${SERVER_DEPS_CFLAGS})
        SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SERVER_FLAGS}")
diff --git a/blacklist.sql b/blacklist.sql
new file mode 100644 (file)
index 0000000..0db3ddb
--- /dev/null
@@ -0,0 +1,8 @@
+PRAGMA user_version = 30; /* Tizen 3.0 */
+PRAGMA journal_mode = WAL;
+
+CREATE TABLE blacklist (
+  uid   INTEGER NOT NULL,
+  pkgid TEXT NOT NULL,
+  UNIQUE (uid, pkgid)
+);
index 41f0ee8..3b0c874 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _PKGMGR_SERVER_H_
 #define _PKGMGR_SERVER_H_
 
+#include <sys/types.h>
 #include <glib.h>
 
 #ifdef LOG_TAG
@@ -60,6 +61,9 @@ enum request_type {
        PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
        PKGMGR_REQUEST_TYPE_REGISTER_LICENSE,
        PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE,
+       PKGMGR_REQUEST_TYPE_ADD_BLACKLIST,
+       PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST,
+       PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST,
 };
 
 typedef struct {
@@ -85,5 +89,8 @@ gboolean queue_job(void *data);
 int __return_value_to_caller(const char *req_key, GVariant *result);
 int __init_request_handler(void);
 void __fini_request_handler(void);
+int __add_blacklist(uid_t uid, const char *pkgid);
+int __remove_blacklist(uid_t uid, const char *pkgid);
+int __check_blacklist(uid_t uid, const char *pkgid, int *result);
 
 #endif/*  _PKGMGR_SERVER_H_ */
index 20519d0..c237b44 100644 (file)
@@ -21,5 +21,8 @@
                <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="generate_license_request" privilege="http://tizen.org/privilege/packagemanager.admin"/>
                <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="register_license" privilege="http://tizen.org/privilege/packagemanager.admin"/>
                <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="decrypt_package" privilege="http://tizen.org/privilege/packagemanager.admin"/>
+               <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="add_blacklist" privilege="http://tizen.org/privilege/packagemanager.admin"/>
+               <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="remove_blacklist" privilege="http://tizen.org/privilege/packagemanager.admin"/>
+               <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="check_blacklist" privilege="http://tizen.org/privilege/packagemanager.admin"/>
         </policy>
 </busconfig>
index a881917..80cd390 100644 (file)
@@ -23,6 +23,7 @@ BuildRequires:  pkgconfig(db-util)
 BuildRequires:  pkgconfig(libsmack)
 BuildRequires:  pkgconfig(pkgmgr)
 BuildRequires:  pkgconfig(drm-service-core-tizen)
+BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgmgr-info-parser-devel
 BuildRequires:  pkgmgr-info-parser
 BuildRequires:  fdupes
@@ -34,8 +35,12 @@ Packager Manager server package for packaging
 %setup -q
 cp %{SOURCE1001} .
 
+%define db_dir %{_localstatedir}/lib/package-manager
+
 %build
-%cmake .
+sqlite3 blacklist.db < ./blacklist.sql
+
+%cmake . -DDB_DIR=%{db_dir}
 
 %__make %{?_smp_mflags}
 
@@ -46,6 +51,9 @@ mkdir -p %{buildroot}/usr/share/license
 cp LICENSE %{buildroot}/usr/share/license/%{name}
 mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server
 
+mkdir -p %{buildroot}%{db_dir}
+install -m 0600 blacklist.db %{buildroot}%{db_dir}
+
 %fdupes %{buildroot}
 
 %post
@@ -58,5 +66,6 @@ mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server
 %config %{_sysconfdir}/dbus-1/system.d/org.tizen.pkgmgr.conf
 %{_bindir}/pkgmgr-server
 %{_sysconfdir}/package-manager/server
+%config(noreplace) %{db_dir}/blacklist.db
 %exclude %{_sysconfdir}/package-manager/server/queue_status
 /usr/share/license/%{name}
diff --git a/src/db.c b/src/db.c
new file mode 100644 (file)
index 0000000..c57f995
--- /dev/null
+++ b/src/db.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2000 - 2016 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 <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <sqlite3.h>
+
+#include <package-manager.h>
+#include <package-manager-debug.h>
+
+#include "pkgmgr-server.h"
+
+#ifndef DB_DIR
+#define DB_DIR "/var/lib/package-manager"
+#endif
+
+static const char *_get_db_path(void)
+{
+       return DB_DIR"/blacklist.db";
+}
+
+static sqlite3 *_open_db(void)
+{
+       int ret;
+       const char *path;
+       sqlite3 *db;
+
+       path = _get_db_path();
+       if (path == NULL) {
+               ERR("get db path error");
+               return NULL;
+       }
+
+       ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL);
+       if (ret != SQLITE_OK) {
+               ERR("open db error: %d", ret);
+               return NULL;
+       }
+
+       return db;
+}
+
+static int __add_blacklist_info(sqlite3 *db, uid_t uid, const char *pkgid)
+{
+       static const char query[] =
+               "INSERT INTO blacklist (uid, pkgid) VALUES(?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ERR("prepare error: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       sqlite3_bind_int(stmt, 1, uid);
+       sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC);
+
+       ret = sqlite3_step(stmt);
+       sqlite3_finalize(stmt);
+       if (ret != SQLITE_DONE) {
+               ERR("step error: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
+
+int __add_blacklist(uid_t uid, const char *pkgid)
+{
+       int ret;
+       sqlite3 *db;
+
+       db = _open_db();
+       if (db == NULL)
+               return PKGMGR_R_ERROR;
+
+       ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
+       if (ret != SQLITE_OK) {
+               sqlite3_close_v2(db);
+               ERR("transaction failed");
+               return PKGMGR_R_ERROR;
+       }
+
+       if (__add_blacklist_info(db, uid, pkgid)) {
+               sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
+               sqlite3_close_v2(db);
+               return PKGMGR_R_ERROR;
+       }
+
+       ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
+       if (ret != SQLITE_OK) {
+               ERR("commit error: %s", sqlite3_errmsg(db));
+               sqlite3_close_v2(db);
+               return PKGMGR_R_ERROR;
+       }
+
+       sqlite3_close_v2(db);
+
+       return PKGMGR_R_OK;
+}
+
+static int __remove_blacklist_info(sqlite3 *db, uid_t uid, const char *pkgid)
+{
+       static const char query[] =
+               "DELETE FROM blacklist WHERE uid=? AND pkgid=?";
+       int ret;
+       sqlite3_stmt *stmt;
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ERR("prepare error: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       sqlite3_bind_int(stmt, 1, uid);
+       sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC);
+
+       ret = sqlite3_step(stmt);
+       sqlite3_finalize(stmt);
+       if (ret != SQLITE_DONE) {
+               ERR("step error: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
+
+int __remove_blacklist(uid_t uid, const char *pkgid)
+{
+       int ret;
+       sqlite3 *db;
+
+       db = _open_db();
+       if (db == NULL)
+               return PKGMGR_R_ERROR;
+
+       ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
+       if (ret != SQLITE_OK) {
+               sqlite3_close_v2(db);
+               ERR("transaction failed");
+               return PKGMGR_R_ERROR;
+       }
+
+       if (__remove_blacklist_info(db, uid, pkgid)) {
+               sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
+               sqlite3_close_v2(db);
+               return PKGMGR_R_ERROR;
+       }
+
+       ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
+       if (ret != SQLITE_OK) {
+               ERR("commit error: %s", sqlite3_errmsg(db));
+               sqlite3_close_v2(db);
+               return PKGMGR_R_ERROR;
+       }
+
+       sqlite3_close_v2(db);
+
+       return PKGMGR_R_OK;
+}
+
+int __check_blacklist(uid_t uid, const char *pkgid, int *result)
+{
+       static const char query[] =
+               "SELECT * FROM blacklist WHERE uid=? AND pkgid=?";
+       int ret;
+       sqlite3 *db;
+       sqlite3_stmt *stmt;
+
+       db = _open_db();
+       if (db == NULL) {
+               *result = 0;
+               return PKGMGR_R_ERROR;
+       }
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ERR("prepare error: %s", sqlite3_errmsg(db));
+               *result = 0;
+               sqlite3_close_v2(db);
+               return PKGMGR_R_ERROR;
+       }
+
+       sqlite3_bind_int(stmt, 1, uid);
+       sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC);
+
+       ret = sqlite3_step(stmt);
+       sqlite3_finalize(stmt);
+       if (ret != SQLITE_ROW) {
+               if (ret != SQLITE_DONE)
+                       ERR("step error: %s", sqlite3_errmsg(db));
+               *result = 0;
+               sqlite3_close_v2(db);
+               return ret == SQLITE_DONE ? PKGMGR_R_OK : PKGMGR_R_ERROR;
+       }
+
+       *result = 1;
+       sqlite3_close_v2(db);
+
+       return PKGMGR_R_OK;
+}
index c49af50..1cf0ef5 100644 (file)
@@ -1000,6 +1000,43 @@ static int __process_decrypt_package(pm_dbus_msg *item)
        return 0;
 }
 
+static int __process_add_blacklist(pm_dbus_msg *item)
+{
+       int ret;
+
+       ret = __add_blacklist(item->uid, item->pkgid);
+
+       __return_value_to_caller(item->req_id,
+                       g_variant_new("(i)", ret));
+
+       return ret;
+}
+
+static int __process_remove_blacklist(pm_dbus_msg *item)
+{
+       int ret;
+
+       ret = __remove_blacklist(item->uid, item->pkgid);
+
+       __return_value_to_caller(item->req_id,
+                       g_variant_new("(i)", ret));
+
+       return ret;
+}
+
+static int __process_check_blacklist(pm_dbus_msg *item)
+{
+       int ret;
+       int result = 0;
+
+       ret = __check_blacklist(item->uid, item->pkgid, &result);
+
+       __return_value_to_caller(item->req_id,
+                       g_variant_new("(ii)", result, ret));
+
+       return ret;
+}
+
 gboolean queue_job(void *data)
 {
        pm_dbus_msg *item = NULL;
@@ -1089,6 +1126,15 @@ gboolean queue_job(void *data)
        case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
                ret = __process_decrypt_package(item);
                break;
+       case PKGMGR_REQUEST_TYPE_ADD_BLACKLIST:
+               ret = __process_add_blacklist(item);
+               break;
+       case PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST:
+               ret = __process_remove_blacklist(item);
+               break;
+       case PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST:
+               ret = __process_check_blacklist(item);
+               break;
        default:
                ret = -1;
                break;
index ca27a2e..ba79911 100644 (file)
@@ -115,6 +115,22 @@ static const char instropection_xml[] =
        "      <arg type='s' name='decrypted_file_path' direction='in'/>"
        "      <arg type='i' name='ret' direction='out'/>"
        "    </method>"
+       "    <method name='add_blacklist'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='remove_blacklist'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='check_blacklist'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='result' direction='out'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
        "  </interface>"
        "</node>";
 static GDBusNodeInfo *instropection_data;
@@ -676,6 +692,114 @@ static int __handle_request_decrypt_package(uid_t uid,
        return 0;
 }
 
+static int __handle_request_add_blacklist(uid_t uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *reqkey;
+       char *pkgid = NULL;
+
+       g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("blacklist");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       if (_pm_queue_push(target_uid, reqkey,
+                               PKGMGR_REQUEST_TYPE_ADD_BLACKLIST,
+                               "pkg", pkgid, "")) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               return -1;
+       }
+
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
+static int __handle_request_remove_blacklist(uid_t uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *reqkey;
+       char *pkgid = NULL;
+
+       g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("blacklist");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       if (_pm_queue_push(target_uid, reqkey,
+                               PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST,
+                               "pkg", pkgid, "")) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               return -1;
+       }
+
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
+static int __handle_request_check_blacklist(uid_t uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *reqkey;
+       char *pkgid = NULL;
+
+       g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("blacklist");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       if (_pm_queue_push(target_uid, reqkey,
+                               PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST,
+                               "pkg", pkgid, "")) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               return -1;
+       }
+
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
 {
        GError *err = NULL;
@@ -747,6 +871,15 @@ static void __handle_method_call(GDBusConnection *connection,
        else if (g_strcmp0(method_name, "decrypt_package") == 0)
                ret = __handle_request_decrypt_package(uid, invocation,
                                parameters);
+       else if (g_strcmp0(method_name, "add_blacklist") == 0)
+               ret = __handle_request_add_blacklist(uid, invocation,
+                               parameters);
+       else if (g_strcmp0(method_name, "remove_blacklist") == 0)
+               ret = __handle_request_remove_blacklist(uid, invocation,
+                               parameters);
+       else if (g_strcmp0(method_name, "check_blacklist") == 0)
+               ret = __handle_request_check_blacklist(uid, invocation,
+                               parameters);
        else
                ret = -1;