#include <stdlib.h>
#include <glib.h>
#include <aul.h>
+#include <aul_svc.h>
#include <unistd.h>
#include <ctype.h>
#include <dlog.h>
#include <vconf.h>
#include <tzplatform_config.h>
#include <systemd/sd-login.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
#include <cynara-client.h>
#include <cynara-creds-gdbus.h>
#include <cynara-session.h>
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;
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;
}
#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;
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;
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);
}
}
-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;
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));
}
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);
#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)
" <arg type='s' name='own_name' direction='in'/>"
" <arg type='i' name='ret' direction='out'/>"
" </method>"
+" <method name='LaunchOnEventFromUserEvent'>"
+" <arg type='s' name='eventname' direction='in'/>"
+" <arg type='s' name='eventdata' direction='in'/>"
+" <arg type='i' name='datalen' direction='in'/>"
+" <arg type='b' name='trusted' direction='in'/>"
+" <arg type='i' name='ret' direction='out'/>"
+" </method>"
" </interface>"
"</node>";
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,
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);
}
}
char *appid = NULL;
char *pkgid = NULL;
char *event_name = NULL;
- const char *prefix = "event://";
uid_t uid = 0;
if (cb_data == NULL) {
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;
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;
}