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