From: Inkyun Kil Date: Thu, 24 Jan 2019 00:08:16 +0000 (+0900) Subject: Support launch_on_event with user event X-Git-Tag: submit/tizen/20190705.002737~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=320bb0c784a5ad5b1d07c414a6ed0990fc9af9bd;p=platform%2Fcore%2Fappfw%2Fevent-system.git Support launch_on_event with user event Change-Id: I809ca8ec8727c4ad40f81db6002f55d73af4613c Signed-off-by: Inkyun Kil Signed-off-by: jusung son --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 3936be4..ef58439 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src) ### Required packages INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED dlog bundle pkgmgr-info glib-2.0 gio-2.0 appsvc aul vconf libtzplatform-config libsystemd-daemon cynara-client cynara-creds-gdbus cynara-session security-manager) +pkg_check_modules(pkgs REQUIRED dlog bundle pkgmgr-info glib-2.0 gio-2.0 appsvc aul vconf libtzplatform-config libsystemd-daemon cert-svc-vcore cynara-client cynara-creds-gdbus cynara-session security-manager) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/packaging/esd.spec b/packaging/esd.spec index 873477a..95ed77a 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -19,6 +19,7 @@ BuildRequires: pkgconfig(eventsystem) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(libsystemd-daemon) +BuildRequires: pkgconfig(cert-svc-vcore) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-creds-gdbus) BuildRequires: pkgconfig(cynara-session) diff --git a/src/esd_main.c b/src/esd_main.c index d0b58dc..4826b08 100644 --- a/src/esd_main.c +++ b/src/esd_main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -15,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -96,9 +99,16 @@ typedef struct __eventlaunch_item_param { char *app_id; } eventlaunch_item_param_s; +enum trusted_result { + TRUSTED_UNKNOWN, + TRUSTED_ALLOWED, + TRUSTED_DENIED, +}; + typedef struct esd_list_item { char *pkg_id; char *app_id; + int trusted_info; uid_t uid; } esd_list_item_s; @@ -125,6 +135,10 @@ typedef struct __pkgmgr_event { typedef struct __esd_event_param { char *event_name; bundle *event_data; + uid_t sender_uid; + char *sender_appid; + bool is_user_event; + bool trusted; void *user_data; } esd_event_param; @@ -190,6 +204,74 @@ static int __esd_check_earlier_support(const char *event_name) } #endif +static bool __esd_check_platform_cert(const char *pkgid, uid_t uid) +{ + _D("Checking if %s has a platform certification", pkgid); + + int r; + const char *cert_value; + pkgmgrinfo_certinfo_h certinfo; + CertSvcInstance instance; + CertSvcCertificate certificate; + CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; + + r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); + if (r != PMINFO_R_OK) { + _E("Failed to create certinfo"); + return false; + } + + r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid); + if (r != PMINFO_R_OK) { + _E("Failed to load certinfo"); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, + PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); + if (r != PMINFO_R_OK || cert_value == NULL) { + _E("Failed to get cert value"); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = certsvc_instance_new(&instance); + if (r != CERTSVC_SUCCESS) { + _E("certsvc_instance_new() is failed."); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = certsvc_certificate_new_from_memory(instance, + (const unsigned char *)cert_value, + strlen(cert_value), + CERTSVC_FORM_DER_BASE64, + &certificate); + if (r != CERTSVC_SUCCESS) { + _E("certsvc_certificate_new_from_memory() is failed."); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + certsvc_instance_free(instance); + return false; + } + + r = certsvc_certificate_get_visibility(certificate, &visibility); + if (r != CERTSVC_SUCCESS) + _E("certsvc_certificate_get_visibility() is failed."); + + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + certsvc_instance_free(instance); + certsvc_certificate_free(certificate); + + _D("visibility is %d", visibility); + if (visibility & CERTSVC_VISIBILITY_PLATFORM) { + _D("%s has a platform certification", pkgid); + return true; + } + + return false; +} + static int __esd_check_event_launch_support(const char *event_name) { int i = 0; @@ -544,13 +626,15 @@ static int __esd_add_list_item(uid_t uid, event_launch_item *el_item, item_of_list->uid = uid; item_of_list->app_id = (char *)app_id; item_of_list->pkg_id = (char *)pkg_id; + item_of_list->trusted_info = TRUSTED_UNKNOWN; el_item->app_list_evtlaunch = g_list_append(el_item->app_list_evtlaunch, item_of_list); return ES_R_OK; } -static int __esd_add_launch_item(uid_t uid, const char *event_name, const char *appid, const char *pkgid) +static int __esd_add_launch_item(uid_t uid, const char *event_name, + const char *appid, const char *pkgid) { GList *app_list = NULL; guint subscription_id = 0; @@ -752,18 +836,39 @@ static void __esd_event_launch_with_appid(gpointer data, gpointer user_data) int pid; char event_uri[1024]; bundle *b; + int ret; + + _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)", + app_id, eep->event_name, uid, eep->is_user_event, eep->trusted); - _D("launch_on_event: app_id(%s), event_name(%s), uid(%d)", - app_id, eep->event_name, uid); + if (eep->is_user_event && eep->trusted) { + if (item->trusted_info == TRUSTED_UNKNOWN) { + ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid); + if (ret == ES_R_EINVAL) { + item->trusted_info = TRUSTED_DENIED; + return; + } else if (ret == ES_R_ERROR) { + return; + } else { + item->trusted_info = TRUSTED_ALLOWED; + } + } else if (item->trusted_info == TRUSTED_DENIED) { + return; + } + } if (!aul_app_is_running_for_uid(app_id, uid)) { - snprintf(event_uri, sizeof(event_uri), "event://%s", eep->event_name); b = bundle_dup(eep->event_data); + if (eep->is_user_event) + snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name); + else + snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name); + appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT); appsvc_set_uri(b, event_uri); appsvc_set_appid(b, app_id); - pid = appsvc_usr_run_service(b, req_id++, NULL, eep->user_data, uid); + pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid); _D("uid(%d), pid(%d)", uid, pid); bundle_free(b); @@ -783,7 +888,9 @@ static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_d } } -static void __esd_launch_event_handler(char *event_name, bundle *data, void *user_data) +static void __esd_launch_event_handler(char *event_name, bundle *data, + const bool is_user_event, const bool trusted, + const uid_t sender_uid, char *sender_appid, void *user_data) { const char *val; const char *msg_type; @@ -798,38 +905,40 @@ static void __esd_launch_event_handler(char *event_name, bundle *data, void *use return; if (el_item->app_list_evtlaunch != NULL) { - if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS); - _D("charger val(%s)", val); - if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_USB_STATUS); - _D("usb val(%s)", val); - if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS); - _D("earjack val(%s)", val); - if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) { - msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE); - _D("msg_type(%s)", msg_type); - if (msg_type == NULL) - return; - - msg_id = bundle_get_val(data, EVT_KEY_MSG_ID); - _D("msg_id(%s)", msg_id); - if (msg_id == NULL) - return; - } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_WIFI_STATE); - if (val == NULL) - return; - _D("wifi_state(%s)", val); - if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0) - return; + if (is_user_event == false) { + if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS); + _D("charger val(%s)", val); + if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)) + return; + } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_USB_STATUS); + _D("usb val(%s)", val); + if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)) + return; + } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS); + _D("earjack val(%s)", val); + if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)) + return; + } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) { + msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE); + _D("msg_type(%s)", msg_type); + if (msg_type == NULL) + return; + + msg_id = bundle_get_val(data, EVT_KEY_MSG_ID); + _D("msg_id(%s)", msg_id); + if (msg_id == NULL) + return; + } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_WIFI_STATE); + if (val == NULL) + return; + _D("wifi_state(%s)", val); + if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0) + return; + } } eep = calloc(1, sizeof(esd_event_param)); @@ -839,6 +948,10 @@ static void __esd_launch_event_handler(char *event_name, bundle *data, void *use } eep->event_name = event_name; eep->event_data = data; + eep->sender_uid = sender_uid; + eep->sender_appid = sender_appid; + eep->is_user_event = is_user_event; + eep->trusted = trusted; eep->user_data = (void *)user_data; __esd_check_event_launch_with_eventid(el_item, eep); free(eep); @@ -915,7 +1028,8 @@ static void __esd_event_handler(char *event_name, bundle *data, void *user_data) #endif if (__esd_check_event_launch_support(event_name)) - __esd_launch_event_handler(event_name, data, user_data); + __esd_launch_event_handler(event_name, data, + false, true, ROOT_USER, NULL, user_data); } static void __esd_trusted_busname_remove_item(char *bus_name) @@ -1126,6 +1240,13 @@ static const gchar introspection_xml[] = " " " " " " +" " +" " +" " +" " +" " +" " +" " " " ""; @@ -1614,6 +1735,56 @@ out: g_dbus_method_invocation_return_value(invocation, param); } +static void launch_on_event_from_userevent(GDBusConnection *connection, + const gchar *sender, GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + GVariant *param; + int result = ES_R_OK; + int len; + bool trusted; + int sender_pid; + uid_t sender_uid; + char *event_name; + char app_id[128]; + char *buf; + bundle *b; + + g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted); + + if (!event_name) { + result = ES_R_ERROR; + _E("invalid event_name"); + goto out; + } + + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + b = bundle_decode((bundle_raw *)buf, len); + if (b == NULL) { + _E("Out of memory"); + result = ES_R_ENOMEM; + goto out; + } + + __esd_launch_event_handler(event_name, b, true, trusted, + sender_uid, app_id, NULL); + + bundle_free(b); + +out: + param = g_variant_new("(i)", result); + + g_dbus_method_invocation_return_value(invocation, param); +} + static void handle_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, @@ -1638,6 +1809,8 @@ static void handle_method_call(GDBusConnection *connection, keep_last_data_method_call(connection, sender, parameters, invocation); } else if (g_strcmp0(method_name, "CheckLastData") == 0) { check_last_data_method_call(connection, sender, parameters, invocation); + } else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) { + launch_on_event_from_userevent(connection, sender, parameters, invocation); } } @@ -1905,7 +2078,6 @@ static int __esd_appcontrol_cb(const char *operation, char *appid = NULL; char *pkgid = NULL; char *event_name = NULL; - const char *prefix = "event://"; uid_t uid = 0; if (cb_data == NULL) { @@ -1920,25 +2092,33 @@ static int __esd_appcontrol_cb(const char *operation, uid, appid, pkgid, operation, uri, mime); if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) { - if (uri && !strncmp(uri, prefix, strlen(prefix))) { + if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) { event_name = strdup(&uri[8]); if (event_name) { _D("appid(%s), event_name(%s)", appid, event_name); - if (!__esd_check_event_launch_support(event_name)) { + if (!__esd_check_event_launch_support(event_name)) _E("failed to add item (not support event)"); - } else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) { + else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) _E("failed to add item (no privilege)"); - } else { + else if (__esd_add_launch_item(uid, event_name, appid, pkgid)) + _E("failed to add item"); + + } else { + _E("out of memory"); + } + } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) { + event_name = strdup(uri); + if (event_name) { + _D("appid(%s), event_name(%s)", appid, event_name); + if (__esd_check_platform_cert(pkgid, uid)) { if (__esd_add_launch_item(uid, event_name, appid, pkgid)) _E("failed to add item"); } - FREE_AND_NULL(event_name); } else { _E("out of memory"); } - } else { - _E("Invalid uri(%s) for event_name", uri); } + FREE_AND_NULL(event_name); } return 0; @@ -2041,9 +2221,10 @@ static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, return 0; } ret = pkgmgrinfo_appinfo_get_usr_list(handle, - PMINFO_ALL_APP, __esd_add_appinfo_handler, &target_uid, target_uid); + PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid); if (ret < 0) { _E("failed to get appinfo"); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); __esd_pkgmgr_event_free(pkg_event); return 0; }