static int _e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, uint32_t key, uint32_t mode);
static int _e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, uint32_t key);
+#ifdef ENABLE_CYNARA
+static void _e_keyrouter_util_cynara_log(const char *func_name, int err);
+static Eina_Bool _e_keyrouter_util_do_privilege_check(struct wl_client *client, int socket_fd, uint32_t mode);
+
+#define E_KEYROUTER_CYNARA_ERROR_CHECK_GOTO(func_name, ret, label) \
+ do \
+ { \
+ if (EINA_UNLIKELY(CYNARA_API_SUCCESS != ret)) \
+ { \
+ _e_keyrouter_util_cynara_log(func_name, ret); \
+ goto label; \
+ } \
+ } \
+ while (0)
+#endif
static int
_e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, uint32_t key, uint32_t mode)
{
int res=0;
+#ifdef ENABLE_CYNARA
+ if (EINA_FALSE == _e_keyrouter_util_do_privilege_check(client,
+ wl_client_get_fd(client), mode))
+ {
+ return TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
+ }
+#endif
+
if (!surface)
{
/* Regarding topmost mode, a client must request to grab a key with a valid surface. */
static int
_e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, uint32_t key)
{
+ /* Ungrab top position grabs first. This grab mode do not need privilege */
+ if (!surface)
+ e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
+ else
+ e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
+
+#ifdef ENABLE_CYNARA
+ if (EINA_FALSE == _e_keyrouter_util_do_privilege_check(client,
+ wl_client_get_fd(client), TIZEN_KEYROUTER_MODE_NONE))
+ {
+ return TIZEN_KEYROUTER_ERROR_NONE;
+ }
+#endif
+
if (!surface)
{
/* EXCLUSIVE grab */
/* OVERRIDABLE_EXCLUSIVE grab */
e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
- /* TOPMOST(TOP_POSITION) grab */
- e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
-
/* SHARED grab */
e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_SHARED);
/* OVERRIDABLE_EXCLUSIVE grab */
e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
- /* TOPMOST(TOP_POSITION) grab */
- e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
-
/* SHARED grab */
e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_SHARED);
Eina_List *l;
struct wl_client *wc_data;
- EINA_LIST_FOREACH(krt->none_surface_grab_client, l, wc_data)
+ EINA_LIST_FOREACH(krt->grab_client_list, l, wc_data)
{
if (wc_data)
{
destroy_listener->notify = _e_keyrouter_wl_client_cb_destroy;
wl_client_add_destroy_listener(client, destroy_listener);
- krt->none_surface_grab_client = eina_list_append(krt->none_surface_grab_client, client);
+ krt->grab_client_list = eina_list_append(krt->grab_client_list, client);
KLDBG("Add a wl_client(%p) destroy listener(%p)\n", client, destroy_listener);
Eina_List *l;
struct wl_resource *surface_data;
- EINA_LIST_FOREACH(krt->surface_grab_client, l, surface_data)
+ EINA_LIST_FOREACH(krt->grab_surface_list, l, surface_data)
{
if (surface_data)
{
destroy_listener->notify = _e_keyrouter_wl_surface_cb_destroy;
wl_resource_add_destroy_listener(surface, destroy_listener);
- krt->surface_grab_client = eina_list_append(krt->surface_grab_client, surface);
+ krt->grab_surface_list = eina_list_append(krt->grab_surface_list, surface);
KLDBG("Add a surface(%p) destroy listener(%p)\n", surface, destroy_listener);
E_Keyrouter_Config_Data *kconfig = NULL;
krt = E_NEW(E_Keyrouter, 1);
Eina_Bool res = EINA_FALSE;
+ int ret;
if (!krt)
{
goto err;
}
+#ifdef ENABLE_CYNARA
+ ret = cynara_initialize(&krt->p_cynara, NULL);
+ if (EINA_UNLIKELY(CYNARA_API_SUCCESS != ret))
+ {
+ _e_keyrouter_util_cynara_log("cynara_initialize", ret);
+ krt->p_cynara = NULL;
+ }
+#endif
+
return kconfig;
err:
E_Keyrouter_Config_Data *kconfig = m->data;
e_keyrouter_conf_deinit(kconfig);
_e_keyrouter_deinit_handlers();
+
+#ifdef ENABLE_CYNARA
+ if (krt->p_cynara) cynara_finish(krt->p_cynara);
+#endif
/* TODO: free allocated memory */
return 1;
E_FREE(l);
l = NULL;
- krt->none_surface_grab_client = eina_list_remove(krt->none_surface_grab_client, client);
+ krt->grab_client_list = eina_list_remove(krt->grab_client_list, client);
}
static void
E_FREE(l);
l = NULL;
- krt->surface_grab_client = eina_list_remove(krt->surface_grab_client, surface);
+ krt->grab_surface_list = eina_list_remove(krt->grab_surface_list, surface);
+}
+
+#ifdef ENABLE_CYNARA
+static void
+_e_keyrouter_util_cynara_log(const char *func_name, int err)
+{
+#define CYNARA_BUFSIZE 128
+ char buf[CYNARA_BUFSIZE] = "\0";
+ int ret;
+
+ ret = cynara_strerror(err, buf, CYNARA_BUFSIZE);
+ if (ret != CYNARA_API_SUCCESS)
+ {
+ KLDBG("Failed to cynara_strerror: %d (error log about %s: %d)\n", ret, func_name, err);
+ return;
+ }
+ KLDBG("%s is failed: %s\n", func_name, buf);
+}
+
+static Eina_Bool
+_e_keyrouter_util_do_privilege_check(struct wl_client *client, int socket_fd, uint32_t mode)
+{
+ int ret, pid, retry_cnt=0;
+ char *clientSmack=NULL, *uid=NULL, *client_session=NULL;
+ Eina_Bool res = EINA_FALSE;
+ Eina_List *l;
+ struct wl_client *wc_data;
+ static Eina_Bool retried = EINA_FALSE;
+
+ /* Top position grab is always allowed. This mode do not need privilege.*/
+ if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
+ return EINA_TRUE;
+
+ /* If initialize cynara is failed, allow keygrabs regardless of the previlege permition. */
+ if (krt->p_cynara == NULL)
+ {
+ if (retried == EINA_FALSE)
+ {
+ retried = EINA_TRUE;
+ for(retry_cnt = 0; retry_cnt < 5; retry_cnt++)
+ {
+ KLDBG("Retry cynara initialize: %d\n", retry_cnt+1);
+ ret = cynara_initialize(&krt->p_cynara, NULL);
+ if (EINA_UNLIKELY(CYNARA_API_SUCCESS != ret))
+ {
+ _e_keyrouter_util_cynara_log("cynara_initialize", ret);
+ krt->p_cynara = NULL;
+ }
+ else
+ {
+ KLDBG("Success cynara initialize to try %d times\n", retry_cnt+1);
+ break;
+ }
+ }
+ }
+ return EINA_TRUE;
+ }
+
+ EINA_LIST_FOREACH(krt->grab_client_list, l, wc_data)
+ {
+ if (wc_data == client)
+ {
+ res = EINA_TRUE;
+ goto finish;
+ }
+ }
+
+ ret = cynara_creds_socket_get_client(socket_fd, CLIENT_METHOD_SMACK, &clientSmack);
+ E_KEYROUTER_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_client", ret, finish);
+
+ ret = cynara_creds_socket_get_user(socket_fd, USER_METHOD_UID, &uid);
+ E_KEYROUTER_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_user", ret, finish);
+
+ ret = cynara_creds_socket_get_pid(socket_fd, &pid);
+ E_KEYROUTER_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_pid", ret, finish);
+
+ client_session = cynara_session_from_pid(pid);
+
+ ret = cynara_check(krt->p_cynara, clientSmack, client_session, uid, "http://tizen.org/privilege/keygrab");
+ if (CYNARA_API_ACCESS_ALLOWED == ret)
+ {
+ res = EINA_TRUE;
+ e_keyrouter_add_client_destroy_listener(client);
+ }
+
+finish:
+ E_FREE(client_session);
+ E_FREE(clientSmack);
+ E_FREE(uid);
+
+ return res;
}
+#endif