pepper-devicemgr: check a privilege using cynara APIs 85/207185/1
authorjeon <jhyuni.kang@samsung.com>
Tue, 7 May 2019 12:41:17 +0000 (21:41 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Thu, 30 May 2019 08:34:17 +0000 (17:34 +0900)
Change-Id: Ia1f3416a09204f28cd48c44bdf9b88d47c4572b9

src/lib/devicemgr/Makefile.am
src/lib/devicemgr/devicemgr-internal.h
src/lib/devicemgr/devicemgr.c
src/lib/devicemgr/pepper-devicemgr.c

index 153941cad3ad5323a7f82a728f049ea2b3dc7bc7..ef455d78a4eb6b1f03a2e475b616a2966bf53227 100644 (file)
@@ -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 \
index 754356bcf401df3ba0ec47cf5977f5e4149e00df..f2db076acd54d4fc983ca556d152e675339354c5 100644 (file)
@@ -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 {
index 69063fbe87f716f8ec22f22725c5cb511bf93713..616c7a86e708243c2e7ae9bb665737ef24c684ba 100644 (file)
@@ -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;
        }
index 6640421b1e187063471804db115cba07a2309e6c..52a8c531b9ed1015af2b6b3f84c779abe7d2066c 100644 (file)
 #include "pepper-internal.h"
 #include <tizen-extension-server-protocol.h>
 #include <pepper-xkb.h>
+#ifdef HAVE_CYNARA
+#include <cynara-session.h>
+#include <cynara-client.h>
+#include <cynara-creds-socket.h>
+#include <sys/smack.h>
+#include <stdio.h>
+#include <stdarg.h>
+#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);