Fix stack overflow
[platform/core/appfw/event-system.git] / src / esd_main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <glib.h>
4 #include <aul.h>
5 #include <aul_svc.h>
6 #include <unistd.h>
7 #include <ctype.h>
8 #include <dlog.h>
9 #include <gio/gio.h>
10 #include <package-manager.h>
11 #include <pkgmgr-info.h>
12 #include <appsvc/appsvc.h>
13 #include <eventsystem.h>
14 #include <bundle_internal.h>
15 #include <fcntl.h>
16 #include <vconf.h>
17 #include <tzplatform_config.h>
18 #include <systemd/sd-login.h>
19 #include <cert-svc/ccert.h>
20 #include <cert-svc/cinstance.h>
21 #include <cynara-client.h>
22 #include <cynara-creds-gdbus.h>
23 #include <cynara-session.h>
24 #include <security-manager.h>
25 #include "eventsystem_daemon.h"
26
27 #define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER)
28 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
29 #define ROOT_USER 0
30
31 #define SYS_EVENT_NAME_PREFIX "tizen.system.event"
32 #define SYS_EVENT_OBJ_PATH "/tizen/system/event"
33 #define REQUEST_LAST_DATA "request_last_data"
34
35 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
36
37 static const char *event_launch_support_list[] = {
38         SYS_EVENT_BATTERY_CHARGER_STATUS,
39         SYS_EVENT_USB_STATUS,
40         SYS_EVENT_EARJACK_STATUS,
41         SYS_EVENT_INCOMMING_MSG,
42         SYS_EVENT_OUTGOING_MSG,
43         SYS_EVENT_WIFI_STATE
44 };
45
46 struct privilege_info {
47         const char *event_name;
48         const char *privilege_name;
49 };
50
51 static const struct privilege_info privilege_check_list[] = {
52         {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
53         {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
54         {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"},
55         {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"}
56 };
57
58 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
59
60 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
61 static const char *earlier_event_list[] = {
62         SYS_EVENT_ESD_STATUS,
63         SYS_EVENT_LOW_MEMORY,
64         SYS_EVENT_BOOT_COMPLETED,
65         SYS_EVENT_SYSTEM_SHUTDOWN,
66         SYS_EVENT_BATTERY_CHARGER_STATUS
67 };
68
69 static GHashTable *earlier_event_table; /* table of events for earlier_data */
70
71 typedef struct __earlier_table_item {
72         char *event_name;
73         guint reg_id;
74         bundle *earlier_data; /* event-data from earlier occurrence */
75 } earlier_item;
76
77 #endif
78
79 static GHashTable *user_last_event_table; /* table of user events for last data */
80
81 struct __last_event_item {
82         char *key;
83         char *app_id;
84         char *event_name;
85         char *own_name;
86         uid_t uid;
87 };
88
89 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
90
91 typedef struct __trusted_busname_item {
92         char *app_id;
93         char *bus_name;
94         int pid;
95         uid_t uid;
96 } trusted_item;
97
98 typedef struct __eventlaunch_item_param {
99         char *app_id;
100 } eventlaunch_item_param_s;
101
102 enum trusted_result {
103         TRUSTED_UNKNOWN,
104         TRUSTED_ALLOWED,
105         TRUSTED_DENIED,
106 };
107
108 typedef struct esd_list_item {
109         char *pkg_id;
110         char *app_id;
111         int trusted_info;
112         uid_t uid;
113 } esd_list_item_s;
114
115 typedef struct  __event_launch_table_item {
116         char *event_name;
117         char *package_name; /* just for passing pointer to app-list removal func */
118         GList *app_list_evtlaunch; /* app-list for on-event-launch */
119         guint reg_id;
120         uid_t uid;
121 } event_launch_item;
122
123 enum __pkg_event_type {
124         UNKNOWN = 0,
125         INSTALL,
126         UNINSTALL,
127         UPDATE,
128 };
129
130 typedef struct __pkgmgr_event {
131         int type;
132         char *pkgid;
133 } esd_pkgmgr_event;
134
135 typedef struct __esd_event_param {
136         char *event_name;
137         bundle *event_data;
138         uid_t sender_uid;
139         char *sender_appid;
140         bool is_user_event;
141         bool trusted;
142         void *user_data;
143 } esd_event_param;
144
145 typedef struct esd_info {
146         pkgmgr_client *client;
147 } esd_info_s;
148 static esd_info_s s_info;
149
150 typedef struct __esd_appctrl_cb_data {
151         char *appid;
152         char *pkgid;
153         uid_t uid;
154 } esd_appctrl_cb_data;
155
156 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
157 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
158
159 static cynara *r_cynara;
160
161 static int __esd_init_cynara(void)
162 {
163         int ret;
164
165         ret  = cynara_initialize(&r_cynara, NULL);
166         if (ret != CYNARA_API_SUCCESS) {
167                 _E("cynara initialize failed.");
168                 return ret;
169         }
170
171         return 0;
172 }
173
174 static void __esd_finish_cynara(void)
175 {
176         if (r_cynara)
177                 cynara_finish(r_cynara);
178         r_cynara = NULL;
179 }
180
181 static void free_saved_event(struct __last_event_item *item)
182 {
183         if (!item)
184                 return;
185
186         free(item->event_name);
187         free(item->own_name);
188         free(item->app_id);
189         free(item);
190 }
191
192 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
193 static int __esd_check_earlier_support(const char *event_name)
194 {
195         int i = 0;
196         int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
197
198         for (i = 0; i < size; i++) {
199                 if (strcmp(earlier_event_list[i], event_name) == 0)
200                         return true;
201         }
202
203         return false;
204 }
205 #endif
206
207 static bool __esd_check_platform_cert(const char *pkgid, uid_t uid)
208 {
209         _D("Checking if %s has a platform certification", pkgid);
210
211         int r;
212         const char *cert_value;
213         pkgmgrinfo_certinfo_h certinfo;
214         CertSvcInstance instance;
215         CertSvcCertificate certificate;
216         CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
217
218         r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
219         if (r != PMINFO_R_OK) {
220                 _E("Failed to create certinfo");
221                 return false;
222         }
223
224         r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
225         if (r != PMINFO_R_OK) {
226                 _E("Failed to load certinfo");
227                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
228                 return false;
229         }
230
231         r = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
232                         PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
233         if (r != PMINFO_R_OK || cert_value == NULL) {
234                 _E("Failed to get cert value");
235                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
236                 return false;
237         }
238
239         r = certsvc_instance_new(&instance);
240         if (r != CERTSVC_SUCCESS) {
241                 _E("certsvc_instance_new() is failed.");
242                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
243                 return false;
244         }
245
246         r = certsvc_certificate_new_from_memory(instance,
247                         (const unsigned char *)cert_value,
248                         strlen(cert_value),
249                         CERTSVC_FORM_DER_BASE64,
250                         &certificate);
251         if (r != CERTSVC_SUCCESS) {
252                 _E("certsvc_certificate_new_from_memory() is failed.");
253                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
254                 certsvc_instance_free(instance);
255                 return false;
256         }
257
258         r = certsvc_certificate_get_visibility(certificate, &visibility);
259         if (r != CERTSVC_SUCCESS)
260                 _E("certsvc_certificate_get_visibility() is failed.");
261
262         pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
263         certsvc_instance_free(instance);
264         certsvc_certificate_free(certificate);
265
266         _D("visibility is %d", visibility);
267         if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
268                 _D("%s has a platform certification", pkgid);
269                 return true;
270         }
271
272         return false;
273 }
274
275 static int __esd_check_event_launch_support(const char *event_name)
276 {
277         int i = 0;
278         int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
279
280         for (i = 0; i < size; i++) {
281                 if (strcmp(event_launch_support_list[i], event_name) == 0)
282                         return true;
283         }
284
285         return false;
286 }
287
288 static int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
289 {
290         GDBusMessage *msg = NULL;
291         GDBusMessage *reply = NULL;
292         GError *err = NULL;
293         GVariant *body;
294         int ret = -1;
295         unsigned int value;
296
297         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
298                 "org.freedesktop.DBus", type);
299         if (!msg) {
300                 _E("Can't allocate new method call");
301                 goto out;
302         }
303
304         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
305         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
306                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
307
308         if (!reply) {
309                 if (err != NULL) {
310                         _E("Failed to get info [%s]", err->message);
311                         g_error_free(err);
312                 }
313                 goto out;
314         }
315
316         body = g_dbus_message_get_body(reply);
317         g_variant_get(body, "(u)", &value);
318         ret = (int)value;
319
320 out:
321         if (msg)
322                 g_object_unref(msg);
323         if (reply)
324                 g_object_unref(reply);
325
326         return ret;
327 }
328
329 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
330 {
331         int pid = 0;
332
333         pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
334         if (pid < 0) {
335                 _E("failed to get pid");
336                 pid = 0;
337         }
338
339         _D("sender_name(%s), pid(%d)", sender_name, pid);
340
341         return pid;
342 }
343
344 static int __get_sender_uid(GDBusConnection *conn, const char *sender_name)
345 {
346         int uid = -1;
347
348         uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
349         if (uid < 0)
350                 _E("failed to get uid");
351
352         _D("sender_name(%s), uid(%d)", sender_name, uid);
353
354         return uid;
355 }
356
357 static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid)
358 {
359         pkgmgrinfo_cert_compare_result_type_e res;
360         int ret = 0;
361
362         _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
363
364         ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res);
365         if (ret < 0) {
366                 _E("failed to check certificate");
367                 return ES_R_ERROR;
368         }
369
370         if (res != PMINFO_CERT_COMPARE_MATCH) {
371                 _D("certificat not match (%s)", app_id);
372                 return ES_R_EINVAL;
373         }
374
375         return ES_R_OK;
376 }
377
378 static bool __esd_check_application_validation(uid_t uid, const char *appid)
379 {
380         int ret = 0;
381         pkgmgrinfo_appinfo_h handle;
382
383         ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
384         if (ret != PMINFO_R_OK)
385                 return false;
386
387         pkgmgrinfo_appinfo_destroy_appinfo(handle);
388
389         if (!aul_app_is_running_for_uid(appid, uid))
390                 return false;
391
392         return true;
393 }
394
395 static void __esd_trusted_busname_print_items(void)
396 {
397         GHashTableIter iter;
398         gpointer key;
399         gpointer value;
400
401         g_hash_table_iter_init(&iter, trusted_busname_table);
402
403         while (g_hash_table_iter_next(&iter, &key, &value)) {
404                 trusted_item *item = (trusted_item *)value;
405                 if (item)
406                         _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
407         }
408 }
409
410 static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid)
411 {
412         char *app_id = NULL;
413         char *bus_name = NULL;
414         trusted_item *item = NULL;
415         trusted_item *new_item;
416
417         app_id = strdup(appid);
418         if (app_id == NULL) {
419                 _E("out of memory");
420                 return ES_R_ENOMEM;
421         }
422
423         bus_name = strdup(busname);
424         if (bus_name == NULL) {
425                 _E("out of memory");
426                 FREE_AND_NULL(app_id);
427                 return ES_R_ENOMEM;
428         }
429
430         item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
431
432         if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
433                 (item->uid == uid)) {
434                 _D("already exist (%s, %s)", app_id, bus_name);
435                 FREE_AND_NULL(app_id);
436                 FREE_AND_NULL(bus_name);
437         } else {
438                 new_item = calloc(1, sizeof(trusted_item));
439                 if (new_item == NULL) {
440                         _E("memory alloc failed");
441                         FREE_AND_NULL(app_id);
442                         FREE_AND_NULL(bus_name);
443                         return ES_R_ENOMEM;
444                 }
445                 new_item->uid = uid;
446                 new_item->app_id = app_id;
447                 new_item->bus_name = bus_name;
448                 new_item->pid = pid;
449                 g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
450                 _D("added busname(%s)", new_item->bus_name);
451         }
452
453         return ES_R_OK;
454 }
455
456 static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name)
457 {
458         GVariant *result;
459         GError *error = NULL;
460         GVariantIter *iter;
461         gchar *str;
462         char tmp_appid[128] = {0, };
463         int pid = 0;
464         int uid = 0;
465         int ret = 0;
466
467         result = g_dbus_connection_call_sync(conn,
468                 "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
469                 list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
470                 -1, NULL, &error);
471
472         if (result == NULL) {
473                 _E("get (%s) error(%s)", list_name, error->message);
474                 g_error_free(error);
475                 return ES_R_ERROR;
476         }
477
478         g_variant_get(result, "(as)", &iter);
479         while (g_variant_iter_loop(iter, "s", &str)) {
480                 if (!strstr((const char *)str, "event.busname.session"))
481                         continue;
482
483                 _D("list(%s), name(%s)", list_name, str);
484                 pid = __get_sender_pid(conn, (const char *)str);
485                 if (pid <= 0) {
486                         _E("failed to get pid(%d)", pid);
487                         continue;
488                 }
489
490                 uid = __get_sender_uid(conn, (const char *)str);
491                 if (uid < 0) {
492                         _E("failed to get uid(%d)", uid);
493                         continue;
494                 }
495                 _D("uid(%d)", uid);
496
497                 memset(tmp_appid, 0, sizeof(tmp_appid));
498                 ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid);
499                 if (ret != AUL_R_OK) {
500                         _E("failed to get appid by pid(%d)", pid);
501                         continue;
502                 }
503
504                 _D("appid(%s)", tmp_appid);
505                 if (__esd_check_application_validation((uid_t)uid, tmp_appid)) {
506                         _D("add to table");
507                         ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid);
508                         if (ret < 0)
509                                 _E("failed to add item");
510                 }
511         }
512         g_variant_iter_free(iter);
513         g_variant_unref(result);
514
515         return ES_R_OK;
516 }
517
518 static int __esd_check_privilege_name(const char *event_name, char **privilege_name)
519 {
520         int i = 0;
521
522         *privilege_name = NULL;
523
524         for (i = 0; i < privilege_check_size; i++) {
525                 if (strcmp(event_name, privilege_check_list[i].event_name) == 0) {
526                         *privilege_name = (char *)privilege_check_list[i].privilege_name;
527                         _D("[%d] privilege_name(%s)", i, *privilege_name);
528                         break;
529                 }
530         }
531
532         return ES_R_OK;
533 }
534
535 static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client,
536         const char *session, const char *user, const char *privilege_name)
537 {
538         int ret = 0;
539         bool has_privilege = false;
540
541         _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name);
542
543         ret = cynara_check(r_cynara, client, session, user, privilege_name);
544         if (ret == CYNARA_API_ACCESS_ALLOWED) {
545                 _D("valid privilege");
546                 has_privilege = true;
547         } else if (ret == CYNARA_API_ACCESS_DENIED) {
548                 _E("invalid privilege");
549         } else {
550                 _E("failed to check privilege, error(%d)", ret);
551         }
552
553         return has_privilege;
554 }
555
556 static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name)
557 {
558         char *privilege_name = NULL;
559         int ret = 0;
560         int result = 0;
561
562         _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid);
563
564         __esd_check_privilege_name(event_name, &privilege_name);
565
566         if (privilege_name) {
567                 ret = security_manager_app_has_privilege(appid, privilege_name, uid, &result);
568                 if (ret != SECURITY_MANAGER_SUCCESS)
569                         _E("failed to check privilege(%d)", ret);
570                 _D("result(%d)", result);
571         } else {
572                 result = 1;
573         }
574
575         return result;
576 }
577
578 static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data)
579 {
580         esd_list_item_s *item = (esd_list_item_s *)data;
581         char *event_name = (char *)user_data;
582
583         _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
584 }
585
586 static void __esd_print_interested_event(gpointer data, gpointer user_data)
587 {
588         event_launch_item *el_item = (event_launch_item *)data;
589         char *event_name = (char *)el_item->event_name;
590         _D("event_name = (%s)", event_name);
591         g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
592 }
593
594 static void __esd_launch_table_print_items(void)
595 {
596         GHashTableIter iter;
597         gpointer key;
598         gpointer value;
599
600         g_hash_table_iter_init(&iter, event_launch_table);
601
602         while (g_hash_table_iter_next(&iter, &key, &value))
603                 __esd_print_interested_event(value, NULL);
604 }
605
606 static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data)
607 {
608         esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
609         esd_list_item_s *item_2 = (esd_list_item_s *)data;
610
611         return (item_1->uid != item_2->uid) |
612                 strcmp(item_1->app_id, item_2->app_id) |
613                 strcmp(item_1->pkg_id, item_2->pkg_id);
614 }
615
616 static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
617                 const char *app_id, const char *pkg_id)
618 {
619         esd_list_item_s *item_of_list = NULL;
620
621         item_of_list = calloc(1, sizeof(esd_list_item_s));
622         if (item_of_list == NULL) {
623                 _E("out_of_memory");
624                 return ES_R_ENOMEM;
625         }
626         item_of_list->uid = uid;
627         item_of_list->app_id = (char *)app_id;
628         item_of_list->pkg_id = (char *)pkg_id;
629         item_of_list->trusted_info = TRUSTED_UNKNOWN;
630         el_item->app_list_evtlaunch =
631                 g_list_append(el_item->app_list_evtlaunch, item_of_list);
632
633         return ES_R_OK;
634 }
635
636 static int __esd_add_launch_item(uid_t uid, const char *event_name,
637                 const char *appid, const char *pkgid)
638 {
639         GList *app_list = NULL;
640         guint subscription_id = 0;
641         char *app_id = NULL;
642         char *pkg_id = NULL;
643         esd_list_item_s *item_of_list = NULL;
644         event_launch_item *eli;
645         event_launch_item *el_item =
646                 (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
647
648         if (el_item) {
649                 item_of_list = calloc(1, sizeof(esd_list_item_s));
650                 if (item_of_list == NULL) {
651                         _E("memory alloc failed");
652                         return ES_R_ENOMEM;
653                 }
654                 item_of_list->uid = uid;
655                 item_of_list->app_id = (char *)appid;
656                 item_of_list->pkg_id = (char *)pkgid;
657
658                 app_list = g_list_find_custom(el_item->app_list_evtlaunch,
659                         item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
660                 free(item_of_list);
661                 if (app_list == NULL) {
662                         _D("add new item (list item only)");
663                         app_id = strdup((char *)appid);
664                         if (!app_id) {
665                                 _E("out_of_memory");
666                                 return ES_R_ENOMEM;
667                         }
668                         pkg_id = strdup((char *)pkgid);
669                         if (!pkg_id) {
670                                 _E("out_of_memory");
671                                 FREE_AND_NULL(app_id);
672                                 return ES_R_ENOMEM;
673                         }
674                         if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
675                                 _E("failed to add list item");
676                                 FREE_AND_NULL(app_id);
677                                 FREE_AND_NULL(pkg_id);
678                                 return ES_R_ERROR;
679                         }
680                 }
681         } else {
682                 _D("add new item (all)");
683                 eli = calloc(1, sizeof(event_launch_item));
684                 if (!eli) {
685                         _E("memory alloc failed");
686                         return ES_R_ENOMEM;
687                 }
688
689                 eli->event_name = strdup(event_name);
690                 if (!eli->event_name) {
691                         _E("out_of_memory");
692                         FREE_AND_NULL(eli);
693                         return ES_R_ENOMEM;
694                 }
695
696                 app_id = strdup((char *)appid);
697                 if (!app_id) {
698                         _E("out_of_memory");
699                         FREE_AND_NULL(eli->event_name);
700                         FREE_AND_NULL(eli);
701                         return ES_R_ENOMEM;
702                 }
703
704                 pkg_id = strdup((char *)pkgid);
705                 if (!pkg_id) {
706                         _E("out_of_memory");
707                         FREE_AND_NULL(app_id);
708                         FREE_AND_NULL(eli->event_name);
709                         FREE_AND_NULL(eli);
710                         return ES_R_ENOMEM;
711                 }
712
713                 if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
714                         _E("failed to add list item");
715                         FREE_AND_NULL(app_id);
716                         FREE_AND_NULL(pkg_id);
717                         FREE_AND_NULL(eli->event_name);
718                         FREE_AND_NULL(eli);
719                         return ES_R_ERROR;
720                 }
721
722                 g_hash_table_insert(event_launch_table, eli->event_name, eli);
723
724                 eventsystem_register_event(eli->event_name, &subscription_id,
725                         (eventsystem_handler)__esd_event_handler, NULL);
726                 if (subscription_id == 0) {
727                         _E("signal subscription error, event_name(%s), app_id(%s)",
728                                 eli->event_name, app_id);
729                         return ES_R_ERROR;
730                 } else {
731                         eli->reg_id = subscription_id;
732                 }
733         }
734
735         return ES_R_OK;
736 }
737
738 static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data)
739 {
740         esd_list_item_s *item = (esd_list_item_s *)data;
741         event_launch_item *eli = (event_launch_item *)user_data;
742
743         if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
744                 _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
745                 eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
746         }
747 }
748
749 static int __esd_launch_table_remove_private_usr_items(void)
750 {
751         GHashTableIter iter;
752         gpointer key;
753         gpointer value;
754         event_launch_item *eli = NULL;
755         GList *first_list = NULL;
756
757         g_hash_table_iter_init(&iter, event_launch_table);
758
759         while (g_hash_table_iter_next(&iter, &key, &value)) {
760                 eli = (event_launch_item *)value;
761                 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
762
763                 first_list = g_list_first(eli->app_list_evtlaunch);
764                 if (first_list == NULL) {
765                         if (eli->reg_id)
766                                 eventsystem_unregister_event(eli->reg_id);
767
768                         g_hash_table_iter_remove(&iter);
769                 }
770         }
771
772         return ES_R_OK;
773 }
774
775 static void __esd_remove_app_list(gpointer data, gpointer user_data)
776 {
777         bool skip = false;
778         esd_list_item_s *item = (esd_list_item_s *)data;
779         event_launch_item *eli = (event_launch_item *)user_data;
780
781         if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
782                 skip = true;
783
784         if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
785                 _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
786                 eli->app_list_evtlaunch =
787                         g_list_remove_all(eli->app_list_evtlaunch, data);
788         }
789 }
790
791 static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id)
792 {
793         event_launch_item *eli = (event_launch_item *)data;
794         GList *first_list = NULL;
795
796         eli->uid = uid;
797         eli->package_name = (char *)pkg_id;
798         g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
799
800         first_list = g_list_first(eli->app_list_evtlaunch);
801         if (first_list == NULL) {
802                 if (eli->reg_id)
803                         eventsystem_unregister_event(eli->reg_id);
804
805                 return ES_R_REMOVE;
806         }
807
808         return ES_R_OK;
809 }
810
811 static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id)
812 {
813         GHashTableIter iter;
814         gpointer key;
815         gpointer value;
816
817         g_hash_table_iter_init(&iter, event_launch_table);
818
819         while (g_hash_table_iter_next(&iter, &key, &value)) {
820                 if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
821                         _D("remove item itself");
822                         g_hash_table_iter_remove(&iter);
823                 }
824         }
825
826         return ES_R_OK;
827 }
828
829 static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
830 {
831         esd_list_item_s *item = (esd_list_item_s *)data;
832         uid_t uid = item->uid;
833         char *app_id = item->app_id;
834         esd_event_param *eep = (esd_event_param *)user_data;
835         static unsigned int req_id;
836         int pid;
837         char event_uri[1024];
838         bundle *b;
839         int ret;
840
841         _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)",
842                         app_id, eep->event_name, uid, eep->is_user_event, eep->trusted);
843
844         if (eep->is_user_event && eep->trusted) {
845                 if (item->trusted_info == TRUSTED_UNKNOWN) {
846                         ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid);
847                         if (ret == ES_R_EINVAL) {
848                                 item->trusted_info = TRUSTED_DENIED;
849                                 return;
850                         } else if (ret == ES_R_ERROR) {
851                                 return;
852                         } else {
853                                 item->trusted_info = TRUSTED_ALLOWED;
854                         }
855                 } else if (item->trusted_info == TRUSTED_DENIED) {
856                         return;
857                 }
858         }
859
860         if (!aul_app_is_running_for_uid(app_id, uid)) {
861                 b = bundle_dup(eep->event_data);
862                 if (eep->is_user_event)
863                         snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name);
864                 else
865                         snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name);
866
867                 appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
868                 appsvc_set_uri(b, event_uri);
869                 appsvc_set_appid(b, app_id);
870
871                 pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid);
872                 _D("uid(%d), pid(%d)", uid, pid);
873
874                 bundle_free(b);
875         } else {
876                 _D("already is running or launch failed");
877         }
878 }
879
880 static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data)
881 {
882         event_launch_item *el_item = (event_launch_item *)data;
883         esd_event_param *eep = (esd_event_param *)user_data;
884
885         if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
886                 g_list_foreach(el_item->app_list_evtlaunch,
887                         __esd_event_launch_with_appid, user_data);
888         }
889 }
890
891 static void __esd_launch_event_handler(char *event_name, bundle *data,
892                 const bool is_user_event, gboolean trusted,
893                 const uid_t sender_uid, char *sender_appid, void *user_data)
894 {
895         const char *val;
896         const char *msg_type;
897         const char *msg_id;
898         esd_event_param *eep;
899         event_launch_item *el_item;
900
901         _D("event_name(%s)", event_name);
902
903         el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
904         if (el_item == NULL)
905                 return;
906
907         if (el_item->app_list_evtlaunch != NULL) {
908                 if (is_user_event == false) {
909                         if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
910                                 val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
911                                 _D("charger val(%s)", val);
912                                 if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0))
913                                         return;
914                         } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
915                                 val = bundle_get_val(data, EVT_KEY_USB_STATUS);
916                                 _D("usb val(%s)", val);
917                                 if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0))
918                                         return;
919                         } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
920                                 val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
921                                 _D("earjack val(%s)", val);
922                                 if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0))
923                                         return;
924                         } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
925                                 msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
926                                 _D("msg_type(%s)", msg_type);
927                                 if (msg_type == NULL)
928                                         return;
929
930                                 msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
931                                 _D("msg_id(%s)", msg_id);
932                                 if (msg_id == NULL)
933                                         return;
934                         } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) {
935                                 val = bundle_get_val(data, EVT_KEY_WIFI_STATE);
936                                 if (val == NULL)
937                                         return;
938                                 _D("wifi_state(%s)", val);
939                                 if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0)
940                                         return;
941                         }
942                 }
943
944                 eep = calloc(1, sizeof(esd_event_param));
945                 if (!eep) {
946                         _E("memory alloc failed");
947                         return;
948                 }
949                 eep->event_name = event_name;
950                 eep->event_data = data;
951                 eep->sender_uid = sender_uid;
952                 eep->sender_appid = sender_appid;
953                 eep->is_user_event = is_user_event;
954                 eep->trusted = (bool)trusted;
955                 eep->user_data = (void *)user_data;
956                 __esd_check_event_launch_with_eventid(el_item, eep);
957                 free(eep);
958         }
959 }
960
961 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
962 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
963 {
964         earlier_item *item = (earlier_item *)data;
965         char *event_name = (char *)item->event_name;
966         const char *val;
967
968         _D("event_name = (%s)", event_name);
969
970         if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
971                 if (item->earlier_data) {
972                         val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
973                         _D("boot_completed(%s)", val);
974                 }
975         } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
976                 if (item->earlier_data) {
977                         val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
978                         _D("shutdown(%s)", val);
979                 }
980         } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
981                 if (item->earlier_data) {
982                         val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
983                         _D("low_memory(%s)", val);
984                 }
985         } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
986                 if (item->earlier_data) {
987                         val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
988                         _D("charger_status(%s)", val);
989                 }
990         }
991 }
992
993 static void __esd_earlier_table_print_items(void)
994 {
995         GHashTableIter iter;
996         gpointer key;
997         gpointer value;
998
999         g_hash_table_iter_init(&iter, earlier_event_table);
1000
1001         while (g_hash_table_iter_next(&iter, &key, &value))
1002                 __esd_print_earlier_event(value, NULL);
1003 }
1004
1005 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
1006 {
1007         earlier_item *item;
1008         _D("event_name(%s)", event_name);
1009
1010         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1011         if (item) {
1012                 /* update earlier value */
1013                 if (item->earlier_data != NULL)
1014                         bundle_free(item->earlier_data);
1015
1016                 item->earlier_data = bundle_dup(data);
1017         }
1018 }
1019 #endif
1020
1021 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
1022 {
1023         _D("event_name(%s)", event_name);
1024
1025 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1026         if (__esd_check_earlier_support(event_name))
1027                 __esd_earlier_event_handler(event_name, data, user_data);
1028 #endif
1029
1030         if (__esd_check_event_launch_support(event_name))
1031                 __esd_launch_event_handler(event_name, data,
1032                                 false, TRUE, ROOT_USER, NULL, user_data);
1033 }
1034
1035 static void __esd_trusted_busname_remove_item(char *bus_name)
1036 {
1037         GHashTableIter iter;
1038         gpointer key;
1039         gpointer value;
1040         trusted_item *item;
1041
1042         g_hash_table_iter_init(&iter, trusted_busname_table);
1043
1044         while (g_hash_table_iter_next(&iter, &key, &value)) {
1045                 item = (trusted_item *)value;
1046                 if (item) {
1047                         if (strcmp(bus_name, item->bus_name) == 0) {
1048                                 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
1049                                 FREE_AND_NULL(item->app_id);
1050                                 FREE_AND_NULL(item->bus_name);
1051                                 FREE_AND_NULL(item);
1052                                 g_hash_table_iter_remove(&iter);
1053
1054                                 __esd_trusted_busname_print_items();
1055                         }
1056                 }
1057         }
1058 }
1059
1060 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
1061                 const gchar *sender_name, const gchar *object_path,
1062                 const gchar *interface_name, const gchar *signal_name,
1063                 GVariant *parameters, gpointer user_data)
1064 {
1065         char *name = NULL;
1066         char *old_owner = NULL;
1067         char *new_owner = NULL;
1068         int old_len = 0;
1069         int new_len = 0;
1070
1071         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
1072
1073         if (strstr(name, "event.busname.session")) {
1074                 old_len = strlen(old_owner);
1075                 new_len = strlen(new_owner);
1076
1077                 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
1078                         name, old_owner, old_len, new_owner, new_len);
1079
1080                 if (old_len > 0 && new_len == 0)
1081                         __esd_trusted_busname_remove_item(name);
1082                 else if (old_len == 0 && new_len > 0)
1083                         _D("new name owned");
1084                 else
1085                         _E("not-expected name change");
1086         }
1087 }
1088
1089 static int __esd_dbus_name_monitor(GDBusConnection *connection)
1090 {
1091         guint name_owner_changed_id = 0;
1092
1093         name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
1094                 "org.freedesktop.DBus", "org.freedesktop.DBus",
1095                 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1096                 __esd_filter_name_owner_changed, NULL, NULL);
1097
1098         _I("name_owner_changed_id(%d)", name_owner_changed_id);
1099
1100         return ES_R_OK;
1101 }
1102
1103 static int __esd_get_user_items(uid_t uid)
1104 {
1105         int ret = 0;
1106         pkgmgrinfo_appinfo_filter_h handle = NULL;
1107
1108         _I("get user items for uid(%d)", uid);
1109         /* reset user's item */
1110         __esd_launch_table_remove_private_usr_items();
1111
1112         ret = pkgmgrinfo_appinfo_filter_create(&handle);
1113         if (ret < 0) {
1114                 _E("failed to create appinfo filter");
1115                 return ES_R_ERROR;
1116         }
1117         ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1118                         PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
1119         if (ret < 0) {
1120                 _E("failed to add appinfo filter string");
1121                 pkgmgrinfo_appinfo_filter_destroy(handle);
1122                 return ES_R_ERROR;
1123         }
1124         ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1125                         PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
1126         if (ret < 0) {
1127                 _E("failed to add appinfo filter string");
1128                 pkgmgrinfo_appinfo_filter_destroy(handle);
1129                 return ES_R_ERROR;
1130         }
1131         ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
1132                         __esd_add_appinfo_handler, &uid, uid);
1133         if (ret < 0) {
1134                 _E("appinfo filter foreach error");
1135                 pkgmgrinfo_appinfo_filter_destroy(handle);
1136                 return ES_R_ERROR;
1137         }
1138         pkgmgrinfo_appinfo_filter_destroy(handle);
1139
1140         __esd_launch_table_print_items();
1141
1142         return ES_R_OK;
1143 }
1144
1145 static void __esd_signal_handler(GDBusConnection *connection,
1146                 const gchar *sender_name,
1147                 const gchar *object_path,
1148                 const gchar *interface_name,
1149                 const gchar *signal_name,
1150                 GVariant *parameters,
1151                 gpointer user_data)
1152 {
1153         int handle;
1154         bundle *b;
1155         guint64 uid = 0;
1156
1157         if (!g_strcmp0(signal_name,
1158                                 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
1159                 _I("System session finished");
1160
1161                 b = bundle_create();
1162                 bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
1163                         EVT_VAL_BOOT_COMPLETED_TRUE);
1164                 eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
1165                 bundle_free(b);
1166
1167                 handle = creat(ESD_BOOT_COMPLETED, 0640);
1168                 if (handle != -1)
1169                         close(handle);
1170         } else if (!g_strcmp0(signal_name,
1171                                 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
1172                 g_variant_get(parameters, "(t)", &uid);
1173                 _I("User session finished uid : %d", (int)uid);
1174                 if ((uid_t)uid != DEFAULT_USER)
1175                         __esd_get_user_items((uid_t)uid);
1176         }
1177 }
1178
1179 static GDBusNodeInfo *introspection_data;
1180 static const gchar introspection_xml[] =
1181 "<node>"
1182 "       <interface name='tizen.system.event.app2esd'>"
1183 "               <method name='CheckSenderValidation'>"
1184 "                       <arg type='i' name='senderpid' direction='in'/>"
1185 "                       <arg type='s' name='eventname' direction='in'/>"
1186 "                       <arg type='i' name='ret' direction='out'/>"
1187 "                       <arg type='s' name='senderid' direction='out'/>"
1188 "               </method>"
1189 "               <method name='GetTrustedPeerList'>"
1190 "                       <arg type='s' name='eventname' direction='in'/>"
1191 "                       <arg type='i' name='ret' direction='out'/>"
1192 "                       <arg type='as' name='dest_list' direction='out'/>"
1193 "               </method>"
1194 "               <method name='SetupTrustedPeer'>"
1195 "                       <arg type='s' name='eventname' direction='in'/>"
1196 "                       <arg type='s' name='destination' direction='in'/>"
1197 "                       <arg type='i' name='ret' direction='out'/>"
1198 "               </method>"
1199 "               <method name='CheckPrivilegeValidation'>"
1200 "                       <arg type='s' name='eventname' direction='in'/>"
1201 "                       <arg type='i' name='ret' direction='out'/>"
1202 "               </method>"
1203 "               <method name='CheckUserSendValidation'>"
1204 "                       <arg type='s' name='eventname' direction='in'/>"
1205 "                       <arg type='i' name='ret' direction='out'/>"
1206 "               </method>"
1207 "               <method name='RequestTrustedEventLaunch'>"
1208 "                       <arg type='s' name='eventname' direction='in'/>"
1209 "                       <arg type='s' name='eventdata' direction='in'/>"
1210 "                       <arg type='i' name='datalen' direction='in'/>"
1211 "                       <arg type='i' name='ret' direction='out'/>"
1212 "               </method>"
1213 "               <method name='RequestEventLaunch'>"
1214 "                       <arg type='s' name='eventname' direction='in'/>"
1215 "                       <arg type='s' name='eventdata' direction='in'/>"
1216 "                       <arg type='i' name='datalen' direction='in'/>"
1217 "                       <arg type='i' name='ret' direction='out'/>"
1218 "               </method>"
1219 "               <method name='RequestSendingEvent'>"
1220 "                       <arg type='s' name='eventname' direction='in'/>"
1221 "                       <arg type='s' name='eventdata' direction='in'/>"
1222 "                       <arg type='i' name='datalen' direction='in'/>"
1223 "                       <arg type='i' name='ret' direction='out'/>"
1224 "               </method>"
1225 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1226 "               <method name='GetEarlierData'>"
1227 "                       <arg type='s' name='appid' direction='in'/>"
1228 "                       <arg type='i' name='ret' direction='out'/>"
1229 "                       <arg type='i' name='len' direction='out'/>"
1230 "                       <arg type='s' name='earlier_data' direction='out'/>"
1231 "               </method>"
1232 #endif
1233 "               <method name='KeepLastData'>"
1234 "                       <arg type='s' name='eventname' direction='in'/>"
1235 "                       <arg type='s' name='own_name' direction='in'/>"
1236 "                       <arg type='i' name='ret' direction='out'/>"
1237 "               </method>"
1238 "               <method name='CheckLastData'>"
1239 "                       <arg type='s' name='eventname' direction='in'/>"
1240 "                       <arg type='s' name='own_name' direction='in'/>"
1241 "                       <arg type='i' name='ret' direction='out'/>"
1242 "               </method>"
1243 "               <method name='LaunchOnEventFromUserEvent'>"
1244 "                       <arg type='s' name='eventname' direction='in'/>"
1245 "                       <arg type='s' name='eventdata' direction='in'/>"
1246 "                       <arg type='i' name='datalen' direction='in'/>"
1247 "                       <arg type='b' name='trusted' direction='in'/>"
1248 "                       <arg type='i' name='ret' direction='out'/>"
1249 "               </method>"
1250 "       </interface>"
1251 "</node>";
1252
1253 static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
1254 {
1255         int retval = ES_R_OK;
1256         int ret = 0;
1257
1258         if (pid <= 0) {
1259                 _E("invalid pid(%d)", pid);
1260                 retval = ES_R_ERROR;
1261         } else if (uid <= 0) {
1262                 _E("invalid uid(%d)", uid);
1263                 retval = ES_R_ERROR;
1264         } else {
1265                 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1266                 if (ret != AUL_R_OK) {
1267                         _E("failed to get appid by pid");
1268                         retval = ES_R_ERROR;
1269                 }
1270                 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1271         }
1272
1273         return retval;
1274 }
1275
1276 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1277 {
1278         char *valid_name = NULL;
1279         char *temp_name = NULL;
1280         char *tmp = NULL;
1281         int retval = ES_R_OK;
1282         int len = 0;
1283         int valid_name_len = 0;
1284
1285         temp_name = strdup(event_name);
1286         if (temp_name == NULL) {
1287                 _E("out of memory");
1288                 return ES_R_ENOMEM;
1289         }
1290
1291         tmp = strrchr(temp_name, '.');
1292         if (tmp == NULL || strlen(tmp) == 0) {
1293                 _E("invalid event name");
1294                 FREE_AND_NULL(temp_name);
1295                 return ES_R_EINVAL;
1296         }
1297         len = strlen(tmp);
1298         if (len <= 1 || len > 128) {
1299                 _E("invalid length(%d) of user-defined name", len);
1300                 FREE_AND_NULL(temp_name);
1301                 return ES_R_EINVAL;
1302         }
1303         *tmp = '\0';
1304
1305         _D("app_id(%s), len(%zu)", app_id, strlen(app_id));
1306
1307         valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1308         valid_name = calloc(1, valid_name_len);
1309         if (valid_name == NULL) {
1310                 _E("memory alloc failed");
1311                 FREE_AND_NULL(temp_name);
1312                 return ES_R_ENOMEM;
1313         }
1314         snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1315         _D("valid_name(%s)", valid_name);
1316
1317         if (strcmp(temp_name, valid_name) != 0) {
1318                 _E("appid misamatch");
1319                 retval = ES_R_EINVAL;
1320         }
1321
1322         FREE_AND_NULL(temp_name);
1323         FREE_AND_NULL(valid_name);
1324
1325         return retval;
1326 }
1327
1328 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1329         GVariant *parameters, GDBusMethodInvocation *invocation)
1330 {
1331         GVariant *param = NULL;
1332         int result = 0;
1333         char *event_name = NULL;
1334         char app_id[128] = {0, };
1335         int event_sender_pid = 0;
1336         uid_t sender_uid = 0;
1337
1338         g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
1339         _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1340
1341         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1342         if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1343                 result = ES_R_ERROR;
1344         } else {
1345                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1346                         _E("invalid sender");
1347                         result = ES_R_EINVAL;
1348                 } else {
1349                         result = 1;
1350                 }
1351         }
1352
1353         param = g_variant_new("(is)", result, app_id);
1354         _D("event_name(%s), result(%d)", event_name, result);
1355         g_dbus_method_invocation_return_value(invocation, param);
1356 }
1357
1358 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1359         GVariant *parameters, GDBusMethodInvocation *invocation)
1360 {
1361         GVariant *param = NULL;
1362         int result = 0;
1363         char *event_name = NULL;
1364         char app_id[128] = {0, };
1365         int sender_pid = 0;
1366         uid_t sender_uid = 0;
1367
1368         g_variant_get(parameters, "(&s)", &event_name);
1369         _D("event_name(%s)", event_name);
1370
1371         sender_pid = __get_sender_pid(connection, sender);
1372         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1373         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1374                 result = ES_R_ERROR;
1375         } else {
1376                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1377                         _E("invalid sender");
1378                         result = ES_R_EINVAL;
1379                 } else {
1380                         result = 1;
1381                 }
1382         }
1383
1384         param = g_variant_new("(i)", result);
1385         _D("event_name(%s), result(%d)", event_name, result);
1386         g_dbus_method_invocation_return_value(invocation, param);
1387 }
1388
1389 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1390         GVariant *parameters, GDBusMethodInvocation *invocation)
1391 {
1392         GVariant *param = NULL;
1393         int result = 0;
1394         GVariantBuilder *builder = NULL;
1395         GHashTableIter iter;
1396         gpointer key, value;
1397         char *event_name = NULL;
1398         char app_id[128] = {0, };
1399         int sender_pid = 0;
1400         uid_t sender_uid = 0;
1401         int ret = 0;
1402         uid_t uid = 0;
1403         char *_appid = NULL;
1404         char *_busname = NULL;
1405         trusted_item *item;
1406
1407         g_variant_get(parameters, "(&s)", &event_name);
1408         _D("event_name(%s)", event_name);
1409
1410         sender_pid = __get_sender_pid(connection, sender);
1411         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1412         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1413                 result = ES_R_ERROR;
1414         } else {
1415                 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1416
1417                 g_hash_table_iter_init(&iter, trusted_busname_table);
1418                 while (g_hash_table_iter_next(&iter, &key, &value)) {
1419                         item = (trusted_item *)value;
1420                         uid = item->uid;
1421                         _appid = item->app_id;
1422                         _busname = item->bus_name;
1423
1424                         if (uid != GLOBAL_USER && uid != sender_uid)
1425                                 continue;
1426
1427                         ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1428                         if (ret == ES_R_OK)
1429                                 g_variant_builder_add(builder, "s", _busname);
1430                 }
1431
1432                 result = 1;
1433         }
1434
1435         param = g_variant_new("(ias)", result, builder);
1436         _D("result(%d)", result);
1437         g_dbus_method_invocation_return_value(invocation, param);
1438         if (builder)
1439                 g_variant_builder_unref(builder);
1440 }
1441
1442 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1443         GVariant *parameters, GDBusMethodInvocation *invocation)
1444 {
1445         GVariant *param = NULL;
1446         int result = 0;
1447         char *event_name = NULL;
1448         char *destination_name = NULL;
1449         char app_id[128] = {0, };
1450         int sender_pid = 0;
1451         uid_t sender_uid = 0;
1452         int ret = 0;
1453
1454         g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
1455         _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1456
1457         if (destination_name && destination_name[0] != '\0') {
1458                 sender_pid = __get_sender_pid(connection, sender);
1459                 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1460                 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1461                         result = ES_R_ERROR;
1462                 } else {
1463                         ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1464                                 sender_pid);
1465                         if (ret < 0) {
1466                                 _E("failed to add trusted busname item");
1467                                 result = ES_R_ERROR;
1468                         } else {
1469                                 result = 1;
1470                         }
1471                 }
1472         } else {
1473                 _E("invalid destination name");
1474                 result = ES_R_ERROR;
1475         }
1476
1477         param = g_variant_new("(i)", result);
1478         _D("event_name(%s), result(%d)", event_name, result);
1479         g_dbus_method_invocation_return_value(invocation, param);
1480 }
1481
1482 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1483         GVariant *parameters, GDBusMethodInvocation *invocation)
1484 {
1485         GVariant *param = NULL;
1486         int result = 0;
1487         char *event_name = NULL;
1488         char *privilege_name = NULL;
1489         char app_id[128] = {0, };
1490         int sender_pid = 0;
1491         uid_t sender_uid = 0;
1492         char *client = NULL;
1493         char *session = NULL;
1494         char *user = NULL;
1495         int ret = 0;
1496
1497         g_variant_get(parameters, "(&s)", &event_name);
1498         __esd_check_privilege_name(event_name, &privilege_name);
1499         _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1500
1501         if (privilege_name) {
1502                 sender_pid = __get_sender_pid(connection, sender);
1503                 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1504                 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1505                         result = ES_R_ERROR;
1506                 } else {
1507                         ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1508                         if (ret != CYNARA_API_SUCCESS) {
1509                                 _E("failed to get client");
1510                                 result = ES_R_EINVAL;
1511                                 goto out;
1512                         }
1513
1514                         ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1515                         if (ret != CYNARA_API_SUCCESS) {
1516                                 _E("failed to get user");
1517                                 result = ES_R_EINVAL;
1518                                 goto out;
1519                         }
1520
1521                         session = cynara_session_from_pid(sender_pid);
1522                         if (session == NULL) {
1523                                 _E("failed to get session");
1524                                 result = ES_R_EINVAL;
1525                                 goto out;
1526                         }
1527
1528                         _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1529                         if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1530                                 result = 1;
1531                         else
1532                                 result = ES_R_EINVAL;
1533                 }
1534         } else {
1535                 result = 1;
1536         }
1537
1538 out:
1539         g_free(client);
1540         g_free(user);
1541         g_free(session);
1542         param = g_variant_new("(i)", result);
1543         _D("event_name(%s), result(%d)", event_name, result);
1544         g_dbus_method_invocation_return_value(invocation, param);
1545 }
1546
1547 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1548 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1549 {
1550         GVariant *param = NULL;
1551         int result = 0;
1552         char *event_name = NULL;
1553         bundle *b = NULL;
1554         bundle_raw *raw = NULL;
1555         int len = 0;
1556         earlier_item *item;
1557
1558         g_variant_get(parameters, "(&s)", &event_name);
1559
1560         if (event_name && strlen(event_name) > 0) {
1561                 _D("event_name(%s)", event_name);
1562                 result = ES_R_OK;
1563         } else {
1564                 _E("invalid event_name(%s)", event_name);
1565                 result = ES_R_ERROR;
1566         }
1567
1568         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1569         if (item != NULL) {
1570                 if (item->earlier_data) {
1571                         b = bundle_dup(item->earlier_data);
1572                         bundle_add_str(b, "is_earlier_data", "true");
1573                         bundle_encode(b, &raw, &len);
1574                         bundle_free(b);
1575                 }
1576         }
1577
1578         param = g_variant_new("(iis)", result, len, raw);
1579
1580         _D("result(%d), len(%d)", result, len);
1581         g_dbus_method_invocation_return_value(invocation, param);
1582
1583         bundle_free_encoded_rawdata(&raw);
1584 }
1585 #endif
1586
1587 static void keep_last_data_method_call(GDBusConnection *connection,
1588                 const gchar *sender, GVariant *parameters,
1589                 GDBusMethodInvocation *invocation)
1590 {
1591         GVariant *param;
1592         int result = ES_R_OK;
1593         char *event_name;
1594         char *own_name;
1595         char *key;
1596         char app_id[128];
1597         int sender_pid;
1598         uid_t sender_uid;
1599         struct __last_event_item *item;
1600
1601         g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1602
1603         if (!event_name || !own_name) {
1604                 result = ES_R_ERROR;
1605                 _E("invalid event_name and own_name");
1606                 goto out;
1607         }
1608
1609         sender_pid = __get_sender_pid(connection, sender);
1610         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1611         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1612                                 sizeof(app_id)) < 0) {
1613                 _E("failed to get appid by pid");
1614                 result = ES_R_ERROR;
1615                 goto out;
1616         }
1617
1618         key = (char *)malloc(sizeof(event_name) + 10);
1619         if (!key) {
1620                 result = ES_R_ENOMEM;
1621                 _E("out of memory");
1622                 goto out;
1623         }
1624
1625         snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1626         item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1627                         key);
1628         if (!item) {
1629                 item = calloc(1, sizeof(*item));
1630                 if (!item) {
1631                         result = ES_R_ERROR;
1632                         goto out;
1633                 }
1634                 item->key = key;
1635                 item->event_name = strdup(event_name);
1636                 item->own_name = strdup(own_name);
1637                 item->uid = sender_uid;
1638                 item->app_id = strdup(app_id);
1639                 g_hash_table_insert(user_last_event_table,
1640                                 item->key, item);
1641         } else {
1642                 free(item->own_name);
1643                 item->own_name = strdup(own_name);
1644         }
1645
1646 out:
1647         param = g_variant_new("(i)", result);
1648
1649         g_dbus_method_invocation_return_value(invocation, param);
1650 }
1651
1652 static void check_last_data_method_call(GDBusConnection *connection,
1653                 const gchar *sender, GVariant *parameters,
1654                 GDBusMethodInvocation *invocation)
1655 {
1656         GVariant *param;
1657         int result = ES_R_OK;
1658         char *event_name;
1659         char *own_name;
1660         char *key;
1661         char app_id[128];
1662         int sender_pid;
1663         uid_t sender_uid;
1664         struct __last_event_item *item;
1665
1666         g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1667
1668         if (!event_name || !own_name) {
1669                 result = ES_R_ERROR;
1670                 _E("invalid event_name and own_name");
1671                 goto out;
1672         }
1673
1674         sender_pid = __get_sender_pid(connection, sender);
1675         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1676         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1677                                 sizeof(app_id)) < 0) {
1678                 result = ES_R_ERROR;
1679                 _E("failed to get appid by pid");
1680                 goto out;
1681         }
1682
1683         key = (char *)malloc(sizeof(event_name) + 10);
1684         if (!key) {
1685                 result = ES_R_ENOMEM;
1686                 _E("out of memory");
1687                 goto out;
1688         }
1689
1690         snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1691         item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1692                         key);
1693         free(key);
1694         if (item) {
1695                 GVariant *gv;
1696                 bundle *b;
1697                 bundle_raw *raw;
1698                 int len;
1699                 int ret;
1700                 GError *error = NULL;
1701
1702                 b = bundle_create();
1703                 if (!b) {
1704                         result = ES_R_ERROR;
1705                         goto out;
1706                 }
1707                 bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
1708                 bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
1709                 if (__esd_check_certificate_match(item->uid, item->app_id,
1710                                 sender_uid, app_id) == ES_R_OK)
1711                         bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
1712                 else
1713                         bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
1714
1715                 bundle_encode(b, &raw, &len);
1716                 gv  = g_variant_new("(us)", len, raw);
1717                 ret = g_dbus_connection_emit_signal(connection,
1718                                 item->own_name,
1719                                 SYS_EVENT_OBJ_PATH,
1720                                 SYS_EVENT_NAME_PREFIX,
1721                                 REQUEST_LAST_DATA,
1722                                 gv,
1723                                 &error);
1724                 if (ret == FALSE) {
1725                         _E("Unable to emit signal: %s", error->message);
1726                         g_error_free(error);
1727                 }
1728                 bundle_free_encoded_rawdata(&raw);
1729                 bundle_free(b);
1730         }
1731
1732 out:
1733         param = g_variant_new("(i)", result);
1734
1735         g_dbus_method_invocation_return_value(invocation, param);
1736 }
1737
1738 static void launch_on_event_from_userevent(GDBusConnection *connection,
1739                 const gchar *sender, GVariant *parameters,
1740                 GDBusMethodInvocation *invocation)
1741 {
1742         GVariant *param;
1743         int result = ES_R_OK;
1744         int len;
1745         gboolean trusted;
1746         int sender_pid;
1747         uid_t sender_uid;
1748         char *event_name;
1749         char app_id[128];
1750         char *buf;
1751         bundle *b;
1752
1753         g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted);
1754
1755         if (!event_name) {
1756                 result = ES_R_ERROR;
1757                 _E("invalid event_name");
1758                 goto out;
1759         }
1760
1761         sender_pid = __get_sender_pid(connection, sender);
1762         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1763         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1764                                 sizeof(app_id)) < 0) {
1765                 _E("failed to get appid by pid");
1766                 result = ES_R_ERROR;
1767                 goto out;
1768         }
1769
1770         b = bundle_decode((bundle_raw *)buf, len);
1771         if (b == NULL) {
1772                 _E("Out of memory");
1773                 result = ES_R_ENOMEM;
1774                 goto out;
1775         }
1776
1777         __esd_launch_event_handler(event_name, b, true, trusted,
1778                         sender_uid, app_id, NULL);
1779
1780         bundle_free(b);
1781
1782 out:
1783         param = g_variant_new("(i)", result);
1784
1785         g_dbus_method_invocation_return_value(invocation, param);
1786 }
1787
1788 static void handle_method_call(GDBusConnection *connection,
1789         const gchar *sender, const gchar *object_path,
1790         const gchar *interface_name, const gchar *method_name,
1791         GVariant *parameters, GDBusMethodInvocation *invocation,
1792         gpointer user_data)
1793 {
1794         if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
1795                 check_sender_valid_method_call(connection, sender, parameters, invocation);
1796         } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
1797                 get_trusted_peer_method_call(connection, sender, parameters, invocation);
1798         } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
1799                 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
1800         } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
1801                 check_privilege_valid_method_call(connection, sender, parameters, invocation);
1802         } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
1803                 check_send_event_valid_method_call(connection, sender, parameters, invocation);
1804 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1805         } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
1806                 get_earlier_data_method_call(parameters, invocation);
1807 #endif
1808         } else if (g_strcmp0(method_name, "KeepLastData") == 0) {
1809                 keep_last_data_method_call(connection, sender, parameters, invocation);
1810         } else if (g_strcmp0(method_name, "CheckLastData") == 0) {
1811                 check_last_data_method_call(connection, sender, parameters, invocation);
1812         }  else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) {
1813                 launch_on_event_from_userevent(connection, sender, parameters, invocation);
1814         }
1815 }
1816
1817 static const GDBusInterfaceVTable interface_vtable = {
1818         handle_method_call,
1819         NULL,
1820         NULL
1821 };
1822
1823 static void __esd_on_bus_acquired(GDBusConnection *connection,
1824                 const gchar *name, gpointer user_data)
1825 {
1826         _I("bus acquired(%s)", name);
1827
1828         guint reg_id = 0;
1829         guint boot_id = 0;
1830         guint user_boot_id = 0;
1831         GError *error = NULL;
1832
1833         reg_id = g_dbus_connection_register_object(connection,
1834                 ESD_OBJECT_PATH,
1835                 introspection_data->interfaces[0],
1836                 &interface_vtable,
1837                 NULL, NULL, &error);
1838         if (reg_id == 0) {
1839                 _E("g_dbus_connection_register_object error(%s)", error->message);
1840                 g_error_free(error);
1841         }
1842
1843         boot_id = g_dbus_connection_signal_subscribe(connection,
1844                         NULL,
1845                         SYSTEMD_DBUS_IFACE_MANAGER,
1846                         SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
1847                         SYSTEMD_DBUS_PATH,
1848                         NULL,
1849                         G_DBUS_SIGNAL_FLAGS_NONE,
1850                         __esd_signal_handler,
1851                         NULL,
1852                         NULL);
1853
1854         if (boot_id == 0) {
1855                 _E("g_dbus_connection_signal_subscribe() is failed.");
1856                 g_object_unref(connection);
1857         }
1858
1859         user_boot_id = g_dbus_connection_signal_subscribe(connection,
1860                         NULL,
1861                         SYSTEMD_DBUS_IFACE_MANAGER,
1862                         SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
1863                         SYSTEMD_DBUS_PATH,
1864                         NULL,
1865                         G_DBUS_SIGNAL_FLAGS_NONE,
1866                         __esd_signal_handler,
1867                         NULL,
1868                         NULL);
1869
1870         if (user_boot_id == 0) {
1871                 _E("g_dbus_connection_signal_subscribe() is failed.");
1872                 g_object_unref(connection);
1873         }
1874 }
1875
1876 static void __esd_on_name_acquired(GDBusConnection *connection,
1877                 const gchar *name, gpointer user_data)
1878 {
1879         bundle *b;
1880
1881         _I("name acquired(%s)", name);
1882
1883         __esd_check_trusted_events(connection, "ListNames");
1884         __esd_check_trusted_events(connection, "ListActivatableNames");
1885
1886         b = bundle_create();
1887         bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1888         eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1889         bundle_free(b);
1890
1891         __esd_register_vconf_callbacks();
1892
1893         __esd_trusted_busname_print_items();
1894
1895         __esd_get_user_items(DEFAULT_USER);
1896
1897         __esd_dbus_name_monitor(connection);
1898 }
1899
1900 static void __esd_on_name_lost(GDBusConnection *connection,
1901                 const gchar *name, gpointer user_data)
1902 {
1903         _E("name lost(%s)", name);
1904 }
1905
1906 static int __esd_before_loop(void)
1907 {
1908         int ret = 0;
1909         GError *error = NULL;
1910         guint owner_id = 0;
1911
1912 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1913         guint subscription_id = 0;
1914         int i;
1915         int size;
1916         char *event_name;
1917         int fd;
1918         int val;
1919         int status;
1920         int charger_status;
1921         int charge_now;
1922         earlier_item *item;
1923
1924         earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1925         user_last_event_table = g_hash_table_new_full(g_str_hash,
1926                         g_str_equal, NULL, (GDestroyNotify)free_saved_event);
1927
1928         _I("register events for earlier_data");
1929         size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1930         for (i = 0; i < size; i++) {
1931                 event_name = (char *)earlier_event_list[i];
1932                 _I("event_name(%s)", event_name);
1933
1934                 item = calloc(1, sizeof(earlier_item));
1935                 if (item == NULL) {
1936                         _E("memery alloc failed");
1937                         return ES_R_ENOMEM;
1938                 }
1939                 item->event_name = strdup(event_name);
1940                 if (item->event_name == NULL) {
1941                         _E("out of memory");
1942                         free(item);
1943                         return ES_R_ENOMEM;
1944                 }
1945
1946                 /* set initial data */
1947                 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1948                         fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1949                         if (fd < 0) {
1950                                 _D("open file error(%d)", fd);
1951                         } else {
1952                                 item->earlier_data = bundle_create();
1953                                 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1954                                         EVT_VAL_BOOT_COMPLETED_TRUE);
1955                                 close(fd);
1956                         }
1957                 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1958                         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1959                         if (ret != VCONF_OK) {
1960                                 _E("failed to get power_off status (%d)", ret);
1961                         } else {
1962                                 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1963                                         val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1964                                         /* power-off requested */
1965                                         item->earlier_data = bundle_create();
1966                                         bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1967                                                 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1968                                 }
1969                         }
1970                 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1971                         ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1972                         if (ret != VCONF_OK) {
1973                                 _E("failed to get low_memory status (%d)", ret);
1974                         } else {
1975                                 item->earlier_data = bundle_create();
1976                                 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1977                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1978                                                 EVT_VAL_MEMORY_SOFT_WARNING);
1979                                 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1980                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1981                                                 EVT_VAL_MEMORY_HARD_WARNING);
1982                                 else
1983                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1984                                                 EVT_VAL_MEMORY_NORMAL);
1985                         }
1986                 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1987                         ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1988                         if (ret != VCONF_OK) {
1989                                 _E("failed to get charger_status (%d)", ret);
1990                         } else {
1991                                 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1992                                 if (ret != VCONF_OK)
1993                                         _E("failed to get charge_now (%d)", ret);
1994                         }
1995
1996                         if (ret == VCONF_OK) {
1997                                 item->earlier_data = bundle_create();
1998                                 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1999                                         if (charge_now == 0) {
2000                                                 bundle_add_str(item->earlier_data,
2001                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
2002                                                         EVT_VAL_BATTERY_CHARGER_DISCHARGING);
2003                                         } else {
2004                                                 bundle_add_str(item->earlier_data,
2005                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
2006                                                         EVT_VAL_BATTERY_CHARGER_CHARGING);
2007                                         }
2008                                 } else {
2009                                         bundle_add_str(item->earlier_data,
2010                                                 EVT_KEY_BATTERY_CHARGER_STATUS,
2011                                                 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
2012                                 }
2013                         }
2014                 }
2015
2016                 eventsystem_register_event(event_name, &subscription_id,
2017                         (eventsystem_handler)__esd_event_handler, NULL);
2018                 if (subscription_id == 0) {
2019                         _E("signal subscription error, event_name(%s)", event_name);
2020                         if (item->earlier_data)
2021                                 bundle_free(item->earlier_data);
2022                         free(item->event_name);
2023                         free(item);
2024
2025                         return ES_R_ERROR;
2026                 } else {
2027                         item->reg_id = subscription_id;
2028                 }
2029
2030                 g_hash_table_insert(earlier_event_table, event_name, item);
2031         }
2032
2033         __esd_earlier_table_print_items();
2034 #endif
2035
2036         event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
2037         trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
2038
2039         /* gdbus setup for method call */
2040         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
2041         if (!introspection_data) {
2042                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
2043                 g_error_free(error);
2044                 return ES_R_ERROR;
2045         }
2046
2047         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
2048                 ESD_BUS_NAME,
2049                 G_BUS_NAME_OWNER_FLAGS_NONE,
2050                 __esd_on_bus_acquired,
2051                 __esd_on_name_acquired,
2052                 __esd_on_name_lost,
2053                 NULL, NULL);
2054         if (!owner_id) {
2055                 _E("g_bus_own_name error");
2056                 g_dbus_node_info_unref(introspection_data);
2057                 return ES_R_ERROR;
2058         }
2059
2060         _I("esd before_loop done");
2061
2062         return ES_R_OK;
2063 }
2064
2065 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
2066 {
2067         pkg_event->type = UNKNOWN;
2068         if (pkg_event->pkgid) {
2069                 free(pkg_event->pkgid);
2070                 pkg_event->pkgid = NULL;
2071         }
2072 }
2073
2074 static int __esd_appcontrol_cb(const char *operation,
2075                 const char *uri, const char *mime, void *data)
2076 {
2077         esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
2078         char *appid = NULL;
2079         char *pkgid = NULL;
2080         char *event_name = NULL;
2081         uid_t uid = 0;
2082
2083         if (cb_data == NULL) {
2084                 _E("invalid data");
2085                 return 0;
2086         }
2087         appid = cb_data->appid;
2088         pkgid = cb_data->pkgid;
2089         uid = cb_data->uid;
2090
2091         _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
2092                 uid, appid, pkgid, operation, uri, mime);
2093
2094         if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
2095                 if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) {
2096                         event_name = strdup(&uri[8]);
2097                         if (event_name) {
2098                                 _D("appid(%s), event_name(%s)", appid, event_name);
2099                                 if (!__esd_check_event_launch_support(event_name))
2100                                         _E("failed to add item (not support event)");
2101                                 else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name))
2102                                         _E("failed to add item (no privilege)");
2103                                 else if (__esd_add_launch_item(uid, event_name, appid, pkgid))
2104                                         _E("failed to add item");
2105
2106                         } else {
2107                                 _E("out of memory");
2108                         }
2109                 } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) {
2110                         event_name = strdup(uri);
2111                         if (event_name) {
2112                                 _D("appid(%s), event_name(%s)", appid, event_name);
2113                                 if (__esd_check_platform_cert(pkgid, uid)) {
2114                                         if (__esd_add_launch_item(uid, event_name, appid, pkgid))
2115                                                 _E("failed to add item");
2116                                 }
2117                         } else {
2118                                 _E("out of memory");
2119                         }
2120                 }
2121                 FREE_AND_NULL(event_name);
2122         }
2123
2124         return 0;
2125 }
2126
2127 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
2128 {
2129         char *appid = NULL;
2130         char *pkgid = NULL;
2131         int ret = 0;
2132         uid_t *p_uid = NULL;
2133
2134         if (data == NULL) {
2135                 _E("invalid data");
2136                 return ES_R_ERROR;
2137         }
2138
2139         p_uid = (uid_t *)data;
2140
2141         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2142         if (ret < 0) {
2143                 _E("failed to get appid");
2144                 return ES_R_ERROR;
2145         }
2146
2147         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2148         if (ret < 0) {
2149                 _E("failed to get appid");
2150                 return ES_R_ERROR;
2151         }
2152
2153         esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
2154
2155         if (cb_data == NULL) {
2156                 _E("memory alloc failed");
2157                 return ES_R_ENOMEM;
2158         }
2159         cb_data->appid = strdup(appid);
2160         if (cb_data->appid == NULL) {
2161                 _E("out_of_memory");
2162                 FREE_AND_NULL(cb_data);
2163                 return ES_R_ENOMEM;
2164         }
2165         cb_data->pkgid = strdup(pkgid);
2166         if (cb_data->pkgid == NULL) {
2167                 _E("out_of_memory");
2168                 FREE_AND_NULL(cb_data->appid);
2169                 FREE_AND_NULL(cb_data);
2170                 return ES_R_ENOMEM;
2171         }
2172         cb_data->uid = *p_uid;
2173
2174         ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
2175                 (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
2176
2177         FREE_AND_NULL(cb_data->pkgid);
2178         FREE_AND_NULL(cb_data->appid);
2179         FREE_AND_NULL(cb_data);
2180
2181         if (ret < 0) {
2182                 _E("failed to get appcontrol info");
2183                 return ES_R_ERROR;
2184         }
2185
2186         return ES_R_OK;
2187 }
2188
2189 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
2190                 const char *pkg_type, const char *pkgid, const char *key,
2191                 const char *val, const void *pmsg, void *data)
2192 {
2193         esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
2194         pkgmgrinfo_pkginfo_h handle = NULL;
2195         int ret = 0;
2196
2197         _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
2198                 target_uid, req_id, pkg_type, pkgid, key, val);
2199
2200         if (strncmp(key, "start", strlen(key)) == 0) {
2201                 if (strcmp(val, "install") == 0) {
2202                         _D("install start");
2203                         pkg_event->type = INSTALL;
2204                 } else if (strcmp(val, "uninstall") == 0) {
2205                         _D("unistall start");
2206                         pkg_event->type = UNINSTALL;
2207                 } else if (strcmp(val, "update") == 0) {
2208                         _D("update start");
2209                         pkg_event->type = UPDATE;
2210                 } else {
2211                         _D("val(%s) start", val);
2212                         __esd_pkgmgr_event_free(pkg_event);
2213                 }
2214         } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
2215                 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
2216                         _D("install end (ok)");
2217                         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
2218                         if (ret < 0) {
2219                                 _E("failed to get pkginfo");
2220                                 __esd_pkgmgr_event_free(pkg_event);
2221                                 return 0;
2222                         }
2223                         ret = pkgmgrinfo_appinfo_get_usr_list(handle,
2224                                 PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
2225                         if (ret < 0) {
2226                                 _E("failed to get appinfo");
2227                                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2228                                 __esd_pkgmgr_event_free(pkg_event);
2229                                 return 0;
2230                         }
2231                         ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2232                         if (ret < 0) {
2233                                 _E("failed to destroy pkginfo");
2234                                 __esd_pkgmgr_event_free(pkg_event);
2235                                 return 0;
2236                         }
2237                 } else if (pkg_event->type == UNINSTALL) {
2238                         _D("uninstall end (ok)");
2239                         __esd_launch_table_remove_items(target_uid, pkgid);
2240                         __esd_launch_table_print_items();
2241                 }
2242                 __esd_pkgmgr_event_free(pkg_event);
2243         } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
2244                 _E("pkg_event(%d) falied", pkg_event->type);
2245                 __esd_pkgmgr_event_free(pkg_event);
2246         } else {
2247                 if (strcmp(key, "install_percent") != 0)
2248                         __esd_pkgmgr_event_free(pkg_event);
2249         }
2250
2251         return 0;
2252 }
2253
2254 static int __esd_init()
2255 {
2256         int req_id = 0;
2257         int ret = 0;
2258         pkgmgr_client *client;
2259         esd_pkgmgr_event *pkg_event;
2260
2261 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
2262         g_type_init();
2263 #endif
2264         __esd_init_cynara();
2265
2266         client = pkgmgr_client_new(PC_LISTENING);
2267         if (client == NULL) {
2268                 _E("set pkgmgr client failed");
2269                 __esd_finish_cynara();
2270                 return ES_R_ERROR;
2271         }
2272
2273         pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
2274         if (pkg_event == NULL) {
2275                 _E("memory alloc failed");
2276                 ret = pkgmgr_client_free(client);
2277                 if (ret != PKGMGR_R_OK)
2278                         _E("pkgmgr_client_free failed(%d)", ret);
2279                 __esd_finish_cynara();
2280                 return ES_R_ENOMEM;
2281         }
2282
2283         req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
2284         if (req_id < 0) {
2285                 _E("pkgmgr client listen failed");
2286                 ret = pkgmgr_client_free(client);
2287                 if (ret != PKGMGR_R_OK)
2288                         _E("pkgmgr_client_free failed(%d)", ret);
2289                 free(pkg_event);
2290                 __esd_finish_cynara();
2291                 return ES_R_ERROR;
2292         }
2293
2294         s_info.client = client;
2295
2296         _I("esd init done");
2297
2298         return 0;
2299 }
2300
2301 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
2302 {
2303         esd_list_item_s *item = (esd_list_item_s *)data;
2304
2305         free(item->app_id);
2306         free(item->pkg_id);
2307 }
2308
2309 static void __esd_finalize(void)
2310 {
2311         gpointer key;
2312         gpointer value;
2313         GHashTableIter iter;
2314         trusted_item *item;
2315         event_launch_item *el_item;
2316         int ret = 0;
2317 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2318         earlier_item *er_item;
2319 #endif
2320
2321         _D("esd finalize");
2322
2323         if (trusted_busname_table) {
2324                 g_hash_table_iter_init(&iter, trusted_busname_table);
2325                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2326                         item = (trusted_item *)value;
2327                         if (item) {
2328                                 free(item->app_id);
2329                                 free(item->bus_name);
2330                                 free(item);
2331                         } else {
2332                                 _E("item is null");
2333                         }
2334                         g_hash_table_iter_remove(&iter);
2335                 }
2336                 g_hash_table_unref(trusted_busname_table);
2337         }
2338
2339 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2340         if (earlier_event_table) {
2341                 g_hash_table_iter_init(&iter, earlier_event_table);
2342                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2343                         er_item = (earlier_item *)value;
2344                         if (er_item) {
2345                                 eventsystem_unregister_event(er_item->reg_id);
2346                                 free(er_item->event_name);
2347                                 bundle_free(er_item->earlier_data);
2348                                 free(er_item);
2349                         } else {
2350                                 _E("ealier item is NULL");
2351                         }
2352                         g_hash_table_iter_remove(&iter);
2353                 }
2354                 g_hash_table_unref(earlier_event_table);
2355         }
2356
2357         g_hash_table_destroy(user_last_event_table);
2358 #endif
2359
2360         if (event_launch_table) {
2361                 g_hash_table_iter_init(&iter, event_launch_table);
2362                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2363                         el_item = (event_launch_item *)value;
2364                         if (el_item) {
2365                                 eventsystem_unregister_event(el_item->reg_id);
2366                                 free(el_item->event_name);
2367                                 g_list_foreach(el_item->app_list_evtlaunch,
2368                                         __esd_remove_esd_list_item, NULL);
2369                                 g_list_free(el_item->app_list_evtlaunch);
2370                                 free(el_item);
2371                         } else {
2372                                 _E("item is NULL");
2373                         }
2374                         g_hash_table_iter_remove(&iter);
2375                 }
2376                 g_hash_table_unref(event_launch_table);
2377         }
2378
2379         if (introspection_data)
2380                 g_dbus_node_info_unref(introspection_data);
2381
2382         if (s_info.client) {
2383                 ret = pkgmgr_client_free(s_info.client);
2384                 if (ret != PKGMGR_R_OK)
2385                         _E("pkgmgr_client_free failed(%d)", ret);
2386         }
2387
2388         __esd_finish_cynara();
2389
2390         _D("esd finalize end");
2391 }
2392
2393 int main(int argc, char *argv[])
2394 {
2395         GMainLoop *mainloop;
2396         _I("event system daemon : main()");
2397
2398         mainloop = g_main_loop_new(NULL, FALSE);
2399         if (mainloop == NULL) {
2400                 _E("out of memory");
2401                 return ES_R_ERROR;
2402         }
2403
2404         if (__esd_init() != 0) {
2405                 _E("ESD Initialization failed!");
2406                 g_main_loop_unref(mainloop);
2407                 return ES_R_ERROR;
2408         }
2409
2410         if (__esd_before_loop() < 0) {
2411                 _E("ESD failed!");
2412                 __esd_finalize();
2413                 g_main_loop_unref(mainloop);
2414                 return ES_R_ERROR;
2415         }
2416
2417         g_main_loop_run(mainloop);
2418
2419         _E("shutdown");
2420
2421         __esd_finalize();
2422
2423         g_main_loop_unref(mainloop);
2424
2425         return 0;
2426 }