From b8ce48530da415b188811d0d90cdd55194758606 Mon Sep 17 00:00:00 2001 From: jeon Date: Tue, 7 May 2019 21:41:17 +0900 Subject: [PATCH] pepper-devicemgr: check a privilege using cynara APIs Change-Id: Ia1f3416a09204f28cd48c44bdf9b88d47c4572b9 --- src/lib/devicemgr/Makefile.am | 4 +- src/lib/devicemgr/devicemgr-internal.h | 1 + src/lib/devicemgr/devicemgr.c | 11 +- src/lib/devicemgr/pepper-devicemgr.c | 148 +++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 4 deletions(-) diff --git a/src/lib/devicemgr/Makefile.am b/src/lib/devicemgr/Makefile.am index 153941c..ef455d7 100644 --- a/src/lib/devicemgr/Makefile.am +++ b/src/lib/devicemgr/Makefile.am @@ -5,8 +5,8 @@ AM_CFLAGS = $(GCC_CFLAGS) libpepper_devicemgr_includedir=$(includedir)/pepper libpepper_devicemgr_include_HEADERS = devicemgr.h pepper-devicemgr.h -libpepper_devicemgr_la_CFLAGS = $(AM_CFLAGS) $(PEPPER_DEVICEMGR_CFLAGS) -libpepper_devicemgr_la_LIBADD = $(PEPPER_DEVICEMGR_LIBS) +libpepper_devicemgr_la_CFLAGS = $(AM_CFLAGS) $(PEPPER_DEVICEMGR_CFLAGS) $(CYNARA_CFLAGS) +libpepper_devicemgr_la_LIBADD = $(PEPPER_DEVICEMGR_LIBS) $(CYNARA_LIBS) libpepper_devicemgr_la_SOURCES = devicemgr-internal.h \ devicemgr.c \ diff --git a/src/lib/devicemgr/devicemgr-internal.h b/src/lib/devicemgr/devicemgr-internal.h index 754356b..f2db076 100644 --- a/src/lib/devicemgr/devicemgr-internal.h +++ b/src/lib/devicemgr/devicemgr-internal.h @@ -36,6 +36,7 @@ struct devicemgr_device { char name[UINPUT_MAX_NAME_SIZE + 1]; pepper_input_device_t *input_device; + pepper_bool_t created; }; struct devicemgr { diff --git a/src/lib/devicemgr/devicemgr.c b/src/lib/devicemgr/devicemgr.c index 69063fb..616c7a8 100644 --- a/src/lib/devicemgr/devicemgr.c +++ b/src/lib/devicemgr/devicemgr.c @@ -82,6 +82,8 @@ _devicemgr_input_generator_keyboard_create(devicemgr_t *devicemgr, const char *n devicemgr->keyboard->input_device = pepper_input_device_create(devicemgr->compositor, WL_SEAT_CAPABILITY_KEYBOARD, NULL, NULL); PEPPER_CHECK(devicemgr->keyboard->input_device, return PEPPER_FALSE, "Failed to create input device !\n"); + devicemgr->keyboard->created = PEPPER_TRUE; + return PEPPER_TRUE; } @@ -106,6 +108,8 @@ _devicemgr_input_generator_keyboard_close(devicemgr_t *devicemgr) { if (!devicemgr->keyboard->input_device) return; pepper_input_device_destroy(devicemgr->keyboard->input_device); + devicemgr->keyboard->input_device = NULL; + devicemgr->keyboard->created = PEPPER_FALSE; } PEPPER_API int @@ -115,7 +119,8 @@ devicemgr_input_generator_deinit(devicemgr_t *devicemgr) if (!devicemgr->keyboard) return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; - _devicemgr_input_generator_keyboard_close(devicemgr); + if (devicemgr->keyboard->created) + _devicemgr_input_generator_keyboard_close(devicemgr); memset(devicemgr->keyboard->name, 0, UINPUT_MAX_NAME_SIZE); return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; @@ -150,7 +155,9 @@ devicemgr_destroy(devicemgr_t *devicemgr) PEPPER_CHECK(devicemgr, return, "Invalid devicemgr resource.\n"); if (devicemgr->keyboard) { - _devicemgr_input_generator_keyboard_close(devicemgr); + if (devicemgr->keyboard->created) + _devicemgr_input_generator_keyboard_close(devicemgr); + free(devicemgr->keyboard); devicemgr->keyboard = NULL; } diff --git a/src/lib/devicemgr/pepper-devicemgr.c b/src/lib/devicemgr/pepper-devicemgr.c index 6640421..52a8c53 100644 --- a/src/lib/devicemgr/pepper-devicemgr.c +++ b/src/lib/devicemgr/pepper-devicemgr.c @@ -25,6 +25,14 @@ #include "pepper-internal.h" #include #include +#ifdef HAVE_CYNARA +#include +#include +#include +#include +#include +#include +#endif #define MIN(a,b) ((a)<(b)?(a):(b)) @@ -47,6 +55,9 @@ struct pepper_devicemgr { devicemgr_t *devicemgr; int ref; +#ifdef HAVE_CYNARA + cynara *p_cynara; +#endif }; struct pepper_devicemgr_resource { @@ -55,6 +66,117 @@ struct pepper_devicemgr_resource { pepper_list_t link; }; +#ifdef HAVE_CYNARA +static void +_pepper_devicemgr_util_cynara_log(int err, const char *fmt, ...) +{ +#define CYNARA_BUFSIZE 128 + char buf[CYNARA_BUFSIZE] = "\0", tmp[CYNARA_BUFSIZE + CYNARA_BUFSIZE] = "\0"; + va_list args; + int ret; + + if (fmt) { + va_start(args, fmt); + vsnprintf(tmp, CYNARA_BUFSIZE + CYNARA_BUFSIZE, fmt, args); + va_end(args); + } + + ret = cynara_strerror(err, buf, CYNARA_BUFSIZE); + if (ret != CYNARA_API_SUCCESS) { + PEPPER_ERROR("Failed to cynara_strerror: %d (error log about %s: %d)\n", ret, tmp, err); + return; + } + + PEPPER_ERROR("%s is failed: %s\n", tmp, buf); +} +#endif + +static pepper_bool_t +_pepper_devicemgr_util_cynara_init(pepper_devicemgr_t *pepper_devicemgr) +{ +#ifdef HAVE_CYNARA + int ret; + if (pepper_devicemgr->p_cynara) return PEPPER_TRUE; + + ret = cynara_initialize(&pepper_devicemgr->p_cynara, NULL); + if (CYNARA_API_SUCCESS != ret) { + _pepper_devicemgr_util_cynara_log(ret, "cynara_initialize"); + return PEPPER_FALSE; + } +#endif + return PEPPER_TRUE; +} + +static void +_pepper_devicemgr_util_cynara_deinit(pepper_devicemgr_t *pepper_devicemgr) +{ +#ifdef HAVE_CYNARA + if (pepper_devicemgr->p_cynara) cynara_finish(pepper_devicemgr->p_cynara); +#else + ; +#endif +} + +static pepper_bool_t +_pepper_devicemgr_util_do_privilege_check(pepper_devicemgr_t *pepper_devicemgr, struct wl_client *client, const char *rule) +{ + pepper_bool_t res = PEPPER_TRUE; +#ifdef HAVE_CYNARA + int ret, retry_cnt = 0, len = 0; + char *clientSmack = NULL, *client_session = NULL, uid2[16]={0, }; + static pepper_bool_t retried = PEPPER_FALSE; + pid_t pid = 0; + uid_t uid = 0; + gid_t gid = 0; + + res = PEPPER_FALSE; + + /* Top position grab is always allowed. This mode do not need privilege.*/ + if (!client) return PEPPER_FALSE; + + /* If initialize cynara is failed, allow keygrabs regardless of the previlege permition. */ + if (pepper_devicemgr->p_cynara == NULL) { + if (retried == PEPPER_FALSE) { + retried = PEPPER_TRUE; + for(retry_cnt = 0; retry_cnt < 5; retry_cnt++) { + PEPPER_TRACE("Retry cynara initialize: %d\n", retry_cnt + 1); + + ret = cynara_initialize(&pepper_devicemgr->p_cynara, NULL); + if (CYNARA_API_SUCCESS != ret) { + _pepper_devicemgr_util_cynara_log(ret, "cynara_initialize retry.."); + pepper_devicemgr->p_cynara = NULL; + } else { + PEPPER_TRACE("Success cynara initialize to try %d times\n", retry_cnt + 1); + break; + } + } + } + if (!pepper_devicemgr->p_cynara) return PEPPER_TRUE; + } + + wl_client_get_credentials(client, &pid, &uid, &gid); + + len = smack_new_label_from_process((int)pid, &clientSmack); + if (len <= 0) goto finish; + + snprintf(uid2, 15, "%d", (int)uid); + client_session = cynara_session_from_pid(pid); + + ret = cynara_check(pepper_devicemgr->p_cynara, clientSmack, client_session, uid2, rule); + if (CYNARA_API_ACCESS_ALLOWED == ret) { + res = PEPPER_TRUE; + PEPPER_TRACE("Success to check cynara, clientSmack: %s client_session: %s, uid2: %s\n", clientSmack, client_session, uid2); + } else { + _pepper_devicemgr_util_cynara_log(ret, "rule: %s, clientsmack: %s, pid: %d", rule, clientSmack, pid); + } + +finish: + if (client_session) free(client_session); + if (clientSmack) free(clientSmack); +#endif + return res; +} + static void _pepper_devicemgr_handle_keyboard_keymap_update(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data) { @@ -156,11 +278,16 @@ _pepper_devicemgr_cb_init_generator(struct wl_client *client, struct wl_resource { pepper_devicemgr_t *pepper_devicemgr; int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + pepper_bool_t res; pepper_devicemgr = wl_resource_get_user_data(resource); PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n"); PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + res = _pepper_devicemgr_util_do_privilege_check(pepper_devicemgr, client, "http://tizen.org/privilege/inputgenerator"); + PEPPER_CHECK(res == PEPPER_TRUE, goto failed, "Current client has no permission to input generate\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; PEPPER_CHECK(clas == TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, goto failed, "only support keyboard device. (requested: 0x%x)\n", clas); @@ -177,11 +304,16 @@ _pepper_devicemgr_cb_init_generator_with_name(struct wl_client *client, struct w { pepper_devicemgr_t *pepper_devicemgr; int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + pepper_bool_t res; pepper_devicemgr = wl_resource_get_user_data(resource); PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n"); PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + res = _pepper_devicemgr_util_do_privilege_check(pepper_devicemgr, client, "http://tizen.org/privilege/inputgenerator"); + PEPPER_CHECK(res == PEPPER_TRUE, goto failed, "Current client has no permission to input generate\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; PEPPER_CHECK(clas == TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, goto failed, "only support keyboard device. (requested: 0x%x)\n", clas); @@ -201,11 +333,16 @@ _pepper_devicemgr_cb_deinit_generator(struct wl_client *client, struct wl_resour { pepper_devicemgr_t *pepper_devicemgr; int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + pepper_bool_t res; pepper_devicemgr = wl_resource_get_user_data(resource); PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n"); PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + res = _pepper_devicemgr_util_do_privilege_check(pepper_devicemgr, client, "http://tizen.org/privilege/inputgenerator"); + PEPPER_CHECK(res == PEPPER_TRUE, goto failed, "Current client has no permission to input generate\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; PEPPER_CHECK(clas == TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, goto failed, "only support keyboard device. (requested: 0x%x)\n", clas); @@ -254,11 +391,16 @@ _pepper_devicemgr_cb_generate_key(struct wl_client *client, struct wl_resource * pepper_devicemgr_t *pepper_devicemgr; int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; int keycode = 0; + pepper_bool_t res; pepper_devicemgr = wl_resource_get_user_data(resource); PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n"); PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + res = _pepper_devicemgr_util_do_privilege_check(pepper_devicemgr, client, "http://tizen.org/privilege/inputgenerator"); + PEPPER_CHECK(res == PEPPER_TRUE, goto failed, "Current client has no permission to input generate\n"); + if (pepper_devicemgr->xkb_info) { keycode = pepper_xkb_info_keyname_to_keycode(pepper_devicemgr->xkb_info, keyname); } @@ -376,6 +518,7 @@ pepper_devicemgr_create(pepper_compositor_t *compositor, pepper_seat_t *seat) struct wl_display *display = NULL; struct wl_global *global = NULL; pepper_devicemgr_t *pepper_devicemgr; + pepper_bool_t ret; PEPPER_CHECK(compositor, return PEPPER_FALSE, "Invalid compositor\n"); @@ -403,6 +546,9 @@ pepper_devicemgr_create(pepper_compositor_t *compositor, pepper_seat_t *seat) pepper_devicemgr->devicemgr = devicemgr_create(compositor, seat); PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "Failed to create devicemgr\n"); + ret = _pepper_devicemgr_util_cynara_init(pepper_devicemgr); + if (!ret) PEPPER_TRACE("cynara initialize is failed. process devicemgr without cynara\n"); + return pepper_devicemgr; failed: @@ -424,6 +570,8 @@ pepper_devicemgr_destroy(pepper_devicemgr_t *pepper_devicemgr) PEPPER_CHECK(pepper_devicemgr, return, "Pepper devicemgr is not initialized\n"); + _pepper_devicemgr_util_cynara_deinit(pepper_devicemgr); + pepper_list_for_each_safe(rdata, rtmp, &pepper_devicemgr->resources, link) { wl_resource_destroy(rdata->resource); pepper_list_remove(&rdata->link); -- 2.34.1