3 // Copyright (c) 2015 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file message-port.cpp
20 * @brief This is the implementation file for the MessagePort.
28 #include <openssl/md5.h>
30 #include <pkgmgr-info.h>
32 #include "message-port.h"
33 #include "message-port-log.h"
36 #define MAX_PACKAGE_STR_SIZE 512
37 #define MESSAGEPORT_BUS_NAME_PREFIX "org.tizen.messageport._"
38 #define MESSAGEPORT_OBJECT_PATH "/org/tizen/messageport"
39 #define MESSAGEPORT_INTERFACE "org.tizen.messageport"
43 #define retvm_if(expr, val, fmt, arg...) do { \
46 _LOGE("(%s) -> %s() return", #expr, __func__); \
51 #define retv_if(expr, val) do { \
53 _LOGE("(%s) -> %s() return", #expr, __func__); \
58 #define FREE_AND_NULL(ptr) do { \
65 static bool _initialized = false;
66 static GDBusConnection *__gdbus_conn = NULL;
67 static char *__app_id;
68 static GHashTable *__local_port_info = NULL;
69 static GHashTable *__remote_port_info = NULL;;
70 static GHashTable *__sender_appid_hash = NULL;;
71 static GHashTable *__checked_app_list_hash = NULL;
72 static GHashTable *__trusted_app_list_hash = NULL;
73 static const int MAX_MESSAGE_SIZE = 16 * 1024;
77 enum __certificate_info_type {
80 CERTIFICATE_NOT_MATCH,
83 typedef struct message_port_local_port_info {
84 messageport_message_cb callback;
88 } message_port_local_port_info_s;
90 typedef struct message_port_remote_port_info {
91 char *encoded_bus_name;
97 } message_port_remote_app_info_s;
99 typedef struct port_list_info {
105 static char *__get_encoded_bus_name(const char *bus_name, const char *prefix, int len)
107 unsigned char c[MD5_DIGEST_LENGTH] = {0};
108 char *md5_interface = NULL;
112 int interface_len = len + (MD5_DIGEST_LENGTH * 2) + 1;
114 MD5_Init(&mdContext);
115 MD5_Update(&mdContext, bus_name, strlen(bus_name));
116 MD5_Final(c, &mdContext);
118 md5_interface = (char *)calloc(interface_len , sizeof(char));
119 if (md5_interface == NULL) {
120 _LOGI("Malloc failed!!");
124 snprintf(md5_interface, interface_len, "%s", prefix);
125 temp = md5_interface;
128 for (index = 0; index < MD5_DIGEST_LENGTH; index++) {
129 snprintf(temp, 3, "%02x", c[index]);
133 return md5_interface;
136 static char *__get_bus_name(const char *remote_app_id)
138 char *bus_name = NULL;
140 bus_name = __get_encoded_bus_name(remote_app_id, MESSAGEPORT_BUS_NAME_PREFIX, strlen(MESSAGEPORT_BUS_NAME_PREFIX));
142 _LOGE("fail to get bus name");
147 int __get_next_id(void)
149 static int count = 0;
155 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
157 port_list_info_s *key1 = (port_list_info_s *)a;
158 port_list_info_s *key2 = (port_list_info_s *)b;
160 if (key1->is_trusted == key2->is_trusted) {
161 return strcmp(key1->port_name, key2->port_name);
168 static bool __is_preloaded(const char *local_appid, const char *remote_appid)
170 _LOGI("IsPreloaded");
172 bool preload_local = false;
173 bool preload_remote = false;
175 pkgmgrinfo_appinfo_h handle = NULL;
176 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle);
177 if (ret != PMINFO_R_OK) {
178 _LOGE("Failed to get the appinfo. %d", ret);
179 pkgmgrinfo_appinfo_destroy_appinfo(handle);
182 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local);
183 if (ret != PMINFO_R_OK) {
184 _LOGE("Failed to check the preloaded application. %d", ret);
185 pkgmgrinfo_appinfo_destroy_appinfo(handle);
188 ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
189 if (ret != PMINFO_R_OK) {
190 _LOGE("Failed to get the appinfo. %d", ret);
191 pkgmgrinfo_appinfo_destroy_appinfo(handle);
194 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
195 if (ret != PMINFO_R_OK) {
196 _LOGE("Failed to check the preloaded application. %d", ret);
197 pkgmgrinfo_appinfo_destroy_appinfo(handle);
201 if (preload_local && preload_remote) {
202 pkgmgrinfo_appinfo_destroy_appinfo(handle);
205 pkgmgrinfo_appinfo_destroy_appinfo(handle);
209 static int __check_certificate(const char *local_appid, const char *remote_appid)
211 _LOGI("CheckCertificate");
213 pkgmgrinfo_cert_compare_result_type_e res;
214 int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid,
215 remote_appid, getuid(), &res);
217 _LOGE(":CheckCertificate() Failed");
218 return MESSAGEPORT_ERROR_IO_ERROR;
220 if (res != PMINFO_CERT_COMPARE_MATCH) {
221 _LOGE("CheckCertificate() Failed : MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH");
222 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
225 return MESSAGEPORT_ERROR_NONE;
228 static void on_name_appeared (GDBusConnection *connection,
230 const gchar *name_owner,
233 _LOGI("name appeared : %s %s", __app_id, name);
236 static void on_name_vanished (GDBusConnection *connection,
240 _LOGI("name vanished : %s", name);
241 message_port_remote_app_info_s *remote_app_info = (message_port_remote_app_info_s *)user_data;
242 g_bus_unwatch_name(remote_app_info->watcher_id);
243 g_hash_table_remove(__remote_port_info, remote_app_info->remote_app_id);
246 static void __hash_destory_list_value(gpointer data)
248 GList *list = (GList *)data;
249 g_list_foreach(list, (GFunc)g_free, NULL);
254 static void __set_checked_app_list(message_port_local_port_info_s *mi, char *remote_appid) {
256 GList *app_list = (GList *)g_hash_table_lookup(__checked_app_list_hash, mi->port_name);
257 if (app_list == NULL) {
258 app_list = g_list_append(app_list, strdup(remote_appid));
259 _LOGI("set checked_app_list appid: %s", remote_appid);
260 g_hash_table_insert(__checked_app_list_hash, mi->port_name, app_list);
262 GList *app = g_list_find(app_list, (gpointer)remote_appid);
264 app_list = g_list_append(app_list, strdup(remote_appid));
265 _LOGI("set checked_app_list appid: %s", remote_appid);
270 static int __get_local_port_info(int id, message_port_local_port_info_s **info)
272 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(id));
275 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
279 return MESSAGEPORT_ERROR_NONE;
282 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
284 int ret_val = MESSAGEPORT_ERROR_NONE;
285 port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
288 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
291 port_info->port_name = strdup(remote_port);
292 if (!port_info->port_name) {
293 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
296 port_info->is_trusted = is_trusted;
299 if (ret_val != MESSAGEPORT_ERROR_NONE) {
301 FREE_AND_NULL(port_info->port_name);
309 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
311 port_list_info_s *port_info = NULL;
312 message_port_remote_app_info_s *remote_app_info = NULL;
313 int ret_val = MESSAGEPORT_ERROR_NONE;
315 remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
316 if (!remote_app_info) {
317 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
321 remote_app_info->encoded_bus_name = __get_bus_name(remote_app_id);
322 if (remote_app_info->encoded_bus_name == NULL) {
323 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
327 remote_app_info->remote_app_id = strdup(remote_app_id);
328 if (remote_app_info->remote_app_id == NULL) {
329 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;;
333 remote_app_info->watcher_id = g_bus_watch_name(G_BUS_TYPE_SESSION,
334 remote_app_info->encoded_bus_name,
335 G_BUS_NAME_WATCHER_FLAGS_NONE,
341 port_info = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
342 if (port_info == NULL) {
343 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
347 remote_app_info->port_list = g_list_append(remote_app_info->port_list, port_info);
350 if (ret_val != MESSAGEPORT_ERROR_NONE) {
351 if (remote_app_info) {
352 FREE_AND_NULL(remote_app_info->encoded_bus_name);
353 FREE_AND_NULL(remote_app_info->remote_app_id);
354 FREE_AND_NULL(remote_app_info);
358 return remote_app_info;
361 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
362 message_port_remote_app_info_s **mri, port_list_info_s **pli)
364 message_port_remote_app_info_s *remote_app_info = NULL;
365 port_list_info_s port_info;
366 GList *cb_list = NULL;
368 remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_port_info, remote_app_id);
370 if (remote_app_info == NULL) {
371 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
372 retvm_if(!remote_app_info, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "fail to create message_port_remote_app_info_s");
373 g_hash_table_insert(__remote_port_info, remote_app_info->remote_app_id, remote_app_info);
376 *mri = remote_app_info;
378 port_info.port_name = strdup(remote_port);
379 port_info.is_trusted = is_trusted;
380 cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
381 (GCompareFunc)__remote_port_compare_cb);
382 if (port_info.port_name)
383 free(port_info.port_name);
384 if (cb_list == NULL) {
385 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
386 retvm_if(!tmp, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "fail to create port_list_info_s");
387 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
390 *pli = (port_list_info_s *)cb_list->data;
392 return MESSAGEPORT_ERROR_NONE;
395 static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi)
400 g_hash_table_iter_init(&iter, __local_port_info);
402 while (g_hash_table_iter_next(&iter, &key, &value)) {
403 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
405 if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) {
406 *local_id = mi->local_id;
416 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
418 GDBusMessage *msg = NULL;
419 GDBusMessage *reply = NULL;
424 msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
425 "org.freedesktop.DBus", "GetConnectionUnixProcessID");
427 _LOGE("Can't allocate new method call");
431 g_dbus_message_set_body (msg, g_variant_new ("(s)", sender_name));
432 reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
433 G_DBUS_SEND_MESSAGE_FLAGS_NONE, 500, NULL, NULL, &err);
437 _LOGE("Failed to get pid [%s]", err->message);
443 body = g_dbus_message_get_body(reply);
444 g_variant_get(body, "(u)", &pid);
450 g_object_unref(reply);
456 static bool send_message(GVariant *parameters)
458 char *local_port = NULL;
459 char *local_appid = NULL;
460 char *remote_appid = NULL;
461 char *remote_port = NULL;
462 gboolean local_trusted = false;
463 gboolean remote_trusted = false;
464 gboolean bi_dir = false;
468 bundle_raw *raw = NULL;
469 message_port_local_port_info_s *mi;
470 int local_reg_id = 0;
472 g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir,
473 &remote_appid, &remote_port, &remote_trusted, &len, &raw);
476 _LOGE("Invalid argument : remote_port is NULL");
480 _LOGE("Invalid argument : remote_appid is NULL");
483 if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
484 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
488 _LOGE("Invalid argument : local_appid");
492 _LOGE("Invalid argument : local_port");
495 if (strcmp(remote_appid, __app_id) != 0) {
496 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
499 if (strcmp(remote_port, mi->port_name) != 0) {
500 _LOGE("Invalid argument : remote_port (%s)", remote_port);
504 _LOGE("Invalid argument : data_len");
507 if (remote_trusted) {
508 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
509 if (!__is_preloaded(local_appid, remote_appid)) {
510 // Check the certificate
511 int ret = __check_certificate(local_appid, remote_appid);
512 if (ret == MESSAGEPORT_ERROR_NONE) {
513 g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
515 _LOGE("The application (%s) is not signed with the same certificate",
523 data = bundle_decode(raw, len);
524 bundle_free_encoded_rawdata(&raw);
527 _LOGE("Invalid argument : message");
532 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data);
534 mi->callback(mi->local_id, local_appid, NULL, false, data);
541 static int unregister_port(GVariant *parameters)
543 int ret = MESSAGEPORT_ERROR_NONE;
544 char *remote_appid = NULL;
545 char *remote_port = NULL;
547 port_list_info_s *port_info = NULL;
548 message_port_remote_app_info_s *remote_app_info = NULL;
550 g_variant_get(parameters, "(sbs)", &remote_appid, &is_trusted, &remote_port);
553 _LOGE("Invalid argument : remote_appid");
554 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
558 _LOGE("Invalid argument : remote_port");
559 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
563 ret = __get_remote_port_info(remote_appid, remote_port, is_trusted, &remote_app_info, &port_info);
564 if (ret != MESSAGEPORT_ERROR_NONE) {
567 port_info->exist = false;
572 g_free(remote_appid);
578 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
580 _LOGI("Check a remote port : [%s:%s]", remote_app_id, remote_port);
582 GDBusMessage *msg = NULL;
583 GDBusMessage *reply = NULL;
586 int ret_val = MESSAGEPORT_ERROR_NONE;
587 char *bus_name = NULL;
588 message_port_remote_app_info_s *remote_app_info = NULL;
589 port_list_info_s *port_info = NULL;
590 int local_reg_id = 0;
591 message_port_local_port_info_s *mi = NULL;
593 _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
595 ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
596 if (ret_val != MESSAGEPORT_ERROR_NONE) {
600 if (strcmp(remote_app_id, __app_id) == 0) {
602 _LOGI("__is_local_port_registed ");
603 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi)) {
608 _LOGI("__is_local_port_registed : %d ", *exist);
609 return MESSAGEPORT_ERROR_NONE;
613 port_info->exist = false;
614 bus_name = remote_app_info->encoded_bus_name;
616 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH,
617 MESSAGEPORT_INTERFACE, "check_remote_port");
618 _LOGI("bus_name, remote app id:[%s : %s] ", bus_name, remote_app_id);
620 _LOGI("Can't allocate new method call");
621 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
624 g_dbus_message_set_body(msg, g_variant_new("(sbss)", __app_id, is_trusted, remote_app_id, remote_port));
625 reply = g_dbus_connection_send_message_with_reply_sync(
628 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
634 if (err || (reply == NULL)) {
636 _LOGE("No reply. error = %s", err->message);
639 ret_val = MESSAGEPORT_ERROR_IO_ERROR;
641 if (g_dbus_message_to_gerror(reply, &err)) {
642 _LOGE("error = %s", err->message);
644 ret_val = MESSAGEPORT_ERROR_NONE;
647 body = g_dbus_message_get_body(reply);
648 g_variant_get(body, "(i)", &ret_val);
650 if (ret_val == MESSAGEPORT_ERROR_NONE) {
652 port_info->exist = true;
653 } else if (ret_val == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH) {
654 _SECURE_LOGI("The remote application (%s) is not signed with the same certificate", remote_app_id);
662 g_object_unref(reply);
667 static int check_remote_port(GVariant *parameters)
669 int ret = MESSAGEPORT_ERROR_NONE;
670 char *remote_appid = NULL;
671 char *remote_port = NULL;
672 char *local_appid = NULL;
674 int local_reg_id = 0;
675 message_port_local_port_info_s *mi = NULL;
677 g_variant_get(parameters, "(sbss)", &local_appid, &is_trusted, &remote_appid, &remote_port);
680 _LOGE("Invalid argument : local_appid");
681 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
685 _LOGE("Invalid argument : remote_appid");
686 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
690 _LOGE("Invalid argument : remote_port");
691 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
694 if (strcmp(remote_appid, __app_id) != 0) {
695 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
696 ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
699 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi)) {
700 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, is_trusted);
701 ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
705 // Check the preloaded
706 if (!__is_preloaded(local_appid, remote_appid)) {
707 // Check the certificate
708 ret = __check_certificate(local_appid, remote_appid);
709 if (ret == MESSAGEPORT_ERROR_NONE) {
710 g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
715 __set_checked_app_list(mi, local_appid);
722 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
725 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
726 char *local_appid = NULL;
727 int pid = __get_sender_pid(conn, sender);
729 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
730 retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid);
732 g_variant_get_child(parameters, 0, "s", &local_appid);
733 retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid);
735 if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
736 g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid));
745 static void __dbus_method_call_handler(GDBusConnection *conn,
746 const gchar *sender, const gchar *object_path,
747 const gchar *iface_name, const gchar *method_name,
748 GVariant *parameters, GDBusMethodInvocation *invocation,
751 _LOGI("method_name: %s", method_name);
752 gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
753 int ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
754 if (sender_pid == NULL) {
755 if (!__check_sender_validation(parameters, sender, conn))
758 if (g_strcmp0(method_name, "send_message") == 0) {
759 ret =send_message(parameters);
760 } else if (g_strcmp0(method_name, "check_remote_port") == 0) {
761 ret = check_remote_port(parameters);
762 g_dbus_method_invocation_return_value(invocation,
763 g_variant_new("(i)", ret));
764 } else if (g_strcmp0(method_name, "unregister_port") == 0) {
765 ret = unregister_port(parameters);
766 g_dbus_method_invocation_return_value(invocation,
767 g_variant_new("(i)", ret));
773 static const GDBusInterfaceVTable interface_vtable = {
774 __dbus_method_call_handler,
779 static int __dbus_init(void)
781 static gchar introspection[] =
784 MESSAGEPORT_INTERFACE
786 " <method name='send_message'>"
787 " <arg type='s' name='local_appid' direction='in'/>"
788 " <arg type='s' name='local_port' direction='in'/>"
789 " <arg type='b' name='local_trusted' direction='in'/>"
790 " <arg type='b' name='bi_dir' direction='in'/>"
791 " <arg type='s' name='remote_appid' direction='in'/>"
792 " <arg type='s' name='remote_port' direction='in'/>"
793 " <arg type='b' name='remote_trusted' direction='in'/>"
794 " <arg type='u' name='data_len' direction='in'/>"
795 " <arg type='s' name='data' direction='in'/>"
797 " <method name='check_remote_port'>"
798 " <arg type='s' name='local_appid' direction='in'/>"
799 " <arg type='b' name='is_trusted' direction='in'/>"
800 " <arg type='s' name='remote_appid' direction='in'/>"
801 " <arg type='s' name='remote_port' direction='in'/>"
802 " <arg type='i' name='response' direction='out'/>"
804 " <method name='unregister_port'>"
805 " <arg type='s' name='local_appid' direction='in'/>"
806 " <arg type='b' name='is_trusted' direction='in'/>"
807 " <arg type='s' name='remote_port' direction='in'/>"
808 " <arg type='i' name='response' direction='out'/>"
814 int registration_id = 0;
815 char *bus_name = NULL;
817 GError *error = NULL;
818 GDBusNodeInfo *introspection_data = NULL;
820 bus_name = __get_bus_name(__app_id);
821 retvm_if(!bus_name, false, "bus_name is NULL");
823 __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
824 if (__gdbus_conn == NULL) {
826 _LOGE("Failed to get dbus [%s]", error->message);
832 owner_id = g_bus_own_name_on_connection(__gdbus_conn, bus_name,
833 G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
836 _LOGE("Acquiring the own name is failed");
840 introspection_data = g_dbus_node_info_new_for_xml(introspection, NULL);
841 if (!introspection_data) {
842 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
846 registration_id = g_dbus_connection_register_object(__gdbus_conn,
847 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
848 &interface_vtable, NULL, NULL, NULL);
850 _LOGE("registration_id %d", registration_id);
852 if (registration_id == 0) {
853 _LOGE("Failed to g_dbus_connection_register_object");
859 FREE_AND_NULL(bus_name);
861 g_object_unref(__gdbus_conn);
862 if (introspection_data)
863 g_dbus_node_info_unref(introspection_data);
869 void __list_free_port_list(gpointer data)
871 port_list_info_s *n = (port_list_info_s *)data;
873 FREE_AND_NULL(n->port_name);
877 static void __hash_destory_local_value(gpointer data)
879 message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
881 free(mli->port_name);
883 static void __hash_destory_remote_value(gpointer data)
885 message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
888 FREE_AND_NULL(mri->encoded_bus_name);
889 FREE_AND_NULL(mri->sender_id);
890 FREE_AND_NULL(mri->remote_app_id);
891 if (mri->port_list) {
892 g_list_free_full(mri->port_list, __list_free_port_list);
897 static bool __initialize(void)
902 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
905 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
906 retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
908 __app_id = strdup(buffer);
909 retvm_if(!__app_id, false, "Malloc failed");
910 _LOGI("init : %s", __app_id);
912 if (__local_port_info == NULL) {
913 __local_port_info = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destory_local_value);
914 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
917 if (__remote_port_info == NULL) {
918 __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
919 retvm_if(!__remote_port_info, false, "fail to create __remote_port_info");
922 if (__sender_appid_hash == NULL) {
923 __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal);
924 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
927 if (__trusted_app_list_hash == NULL)
928 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
930 if (__checked_app_list_hash == NULL)
931 __checked_app_list_hash =
932 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_list_value);
935 if (!__dbus_init()) {
944 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
946 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
947 retvm_if(!mi, false, "Malloc failed");
949 mi->callback = callback;
950 mi->is_trusted = is_trusted;
951 mi->port_name = strdup(local_port);
952 if (mi->port_name == NULL) {
953 _LOGE("Malloc failed (%s)", local_port);
957 mi->local_id = local_id;
959 g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
963 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
965 _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port);
969 // Check the message port is already registed
970 if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL)) {
974 local_id = __get_next_id();
976 if (!__message_port_register_port(local_id, local_port, is_trusted, callback)) {
977 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
983 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
984 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
986 int ret = MESSAGEPORT_ERROR_NONE;
988 bundle_raw *raw = NULL;
989 char *bus_name = NULL;
991 message_port_remote_app_info_s *remote_app_info = NULL;
992 port_list_info_s *port_info = NULL;
993 GDBusMessage *msg = NULL;
995 GVariant *body = NULL;
997 ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
998 if (ret != MESSAGEPORT_ERROR_NONE) {
1002 if (trusted_message) {
1003 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
1004 if (!__is_preloaded(__app_id, remote_appid)) {
1005 if (__check_certificate(__app_id, remote_appid) != MESSAGEPORT_ERROR_NONE) {
1006 ret = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
1010 remote_app_info->certificate_info = CERTIFICATE_MATCH;
1014 if (port_info->exist == false) {
1016 _LOGI("port exist check !!");
1017 ret = __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1018 if (ret != MESSAGEPORT_ERROR_NONE) {
1020 } else if (!exist) {
1021 ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1026 bus_name = remote_app_info->encoded_bus_name;
1028 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1029 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1033 if (MAX_MESSAGE_SIZE < len) {
1034 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1035 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1038 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1039 remote_appid, remote_port, trusted_message, len, raw);
1041 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, MESSAGEPORT_INTERFACE, "send_message");
1043 _LOGE("Can't allocate new method call");
1044 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1048 g_dbus_message_set_body(msg, body);
1049 g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
1050 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1052 _LOGE("No reply. error = %s", err->message);
1054 ret = MESSAGEPORT_ERROR_IO_ERROR;
1060 g_object_unref(msg);
1062 bundle_free_encoded_rawdata(&raw);
1066 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message)
1068 message_port_local_port_info_s *local_info;
1069 int ret = __get_local_port_info(id, &local_info);
1070 if (ret != MESSAGEPORT_ERROR_NONE) {
1074 _LOGE("bidirectional_message %s", local_info->port_name);
1075 return __message_port_send_message(remote_app_id, remote_port,
1076 local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1079 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
1082 GDBusMessage *msg = NULL;
1083 GDBusMessage *reply = NULL;
1086 char *bus_name = NULL;
1087 GList *checked_app_list = NULL;
1088 GList *checked_app = NULL;
1090 _LOGE("unregister : %d", local_port_id);
1092 message_port_local_port_info_s *mi =
1093 (message_port_local_port_info_s *)
1094 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
1096 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1098 if (mi->is_trusted != trusted_port)
1099 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1101 checked_app_list = (GList *)g_hash_table_lookup(__checked_app_list_hash, mi->port_name);
1103 for (checked_app = checked_app_list; checked_app != NULL;
1104 checked_app = checked_app->next) {
1106 char *checked_app_id = (char *)checked_app->data;
1108 _LOGI("unregister appid: %s", checked_app_id);
1109 bus_name = __get_bus_name(checked_app_id);
1110 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH,
1111 MESSAGEPORT_INTERFACE, "unregister_port");
1113 _LOGI("Can't allocate new method call");
1114 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1117 g_dbus_message_set_body(msg,
1118 g_variant_new("(sbs)", __app_id, mi->is_trusted, mi->port_name));
1119 reply = g_dbus_connection_send_message_with_reply_sync(
1122 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1128 if (err || (reply == NULL)) {
1130 _LOGE("No reply. error = %s", err->message);
1134 if (g_dbus_message_to_gerror(reply, &err)) {
1136 _LOGE("error = %s", err->message);
1140 int ret_val = MESSAGEPORT_ERROR_NONE;
1142 body = g_dbus_message_get_body(reply);
1143 g_variant_get(body, "(u)", &ret_val);
1145 if (ret_val == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH) {
1146 _SECURE_LOGI("The remote application (%s) is not signed with the same certificate"
1152 g_object_unref(msg);
1154 g_object_unref(reply);
1158 g_hash_table_remove(__checked_app_list_hash, mi->port_name);
1159 g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
1162 g_object_unref(msg);
1164 g_object_unref(reply);
1166 return MESSAGEPORT_ERROR_NONE;
1169 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
1171 if (!_initialized) {
1172 if (!__initialize())
1173 return MESSAGEPORT_ERROR_IO_ERROR;
1176 return __register_message_port(local_port, false, callback);
1179 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
1181 if (!_initialized) {
1182 if (!__initialize())
1183 return MESSAGEPORT_ERROR_IO_ERROR;
1186 return __register_message_port(local_port, true, callback);
1190 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1192 if (!_initialized) {
1193 if (!__initialize())
1194 return MESSAGEPORT_ERROR_IO_ERROR;
1197 return __check_remote_port(remote_app_id, remote_port, false, exist);
1200 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1202 if (!_initialized) {
1203 if (!__initialize())
1204 return MESSAGEPORT_ERROR_IO_ERROR;
1207 return __check_remote_port(remote_app_id, remote_port, true, exist);
1210 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
1212 if (!_initialized) {
1213 if (!__initialize())
1214 return MESSAGEPORT_ERROR_IO_ERROR;
1217 return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
1220 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
1222 if (!_initialized) {
1223 if (!__initialize())
1224 return MESSAGEPORT_ERROR_IO_ERROR;
1227 return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
1230 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
1233 if (!_initialized) {
1234 if (!__initialize())
1235 return MESSAGEPORT_ERROR_IO_ERROR;
1238 return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
1241 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
1244 if (!_initialized) {
1245 if (!__initialize())
1246 return MESSAGEPORT_ERROR_IO_ERROR;
1248 return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
1251 int messageport_get_local_port_name(int id, char **name)
1253 message_port_local_port_info_s *local_info;
1254 int ret = __get_local_port_info(id, &local_info);
1256 if (ret != MESSAGEPORT_ERROR_NONE) {
1260 *name = strdup(local_info->port_name);
1262 if (*name == NULL) {
1263 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1266 return MESSAGEPORT_ERROR_NONE;
1269 int messageport_check_trusted_local_port(int id, bool *trusted)
1271 message_port_local_port_info_s *local_info;
1272 int ret = __get_local_port_info(id, &local_info);
1274 if (ret != MESSAGEPORT_ERROR_NONE) {
1278 *trusted = local_info->is_trusted;
1280 return MESSAGEPORT_ERROR_NONE;;