From: jh9216.park Date: Thu, 8 Dec 2022 07:41:31 +0000 (-0500) Subject: Refactor dbus-event module X-Git-Tag: accepted/tizen/unified/20230214.171539~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=98d7d980f9e32ffca705dd6957733b477468d65a;p=platform%2Fcore%2Fappfw%2Fevent-system.git Refactor dbus-event module Change-Id: I9beef08846a1c7710eef8cb3c9c767838eb0eda3 Signed-off-by: jh9216.park --- diff --git a/src/modules/dbus_event/certificate_matcher.cc b/src/modules/dbus_event/certificate_matcher.cc new file mode 100644 index 0000000..2902b96 --- /dev/null +++ b/src/modules/dbus_event/certificate_matcher.cc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "certificate_matcher.hh" + +#include +#include +#include +#include +#include + +#include + +#include "log.hh" + +namespace esd::module { + +int CertificateMatcher::Match(uid_t uid, const std::string& appid, + uid_t from_uid, const std::string& from_appid) { + _D("uid(%d), appid(%s), from_uid(%d), from_appid(%s)", uid, appid.c_str(), + from_uid, from_appid.c_str()); + + pkgmgrinfo_cert_compare_result_type_e res; + int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(appid.c_str(), + from_appid.c_str(), from_uid, &res); + if (ret < 0) { + _E("failed to check certificate"); + return ES_R_ERROR; + } + + if (res != PMINFO_CERT_COMPARE_MATCH) { + _D("certificat not match (%s)", appid.c_str()); + return ES_R_EINVAL; + } + + return ES_R_OK; +} + +bool CertificateMatcher::IsPlatformCert(const std::string& pkgid, uid_t uid) { + _D("Checking if %s has a platform certification", pkgid.c_str()); + + int r; + const char *cert_value; + pkgmgrinfo_certinfo_h certinfo; + CertSvcInstance instance; + CertSvcCertificate certificate; + CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; + + r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); + std::unique_ptr::type, + decltype(pkgmgrinfo_pkginfo_destroy_certinfo)*> + certinfo_auto(certinfo, pkgmgrinfo_pkginfo_destroy_certinfo); + if (r != PMINFO_R_OK) { + _E("Failed to create certinfo"); + return false; + } + + r = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), certinfo, uid); + if (r != PMINFO_R_OK) { + _E("Failed to load certinfo"); + return false; + } + + r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, + PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); + if (r != PMINFO_R_OK || cert_value == nullptr) { + _E("Failed to get cert value"); + return false; + } + + r = certsvc_instance_new(&instance); + if (r != CERTSVC_SUCCESS) { + _E("certsvc_instance_new() is failed."); + return false; + } + + r = certsvc_certificate_new_from_memory(instance, + reinterpret_cast(cert_value), + strlen(cert_value), + CERTSVC_FORM_DER_BASE64, + &certificate); + if (r != CERTSVC_SUCCESS) { + _E("certsvc_certificate_new_from_memory() is failed."); + certsvc_instance_free(instance); + return false; + } + + r = certsvc_certificate_get_visibility(certificate, &visibility); + if (r != CERTSVC_SUCCESS) + _E("certsvc_certificate_get_visibility() is failed."); + + certsvc_instance_free(instance); + certsvc_certificate_free(certificate); + + _D("visibility is %d", visibility); + if (visibility & CERTSVC_VISIBILITY_PLATFORM) { + _D("%s has a platform certification", pkgid.c_str()); + return true; + } + + return false; +} + +} // namespace esd::module diff --git a/src/modules/dbus_event/certificate_matcher.hh b/src/modules/dbus_event/certificate_matcher.hh new file mode 100644 index 0000000..6e0dc5d --- /dev/null +++ b/src/modules/dbus_event/certificate_matcher.hh @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_DBUS_EVENT_CERTIFICATE_MATCHER_HH_ +#define EVENTSYSTEM_MODULES_DBUS_EVENT_CERTIFICATE_MATCHER_HH_ + +#include + +#include + +namespace esd::module { + +class CertificateMatcher { + public: + static int Match(uid_t uid, const std::string& appid, + uid_t from_uid, const std::string& from_appid); + static bool IsPlatformCert(const std::string& pkgid, uid_t uid); +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_CERTIFICATE_MATCHER_HH_ diff --git a/src/modules/dbus_event/dbus_event_module.cc b/src/modules/dbus_event/dbus_event_module.cc index b825c5e..9469ae9 100644 --- a/src/modules/dbus_event/dbus_event_module.cc +++ b/src/modules/dbus_event/dbus_event_module.cc @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dbus_event_module.hh" + #include #include #include @@ -6,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -14,17 +31,14 @@ #include #include #include -#include -#include -#include "log.hh" -#include "dbus_event_module.hh" +#include + +#include +#include +#include -#define FREE_AND_NULL(ptr) do { \ - if (ptr) { \ - free((void *)ptr); \ - ptr = NULL; \ - } \ -} while (0) +#include "certificate_matcher.hh" +#include "log.hh" namespace { @@ -32,22 +46,22 @@ namespace { constexpr const char ESD_BOOT_COMPLETED[] = "/tmp/esd_ready"; constexpr const char SYSTEMD_DBUS_DEST[] = "org.freedesktop.systemd1"; -constexpr const char SYSTEMD_DBUS_IFACE_MANAGER[] = "org.freedesktop.systemd1.Manager"; +constexpr const char SYSTEMD_DBUS_IFACE_MANAGER[] = + "org.freedesktop.systemd1.Manager"; constexpr const char SYSTEMD_DBUS_PATH[] = "/org/freedesktop/systemd1"; -constexpr const char SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED[] = "StartupFinished"; -constexpr const char SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED[] = "UserSessionStartupFinished"; +constexpr const char SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED[] = + "StartupFinished"; +constexpr const char SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED[] = + "UserSessionStartupFinished"; -#define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER) -#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) -constexpr const int ROOT_USER = 0; +const uid_t DEFAULT_USER = tzplatform_getuid(TZ_SYS_DEFAULT_USER); +const uid_t GLOBAL_USER = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); constexpr const char SYS_EVENT_NAME_PREFIX[] = "tizen.system.event"; constexpr const char SYS_EVENT_OBJ_PATH[] = "/tizen/system/event"; constexpr const char REQUEST_LAST_DATA[] = "request_last_data"; -GHashTable *event_launch_table; /* table of events for launch_on_event*/ - -const char *event_launch_support_list[] = { +const std::set event_launch_support_list = { SYS_EVENT_BATTERY_CHARGER_STATUS, SYS_EVENT_USB_STATUS, SYS_EVENT_EARJACK_STATUS, @@ -56,212 +70,35 @@ const char *event_launch_support_list[] = { SYS_EVENT_WIFI_STATE }; -const char *earlier_event_list[] = { - SYS_EVENT_ESD_STATUS, - SYS_EVENT_LOW_MEMORY, - SYS_EVENT_BOOT_COMPLETED, - SYS_EVENT_SYSTEM_SHUTDOWN, - SYS_EVENT_BATTERY_CHARGER_STATUS -}; - -GHashTable *earlier_event_table; /* table of events for earlier_data */ - -typedef struct __earlier_table_item { - char *event_name; - guint reg_id; - bundle *earlier_data; /* event-data from earlier occurrence */ -} earlier_item; - -GHashTable *user_last_event_table; /* table of user events for last data */ - -struct __last_event_item { - char *key; - char *app_id; - char *event_name; - char *own_name; - uid_t uid; -}; +std::map> trusted_busname_table; -GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */ +std::map> event_launch_table; -typedef struct __trusted_busname_item { - char *app_id; - char *bus_name; - int pid; - uid_t uid; -} trusted_item; - -typedef struct __eventlaunch_item_param { - char *app_id; -} eventlaunch_item_param_s; - -enum trusted_result { - TRUSTED_UNKNOWN, - TRUSTED_ALLOWED, - TRUSTED_DENIED, -}; - -typedef struct esd_list_item { - char *pkg_id; - char *app_id; - int trusted_info; - uid_t uid; -} esd_list_item_s; +struct AppCtrlData { + AppCtrlData(std::string_view appid, std::string_view pkgid, uid_t uid) + : appid_(appid), pkgid_(pkgid), uid_(uid) { + } -typedef struct __event_launch_table_item { - char *event_name; - char *package_name; /* just for passing pointer to app-list removal func */ - GList *app_list_evtlaunch; /* app-list for on-event-launch */ - guint reg_id; - uid_t uid; -} event_launch_item; - -enum __pkg_event_type { - UNKNOWN = 0, - INSTALL, - UNINSTALL, - UPDATE, + std::string_view appid_; + std::string_view pkgid_; + uid_t uid_; }; -typedef struct __pkgmgr_event { - int type; - char *pkgid; -} esd_pkgmgr_event; - -typedef struct __esd_event_param { - char *event_name; - bundle *event_data; - uid_t sender_uid; - char *sender_appid; - bool is_user_event; - bool trusted; - void *user_data; -} esd_event_param; - -typedef struct esd_info { - pkgmgr_client *client; -} esd_info_s; -static esd_info_s s_info; - -typedef struct __esd_appctrl_cb_data { - char *appid; - char *pkgid; - uid_t uid; -} esd_appctrl_cb_data; - -void __esd_event_handler(char *event_name, bundle *data, void *user_data); int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data); -void free_saved_event(struct __last_event_item *item) { - if (!item) - return; - - free(item->event_name); - free(item->own_name); - free(item->app_id); - free(item); -} - -int __esd_check_earlier_support(const char *event_name) { - int i = 0; - int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list); - - for (i = 0; i < size; i++) { - if (strcmp(earlier_event_list[i], event_name) == 0) - return true; - } - - return false; -} - -bool __esd_check_platform_cert(const char *pkgid, uid_t uid) { - _D("Checking if %s has a platform certification", pkgid); - - int r; - const char *cert_value; - pkgmgrinfo_certinfo_h certinfo; - CertSvcInstance instance; - CertSvcCertificate certificate; - CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; - - r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); - if (r != PMINFO_R_OK) { - _E("Failed to create certinfo"); - return false; - } - - r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid); - if (r != PMINFO_R_OK) { - _E("Failed to load certinfo"); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, - PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); - if (r != PMINFO_R_OK || cert_value == NULL) { - _E("Failed to get cert value"); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = certsvc_instance_new(&instance); - if (r != CERTSVC_SUCCESS) { - _E("certsvc_instance_new() is failed."); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = certsvc_certificate_new_from_memory(instance, - (const unsigned char *)cert_value, - strlen(cert_value), - CERTSVC_FORM_DER_BASE64, - &certificate); - if (r != CERTSVC_SUCCESS) { - _E("certsvc_certificate_new_from_memory() is failed."); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - certsvc_instance_free(instance); - return false; - } - - r = certsvc_certificate_get_visibility(certificate, &visibility); - if (r != CERTSVC_SUCCESS) - _E("certsvc_certificate_get_visibility() is failed."); - - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - certsvc_certificate_free(certificate); - certsvc_instance_free(instance); - - _D("visibility is %d", visibility); - if (visibility & CERTSVC_VISIBILITY_PLATFORM) { - _D("%s has a platform certification", pkgid); - return true; - } - - return false; -} - -int __esd_check_event_launch_support(const char *event_name) { - int i = 0; - int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list); - - for (i = 0; i < size; i++) { - if (strcmp(event_launch_support_list[i], event_name) == 0) - return true; - } - - return false; -} - -int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type) { - GDBusMessage *msg = NULL; - GDBusMessage *reply = NULL; - GError *err = NULL; +int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, + const char *type) { + GDBusMessage *msg = nullptr; + GDBusMessage *reply = nullptr; + GError *err = nullptr; GVariant *body; int ret = -1; unsigned int value; - msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", + msg = g_dbus_message_new_method_call( + "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", type); if (!msg) { _E("Can't allocate new method call"); @@ -270,10 +107,10 @@ int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name)); reply = g_dbus_connection_send_message_with_reply_sync(conn, msg, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err); + G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err); if (!reply) { - if (err != NULL) { + if (err != nullptr) { _E("Failed to get info [%s]", err->message); g_error_free(err); } @@ -282,7 +119,7 @@ int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const body = g_dbus_message_get_body(reply); g_variant_get(body, "(u)", &value); - ret = (int)value; + ret = static_cast(value); out: if (msg) @@ -296,7 +133,8 @@ out: int __get_sender_pid(GDBusConnection *conn, const char *sender_name) { int pid = 0; - pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID"); + pid = __get_sender_unixinfo(conn, sender_name, + "GetConnectionUnixProcessID"); if (pid < 0) { _E("failed to get pid"); pid = 0; @@ -319,26 +157,6 @@ int __get_sender_uid(GDBusConnection *conn, const char *sender_name) { return uid; } -int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid) { - pkgmgrinfo_cert_compare_result_type_e res; - int ret = 0; - - _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid); - - ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res); - if (ret < 0) { - _E("failed to check certificate"); - return ES_R_ERROR; - } - - if (res != PMINFO_CERT_COMPARE_MATCH) { - _D("certificat not match (%s)", app_id); - return ES_R_EINVAL; - } - - return ES_R_OK; -} - bool __esd_check_application_validation(uid_t uid, const char *appid) { int ret = 0; pkgmgrinfo_appinfo_h handle; @@ -356,67 +174,27 @@ bool __esd_check_application_validation(uid_t uid, const char *appid) { } void __esd_trusted_busname_print_items() { - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, trusted_busname_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - trusted_item *item = (trusted_item *)value; - if (item) - _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name); + for (const auto& i : trusted_busname_table) { + auto [bus_name, pid, uid] = i.second; + _D("uid(%d), appid(%s), pid(%d), busname(%s)", uid, + i.first.c_str(), pid, bus_name.c_str()); } } -int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid) { - char *app_id = NULL; - char *bus_name = NULL; - trusted_item *item = NULL; - trusted_item *new_item; - - app_id = strdup(appid); - if (app_id == NULL) { - _E("out of memory"); - return ES_R_ENOMEM; - } - - bus_name = strdup(busname); - if (bus_name == NULL) { - _E("out of memory"); - FREE_AND_NULL(app_id); - return ES_R_ENOMEM; - } - - item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id); - - if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 && - (item->uid == uid)) { - _D("already exist (%s, %s)", app_id, bus_name); - FREE_AND_NULL(app_id); - FREE_AND_NULL(bus_name); - } else { - new_item = (trusted_item *)calloc(1, sizeof(trusted_item)); - if (new_item == NULL) { - _E("memory alloc failed"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(bus_name); - return ES_R_ENOMEM; - } - new_item->uid = uid; - new_item->app_id = app_id; - new_item->bus_name = bus_name; - new_item->pid = pid; - g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item); - _D("added busname(%s)", new_item->bus_name); +int __esd_trusted_busname_add_item(uid_t uid, const char *appid, + const char *busname, int pid) { + if (trusted_busname_table.find(appid) != trusted_busname_table.end()) { + _D("already exist (%s, %s)", appid, busname); + return ES_R_OK; } + trusted_busname_table[appid] = std::make_tuple(busname, pid, uid); return ES_R_OK; } int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { GVariant *result; - GError *error = NULL; + GError *error = nullptr; GVariantIter *iter; gchar *str; char tmp_appid[128] = {0, }; @@ -426,10 +204,10 @@ int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { result = g_dbus_connection_call_sync(conn, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", - list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); + list_name, nullptr, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE, + -1, nullptr, &error); - if (result == NULL) { + if (result == nullptr) { _E("get (%s) error(%s)", list_name, error->message); g_error_free(error); return ES_R_ERROR; @@ -437,17 +215,17 @@ int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { g_variant_get(result, "(as)", &iter); while (g_variant_iter_loop(iter, "s", &str)) { - if (!strstr((const char *)str, "event.busname.session")) + if (!strstr(reinterpret_cast(str), "event.busname.session")) continue; _D("list(%s), name(%s)", list_name, str); - pid = __get_sender_pid(conn, (const char *)str); + pid = __get_sender_pid(conn, reinterpret_cast(str)); if (pid <= 0) { _E("failed to get pid(%d)", pid); continue; } - uid = __get_sender_uid(conn, (const char *)str); + uid = __get_sender_uid(conn, reinterpret_cast(str)); if (uid < 0) { _E("failed to get uid(%d)", uid); continue; @@ -455,7 +233,8 @@ int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { _D("uid(%d)", uid); memset(tmp_appid, 0, sizeof(tmp_appid)); - ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid); + ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), + (uid_t)uid); if (ret != AUL_R_OK) { _E("failed to get appid by pid(%d)", pid); continue; @@ -464,7 +243,8 @@ int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { _D("appid(%s)", tmp_appid); if (__esd_check_application_validation((uid_t)uid, tmp_appid)) { _D("add to table"); - ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid); + ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, + reinterpret_cast(str), pid); if (ret < 0) _E("failed to add item"); } @@ -475,461 +255,62 @@ int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { return ES_R_OK; } -void __esd_print_appid_with_eventid(gpointer data, gpointer user_data) { - esd_list_item_s *item = (esd_list_item_s *)data; - char *event_name = (char *)user_data; - - _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id); -} - -void __esd_print_interested_event(gpointer data, gpointer user_data) { - event_launch_item *el_item = (event_launch_item *)data; - char *event_name = (char *)el_item->event_name; - _D("event_name = (%s)", event_name); - g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name); -} - void __esd_launch_table_print_items() { - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, event_launch_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) - __esd_print_interested_event(value, NULL); -} - -int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data) { - esd_list_item_s *item_1 = (esd_list_item_s *)user_data; - esd_list_item_s *item_2 = (esd_list_item_s *)data; - - return (item_1->uid != item_2->uid) | - strcmp(item_1->app_id, item_2->app_id) | - strcmp(item_1->pkg_id, item_2->pkg_id); + for (auto& i : event_launch_table) + i.second->Print(i.first); } -int __esd_add_list_item(uid_t uid, event_launch_item *el_item, - const char *app_id, const char *pkg_id) { - esd_list_item_s *item_of_list = NULL; +int __esd_add_launch_item(uid_t uid, const char* event_name, + const char* appid, const char* pkgid) { + auto it = event_launch_table.find(event_name); - item_of_list = (esd_list_item_s *)calloc(1, sizeof(esd_list_item_s)); - if (item_of_list == NULL) { - _E("out_of_memory"); - return ES_R_ENOMEM; - } - item_of_list->uid = uid; - item_of_list->app_id = (char *)app_id; - item_of_list->pkg_id = (char *)pkg_id; - item_of_list->trusted_info = TRUSTED_UNKNOWN; - el_item->app_list_evtlaunch = - g_list_append(el_item->app_list_evtlaunch, item_of_list); - - return ES_R_OK; -} - -int __esd_add_launch_item(uid_t uid, const char *event_name, - const char *appid, const char *pkgid) { - GList *app_list = NULL; - guint subscription_id = 0; - char *app_id = NULL; - char *pkg_id = NULL; - esd_list_item_s *item_of_list = NULL; - event_launch_item *eli; - event_launch_item *el_item = - (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name); - - if (el_item) { - item_of_list = (esd_list_item_s *)calloc(1, sizeof(esd_list_item_s)); - if (item_of_list == NULL) { - _E("memory alloc failed"); - return ES_R_ENOMEM; - } - item_of_list->uid = uid; - item_of_list->app_id = (char *)appid; - item_of_list->pkg_id = (char *)pkgid; - - app_list = g_list_find_custom(el_item->app_list_evtlaunch, - item_of_list, (GCompareFunc)__esd_find_compare_by_list_item); - free(item_of_list); - if (app_list == NULL) { - _D("add new item (list item only)"); - app_id = strdup((char *)appid); - if (!app_id) { - _E("out_of_memory"); - return ES_R_ENOMEM; - } - pkg_id = strdup((char *)pkgid); - if (!pkg_id) { - _E("out_of_memory"); - FREE_AND_NULL(app_id); - return ES_R_ENOMEM; - } - if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) { - _E("failed to add list item"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(pkg_id); - return ES_R_ERROR; - } - } + if (it != event_launch_table.end()) { + auto& el = (*it).second; + el->GetAppListEventLaunch().push_back(esd::module::EsdListItem( + pkgid, appid, uid)); } else { _D("add new item (all)"); - eli = (event_launch_item *)calloc(1, sizeof(event_launch_item)); - if (!eli) { - _E("memory alloc failed"); - return ES_R_ENOMEM; - } - - eli->event_name = strdup(event_name); - if (!eli->event_name) { - _E("out_of_memory"); - FREE_AND_NULL(eli); - return ES_R_ENOMEM; - } - - app_id = strdup((char *)appid); - if (!app_id) { - _E("out_of_memory"); - FREE_AND_NULL(eli->event_name); - FREE_AND_NULL(eli); - return ES_R_ENOMEM; - } - - pkg_id = strdup((char *)pkgid); - if (!pkg_id) { - _E("out_of_memory"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(eli->event_name); - FREE_AND_NULL(eli); - return ES_R_ENOMEM; - } - - if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) { - _E("failed to add list item"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(pkg_id); - FREE_AND_NULL(eli->event_name); - FREE_AND_NULL(eli); - return ES_R_ERROR; - } - - g_hash_table_insert(event_launch_table, eli->event_name, eli); - - eventsystem_register_event(eli->event_name, &subscription_id, - (eventsystem_handler)__esd_event_handler, NULL); - if (subscription_id == 0) { + auto el = std::make_unique(pkgid, appid, uid); + if (!el->Register(event_name)) { _E("signal subscription error, event_name(%s), app_id(%s)", - eli->event_name, app_id); + event_name, appid); return ES_R_ERROR; - } else { - eli->reg_id = subscription_id; } - } - - return ES_R_OK; -} - -void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data) { - esd_list_item_s *item = (esd_list_item_s *)data; - event_launch_item *eli = (event_launch_item *)user_data; - - if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) { - _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name); - eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data); - } -} - -int __esd_launch_table_remove_private_usr_items() { - GHashTableIter iter; - gpointer key; - gpointer value; - event_launch_item *eli = NULL; - GList *first_list = NULL; - - g_hash_table_iter_init(&iter, event_launch_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - eli = (event_launch_item *)value; - g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli); - - first_list = g_list_first(eli->app_list_evtlaunch); - if (first_list == NULL) { - if (eli->reg_id) - eventsystem_unregister_event(eli->reg_id); - - g_hash_table_iter_remove(&iter); - } + event_launch_table[event_name] = std::move(el); } return ES_R_OK; } -void __esd_remove_app_list(gpointer data, gpointer user_data) { - bool skip = false; - esd_list_item_s *item = (esd_list_item_s *)data; - event_launch_item *eli = (event_launch_item *)user_data; - - if (eli->uid != GLOBAL_USER && eli->uid != item->uid) - skip = true; - - if (!skip && !strcmp(eli->package_name, item->pkg_id)) { - _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id); - eli->app_list_evtlaunch = - g_list_remove_all(eli->app_list_evtlaunch, data); - } -} - -int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id) { - event_launch_item *eli = (event_launch_item *)data; - GList *first_list = NULL; - - eli->uid = uid; - eli->package_name = (char *)pkg_id; - g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli); - - first_list = g_list_first(eli->app_list_evtlaunch); - if (first_list == NULL) { - if (eli->reg_id) - eventsystem_unregister_event(eli->reg_id); - - return ES_R_REMOVE; - } - +int __esd_launch_table_remove_private_usr_items() { + event_launch_table.clear(); return ES_R_OK; } int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id) { - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, event_launch_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) { - _D("remove item itself"); - g_hash_table_iter_remove(&iter); + for (auto& i : event_launch_table) { + if (uid != GLOBAL_USER && i.second->GetUid() == uid && + i.second->GetPackageName() == pkg_id) { + event_launch_table.erase(i.first); + break; } } return ES_R_OK; } -void __esd_event_launch_with_appid(gpointer data, gpointer user_data) { - esd_list_item_s *item = (esd_list_item_s *)data; - uid_t uid = item->uid; - char *app_id = item->app_id; - esd_event_param *eep = (esd_event_param *)user_data; - static unsigned int req_id; - int pid; - char event_uri[1024]; - bundle *b; - int ret; - - _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)", - app_id, eep->event_name, uid, eep->is_user_event, eep->trusted); - - if (eep->is_user_event && eep->trusted) { - if (item->trusted_info == TRUSTED_UNKNOWN) { - ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid); - if (ret == ES_R_EINVAL) { - item->trusted_info = TRUSTED_DENIED; - return; - } else if (ret == ES_R_ERROR) { - return; - } else { - item->trusted_info = TRUSTED_ALLOWED; - } - } else if (item->trusted_info == TRUSTED_DENIED) { - return; - } - } - - if (!aul_app_is_running_for_uid(app_id, uid)) { - b = bundle_dup(eep->event_data); - if (eep->is_user_event) - snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name); - else - snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name); - - appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT); - appsvc_set_uri(b, event_uri); - appsvc_set_appid(b, app_id); - - pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid); - _D("uid(%d), pid(%d)", uid, pid); - - bundle_free(b); - } else { - _D("already is running or launch failed"); - } -} - -void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data) { - event_launch_item *el_item = (event_launch_item *)data; - esd_event_param *eep = (esd_event_param *)user_data; - - if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) { - g_list_foreach(el_item->app_list_evtlaunch, - __esd_event_launch_with_appid, user_data); - } -} - -void __esd_launch_event_handler(char *event_name, bundle *data, - const bool is_user_event, gboolean trusted, - const uid_t sender_uid, char *sender_appid, void *user_data) { - const char *val; - const char *msg_type; - const char *msg_id; - esd_event_param *eep; - event_launch_item *el_item; - - _D("event_name(%s)", event_name); - - el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name); - if (el_item == NULL) - return; - - if (el_item->app_list_evtlaunch != NULL) { - if (is_user_event == false) { - if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS); - _D("charger val(%s)", val); - if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_USB_STATUS); - _D("usb val(%s)", val); - if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS); - _D("earjack val(%s)", val); - if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) { - msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE); - _D("msg_type(%s)", msg_type); - if (msg_type == NULL) - return; - - msg_id = bundle_get_val(data, EVT_KEY_MSG_ID); - _D("msg_id(%s)", msg_id); - if (msg_id == NULL) - return; - } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_WIFI_STATE); - if (val == NULL) - return; - _D("wifi_state(%s)", val); - if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0) - return; - } - } - - eep = (esd_event_param *)calloc(1, sizeof(esd_event_param)); - if (!eep) { - _E("memory alloc failed"); - return; - } - eep->event_name = event_name; - eep->event_data = data; - eep->sender_uid = sender_uid; - eep->sender_appid = sender_appid; - eep->is_user_event = is_user_event; - eep->trusted = (bool)trusted; - eep->user_data = (void *)user_data; - __esd_check_event_launch_with_eventid(el_item, eep); - free(eep); - } -} - -void __esd_print_earlier_event(gpointer data, gpointer user_data) { - earlier_item *item = (earlier_item *)data; - char *event_name = (char *)item->event_name; - const char *val; - - _D("event_name = (%s)", event_name); - - if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED); - _D("boot_completed(%s)", val); - } - } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN); - _D("shutdown(%s)", val); - } - } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY); - _D("low_memory(%s)", val); - } - } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS); - _D("charger_status(%s)", val); - } - } -} - -void __esd_earlier_table_print_items() { - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, earlier_event_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) - __esd_print_earlier_event(value, NULL); -} - -void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data) { - earlier_item *item; - _D("event_name(%s)", event_name); - - item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name); - if (item) { - /* update earlier value */ - if (item->earlier_data != NULL) - bundle_free(item->earlier_data); - - item->earlier_data = bundle_dup(data); - } -} - -void __esd_event_handler(char *event_name, bundle *data, void *user_data) { - _D("event_name(%s)", event_name); - - if (__esd_check_earlier_support(event_name)) - __esd_earlier_event_handler(event_name, data, user_data); - - if (__esd_check_event_launch_support(event_name)) - __esd_launch_event_handler(event_name, data, - false, TRUE, ROOT_USER, NULL, user_data); -} - -void __esd_trusted_busname_remove_item(char *bus_name) { - GHashTableIter iter; - gpointer key; - gpointer value; - trusted_item *item; - - g_hash_table_iter_init(&iter, trusted_busname_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - item = (trusted_item *)value; - if (item) { - if (strcmp(bus_name, item->bus_name) == 0) { - _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name); - FREE_AND_NULL(item->app_id); - FREE_AND_NULL(item->bus_name); - FREE_AND_NULL(item); - g_hash_table_iter_remove(&iter); - - __esd_trusted_busname_print_items(); - } +void __esd_trusted_busname_remove_item(const char* bus_name) { + for (auto it = trusted_busname_table.begin(); + it != trusted_busname_table.end();) { + auto [bus_name_org, pid, uid] = (*it).second; + if (bus_name_org == bus_name) { + _D("remove trusted busname item(%s, %s)", (*it).first.c_str(), + bus_name_org.c_str()); + it = trusted_busname_table.erase(it); + __esd_trusted_busname_print_items(); + } else { + ++it; } } } @@ -938,9 +319,9 @@ void __esd_filter_name_owner_changed(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { - char *name = NULL; - char *old_owner = NULL; - char *new_owner = NULL; + char *name = nullptr; + char *old_owner = nullptr; + char *new_owner = nullptr; int old_len = 0; int new_len = 0; @@ -967,8 +348,9 @@ int __esd_dbus_name_monitor(GDBusConnection *connection) { name_owner_changed_id = g_dbus_connection_signal_subscribe(connection, "org.freedesktop.DBus", "org.freedesktop.DBus", - "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE, - __esd_filter_name_owner_changed, NULL, NULL); + "NameOwnerChanged", "/org/freedesktop/DBus", nullptr, + G_DBUS_SIGNAL_FLAGS_NONE, + __esd_filter_name_owner_changed, nullptr, nullptr); _I("name_owner_changed_id(%d)", name_owner_changed_id); @@ -977,7 +359,7 @@ int __esd_dbus_name_monitor(GDBusConnection *connection) { int __esd_get_user_items(uid_t uid) { int ret = 0; - pkgmgrinfo_appinfo_filter_h handle = NULL; + pkgmgrinfo_appinfo_filter_h handle = nullptr; _I("get user items for uid(%d)", uid); /* reset user's item */ @@ -1051,7 +433,8 @@ void __esd_signal_handler(GDBusConnection *connection, static GDBusNodeInfo *introspection_data; -int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, int buf_size) { +int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, + int buf_size) { int retval = ES_R_OK; int ret = 0; @@ -1099,57 +482,6 @@ int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size) { return ret; } -int check_user_event_sender_valid(const char *event_name, const char *app_id) { - char *valid_name = NULL; - char *temp_name = NULL; - char *tmp = NULL; - int retval = ES_R_OK; - int len = 0; - int valid_name_len = 0; - - temp_name = strdup(event_name); - if (temp_name == NULL) { - _E("out of memory"); - return ES_R_ENOMEM; - } - - tmp = strrchr(temp_name, '.'); - if (tmp == NULL || strlen(tmp) == 0) { - _E("invalid event name"); - FREE_AND_NULL(temp_name); - return ES_R_EINVAL; - } - len = strlen(tmp); - if (len <= 1 || len > 128) { - _E("invalid length(%d) of user-defined name", len); - FREE_AND_NULL(temp_name); - return ES_R_EINVAL; - } - *tmp = '\0'; - - _D("app_id(%s), len(%zu)", app_id, strlen(app_id)); - - valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1; - valid_name = (char *)calloc(1, valid_name_len); - if (valid_name == NULL) { - _E("memory alloc failed"); - FREE_AND_NULL(temp_name); - return ES_R_ENOMEM; - } - snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id); - _D("valid_name(%s)", valid_name); - - if (strcmp(temp_name, valid_name) != 0) { - _E("appid misamatch"); - retval = ES_R_EINVAL; - } - - FREE_AND_NULL(temp_name); - FREE_AND_NULL(valid_name); - - return retval; -} - static const GDBusInterfaceVTable interface_vtable = { esd::module::DbusEventModule::HandleMethodCallCb, nullptr, @@ -1163,42 +495,42 @@ void __esd_on_bus_acquired(GDBusConnection *connection, guint reg_id = 0; guint boot_id = 0; guint user_boot_id = 0; - GError *error = NULL; + GError *error = nullptr; reg_id = g_dbus_connection_register_object(connection, ESD_OBJECT_PATH, introspection_data->interfaces[0], &interface_vtable, - user_data, NULL, &error); + user_data, nullptr, &error); if (reg_id == 0) { _E("g_dbus_connection_register_object error(%s)", error->message); g_error_free(error); } boot_id = g_dbus_connection_signal_subscribe(connection, - NULL, + nullptr, SYSTEMD_DBUS_IFACE_MANAGER, SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED, SYSTEMD_DBUS_PATH, - NULL, + nullptr, G_DBUS_SIGNAL_FLAGS_NONE, __esd_signal_handler, - NULL, - NULL); + nullptr, + nullptr); if (boot_id == 0) _E("g_dbus_connection_signal_subscribe() is failed."); user_boot_id = g_dbus_connection_signal_subscribe(connection, - NULL, + nullptr, SYSTEMD_DBUS_IFACE_MANAGER, SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED, SYSTEMD_DBUS_PATH, - NULL, + nullptr, G_DBUS_SIGNAL_FLAGS_NONE, __esd_signal_handler, - NULL, - NULL); + nullptr, + nullptr); if (user_boot_id == 0) _E("g_dbus_connection_signal_subscribe() is failed."); @@ -1221,9 +553,7 @@ void __esd_on_name_acquired(GDBusConnection *connection, mod->SetVconfHandler(); __esd_trusted_busname_print_items(); - __esd_get_user_items(DEFAULT_USER); - __esd_dbus_name_monitor(connection); } @@ -1231,80 +561,64 @@ void __esd_on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data) { } -void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event) { - pkg_event->type = UNKNOWN; - if (pkg_event->pkgid) { - free(pkg_event->pkgid); - pkg_event->pkgid = NULL; - } -} - -int __esd_appcontrol_cb(const char *operation, - const char *uri, const char *mime, void *data) { - esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data; - char *appid = NULL; - char *pkgid = NULL; - char *event_name = NULL; - uid_t uid = 0; - - if (cb_data == NULL) { +int __esd_appcontrol_cb(const char* operation, + const char* uri, const char* mime, void* data) { + if (data == nullptr) { _E("invalid data"); return 0; } - appid = cb_data->appid; - pkgid = cb_data->pkgid; - uid = cb_data->uid; + + AppCtrlData* cb_data = reinterpret_cast(data); + std::string_view appid = cb_data->appid_; + std::string_view pkgid = cb_data->pkgid_; + std::string event_name; + uid_t uid = cb_data->uid_; _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)", - uid, appid, pkgid, operation, uri, mime); + uid, appid.data(), pkgid.data(), operation, uri, mime); if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) { - if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) { - event_name = strdup(&uri[8]); - if (event_name) { - _D("appid(%s), event_name(%s)", appid, event_name); - if (!__esd_check_event_launch_support(event_name)) - _E("failed to add item (not support event)"); - else if (!esd::module::PrivilegeChecker::AppHasPrivilege(uid, std::string(appid), std::string(event_name))) - _E("failed to add item (no privilege)"); - else if (__esd_add_launch_item(uid, event_name, appid, pkgid)) - _E("failed to add item"); - - } else { - _E("out of memory"); + if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, + strlen(SYSTEM_EVENT_NAME_PREFIX))) { + event_name = &uri[8]; + _D("appid(%s), event_name(%s)", appid.data(), event_name.c_str()); + if (event_launch_support_list.find(event_name) == + event_launch_support_list.end()) { + _E("failed to add item (not support event)"); + } else if (!esd::module::PrivilegeChecker::AppHasPrivilege( + uid, std::string(appid), event_name)) { + _E("failed to add item (no privilege)"); + } else if (__esd_add_launch_item(uid, event_name.c_str(), appid.data(), + pkgid.data())) { + _E("failed to add item"); } - } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) { - event_name = strdup(uri); - if (event_name) { - _D("appid(%s), event_name(%s)", appid, event_name); - if (__esd_check_platform_cert(pkgid, uid)) { - if (__esd_add_launch_item(uid, event_name, appid, pkgid)) - _E("failed to add item"); + } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, + strlen(USER_EVENT_NAME_PREFIX))) { + event_name = uri; + _D("appid(%s), event_name(%s)", appid.data(), event_name.c_str()); + if (esd::module::CertificateMatcher::IsPlatformCert(std::string(pkgid), + uid)) { + if (__esd_add_launch_item(uid, event_name.c_str(), appid.data(), + pkgid.data())) { + _E("failed to add item"); } - } else { - _E("out of memory"); } } - FREE_AND_NULL(event_name); } return 0; } int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data) { - char *appid = NULL; - char *pkgid = NULL; - int ret = 0; - uid_t *p_uid = NULL; - - if (data == NULL) { + if (data == nullptr) { _E("invalid data"); return ES_R_ERROR; } - p_uid = (uid_t *)data; - - ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); + char* appid = nullptr; + char* pkgid = nullptr; + uid_t* p_uid = reinterpret_cast(data); + int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); if (ret < 0) { _E("failed to get appid"); return ES_R_ERROR; @@ -1316,33 +630,9 @@ int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data) { return ES_R_ERROR; } - esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)calloc(1, sizeof(esd_appctrl_cb_data)); - - if (cb_data == NULL) { - _E("memory alloc failed"); - return ES_R_ENOMEM; - } - cb_data->appid = strdup(appid); - if (cb_data->appid == NULL) { - _E("out_of_memory"); - FREE_AND_NULL(cb_data); - return ES_R_ENOMEM; - } - cb_data->pkgid = strdup(pkgid); - if (cb_data->pkgid == NULL) { - _E("out_of_memory"); - FREE_AND_NULL(cb_data->appid); - FREE_AND_NULL(cb_data); - return ES_R_ENOMEM; - } - cb_data->uid = *p_uid; - - ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle, - (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data); - - FREE_AND_NULL(cb_data->pkgid); - FREE_AND_NULL(cb_data->appid); - FREE_AND_NULL(cb_data); + AppCtrlData cb_data(appid, pkgid, *p_uid); + ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle, __esd_appcontrol_cb, + &cb_data); if (ret < 0) { _E("failed to get appcontrol info"); @@ -1352,77 +642,6 @@ int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data) { return ES_R_OK; } -int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, - const char *pkg_type, const char *pkgid, const char *key, - const char *val, const void *pmsg, void *data) { - esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data; - pkgmgrinfo_pkginfo_h handle = NULL; - int ret = 0; - - _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)", - target_uid, req_id, pkg_type, pkgid, key, val); - - if (strncmp(key, "start", strlen(key)) == 0) { - if (strcmp(val, "install") == 0) { - _D("install start"); - pkg_event->type = INSTALL; - } else if (strcmp(val, "uninstall") == 0) { - _D("unistall start"); - pkg_event->type = UNINSTALL; - } else if (strcmp(val, "update") == 0) { - _D("update start"); - pkg_event->type = UPDATE; - } else { - _D("val(%s) start", val); - __esd_pkgmgr_event_free(pkg_event); - } - } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) { - if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) { - _D("install end (ok)"); - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle); - if (ret < 0) { - _E("failed to get pkginfo"); - __esd_pkgmgr_event_free(pkg_event); - return 0; - } - ret = pkgmgrinfo_appinfo_get_usr_list(handle, - PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid); - if (ret < 0) { - _E("failed to get appinfo"); - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - __esd_pkgmgr_event_free(pkg_event); - return 0; - } - ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - if (ret < 0) { - _E("failed to destroy pkginfo"); - __esd_pkgmgr_event_free(pkg_event); - return 0; - } - } else if (pkg_event->type == UNINSTALL) { - _D("uninstall end (ok)"); - __esd_launch_table_remove_items(target_uid, pkgid); - __esd_launch_table_print_items(); - } - __esd_pkgmgr_event_free(pkg_event); - } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) { - _E("pkg_event(%d) falied", pkg_event->type); - __esd_pkgmgr_event_free(pkg_event); - } else { - if (strcmp(key, "install_percent") != 0) - __esd_pkgmgr_event_free(pkg_event); - } - - return 0; -} - -void __esd_remove_esd_list_item(gpointer data, gpointer user_data) { - esd_list_item_s *item = (esd_list_item_s *)data; - - free(item->app_id); - free(item->pkg_id); -} - } // namespace namespace esd::module { @@ -1439,115 +658,44 @@ void DbusEventModule::Shutdown() { } bool DbusEventModule::Init() { - int req_id = 0; - int ret = 0; - pkgmgr_client *client; - esd_pkgmgr_event *pkg_event; - auto checker = std::make_unique(); - client = pkgmgr_client_new(PC_LISTENING); - if (client == NULL) { + pkgmgr_client_ = pkgmgr_client_new(PC_LISTENING); + if (pkgmgr_client_ == nullptr) { _E("set pkgmgr client failed"); return false; } - pkg_event = (esd_pkgmgr_event *)calloc(1, sizeof(esd_pkgmgr_event)); - if (pkg_event == NULL) { - _E("memory alloc failed"); - ret = pkgmgr_client_free(client); - if (ret != PKGMGR_R_OK) - _E("pkgmgr_client_free failed(%d)", ret); - return false; - } - - req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event); + int req_id = pkgmgr_client_listen_status(pkgmgr_client_, + PkgmgrEventCb, this); if (req_id < 0) { _E("pkgmgr client listen failed"); - ret = pkgmgr_client_free(client); + int ret = pkgmgr_client_free(pkgmgr_client_); + pkgmgr_client_ = nullptr; if (ret != PKGMGR_R_OK) _E("pkgmgr_client_free failed(%d)", ret); - free(pkg_event); return false; } - s_info.client = client; checker_ = std::move(checker); - _I("esd init done"); return true; } void DbusEventModule::Fini() { - gpointer key; - gpointer value; - GHashTableIter iter; - trusted_item *item; - event_launch_item *el_item; - int ret = 0; - earlier_item *er_item; - _D("esd finalize"); - if (trusted_busname_table) { - g_hash_table_iter_init(&iter, trusted_busname_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - item = (trusted_item *)value; - if (item) { - free(item->app_id); - free(item->bus_name); - free(item); - } else { - _E("item is null"); - } - g_hash_table_iter_remove(&iter); - } - g_hash_table_unref(trusted_busname_table); - } - - if (earlier_event_table) { - g_hash_table_iter_init(&iter, earlier_event_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - er_item = (earlier_item *)value; - if (er_item) { - eventsystem_unregister_event(er_item->reg_id); - free(er_item->event_name); - bundle_free(er_item->earlier_data); - free(er_item); - } else { - _E("ealier item is NULL"); - } - g_hash_table_iter_remove(&iter); - } - g_hash_table_unref(earlier_event_table); - } - - g_hash_table_destroy(user_last_event_table); - - if (event_launch_table) { - g_hash_table_iter_init(&iter, event_launch_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - el_item = (event_launch_item *)value; - if (el_item) { - eventsystem_unregister_event(el_item->reg_id); - free(el_item->event_name); - g_list_foreach(el_item->app_list_evtlaunch, - __esd_remove_esd_list_item, NULL); - g_list_free(el_item->app_list_evtlaunch); - free(el_item); - } else { - _E("item is NULL"); - } - g_hash_table_iter_remove(&iter); - } - g_hash_table_unref(event_launch_table); - } + trusted_busname_table.clear(); + earlier_event_table_.clear(); + user_last_event_table_.clear(); + event_launch_table.clear(); if (introspection_data) g_dbus_node_info_unref(introspection_data); - if (s_info.client) { - ret = pkgmgr_client_free(s_info.client); + if (pkgmgr_client_) { + int ret = pkgmgr_client_free(pkgmgr_client_); + pkgmgr_client_ = nullptr; if (ret != PKGMGR_R_OK) _E("pkgmgr_client_free failed(%d)", ret); } @@ -1557,136 +705,10 @@ void DbusEventModule::Fini() { } bool DbusEventModule::BeforeLoop() { - int ret = 0; - GError *error = NULL; - guint owner_id = 0; - - guint subscription_id = 0; - int i; - int size; - char *event_name; - int fd; - int val; - int status; - int charger_status; - int charge_now; - earlier_item *item; - - earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal); - user_last_event_table = g_hash_table_new_full(g_str_hash, - g_str_equal, NULL, (GDestroyNotify)free_saved_event); - - _I("register events for earlier_data"); - size = sizeof(earlier_event_list)/sizeof(*earlier_event_list); - for (i = 0; i < size; i++) { - event_name = (char *)earlier_event_list[i]; - _I("event_name(%s)", event_name); - - item = (earlier_item *)calloc(1, sizeof(earlier_item)); - if (item == NULL) { - _E("memery alloc failed"); - return false; - } - item->event_name = strdup(event_name); - if (item->event_name == NULL) { - _E("out of memory"); - free(item); - return false; - } - - /* set initial data */ - if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) { - fd = open(ESD_BOOT_COMPLETED, O_RDONLY); - if (fd < 0) { - _D("open file error(%d)", fd); - } else { - item->earlier_data = bundle_create(); - bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED, - EVT_VAL_BOOT_COMPLETED_TRUE); - close(fd); - } - } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) { - ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val); - if (ret != VCONF_OK) { - _E("failed to get power_off status (%d)", ret); - } else { - if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || - val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) { - /* power-off requested */ - item->earlier_data = bundle_create(); - bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN, - EVT_VAL_SYSTEM_SHUTDOWN_TRUE); - } - } - } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) { - ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); - if (ret != VCONF_OK) { - _E("failed to get low_memory status (%d)", ret); - } else { - item->earlier_data = bundle_create(); - if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) - bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, - EVT_VAL_MEMORY_SOFT_WARNING); - else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING) - bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, - EVT_VAL_MEMORY_HARD_WARNING); - else - bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, - EVT_VAL_MEMORY_NORMAL); - } - } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) { - ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status); - if (ret != VCONF_OK) { - _E("failed to get charger_status (%d)", ret); - } else { - ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now); - if (ret != VCONF_OK) - _E("failed to get charge_now (%d)", ret); - } - - if (ret == VCONF_OK) { - item->earlier_data = bundle_create(); - if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) { - if (charge_now == 0) { - bundle_add_str(item->earlier_data, - EVT_KEY_BATTERY_CHARGER_STATUS, - EVT_VAL_BATTERY_CHARGER_DISCHARGING); - } else { - bundle_add_str(item->earlier_data, - EVT_KEY_BATTERY_CHARGER_STATUS, - EVT_VAL_BATTERY_CHARGER_CHARGING); - } - } else { - bundle_add_str(item->earlier_data, - EVT_KEY_BATTERY_CHARGER_STATUS, - EVT_VAL_BATTERY_CHARGER_DISCONNECTED); - } - } - } - - eventsystem_register_event(event_name, &subscription_id, - (eventsystem_handler)__esd_event_handler, NULL); - if (subscription_id == 0) { - _E("signal subscription error, event_name(%s)", event_name); - if (item->earlier_data) - bundle_free(item->earlier_data); - free(item->event_name); - free(item); - - return false; - } else { - item->reg_id = subscription_id; - } + GError* error = nullptr; + earlier_event_table_ = EarlierItem::CreateMap(); - g_hash_table_insert(earlier_event_table, event_name, item); - } - - __esd_earlier_table_print_items(); - - event_launch_table = g_hash_table_new(g_str_hash, g_str_equal); - trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal); - - /* gdbus setup for method call */ + event_launch_table.clear(); introspection_data = g_dbus_node_info_new_for_xml(INTROSPECTION_XML, &error); if (!introspection_data) { _E("g_dbus_node_info_new_for_xml error(%s)", error->message); @@ -1694,13 +716,14 @@ bool DbusEventModule::BeforeLoop() { return false; } - owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + guint owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, ESD_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, __esd_on_bus_acquired, __esd_on_name_acquired, __esd_on_name_lost, - this, NULL); + this, nullptr); + if (!owner_id) { _E("g_bus_own_name error"); g_dbus_node_info_unref(introspection_data); @@ -1708,7 +731,6 @@ bool DbusEventModule::BeforeLoop() { } _I("esd before_loop done"); - return true; } @@ -1722,22 +744,32 @@ void DbusEventModule::HandleMethodCallCb(GDBusConnection *connection, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { - static std::map> dispatcher = { - { "CheckSenderValidation", &DbusEventModule::CheckSenderValidMethodCall }, - { "GetTrustedPeerList", &DbusEventModule::GetTrustedPeerMethodCall }, - { "SetupTrustedPeer", &DbusEventModule::SetupTrustedPeerMethodCall }, - { "CheckPrivilegeValidation", &DbusEventModule::CheckPrivilegeValidMethodCall }, - { "CheckUserSendValidation", &DbusEventModule::CheckSendEventValidMethodCall }, - { "GetEarlierData", &DbusEventModule::GetEarlierDataMethodCall }, - { "KeepLastData", &DbusEventModule::KeepLastDataMethodCall }, - { "CheckLastData", &DbusEventModule::CheckLastDataMethodCall }, - { "LaunchOnEventFromUserEvent", &DbusEventModule::LaunchOnEventFromUserEventMethodCall }, + { "CheckSenderValidation", + &DbusEventModule::CheckSenderValidMethodCall }, + { "GetTrustedPeerList", + &DbusEventModule::GetTrustedPeerMethodCall }, + { "SetupTrustedPeer", + &DbusEventModule::SetupTrustedPeerMethodCall }, + { "CheckPrivilegeValidation", + &DbusEventModule::CheckPrivilegeValidMethodCall }, + { "CheckUserSendValidation", + &DbusEventModule::CheckSendEventValidMethodCall }, + { "GetEarlierData", + &DbusEventModule::GetEarlierDataMethodCall }, + { "KeepLastData", + &DbusEventModule::KeepLastDataMethodCall }, + { "CheckLastData", + &DbusEventModule::CheckLastDataMethodCall }, + { "LaunchOnEventFromUserEvent", + &DbusEventModule::LaunchOnEventFromUserEventMethodCall }, { "CionGetUuid", &DbusEventModule::GetUuidMethodCall }, - { "CionSetDisplayName", &DbusEventModule::SetDisplayNameMethodCall }, - { "CionGetDisplayName", &DbusEventModule::GetDisplayNameMethodCall }, + { "CionSetDisplayName", + &DbusEventModule::SetDisplayNameMethodCall }, + { "CionGetDisplayName", + &DbusEventModule::GetDisplayNameMethodCall }, { "CionSetEnabled", &DbusEventModule::SetEnabledMethodCall }, { "CionGetEnabled", &DbusEventModule::GetEnabledMethodCall } }; @@ -1761,12 +793,12 @@ std::string DbusEventModule::GetSenderAppId(GDBusConnection* connection, return app_id; } -void DbusEventModule::CheckSendEventValidMethodCall(GDBusConnection* connection, - const gchar* sender, GVariant* parameters, +void DbusEventModule::CheckSendEventValidMethodCall( + GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param = NULL; + GVariant *param = nullptr; int result = 0; - char *event_name = NULL; + char *event_name = nullptr; char app_id[128] = {0, }; int sender_pid = 0; uid_t sender_uid = 0; @@ -1776,10 +808,11 @@ void DbusEventModule::CheckSendEventValidMethodCall(GDBusConnection* connection, sender_pid = __get_sender_pid(connection, sender); sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { result = ES_R_ERROR; } else { - if (check_user_event_sender_valid(event_name, app_id) < 0) { + if (CheckUserEventSenderValid(event_name, app_id) < 0) { _E("invalid sender"); result = ES_R_EINVAL; } else { @@ -1795,9 +828,9 @@ void DbusEventModule::CheckSendEventValidMethodCall(GDBusConnection* connection, void DbusEventModule::CheckSenderValidMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param = NULL; + GVariant *param = nullptr; int result = 0; - char *event_name = NULL; + char *event_name = nullptr; char app_id[128] = {0, }; int event_sender_pid = 0; uid_t sender_uid = 0; @@ -1806,10 +839,11 @@ void DbusEventModule::CheckSenderValidMethodCall(GDBusConnection* connection, _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name); sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { result = ES_R_ERROR; } else { - if (check_user_event_sender_valid(event_name, app_id) < 0) { + if (CheckUserEventSenderValid(event_name, app_id) < 0) { _E("invalid sender"); result = ES_R_EINVAL; } else { @@ -1825,44 +859,31 @@ void DbusEventModule::CheckSenderValidMethodCall(GDBusConnection* connection, void DbusEventModule::GetTrustedPeerMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param = NULL; + GVariant *param = nullptr; int result = 0; - GVariantBuilder *builder = NULL; - GHashTableIter iter; - gpointer key, value; - char *event_name = NULL; + GVariantBuilder *builder = nullptr; + char *event_name = nullptr; char app_id[128] = {0, }; - int sender_pid = 0; - uid_t sender_uid = 0; - int ret = 0; - uid_t uid = 0; - char *_appid = NULL; - char *_busname = NULL; - trusted_item *item; g_variant_get(parameters, "(&s)", &event_name); _D("event_name(%s)", event_name); - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + int sender_pid = __get_sender_pid(connection, sender); + uid_t sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { result = ES_R_ERROR; } else { builder = g_variant_builder_new(G_VARIANT_TYPE("as")); - g_hash_table_iter_init(&iter, trusted_busname_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - item = (trusted_item *)value; - uid = item->uid; - _appid = item->app_id; - _busname = item->bus_name; - + for (const auto& i : trusted_busname_table) { + auto [busname, pid, uid] = i.second; if (uid != GLOBAL_USER && uid != sender_uid) continue; - ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id); + int ret = CertificateMatcher::Match(uid, i.first, sender_uid, app_id); if (ret == ES_R_OK) - g_variant_builder_add(builder, "s", _busname); + g_variant_builder_add(builder, "s", busname.c_str()); } result = 1; @@ -1878,10 +899,10 @@ void DbusEventModule::GetTrustedPeerMethodCall(GDBusConnection* connection, void DbusEventModule::SetupTrustedPeerMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param = NULL; + GVariant *param = nullptr; int result = 0; - char *event_name = NULL; - char *destination_name = NULL; + char *event_name = nullptr; + char *destination_name = nullptr; char app_id[128] = {0, }; int sender_pid = 0; uid_t sender_uid = 0; @@ -1893,10 +914,12 @@ void DbusEventModule::SetupTrustedPeerMethodCall(GDBusConnection* connection, if (destination_name && destination_name[0] != '\0') { sender_pid = __get_sender_pid(connection, sender); sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { result = ES_R_ERROR; } else { - ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name, + ret = __esd_trusted_busname_add_item(sender_uid, app_id, + destination_name, sender_pid); if (ret < 0) { _E("failed to add trusted busname item"); @@ -1915,12 +938,12 @@ void DbusEventModule::SetupTrustedPeerMethodCall(GDBusConnection* connection, g_dbus_method_invocation_return_value(invocation, param); } -void DbusEventModule::CheckPrivilegeValidMethodCall(GDBusConnection* connection, - const gchar* sender, GVariant* parameters, +void DbusEventModule::CheckPrivilegeValidMethodCall( + GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param = NULL; + GVariant *param = nullptr; int result = 1; - char *event_name = NULL; + char *event_name = nullptr; char app_id[128] = {0, }; int sender_pid = 0; uid_t sender_uid = 0; @@ -1933,10 +956,11 @@ void DbusEventModule::CheckPrivilegeValidMethodCall(GDBusConnection* connection, if (!privilege_name.empty()) { sender_pid = __get_sender_pid(connection, sender); sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { result = ES_R_ERROR; } else { - if(checker_->Check(connection, sender, sender_pid, privilege_name)) + if (checker_->Check(connection, sender, sender_pid, privilege_name)) result = 1; else result = ES_R_EINVAL; @@ -1951,38 +975,26 @@ void DbusEventModule::CheckPrivilegeValidMethodCall(GDBusConnection* connection, void DbusEventModule::GetEarlierDataMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param = NULL; + GVariant *param = nullptr; int result = ES_R_ERROR; - char *event_name = NULL; - bundle *b = NULL; - bundle_raw *raw = NULL; - int len = 0; - earlier_item *item; + char* event_name = nullptr; + tizen_base::Bundle b; g_variant_get(parameters, "(&s)", &event_name); _D("event_name(%s)", event_name); - item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name); - if (item != NULL) { - if (item->earlier_data) { - b = bundle_dup(item->earlier_data); - bundle_add_str(b, "is_earlier_data", "true"); - result = ES_R_OK; - } + auto it = earlier_event_table_.find(event_name); + if (it != earlier_event_table_.end()) { + b = (*it).second->GetData(); + b.Add("is_earlier_data", "true"); + result = ES_R_OK; } - if (result == ES_R_ERROR) - b = bundle_create(); - - bundle_encode(b, &raw, &len); - bundle_free(b); - - param = g_variant_new("(iis)", result, len, raw); + auto raw = b.ToRaw(); + param = g_variant_new("(iis)", result, raw.second, raw.first.get()); - _D("result(%d), len(%d)", result, len); + _D("result(%d), len(%d)", result, raw.second); g_dbus_method_invocation_return_value(invocation, param); - - bundle_free_encoded_rawdata(&raw); } void DbusEventModule::KeepLastDataMethodCall(GDBusConnection* connection, @@ -1990,20 +1002,20 @@ void DbusEventModule::KeepLastDataMethodCall(GDBusConnection* connection, GDBusMethodInvocation* invocation) { GVariant *param; int result = ES_R_OK; - char *event_name; - char *own_name; - char *key; + char* event_name; + char* own_name; char app_id[128]; int sender_pid; uid_t sender_uid; - struct __last_event_item *item; g_variant_get(parameters, "(&s&s)", &event_name, &own_name); if (!event_name || !own_name) { result = ES_R_ERROR; _E("invalid event_name and own_name"); - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } sender_pid = __get_sender_pid(connection, sender); @@ -2012,62 +1024,44 @@ void DbusEventModule::KeepLastDataMethodCall(GDBusConnection* connection, sizeof(app_id)) < 0) { _E("failed to get appid by pid"); result = ES_R_ERROR; - goto out; - } - - key = (char *)malloc(sizeof(event_name) + 10); - if (!key) { - result = ES_R_ENOMEM; - _E("out of memory"); - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } - snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid); - item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table, - key); - if (!item) { - item = (struct __last_event_item *)calloc(1, sizeof(*item)); - if (!item) { - result = ES_R_ERROR; - goto out; - } - item->key = key; - item->event_name = strdup(event_name); - item->own_name = strdup(own_name); - item->uid = sender_uid; - item->app_id = strdup(app_id); - g_hash_table_insert(user_last_event_table, - item->key, item); + std::string key(event_name); + key += "_" + std::to_string(sender_uid); + auto it = user_last_event_table_.find(key); + if (it == user_last_event_table_.end()) { + user_last_event_table_[key] = LastEventItem(app_id, event_name, + own_name, sender_uid); } else { - free(item->own_name); - item->own_name = strdup(own_name); + user_last_event_table_[key].SetOwnName(own_name); } -out: param = g_variant_new("(i)", result); - g_dbus_method_invocation_return_value(invocation, param); } void DbusEventModule::CheckLastDataMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { - GVariant *param; + GVariant* param; int result = ES_R_OK; - char *event_name; - char *own_name; - char *key; + char* event_name; + char* own_name; char app_id[128]; int sender_pid; uid_t sender_uid; - struct __last_event_item *item; g_variant_get(parameters, "(&s&s)", &event_name, &own_name); if (!event_name || !own_name) { result = ES_R_ERROR; _E("invalid event_name and own_name"); - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } sender_pid = __get_sender_pid(connection, sender); @@ -2076,37 +1070,34 @@ void DbusEventModule::CheckLastDataMethodCall(GDBusConnection* connection, sizeof(app_id)) < 0) { result = ES_R_ERROR; _E("failed to get appid by pid"); - goto out; - } - - key = (char *)malloc(sizeof(event_name) + 10); - if (!key) { - result = ES_R_ENOMEM; - _E("out of memory"); - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } - snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid); - item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table, - key); - free(key); - if (item) { + std::string key(event_name); + key += "_" + std::to_string(sender_uid); + auto it = user_last_event_table_.find(key); + if (it != user_last_event_table_.end()) { GVariant *gv; bundle *b; bundle_raw *raw; int len; int ret; - GError *error = NULL; + GError *error = nullptr; b = bundle_create(); if (!b) { result = ES_R_ERROR; - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } + bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name); bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name); - if (__esd_check_certificate_match(item->uid, item->app_id, - sender_uid, app_id) == ES_R_OK) + if (CertificateMatcher::Match((*it).second.GetUid(), + (*it).second.GetAppId(), sender_uid, app_id) == ES_R_OK) bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true"); else bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false"); @@ -2114,7 +1105,7 @@ void DbusEventModule::CheckLastDataMethodCall(GDBusConnection* connection, bundle_encode(b, &raw, &len); gv = g_variant_new("(us)", len, raw); ret = g_dbus_connection_emit_signal(connection, - item->own_name, + (*it).second.GetOwnName().c_str(), SYS_EVENT_OBJ_PATH, SYS_EVENT_NAME_PREFIX, REQUEST_LAST_DATA, @@ -2128,14 +1119,12 @@ void DbusEventModule::CheckLastDataMethodCall(GDBusConnection* connection, bundle_free(b); } -out: param = g_variant_new("(i)", result); - g_dbus_method_invocation_return_value(invocation, param); } -void DbusEventModule::LaunchOnEventFromUserEventMethodCall(GDBusConnection* connection, - const gchar* sender, GVariant* parameters, +void DbusEventModule::LaunchOnEventFromUserEventMethodCall( + GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation) { GVariant *param; int result = ES_R_OK; @@ -2146,14 +1135,15 @@ void DbusEventModule::LaunchOnEventFromUserEventMethodCall(GDBusConnection* conn char *event_name; char app_id[128]; char *buf; - bundle *b; g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted); if (!event_name) { result = ES_R_ERROR; _E("invalid event_name"); - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } sender_pid = __get_sender_pid(connection, sender); @@ -2162,24 +1152,19 @@ void DbusEventModule::LaunchOnEventFromUserEventMethodCall(GDBusConnection* conn sizeof(app_id)) < 0) { _E("failed to get appid by pid"); result = ES_R_ERROR; - goto out; + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); + return; } - b = bundle_decode((bundle_raw *)buf, len); - if (b == NULL) { - _E("Out of memory"); - result = ES_R_ENOMEM; - goto out; + tizen_base::Bundle b(buf); + auto it = event_launch_table.find(event_name); + if (it != event_launch_table.end()) { + (*it).second->Notify(event_name, b, true, static_cast(trusted), + sender_uid, app_id); } - __esd_launch_event_handler(event_name, b, true, trusted, - sender_uid, app_id, NULL); - - bundle_free(b); - -out: param = g_variant_new("(i)", result); - g_dbus_method_invocation_return_value(invocation, param); } @@ -2230,8 +1215,9 @@ void DbusEventModule::SetDisplayNameMethodCall(GDBusConnection* connection, g_variant_get(parameters, "(&s&s)", &service_name, &display_name); if (!tools_->GetMethodBroker() - .Invoke( - "Cion.SetDisplayName", app_id, service_name, display_name, ret)) { + .Invoke("Cion.SetDisplayName", app_id, service_name, display_name, + ret)) { result = ES_R_ERROR; } @@ -2296,7 +1282,8 @@ void DbusEventModule::SetEnabledMethodCall(GDBusConnection* connection, if (!tools_->GetMethodBroker() .Invoke( - "Cion.SetEnabled", app_id, service_name, (bool)enabled, ret)) { + "Cion.SetEnabled", app_id, service_name, static_cast(enabled), + ret)) { result = ES_R_ERROR; } @@ -2340,5 +1327,90 @@ void DbusEventModule::GetEnabledMethodCall(GDBusConnection* connection, g_dbus_method_invocation_return_value(invocation, param); } +int DbusEventModule::PkgmgrEventCb(uid_t target_uid, int req_id, + const char *pkg_type, const char *pkgid, const char *key, + const char *val, const void *pmsg, void *data) { + DbusEventModule* obj = reinterpret_cast(data); + pkgmgrinfo_pkginfo_h handle = nullptr; + int ret = 0; + + _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)", + target_uid, req_id, pkg_type, pkgid, key, val); + + if (strncmp(key, "start", strlen(key)) == 0) { + if (strcmp(val, "install") == 0) { + _D("install start"); + obj->pkg_event_type_ = INSTALL; + } else if (strcmp(val, "uninstall") == 0) { + _D("unistall start"); + obj->pkg_event_type_ = UNINSTALL; + } else if (strcmp(val, "update") == 0) { + _D("update start"); + obj->pkg_event_type_ = UPDATE; + } else { + _D("val(%s) start", val); + } + } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) { + if (obj->pkg_event_type_ == INSTALL || obj->pkg_event_type_ == UPDATE) { + _D("install end (ok)"); + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle); + if (ret < 0) { + _E("failed to get pkginfo"); + return 0; + } + + ret = pkgmgrinfo_appinfo_get_usr_list(handle, + PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid); + if (ret < 0) { + _E("failed to get appinfo"); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return 0; + } + + ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + if (ret < 0) { + _E("failed to destroy pkginfo"); + return 0; + } + } else if (obj->pkg_event_type_ == UNINSTALL) { + _D("uninstall end (ok)"); + __esd_launch_table_remove_items(target_uid, pkgid); + __esd_launch_table_print_items(); + } + } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) { + _E("pkg_event(%d) falied", obj->pkg_event_type_); + } + + return 0; +} + +int DbusEventModule::CheckUserEventSenderValid(std::string_view event_name, + std::string_view app_id) { + auto it = event_name.rfind('.'); + + if (it == std::string::npos) { + _E("invalid event name"); + return ES_R_EINVAL; + } + + event_name = event_name.substr(0, it); + auto len = event_name.length(); + if (len <= 1 || len > 128) { + _E("invalid length(%d) of user-defined name", len); + return ES_R_EINVAL; + } + + _D("app_id(%s), len(%zu)", app_id.data(), app_id.length()); + + std::string valid_name = USER_EVENT_NAME_PREFIX + std::string(app_id); + _D("valid_name(%s)", valid_name.c_str()); + + if (valid_name != event_name) { + _E("appid misamatch"); + return ES_R_EINVAL; + } + + return ES_R_OK; +} -} // namespace esd::module \ No newline at end of file +} // namespace esd::module diff --git a/src/modules/dbus_event/dbus_event_module.hh b/src/modules/dbus_event/dbus_event_module.hh index 2a8361c..d6661cf 100644 --- a/src/modules/dbus_event/dbus_event_module.hh +++ b/src/modules/dbus_event/dbus_event_module.hh @@ -19,9 +19,17 @@ #include #include +#include -#include +#include +#include +#include +#include +#include "earlier_item.hh" +#include "event_launch.hh" +#include +#include "last_event_item.hh" #include "vconf_event_handler.hh" #include "privilege_checker.hh" @@ -44,13 +52,21 @@ class DbusEventModule : public api::IModule { gpointer user_data); private: + enum PkgEventType { + UNKNOWN = 0, + INSTALL, + UNINSTALL, + UPDATE, + }; + bool Init(); void Fini(); bool BeforeLoop(); void GetUuidMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation); void SetDisplayNameMethodCall(GDBusConnection* connection, - const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation); + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); void GetDisplayNameMethodCall(GDBusConnection* connection, const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation); @@ -88,13 +104,24 @@ class DbusEventModule : public api::IModule { const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation); std::string GetSenderAppId(GDBusConnection* connection, const gchar* sender); + int CheckUserEventSenderValid(std::string_view event_name, + std::string_view app_id); + + static int PkgmgrEventCb(uid_t target_uid, int req_id, const char* pkg_type, + const char* pkgid, const char* key, const char* val, const void* pmsg, + void* data); private: api::ToolBox* tools_ = nullptr; std::unique_ptr vconf_handler_; std::unique_ptr checker_; + std::map> earlier_event_table_; + std::map user_last_event_table_; + pkgmgr_client* pkgmgr_client_ = nullptr; + std::string pkg_event_pkgid_; + int pkg_event_type_; }; } // namespace esd::module -#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_DBUS_EVENT_MODULE_HH_ \ No newline at end of file +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_DBUS_EVENT_MODULE_HH_ diff --git a/src/modules/dbus_event/earlier_item.cc b/src/modules/dbus_event/earlier_item.cc new file mode 100644 index 0000000..3997a14 --- /dev/null +++ b/src/modules/dbus_event/earlier_item.cc @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "earlier_item.hh" + +#include +#include +#include +#include +#include +#include + +#include + +#include "log.hh" + +namespace { + +constexpr const char ESD_BOOT_COMPLETED[] = "/tmp/esd_ready"; + +const std::set earlier_event_list = { + SYS_EVENT_ESD_STATUS, + SYS_EVENT_LOW_MEMORY, + SYS_EVENT_BOOT_COMPLETED, + SYS_EVENT_SYSTEM_SHUTDOWN, + SYS_EVENT_BATTERY_CHARGER_STATUS +}; + +} // namespace + +namespace esd::module { + +EarlierItem::EarlierItem(tizen_base::Bundle data) + : data_(std::move(data)) { +} + +EarlierItem::~EarlierItem() { + if (reg_id_) + eventsystem_unregister_event(reg_id_); +} + +bool EarlierItem::Register(std::string_view event_name) { + if (eventsystem_register_event(event_name.data(), ®_id_, + EsdEventHandlerCb, this) != 0) { + return false; + } + + return true; +} + +const tizen_base::Bundle& EarlierItem::GetData() const { + return data_; +} + +void EarlierItem::OnEvent(const char* event_name, bundle* data) { + _D("event_name(%s)", event_name); + data_ = tizen_base::Bundle(data); +} + +void EarlierItem::EsdEventHandlerCb(const char* event_name, bundle* data, + void* user_data) { + _D("event_name(%s)", event_name); + EarlierItem* ei = reinterpret_cast(user_data); + if (earlier_event_list.find(event_name) != earlier_event_list.end()) + ei->OnEvent(event_name, data); +} + +std::map> EarlierItem::CreateMap() { + int fd; + int ret; + std::map> events; + int val; + int status; + int charger_status; + int charge_now; + + _I("register events for earlier_data"); + for (const auto& event_name : earlier_event_list) { + _I("event_name(%s)", event_name.data()); + + tizen_base::Bundle b; + if (event_name == SYS_EVENT_BOOT_COMPLETED) { + fd = open(ESD_BOOT_COMPLETED, O_RDONLY); + if (fd < 0) { + _D("open file error(%d)", fd); + } else { + b.Add(EVT_KEY_BOOT_COMPLETED, EVT_VAL_BOOT_COMPLETED_TRUE); + close(fd); + } + } else if (event_name == SYS_EVENT_SYSTEM_SHUTDOWN) { + ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val); + if (ret != VCONF_OK) { + _E("failed to get power_off status (%d)", ret); + } else { + if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || + val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) { + b.Add(EVT_KEY_SYSTEM_SHUTDOWN, EVT_VAL_SYSTEM_SHUTDOWN_TRUE); + } + } + } else if (event_name == SYS_EVENT_LOW_MEMORY) { + ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); + if (ret != VCONF_OK) { + _E("failed to get low_memory status (%d)", ret); + } else { + if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) + b.Add(EVT_KEY_LOW_MEMORY, EVT_VAL_MEMORY_SOFT_WARNING); + else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING) + b.Add(EVT_KEY_LOW_MEMORY, EVT_VAL_MEMORY_HARD_WARNING); + else + b.Add(EVT_KEY_LOW_MEMORY, EVT_VAL_MEMORY_NORMAL); + } + } else if (event_name == SYS_EVENT_BATTERY_CHARGER_STATUS) { + ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status); + if (ret != VCONF_OK) { + _E("failed to get charger_status (%d)", ret); + } else { + ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now); + if (ret != VCONF_OK) + _E("failed to get charge_now (%d)", ret); + } + + if (ret == VCONF_OK) { + if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) { + if (charge_now == 0) { + b.Add(EVT_KEY_BATTERY_CHARGER_STATUS, + EVT_VAL_BATTERY_CHARGER_DISCHARGING); + } else { + b.Add(EVT_KEY_BATTERY_CHARGER_STATUS, + EVT_VAL_BATTERY_CHARGER_CHARGING); + } + } else { + b.Add(EVT_KEY_BATTERY_CHARGER_STATUS, + EVT_VAL_BATTERY_CHARGER_DISCONNECTED); + } + } + } + + auto ei = std::make_unique(std::move(b)); + if (!ei->Register(event_name)) { + _E("signal subscription error, event_name(%s)", event_name.data()); + continue; + } + + events[std::string(event_name)] = std::move(ei); + } + + return events; +} + +} // namespace esd::module diff --git a/src/modules/dbus_event/earlier_item.hh b/src/modules/dbus_event/earlier_item.hh new file mode 100644 index 0000000..3fbd86b --- /dev/null +++ b/src/modules/dbus_event/earlier_item.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_DBUS_EVENT_EARLIER_ITEM_HH_ +#define EVENTSYSTEM_MODULES_DBUS_EVENT_EARLIER_ITEM_HH_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace esd::module { + +class EarlierItem { + public: + EarlierItem() = default; + explicit EarlierItem(tizen_base::Bundle data); + EarlierItem(const EarlierItem&) = delete; + EarlierItem& operator = (const EarlierItem&) = delete; + ~EarlierItem(); + + bool Register(std::string_view event_name); + const tizen_base::Bundle& GetData() const; + + static std::map> CreateMap(); + + private: + void OnEvent(const char* event_name, bundle* data); + static void EsdEventHandlerCb(const char* event_name, bundle* data, + void* user_data); + + private: + guint reg_id_ = 0; + tizen_base::Bundle data_; +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_EARLIER_ITEM_HH_ diff --git a/src/modules/dbus_event/esd_list_item.cc b/src/modules/dbus_event/esd_list_item.cc new file mode 100644 index 0000000..67be5e1 --- /dev/null +++ b/src/modules/dbus_event/esd_list_item.cc @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "esd_list_item.hh" + +#include "log.hh" + +namespace esd::module { + +EsdListItem::EsdListItem(std::string pkg_id, std::string app_id, uid_t uid) + : pkg_id_(std::move(pkg_id)), app_id_(std::move(app_id)), uid_(uid) { +} + +void EsdListItem::Print(const std::string& event_name) { + _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", + event_name.c_str(), uid_, app_id_.c_str(), pkg_id_.c_str()); +} + +const std::string& EsdListItem::GetAppId() const { + return app_id_; +} + +int EsdListItem::GetTrustedInfo() const { + return trusted_info_; +} + +void EsdListItem::SetTrustedInfo(int info) { + trusted_info_ = info; +} + +uid_t EsdListItem::GetUid() const { + return uid_; +} + +} // namespace esd::module diff --git a/src/modules/dbus_event/esd_list_item.hh b/src/modules/dbus_event/esd_list_item.hh new file mode 100644 index 0000000..6f06cdd --- /dev/null +++ b/src/modules/dbus_event/esd_list_item.hh @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_DBUS_EVENT_ESD_LIST_ITEM_HH_ +#define EVENTSYSTEM_MODULES_DBUS_EVENT_ESD_LIST_ITEM_HH_ + +#include + +#include +#include +#include +#include +#include + +namespace esd::module { + +class EsdListItem { + public: + enum TrustedResult { + TRUSTED_UNKNOWN, + TRUSTED_ALLOWED, + TRUSTED_DENIED, + }; + + EsdListItem() = default; + EsdListItem(std::string pkg_id, std::string app_id, uid_t uid); + + void Print(const std::string& event_name); + const std::string& GetAppId() const; + int GetTrustedInfo() const; + void SetTrustedInfo(int info); + uid_t GetUid() const; + + private: + std::string pkg_id_; + std::string app_id_; + int trusted_info_ = TRUSTED_UNKNOWN; + uid_t uid_ = 0; +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_ESD_LIST_ITEM_HH_ diff --git a/src/modules/dbus_event/event_launch.cc b/src/modules/dbus_event/event_launch.cc new file mode 100644 index 0000000..0df70a4 --- /dev/null +++ b/src/modules/dbus_event/event_launch.cc @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "event_launch.hh" + +#include +#include +#include +#include +#include + +#include + +#include "certificate_matcher.hh" +#include "log.hh" + +namespace { + +constexpr const int ROOT_USER = 0; + +const std::set event_launch_support_list = { + SYS_EVENT_BATTERY_CHARGER_STATUS, + SYS_EVENT_USB_STATUS, + SYS_EVENT_EARJACK_STATUS, + SYS_EVENT_INCOMMING_MSG, + SYS_EVENT_OUTGOING_MSG, + SYS_EVENT_WIFI_STATE +}; + +} // namespace + +namespace esd::module { + +EventLaunch::EventLaunch(std::string pkgid, std::string appid, uid_t uid) + : package_name_(std::move(pkgid)), + uid_(uid) { + app_list_evtlaunch_.push_back(EsdListItem(package_name_, std::move(appid), + uid)); +} + +EventLaunch::~EventLaunch() { + if (reg_id_) + eventsystem_unregister_event(reg_id_); +} + +bool EventLaunch::Register(std::string_view event_name) { + if (eventsystem_register_event(event_name.data(), ®_id_, + EsdEventHandlerCb, this) != 0) { + return false; + } + + return true; +} + +void EventLaunch::Print(const std::string& event_name) { + for (auto& i : app_list_evtlaunch_) + i.Print(event_name); +} + +uid_t EventLaunch::GetUid() const { + return uid_; +} + +const std::string& EventLaunch::GetPackageName() const { + return package_name_; +} + +std::list& EventLaunch::GetAppListEventLaunch() { + return app_list_evtlaunch_; +} + +void EventLaunch::EsdEventHandlerCb(const char* event_name, bundle* data, + void* user_data) { + _D("event_name(%s)", event_name); + EventLaunch* el = reinterpret_cast(user_data); + if (event_launch_support_list.find(event_name) != + event_launch_support_list.end()) { + el->OnEvent(event_name, tizen_base::Bundle(data, false, false), false, + true, ROOT_USER, ""); + } +} + +bool EventLaunch::CheckEvent(std::string_view event_name, + const tizen_base::Bundle& data) { + if (event_name == SYS_EVENT_BATTERY_CHARGER_STATUS) { + auto val = data.GetString(EVT_KEY_BATTERY_CHARGER_STATUS); + _D("charger val(%s)", val.c_str()); + if (val != EVT_VAL_BATTERY_CHARGER_CONNECTED) + return false; + } else if (event_name == SYS_EVENT_USB_STATUS) { + auto val = data.GetString(EVT_KEY_USB_STATUS); + _D("usb val(%s)", val.c_str()); + if (val != EVT_VAL_USB_CONNECTED) + return false; + } else if (event_name == SYS_EVENT_EARJACK_STATUS) { + auto val = data.GetString(EVT_KEY_EARJACK_STATUS); + _D("earjack val(%s)", val.c_str()); + if (val != EVT_VAL_EARJACK_CONNECTED) + return false; + } else if (event_name == SYS_EVENT_INCOMMING_MSG) { + auto msg_type = data.GetString(EVT_KEY_MSG_TYPE); + _D("msg_type(%s)", msg_type.c_str()); + if (msg_type.empty()) + return false; + auto msg_id = data.GetString(EVT_KEY_MSG_ID); + _D("msg_id(%s)", msg_id.c_str()); + if (msg_id.empty()) + return false; + } else if (event_name == SYS_EVENT_WIFI_STATE) { + auto val = data.GetString(EVT_KEY_WIFI_STATE); + if (val.empty()) + return false; + _D("wifi_state(%s)", val.c_str()); + if (val != EVT_VAL_WIFI_CONNECTED) + return false; + } + + return true; +} + +void EventLaunch::Notify(std::string_view event_name, + const tizen_base::Bundle& data, bool is_user_event, bool trusted, + uid_t sender_uid, std::string_view sender_appid) { + OnEvent(event_name, data, is_user_event, trusted, sender_uid, sender_appid); +} + +void EventLaunch::OnEvent(std::string_view event_name, + const tizen_base::Bundle& data, bool is_user_event, bool trusted, + uid_t sender_uid, std::string_view sender_appid) { + _D("event_name(%s)", event_name.data()); + + if (app_list_evtlaunch_.empty()) + return; + + if (!is_user_event && !CheckEvent(event_name, data)) + return; + + static int req_id; + for (auto& i : app_list_evtlaunch_) { + _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d)," + " trusted(%d)", + i.GetAppId().c_str(), event_name.data(), i.GetUid(), + is_user_event, trusted); + + if (is_user_event && trusted) { + if (i.GetTrustedInfo() == EsdListItem::TRUSTED_UNKNOWN) { + int ret = CertificateMatcher::Match(i.GetUid(), + i.GetAppId(), sender_uid, sender_appid.data()); + if (ret == ES_R_EINVAL) { + i.SetTrustedInfo(EsdListItem::TRUSTED_DENIED); + continue; + } else if (ret == ES_R_ERROR) { + continue; + } else { + i.SetTrustedInfo(EsdListItem::TRUSTED_ALLOWED); + } + } else if (i.GetTrustedInfo() == EsdListItem::TRUSTED_DENIED) { + continue; + } + } + + if (aul_app_is_running_for_uid(i.GetAppId().c_str(), i.GetUid())) { + _D("already is running or launch failed"); + continue; + } + + tizen_base::Bundle b(data); + std::string event_uri; + if (is_user_event) { + event_uri = USER_EVENT_NAME_PREFIX + std::string(event_name); + } else { + event_uri = SYSTEM_EVENT_NAME_PREFIX + std::string(event_name); + } + + appsvc_set_operation(b.GetHandle(), APPSVC_OPERATION_LAUNCH_ON_EVENT); + appsvc_set_uri(b.GetHandle(), event_uri.c_str()); + appsvc_set_appid(b.GetHandle(), i.GetAppId().c_str()); + + int pid = aul_svc_run_service_async_for_uid(b.GetHandle(), req_id++, + nullptr, nullptr, i.GetUid()); + _D("uid(%d), pid(%d)", i.GetUid(), pid); + } +} + +} // namespace esd::module diff --git a/src/modules/dbus_event/event_launch.hh b/src/modules/dbus_event/event_launch.hh new file mode 100644 index 0000000..e9b0871 --- /dev/null +++ b/src/modules/dbus_event/event_launch.hh @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_DBUS_EVENT_EVENT_LAUNCH_HH_ +#define EVENTSYSTEM_MODULES_DBUS_EVENT_EVENT_LAUNCH_HH_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "esd_list_item.hh" + +namespace esd::module { + +class EventLaunch { + public: + EventLaunch() = default; + EventLaunch(std::string pkgid, std::string appid, uid_t uid); + EventLaunch(const EventLaunch&) = delete; + EventLaunch& operator = (const EventLaunch&) = delete; + ~EventLaunch(); + + bool Register(std::string_view event_name); + void Print(const std::string& event_name); + uid_t GetUid() const; + const std::string& GetPackageName() const; + std::list& GetAppListEventLaunch(); + void Notify(std::string_view event_name, const tizen_base::Bundle& data, + bool is_user_event, bool trusted, uid_t sender_uid, + std::string_view sender_appid); + + private: + bool CheckEvent(std::string_view event_name, const tizen_base::Bundle& data); + void OnEvent(std::string_view event_name, const tizen_base::Bundle& data, + bool is_user_event, bool trusted, uid_t sender_uid, + std::string_view sender_appid); + + static void EsdEventHandlerCb(const char* event_name, bundle* data, + void* user_data); + + private: + std::string package_name_; + std::list app_list_evtlaunch_; + guint reg_id_ = 0; + uid_t uid_ = 0; +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_EVENT_LAUNCH_HH_ diff --git a/src/modules/dbus_event/last_event_item.hh b/src/modules/dbus_event/last_event_item.hh new file mode 100644 index 0000000..4bc9be4 --- /dev/null +++ b/src/modules/dbus_event/last_event_item.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_DBUS_EVENT_LAST_EVENT_ITEM_HH_ +#define EVENTSYSTEM_MODULES_DBUS_EVENT_LAST_EVENT_ITEM_HH_ + +#include +#include + +namespace esd::module { + +class LastEventItem { + public: + LastEventItem() = default; + LastEventItem(std::string app_id, std::string event_name, + std::string own_name, uid_t uid) + : app_id_(std::move(app_id)), event_name_(std::move(event_name)), + own_name_(std::move(own_name)), uid_(uid) { + } + + const std::string& GetAppId() const { + return app_id_; + } + + const std::string& GetEventName() const { + return event_name_; + } + + const std::string& GetOwnName() const { + return own_name_; + } + + uid_t GetUid() const { + return uid_; + } + + void SetOwnName(std::string own_name) { + own_name_ = std::move(own_name); + } + + private: + std::string app_id_; + std::string event_name_; + std::string own_name_; + uid_t uid_; +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_LAST_EVENT_ITEM_HH_