Move privilege checker to gesture-server 92/242092/6 accepted/tizen/unified/20200829.113355 submit/tizen/20200827.080411
authorsooyeon.kim <sooyeon.kim@samsung.com>
Mon, 24 Aug 2020 06:43:22 +0000 (15:43 +0900)
committerSungwook Park <sungwook79.park@samsung.com>
Thu, 27 Aug 2020 07:42:12 +0000 (16:42 +0900)
Change-Id: I013b3509f39f47ca776262a3eeb0e178f406ee6f
Signed-off-by: sooyeon.kim <sooyeon.kim@samsung.com>
client/gesture.c
client/gesture_client_dbus.c
client/gesture_client_dbus.h
client/gesture_main.h
engine/gesture_engine_dbus.c
manager/gestured_client_manager.cpp
manager/gestured_client_manager.h
server/gestured_dbus.c

index df6ae46..17065d1 100644 (file)
@@ -51,26 +51,35 @@ static int _cynara_initialize()
        return ret;
 }
 
-static int _check_privilege(const char *uid, const char *privilege)
+static char * _get_smack_label()
 {
-       int ret;
        FILE *fp = NULL;
        char label_path[1024] = "/proc/self/attr/current";
-       char smack_label[1024] = {'\0',};
-
-       if (!p_cynara) {
-               return -1;
-       }
+       static char smack_label[1024] = {'\0',};
 
        fp = fopen(label_path, "r");
        if (fp != NULL) {
-               ret = fread(smack_label, 1, sizeof(smack_label), fp);
+               int ret = fread(smack_label, 1, sizeof(smack_label), fp);
                if (ret <= 0)
                        LOGE("Failed to fread");
 
                fclose(fp);
        }
 
+       return smack_label;
+}
+
+static int _check_privilege(const char *uid, const char *privilege)
+{
+       int ret;
+       char smack_label[1024] = {'\0',};
+
+       if (!p_cynara) {
+               return -1;
+       }
+
+       strcpy(smack_label, _get_smack_label());
+
        pid_t pid = getpid();
        char *session = cynara_session_from_pid(pid);
        ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
@@ -93,7 +102,8 @@ static void _cynara_deinitialize()
        p_cynara = NULL;
 }
 
-static int _gesture_check_privilege() {
+static int _gesture_check_privilege()
+{
        char uid[16];
        int ret = HAND_GESTURE_ERROR_NONE;
 
@@ -130,22 +140,31 @@ EXPORT_API int hand_gesture_create(hand_gesture_h *handle)
        if (!_struct)
                return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
 
+       /* get uid and smack label */
+       snprintf(_struct->uid, 16, "%d", getuid());
+
+       strcpy(_struct->smack_label, _get_smack_label());
+
+       LOGI("uid(%s), smack(%s)", _struct->uid, _struct->smack_label);
+
        ret = gesture_client_dbus_init(&_struct->gdbus_connection, &_struct->server_watcher_id,
-               &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, (void *)_struct);
+               &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, _struct->uid, _struct->smack_label, (void *)_struct);
        if (ret != HAND_GESTURE_ERROR_NONE) {
                LOGE("Failed to initialize dbus : %d", ret);
                free(_struct);
                return HAND_GESTURE_ERROR_OPERATION_FAILED;
        }
 
-       *handle = _struct;
-
        ret = gesture_client_dbus_initialize_engine(_struct->gdbus_connection);
        if (ret != HAND_GESTURE_ERROR_NONE) {
                LOGE("Failed to initialize engine dbus : %d", ret);
+               free(_struct);
                return HAND_GESTURE_ERROR_OPERATION_FAILED;
        }
 
+       *handle = _struct;
+
+
        return HAND_GESTURE_ERROR_NONE;
 }
 
index ce5eec6..532ac88 100644 (file)
@@ -34,6 +34,7 @@ static int g_sensitivity = 1;
 static char *g_engine_app_id;
 static char *g_engine_name;
 
+
 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
 {
        LOGD("name : %s, name_owner : %s", name, name_owner);
@@ -338,19 +339,22 @@ static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVar
        return ret;
 }
 
-static int _monitor_register(GDBusConnection *gdbus_connection)
+static int _monitor_register(GDBusConnection *gdbus_connection, const char *uid, const char *smack_label)
 {
        int ret;
        GDBusMessage *reply = NULL;
        GVariant *client_body = NULL;
 
        char appid[1024] = {0, };
-       ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+       int pid = getpid();
+       ret = aul_app_get_appid_bypid(pid, appid, sizeof(appid));
        if (ret != 0) {
                LOGE("aul_app_get_appid_bypid() failed : %d", ret);
        }
 
-       client_body = g_variant_new("(iis)", 11, GESTURE_CLIENT_LIB_GESTURE, appid);
+       LOGI("[INFO] appid(%s), pid(%d), uid(%s), smack_label(%s)", appid, pid, uid, smack_label);
+
+       client_body = g_variant_new("(iisiss)", 11, GESTURE_CLIENT_LIB_GESTURE, appid, pid, uid, smack_label);
 
        ret = gdbus_send_message_with_sync(gdbus_connection, client_body, &reply, GESTURE_MSG_SERVICE_REGISTER);
        if (reply)
@@ -373,8 +377,12 @@ static void _on_name_appeared(GDBusConnection *connection,
                const gchar     *name_owner,
                gpointer         user_data)
 {
-       if (is_server_started == 0)
-       _monitor_register(connection);
+       struct hand_gesture_s *_struct = user_data;
+
+       if (is_server_started == 0) {
+               LOGI("uid(%s), smack_label(%s)", _struct->uid, _struct->smack_label);
+               _monitor_register(connection, _struct->uid, _struct->smack_label);
+       }
 }
 
 static void _on_name_vanished(GDBusConnection *connection,
@@ -385,7 +393,7 @@ static void _on_name_vanished(GDBusConnection *connection,
 }
 
 int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
-                               int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data)
+                               int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, const char *uid, const char *smack_label, void *data)
 {
        LOGD("gesture_client_dbus_init start");
 
@@ -403,7 +411,7 @@ int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_w
                return ret;
        }
 
-       ret = _monitor_register(*gdbus_connection);
+       ret = _monitor_register(*gdbus_connection, uid, smack_label);
        if (ret != HAND_GESTURE_ERROR_NONE) {
                LOGE("_monitor_register() failed : %d", ret);
                return ret;
@@ -416,7 +424,7 @@ int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_w
                                G_BUS_NAME_WATCHER_FLAGS_NONE,
                                _on_name_appeared,
                                _on_name_vanished,
-                               NULL,
+                               data,
                                NULL);
                if (*server_monitor_id == 0) {
                        g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
index b3666be..0ae8bdc 100644 (file)
@@ -31,7 +31,7 @@
 extern "C" {
 #endif
 
-int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data);
+int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, const char *uid, const char *smack_label, void *data);
 int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id);
 int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection);
 int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection);
index 4688228..04f0480 100644 (file)
@@ -33,6 +33,9 @@ struct hand_gesture_s {
        int monitor_id;
        int server_monitor_id;
 
+       char uid[16];
+       char smack_label[1024];
+
        hand_gesture_recognition_cb recog_cb;
        void* recog_user_data;
        hand_gesture_error_cb error_cb;
index c0aa267..3eeb674 100644 (file)
@@ -367,7 +367,7 @@ static int _monitor_register(GDBusConnection *gdbus_connection)
                return GESTURE_ENGINE_ERROR_OPERATION_FAILED;
        }
 
-       engine_body = g_variant_new("(iis)", 22, GESTURE_CLIENT_LIB_ENGINE, appid);
+       engine_body = g_variant_new("(iisiss)", 22, GESTURE_CLIENT_LIB_ENGINE, appid, getpid(), "NULL", "NULL");
 
        ret = gdbus_send_message_with_sync(gdbus_connection, engine_body, &reply, GESTURE_MSG_SERVICE_REGISTER);
        if (reply)
index 970f080..04930a4 100644 (file)
@@ -31,7 +31,7 @@ gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name)
                client = NULL;
                return NULL;
        }
-       
+
        client->gestureType = -1;
        client->requestTypeCount = -1;
        client->clientLib = GESTURE_CLIENT_LIB_NONE;
@@ -41,6 +41,7 @@ gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name)
        client->gdbus_connection = NULL;
        client->state = CLIENT_STATE_NONE;
        client->response_cb = NULL;
+       client->is_permitted = false;
 
        return client;
 }
index 35238b6..66b6b14 100644 (file)
@@ -31,6 +31,7 @@ typedef struct {
        GDBusConnection *gdbus_connection;
        gesture_manager_client_state_e state;
        hand_gesture_recognition_cb *response_cb;
+       bool is_permitted;
 } gesture_manager_client_s;
 
 gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name);
index 88f7c5b..20a956e 100644 (file)
@@ -21,6 +21,9 @@
 #include <dlog.h>
 #include <app_control.h>
 #include <app_manager.h>
+#include <cynara-client.h>
+#include <cynara-error.h>
+#include <cynara-session.h>
 
 #include "gestured_dbus.h"
 #include "gestured_error.h"
@@ -43,10 +46,68 @@ static GDBusConnection *_gdbus_connection;
 static const char *_client_bus_name;
 static const char *_engine_bus_name;
 
+
 static bool __is_engine_installed(const char* appid);
 static bool __is_engine_launched(const char* appid);
 
 
+static cynara *p_cynara = NULL;
+static int _cynara_initialize()
+{
+       int ret = cynara_initialize(&p_cynara, NULL);
+       if (ret != CYNARA_API_SUCCESS)
+               LOGE("Failed to cynara initialize");
+
+       return ret;
+}
+
+static int _check_privilege(const char *uid, const int pid, const char *label, const char *privilege)
+{
+       int ret;
+
+       if (!p_cynara) {
+               return -1;
+       }
+
+       char *session = cynara_session_from_pid(pid);
+       ret = cynara_check(p_cynara, label, session, uid, privilege);
+       if (session)
+               free(session);
+       if (ret != CYNARA_API_ACCESS_ALLOWED) {
+               LOGE("Access denied. The result of cynara_check() : %d.", ret);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void _cynara_deinitialize()
+{
+       if (p_cynara)
+               cynara_finish(p_cynara);
+
+       p_cynara = NULL;
+}
+
+static int _gesture_check_privilege(const char *uid, const int pid, const char *label)
+{
+       int ret = GESTURED_ERROR_NONE;
+
+       if (_cynara_initialize() != CYNARA_API_SUCCESS)
+               return GESTURED_ERROR_PERMISSION_DENIED;
+
+       if (_check_privilege(uid, pid, label, GESTURE_PRIVILEGE_APPLAUNCH) < 0) {
+               LOGE("Permission is denied");
+               ret = GESTURED_ERROR_PERMISSION_DENIED;
+       }
+
+       _cynara_deinitialize();
+
+       return ret;
+}
+
+
+
 int gestured_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler,
                GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash)
 {
@@ -57,14 +118,20 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const
        uid_t request_uid = 0;
        CLIENT_LIB clientLib;
        char *pkgName = NULL;
+       int client_pid = 0;
+       char *client_uid = NULL;
+       char *client_smack_label = NULL;
 
        if (bus_name == NULL)
                return GESTURED_ERROR_IO_ERROR;
 
-       g_variant_get(parameters, "(iis)", &request_uid, &clientLib, &pkgName);
+       g_variant_get(parameters, "(iisiss)", &request_uid, &clientLib, &pkgName, &client_pid, &client_uid, &client_smack_label);
        LOGD("gestured_server_register > request_uid: %d", request_uid);
        LOGD("gestured_server_register > clientLib: %d", clientLib);
        LOGD("gestured_server_register > pkgName: %s", pkgName);
+       LOGD("gestured_server_register > client_pid: %d", client_pid);
+       LOGD("gestured_server_register > client_uid: %s", (NULL == client_uid) ? "NULL" : client_uid);
+       LOGD("gestured_server_register > client_smack_label: %s", (NULL == client_smack_label) ? "NULL" : client_smack_label);
 
        if (clientLib == GESTURE_CLIENT_LIB_ENGINE) {
                _engine_bus_name = g_strdup(bus_name);
@@ -73,6 +140,15 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const
        }
 
        if (clientLib == GESTURE_CLIENT_LIB_GESTURE) {
+               /* check privilege */
+               if (GESTURED_ERROR_NONE != _gesture_check_privilege(client_uid, client_pid, client_smack_label)) {
+                       LOGE("[ERROR] Permission denied");
+
+                       return GESTURED_ERROR_PERMISSION_DENIED;
+               } else {
+                       LOGI("[INFO] Permission allowed");
+               }
+
                /* launch engine process if engine is not running */
                bool is_launched = __is_engine_launched("org.tizen.gesture-engine-default");
                if (false == is_launched) {
@@ -96,6 +172,7 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const
                        LOGE("Fail to create a new client");
                        return GESTURED_ERROR_OPERATION_FAILED;
                }
+               client->is_permitted = true;
                client->clientLib = clientLib;
                client->request_uid = request_uid;
                client->gdbus_bus_name = strdup(bus_name);
@@ -118,6 +195,7 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const
                        LOGE("Failed to add client to GestureManager");
                        return GESTURED_ERROR_OPERATION_FAILED;
                }
+
                LOGD("GestureManager Client count = %d", GestureManagerClientNums());
        } else if (clientLib == GESTURE_CLIENT_LIB_ENGINE) {
                /* Check this engine is already registerd to server or not */
@@ -466,6 +544,9 @@ int gestured_register_dbus_interface(void)
                        "                       <arg type='i' name='value' direction='in'/>"
                        "                       <arg type='i' name='clientlib' direction='in'/>"
                        "                       <arg type='s' name='pkgName' direction='in'/>"
+                       "                       <arg type='i' name='client_pid' direction='in'/>"
+                       "                       <arg type='s' name='client_uid' direction='in'/>"
+                       "                       <arg type='s' name='client_smack_label' direction='in'/>"
                        "               </method>"
 
                        "               <method name='gesture_client_initialize_engine'>"
@@ -558,6 +639,18 @@ int gestured_client_initialize_engine(GVariant *parameters, GVariant **reply_bod
                return GESTURED_ERROR_INVALID_PARAMETER;
        }
 
+       /* check privilege */
+       gesture_manager_client_s *client = GestureManagerClientGetWithBusName(sender);
+       if (!client) {
+               LOGE("failed to GestureManagerClientGet");
+               return GESTURED_ERROR_OPERATION_FAILED;
+       }
+
+       if (false == client->is_permitted) {
+               LOGE("[ERROR] Permission denied");
+               return GESTURED_ERROR_PERMISSION_DENIED;
+       }
+
        ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE);
        if (ret != GESTURED_ERROR_NONE)
                LOGE("Failed to start to engine");