From: sooyeon.kim Date: Mon, 24 Aug 2020 06:43:22 +0000 (+0900) Subject: Move privilege checker to gesture-server X-Git-Tag: accepted/tizen/unified/20200829.113355^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=decd5d812343bd03855955b33bcd287995b77e63;p=platform%2Fcore%2Fapi%2Fgesture.git Move privilege checker to gesture-server Change-Id: I013b3509f39f47ca776262a3eeb0e178f406ee6f Signed-off-by: sooyeon.kim --- diff --git a/client/gesture.c b/client/gesture.c index df6ae46..17065d1 100644 --- a/client/gesture.c +++ b/client/gesture.c @@ -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; } diff --git a/client/gesture_client_dbus.c b/client/gesture_client_dbus.c index ce5eec6..532ac88 100644 --- a/client/gesture_client_dbus.c +++ b/client/gesture_client_dbus.c @@ -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); diff --git a/client/gesture_client_dbus.h b/client/gesture_client_dbus.h index b3666be..0ae8bdc 100644 --- a/client/gesture_client_dbus.h +++ b/client/gesture_client_dbus.h @@ -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); diff --git a/client/gesture_main.h b/client/gesture_main.h index 4688228..04f0480 100644 --- a/client/gesture_main.h +++ b/client/gesture_main.h @@ -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; diff --git a/engine/gesture_engine_dbus.c b/engine/gesture_engine_dbus.c index c0aa267..3eeb674 100644 --- a/engine/gesture_engine_dbus.c +++ b/engine/gesture_engine_dbus.c @@ -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) diff --git a/manager/gestured_client_manager.cpp b/manager/gestured_client_manager.cpp index 970f080..04930a4 100644 --- a/manager/gestured_client_manager.cpp +++ b/manager/gestured_client_manager.cpp @@ -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; } diff --git a/manager/gestured_client_manager.h b/manager/gestured_client_manager.h index 35238b6..66b6b14 100644 --- a/manager/gestured_client_manager.h +++ b/manager/gestured_client_manager.h @@ -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); diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index 88f7c5b..20a956e 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #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) " " " " " " + " " + " " + " " " " " " @@ -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");