4 Copyright (c) 2015 Samsung Electronics Co., Ltd.
6 Licensed under the Apache License, Version 2.0 (the License);
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
20 * @file message-port.cpp
21 * @brief This is the implementation file for the MessagePort.
24 #include <sys/socket.h>
30 #include <openssl/md5.h>
32 #include <bundle_internal.h>
33 #include <pkgmgr-info.h>
36 #include <gio/gunixfdlist.h>
38 #include "message-port.h"
39 #include "message-port-log.h"
41 #define MAX_PACKAGE_STR_SIZE 512
42 #define MESSAGEPORT_BUS_NAME_PREFIX "org.tizen.messageport._"
43 #define MESSAGEPORT_OBJECT_PATH "/org/tizen/messageport"
44 #define MESSAGEPORT_INTERFACE_PREFIX "org.tizen.messageport._"
46 #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
47 #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
48 #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
50 #define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /* *< Service was released from the given name */
51 #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /* *< The given name does not exist on the bus */
52 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /* *< Service is not an owner of the given name */
54 #define MAX_RETRY_CNT 2
56 #define retvm_if(expr, val, fmt, arg...) do { \
59 _LOGE("(%s) -> %s() return", #expr, __func__); \
64 #define retv_if(expr, val) do { \
66 _LOGE("(%s) -> %s() return", #expr, __func__); \
71 #define FREE_AND_NULL(ptr) do { \
78 static bool _initialized = false;
79 static GDBusConnection *__gdbus_conn = NULL;
80 static char *__app_id;
81 static GHashTable *__local_port_info = NULL;
82 static GHashTable *__remote_port_info = NULL;;
83 static GHashTable *__sender_appid_hash = NULL;;
84 static GHashTable *__trusted_app_list_hash = NULL;
85 static const int MAX_MESSAGE_SIZE = 16 * 1024;
87 enum __certificate_info_type {
90 CERTIFICATE_NOT_MATCH,
93 typedef struct message_port_pkt {
94 int remote_port_name_len;
95 char *remote_port_name;
100 } message_port_pkt_s;
102 typedef struct message_port_callback_info {
103 messageport_message_cb callback;
106 GIOChannel *gio_read;
108 } message_port_callback_info_s;
110 typedef struct message_port_local_port_info {
111 messageport_message_cb callback;
115 } message_port_local_port_info_s;
117 typedef struct message_port_remote_port_info {
120 int certificate_info;
122 } message_port_remote_app_info_s;
124 typedef struct port_list_info {
126 char *encoded_bus_name;
133 static void __callback_info_free(message_port_callback_info_s *callback_info)
135 GError *error = NULL;
136 if (callback_info == NULL)
139 if (callback_info->remote_app_id)
140 free(callback_info->remote_app_id);
142 if (callback_info->gio_read != NULL) {
143 g_io_channel_shutdown(callback_info->gio_read, FALSE, &error);
145 _LOGE("g_io_channel_shutdown error : %s", error->message);
148 g_io_channel_unref(callback_info->gio_read);
149 callback_info->gio_read = NULL;
152 if (callback_info->g_src_id != 0) {
153 g_source_remove(callback_info->g_src_id);
154 callback_info->g_src_id = 0;
160 static char *__get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
163 int prefix_len = strlen(MESSAGEPORT_BUS_NAME_PREFIX);
165 char *postfix = is_trusted ? "1" : "0";
167 unsigned char c[MD5_DIGEST_LENGTH] = {0};
168 char *md5_interface = NULL;
172 int encoded_bus_name_len = prefix_len + postfix_len + (MD5_DIGEST_LENGTH * 2) + 2;
173 int bus_name_len = strlen(remote_app_id) + strlen(port_name) + 2;
174 char *bus_name = (char *)calloc(bus_name_len, sizeof(char));
175 if (bus_name == NULL) {
176 _LOGE("bus_name calloc failed");
180 snprintf(bus_name, bus_name_len, "%s_%s", remote_app_id, port_name);
182 MD5_Init(&mdContext);
183 MD5_Update(&mdContext, bus_name, bus_name_len);
184 MD5_Final(c, &mdContext);
186 md5_interface = (char *)calloc(encoded_bus_name_len , sizeof(char));
187 if (md5_interface == NULL) {
191 _LOGE("md5_interface calloc failed!!");
195 snprintf(md5_interface, encoded_bus_name_len, "%s", MESSAGEPORT_BUS_NAME_PREFIX);
196 temp = md5_interface;
199 for (index = 0; index < MD5_DIGEST_LENGTH; index++) {
200 snprintf(temp, 3, "%02x", c[index]);
204 if (postfix && postfix_len > 0)
205 snprintf(temp, encoded_bus_name_len - (temp - md5_interface), "%s", postfix);
209 _LOGI("encoded_bus_name : %s ", md5_interface);
211 return md5_interface;
214 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
216 port_list_info_s *key1 = (port_list_info_s *)a;
217 port_list_info_s *key2 = (port_list_info_s *)b;
219 if (key1->is_trusted == key2->is_trusted)
220 return strcmp(key1->port_name, key2->port_name);
226 static bool __is_preloaded(const char *local_appid, const char *remote_appid)
228 _LOGI("IsPreloaded");
230 bool preload_local = false;
231 bool preload_remote = false;
233 pkgmgrinfo_appinfo_h handle = NULL;
234 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle);
235 if (ret != PMINFO_R_OK) {
236 _LOGE("Failed to get the appinfo. %d", ret);
237 pkgmgrinfo_appinfo_destroy_appinfo(handle);
240 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local);
241 if (ret != PMINFO_R_OK) {
242 _LOGE("Failed to check the preloaded application. %d", ret);
243 pkgmgrinfo_appinfo_destroy_appinfo(handle);
246 ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
247 if (ret != PMINFO_R_OK) {
248 _LOGE("Failed to get the appinfo. %d", ret);
249 pkgmgrinfo_appinfo_destroy_appinfo(handle);
252 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
253 if (ret != PMINFO_R_OK) {
254 _LOGE("Failed to check the preloaded application. %d", ret);
255 pkgmgrinfo_appinfo_destroy_appinfo(handle);
259 if (preload_local && preload_remote) {
260 pkgmgrinfo_appinfo_destroy_appinfo(handle);
263 pkgmgrinfo_appinfo_destroy_appinfo(handle);
267 static int __check_certificate(const char *local_appid, const char *remote_appid)
269 _LOGI("CheckCertificate");
271 pkgmgrinfo_cert_compare_result_type_e res;
272 int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, remote_appid, getuid(), &res);
274 _LOGE(":CheckCertificate() Failed");
275 return MESSAGEPORT_ERROR_IO_ERROR;
277 if (res != PMINFO_CERT_COMPARE_MATCH) {
278 _LOGE("CheckCertificate() Failed : MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH");
279 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
282 return MESSAGEPORT_ERROR_NONE;
285 static void on_name_appeared(GDBusConnection *connection,
287 const gchar *name_owner,
290 _LOGI("name appeared : %s %s", __app_id, name);
293 static void on_name_vanished(GDBusConnection *connection,
297 _LOGI("name vanished : %s", name);
298 port_list_info_s *pli = (port_list_info_s *)user_data;
299 g_bus_unwatch_name(pli->watcher_id);
303 static int __get_local_port_info(int id, message_port_local_port_info_s **info)
305 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(id));
308 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
311 return MESSAGEPORT_ERROR_NONE;
314 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
316 int ret_val = MESSAGEPORT_ERROR_NONE;
317 port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
320 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
323 port_info->port_name = strdup(remote_port);
324 if (!port_info->port_name) {
325 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
328 port_info->is_trusted = is_trusted;
330 port_info->encoded_bus_name = __get_encoded_name(remote_app_id, remote_port, is_trusted);
331 if (port_info->encoded_bus_name == NULL) {
332 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
336 port_info->sock_pair[0] = 0;
337 port_info->sock_pair[1] = 0;
340 if (ret_val != MESSAGEPORT_ERROR_NONE) {
342 FREE_AND_NULL(port_info->port_name);
343 FREE_AND_NULL(port_info->encoded_bus_name);
351 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
353 port_list_info_s *port_info = NULL;
354 message_port_remote_app_info_s *remote_app_info = NULL;
355 int ret_val = MESSAGEPORT_ERROR_NONE;
357 remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
358 if (!remote_app_info) {
359 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
363 remote_app_info->remote_app_id = strdup(remote_app_id);
364 if (remote_app_info->remote_app_id == NULL) {
365 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;;
369 port_info = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
370 if (port_info == NULL) {
371 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
375 remote_app_info->port_list = g_list_append(remote_app_info->port_list, port_info);
378 if (ret_val != MESSAGEPORT_ERROR_NONE) {
379 if (remote_app_info) {
380 FREE_AND_NULL(remote_app_info->remote_app_id);
381 FREE_AND_NULL(remote_app_info);
385 return remote_app_info;
388 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
389 message_port_remote_app_info_s **mri, port_list_info_s **pli)
391 message_port_remote_app_info_s *remote_app_info = NULL;
392 port_list_info_s port_info;
393 GList *cb_list = NULL;
394 int ret_val = MESSAGEPORT_ERROR_NONE;
396 remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_port_info, remote_app_id);
398 if (remote_app_info == NULL) {
399 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
401 if (remote_app_info == NULL) {
402 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
405 g_hash_table_insert(__remote_port_info, remote_app_info->remote_app_id, remote_app_info);
408 *mri = remote_app_info;
410 port_info.port_name = strdup(remote_port);
411 port_info.is_trusted = is_trusted;
412 cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
413 (GCompareFunc)__remote_port_compare_cb);
414 if (port_info.port_name)
415 free(port_info.port_name);
416 if (cb_list == NULL) {
417 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
420 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
423 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
425 g_hash_table_insert(__remote_port_info, (*pli)->encoded_bus_name, *pli);
427 *pli = (port_list_info_s *)cb_list->data;
435 static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi)
440 g_hash_table_iter_init(&iter, __local_port_info);
442 while (g_hash_table_iter_next(&iter, &key, &value)) {
443 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
445 if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) {
446 *local_id = mi->local_id;
455 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
457 GDBusMessage *msg = NULL;
458 GDBusMessage *reply = NULL;
463 msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
464 "org.freedesktop.DBus", "GetConnectionUnixProcessID");
466 _LOGE("Can't allocate new method call");
470 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
471 reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
472 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
476 _LOGE("Failed to get pid [%s]", err->message);
482 body = g_dbus_message_get_body(reply);
483 g_variant_get(body, "(u)", &pid);
489 g_object_unref(reply);
494 static int __write_socket(int fd,
497 unsigned int *bytes_write)
499 unsigned int left = nbytes;
504 while (left && (retry_cnt < MAX_RETRY_CNT)) {
505 nb = write(fd, buffer, left);
507 if (errno == EINTR) {
508 LOGE("__write_socket: EINTR error continue ...");
512 LOGE("__write_socket: ...error fd %d: errno %d\n", fd, errno);
513 return MESSAGEPORT_ERROR_IO_ERROR;
521 return MESSAGEPORT_ERROR_NONE;
524 static int __write_string_to_socket(int fd, const char *buffer, int string_len)
527 if (__write_socket(fd, (char *)&string_len, sizeof(string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
528 _LOGE("write string_len fail");
529 return MESSAGEPORT_ERROR_IO_ERROR;
532 if (string_len > 0) {
533 if (__write_socket(fd, buffer, string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
534 _LOGE("wirte buffer fail");
535 return MESSAGEPORT_ERROR_IO_ERROR;
538 return MESSAGEPORT_ERROR_NONE;
541 static int __read_socket(int fd,
544 unsigned int *bytes_read)
546 unsigned int left = nbytes;
551 while (left && (retry_cnt < MAX_RETRY_CNT)) {
552 nb = read(fd, buffer, left);
554 LOGE("__read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
555 return MESSAGEPORT_ERROR_IO_ERROR;
556 } else if (nb == -1) {
557 if (errno == EINTR) {
558 LOGE("__read_socket: EINTR error continue ...");
562 LOGE("__read_socket: ...error fd %d: errno %d\n", fd, errno);
563 return MESSAGEPORT_ERROR_IO_ERROR;
571 return MESSAGEPORT_ERROR_NONE;
574 static int __read_string_from_socket(int fd, char **buffer, int *string_len)
577 if (__read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
578 LOGE("read socket fail");
579 return MESSAGEPORT_ERROR_IO_ERROR;
581 if (*string_len > 0) {
582 *buffer = (char *)calloc(*string_len, sizeof(char));
583 if (*buffer == NULL) {
584 LOGE("Out of memory.");
585 return MESSAGEPORT_ERROR_IO_ERROR;
587 if (__read_socket(fd, *buffer, *string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
588 LOGE("read socket fail");
589 return MESSAGEPORT_ERROR_IO_ERROR;
592 return MESSAGEPORT_ERROR_NONE;
595 message_port_pkt_s *__message_port_recv_raw(int fd)
597 message_port_pkt_s *pkt = NULL;
600 pkt = (message_port_pkt_s *)calloc(sizeof(message_port_pkt_s), 1);
606 if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
607 LOGE("read socket fail: port_name");
608 free(pkt->remote_port_name);
614 if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
615 LOGE("read socket fail: is_bidirection");
616 free(pkt->remote_port_name);
622 if (__read_socket(fd, (char *)&pkt->is_trusted, sizeof(pkt->is_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
623 LOGE("read socket fail: is_trusted");
624 free(pkt->remote_port_name);
630 if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
631 LOGE("read socket fail: data");
632 free(pkt->remote_port_name);
641 static gboolean __socket_request_handler(GIOChannel *gio,
646 message_port_callback_info_s *mi;
647 message_port_pkt_s *pkt;
649 GError *error = NULL;
651 mi = (message_port_callback_info_s *)data;
654 g_io_channel_shutdown(gio, FALSE, &error);
656 _LOGE("g_io_channel_shutdown error : %s", error->message);
659 g_io_channel_unref(gio);
663 if (cond == G_IO_HUP) {
665 _LOGI("socket G_IO_HUP");
666 __callback_info_free(mi);
671 if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
672 _LOGE("fail to get fd from io channel");
673 __callback_info_free(mi);
677 if ((pkt = __message_port_recv_raw(fd)) == NULL) {
678 _LOGE("recv error on SOCKET");
679 __callback_info_free(mi);
683 kb = bundle_decode(pkt->data, pkt->data_len);
685 if (pkt->is_bidirection)
686 mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, pkt->is_trusted, kb, NULL);
688 mi->callback(mi->local_id, mi->remote_app_id, NULL, pkt->is_trusted, kb, NULL);
691 if (pkt->remote_port_name)
692 free(pkt->remote_port_name);
702 static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation)
704 char *local_port = NULL;
705 char *local_appid = NULL;
706 char *remote_appid = NULL;
707 char *remote_port = NULL;
708 gboolean local_trusted = false;
709 gboolean remote_trusted = false;
710 gboolean bi_dir = false;
714 bundle_raw *raw = NULL;
715 message_port_local_port_info_s *mi;
716 message_port_callback_info_s *callback_info;
717 int local_reg_id = 0;
719 g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir,
720 &remote_appid, &remote_port, &remote_trusted, &len, &raw);
723 _LOGE("Invalid argument : remote_port is NULL");
727 _LOGE("Invalid argument : remote_appid is NULL");
730 if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
731 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
735 _LOGE("Invalid argument : local_appid");
739 _LOGE("Invalid argument : local_port");
742 if (strcmp(remote_appid, __app_id) != 0) {
743 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
746 if (strcmp(remote_port, mi->port_name) != 0) {
747 _LOGE("Invalid argument : remote_port (%s)", remote_port);
751 _LOGE("Invalid argument : data_len");
754 if (remote_trusted) {
755 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
756 if (!__is_preloaded(local_appid, remote_appid)) {
757 /* Check the certificate */
758 int ret = __check_certificate(local_appid, remote_appid);
759 if (ret == MESSAGEPORT_ERROR_NONE)
760 g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
762 _LOGE("The application (%s) is not signed with the same certificate",
770 callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
771 if (callback_info == NULL)
774 callback_info->local_id = mi->local_id;
775 callback_info->remote_app_id = strdup(local_appid);
776 callback_info->callback = mi->callback;
778 GError *error = NULL;
779 GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation);
781 GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list(msg);
782 int fd = g_unix_fd_list_get(fd_list, 0, &error);
784 LOGE("g_unix_fd_list_get fail : %s", error->message);
788 LOGI("g_unix_fd_list_get fd: [%d]", fd);
792 callback_info->gio_read = g_io_channel_unix_new(fd);
793 if (!callback_info->gio_read) {
794 _LOGE("Error is %s\n", strerror(errno));
795 __callback_info_free(callback_info);
799 callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
800 __socket_request_handler, (gpointer)callback_info);
801 if (callback_info->g_src_id == 0) {
802 _LOGE("fail to add watch on socket");
803 __callback_info_free(callback_info);
809 data = bundle_decode(raw, len);
810 bundle_free_encoded_rawdata(&raw);
813 _LOGE("Invalid argument : message");
817 LOGI("call calback %s", local_appid);
819 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
821 mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
828 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
830 _LOGI("Check a remote port : [%s:%s]", remote_app_id, remote_port);
832 GVariant *result = NULL;
834 int ret_val = MESSAGEPORT_ERROR_NONE;
835 char *bus_name = NULL;
836 message_port_remote_app_info_s *remote_app_info = NULL;
837 port_list_info_s *port_info = NULL;
838 int local_reg_id = 0;
839 message_port_local_port_info_s *mi = NULL;
840 gboolean name_exist = false;
842 _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
844 ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
845 if (ret_val != MESSAGEPORT_ERROR_NONE)
850 if (strcmp(remote_app_id, __app_id) == 0) {
852 _LOGI("__is_local_port_registed ");
853 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
858 _LOGI("__is_local_port_registed : %d ", *exist);
859 return MESSAGEPORT_ERROR_NONE;
862 port_info->exist = false;
863 bus_name = port_info->encoded_bus_name;
865 result = g_dbus_connection_call_sync(
871 g_variant_new("(s)", bus_name),
872 G_VARIANT_TYPE("(b)"),
873 G_DBUS_CALL_FLAGS_NONE,
878 if (err || (result == NULL)) {
880 _LOGE("No reply. error = %s", err->message);
883 ret_val = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
885 g_variant_get(result, "(b)", &name_exist);
888 LOGE("Name not exist %s", bus_name);
890 ret_val = MESSAGEPORT_ERROR_NONE;
894 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
895 if (!__is_preloaded(__app_id, remote_app_id)) {
896 if (__check_certificate(__app_id, remote_app_id) != MESSAGEPORT_ERROR_NONE) {
897 ret_val = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
901 remote_app_info->certificate_info = CERTIFICATE_MATCH;
905 port_info->watcher_id = g_bus_watch_name_on_connection(
907 port_info->encoded_bus_name,
908 G_BUS_NAME_WATCHER_FLAGS_NONE,
914 port_info->exist = true;
916 ret_val = MESSAGEPORT_ERROR_NONE;
917 _LOGI("Exist port: %s", bus_name);
923 g_variant_unref(result);
928 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
931 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
932 char *local_appid = NULL;
933 int pid = __get_sender_pid(conn, sender);
935 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
936 retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid);
938 g_variant_get_child(parameters, 0, "s", &local_appid);
939 retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid);
941 if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
942 g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid));
951 static void __dbus_method_call_handler(GDBusConnection *conn,
952 const gchar *sender, const gchar *object_path,
953 const gchar *iface_name, const gchar *method_name,
954 GVariant *parameters, GDBusMethodInvocation *invocation,
957 _LOGI("method_name: %s", method_name);
958 gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
959 if (sender_pid == NULL) {
960 if (!__check_sender_validation(parameters, sender, conn))
964 if (g_strcmp0(method_name, "send_message") == 0)
965 send_message(parameters, invocation);
969 static const GDBusInterfaceVTable interface_vtable = {
970 __dbus_method_call_handler,
975 static int __dbus_init(void)
978 GError *error = NULL;
980 __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
981 if (__gdbus_conn == NULL) {
983 _LOGE("Failed to get dbus [%s]", error->message);
993 g_object_unref(__gdbus_conn);
1000 int __register_dbus_interface(const char *port_name, bool is_trusted)
1003 GDBusNodeInfo *introspection_data = NULL;
1004 int registration_id = 0;
1006 static gchar introspection_prefix[] =
1008 " <interface name='";
1010 static gchar introspection_postfix[] =
1012 " <method name='send_message'>"
1013 " <arg type='s' name='local_appid' direction='in'/>"
1014 " <arg type='s' name='local_port' direction='in'/>"
1015 " <arg type='b' name='local_trusted' direction='in'/>"
1016 " <arg type='b' name='bi_dir' direction='in'/>"
1017 " <arg type='s' name='remote_appid' direction='in'/>"
1018 " <arg type='s' name='remote_port' direction='in'/>"
1019 " <arg type='b' name='remote_trusted' direction='in'/>"
1020 " <arg type='u' name='data_len' direction='in'/>"
1021 " <arg type='s' name='data' direction='in'/>"
1026 char *introspection_xml = NULL;
1027 int introspection_xml_len = 0;
1031 GError *error = NULL;
1032 char *bus_name = NULL;
1033 char *interface_name = NULL;
1034 GVariant *result = NULL;
1036 bus_name = __get_encoded_name(__app_id, port_name, is_trusted);
1038 _LOGE("Fail to get bus name");
1041 interface_name = bus_name;
1043 introspection_xml_len = strlen(introspection_prefix) + strlen(interface_name) +
1044 strlen(introspection_postfix) + 1;
1046 introspection_xml = (char *)calloc(introspection_xml_len, sizeof(char));
1047 if (!introspection_xml) {
1048 _LOGE("out of memory");
1053 result = g_dbus_connection_call_sync(
1057 DBUS_INTERFACE_DBUS,
1059 g_variant_new("(su)", bus_name, G_BUS_NAME_OWNER_FLAGS_NONE),
1060 G_VARIANT_TYPE("(u)"),
1061 G_DBUS_CALL_FLAGS_NONE,
1066 _LOGE("RequestName fail : %s", error->message);
1069 if (result == NULL) {
1070 _LOGE("fail to get name NULL");
1073 g_variant_get(result, "(u)", &owner_id);
1074 if (owner_id == 0) {
1075 _LOGE("Acquiring the own name is failed");
1079 _LOGI("Acquiring the own name : %d", owner_id);
1081 snprintf(introspection_xml, introspection_xml_len, "%s%s%s", introspection_prefix, interface_name, introspection_postfix);
1083 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
1084 if (!introspection_data) {
1085 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
1089 registration_id = g_dbus_connection_register_object(__gdbus_conn,
1090 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
1091 &interface_vtable, NULL, NULL, NULL);
1093 _LOGI("registration_id %d", registration_id);
1095 if (registration_id == 0) {
1096 _LOGE("Failed to g_dbus_connection_register_object");
1101 if (introspection_data)
1102 g_dbus_node_info_unref(introspection_data);
1103 if (introspection_xml)
1104 free(introspection_xml);
1108 g_variant_unref(result);
1111 return registration_id;
1115 void __list_free_port_list(gpointer data)
1117 port_list_info_s *n = (port_list_info_s *)data;
1119 FREE_AND_NULL(n->encoded_bus_name);
1120 FREE_AND_NULL(n->port_name);
1124 static void __hash_destory_local_value(gpointer data)
1126 message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
1128 free(mli->port_name);
1130 static void __hash_destory_remote_value(gpointer data)
1132 message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
1135 FREE_AND_NULL(mri->sender_id);
1136 FREE_AND_NULL(mri->remote_app_id);
1138 g_list_free_full(mri->port_list, __list_free_port_list);
1142 static bool __initialize(void)
1145 #if !GLIB_CHECK_VERSION(2, 35, 0)
1151 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1153 _LOGI("initialize");
1154 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1155 retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1157 __app_id = strdup(buffer);
1158 retvm_if(!__app_id, false, "Malloc failed");
1159 _LOGI("init : %s", __app_id);
1161 if (__local_port_info == NULL) {
1162 __local_port_info = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destory_local_value);
1163 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1166 if (__remote_port_info == NULL) {
1167 __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1168 retvm_if(!__remote_port_info, false, "fail to create __remote_port_info");
1171 if (__sender_appid_hash == NULL) {
1172 __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal);
1173 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1176 if (__trusted_app_list_hash == NULL) {
1177 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1178 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1183 _initialized = true;
1189 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1191 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1192 retvm_if(!mi, false, "Malloc failed");
1194 mi->callback = callback;
1195 mi->is_trusted = is_trusted;
1196 mi->port_name = strdup(local_port);
1197 if (mi->port_name == NULL) {
1198 _LOGE("Malloc failed (%s)", local_port);
1202 mi->local_id = local_id;
1204 g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1208 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1210 _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port);
1214 /* Check the message port is already registed */
1215 if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1218 local_id = __register_dbus_interface(local_port, is_trusted);
1220 _LOGE("register_dbus_interface fail !!");
1221 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1224 if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1225 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1230 int __message_port_send_async(int sockfd, bundle *kb, const char *local_port,
1231 bool local_trusted, bool is_bidirection)
1235 int local_port_len = 0;
1237 bundle_raw *kb_data = NULL;
1239 if (local_port != NULL)
1240 local_port_len = strlen(local_port) + 1;
1242 if (__write_string_to_socket(sockfd, local_port, local_port_len) != MESSAGEPORT_ERROR_NONE) {
1243 _LOGE("write local_port fail");
1244 return MESSAGEPORT_ERROR_IO_ERROR;
1247 if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
1248 _LOGE("write is_bidirection fail");
1249 return MESSAGEPORT_ERROR_IO_ERROR;
1252 if (__write_socket(sockfd, (char *)&local_trusted, sizeof(local_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
1253 _LOGE("write local_trusted fail");
1254 return MESSAGEPORT_ERROR_IO_ERROR;
1257 bundle_encode(kb, &kb_data, &data_len);
1258 if (kb_data == NULL) {
1259 _LOGE("bundle encode fail");
1260 ret = MESSAGEPORT_ERROR_IO_ERROR;
1264 if (data_len > MAX_MESSAGE_SIZE) {
1265 _LOGE("bigger than max size\n");
1266 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1270 if (__write_string_to_socket(sockfd, (void *)kb_data, data_len) != MESSAGEPORT_ERROR_NONE) {
1271 _LOGE("write kb_data fail");
1272 ret = MESSAGEPORT_ERROR_IO_ERROR;
1281 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1282 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1285 int ret = MESSAGEPORT_ERROR_NONE;
1286 GUnixFDList *fd_list = NULL;
1287 GError *error = NULL;
1290 bundle_raw *raw = NULL;
1291 char *bus_name = NULL;
1292 char *interface_name = NULL;
1294 message_port_remote_app_info_s *remote_app_info = NULL;
1295 port_list_info_s *port_info = NULL;
1296 GDBusMessage *msg = NULL;
1298 GVariant *body = NULL;
1300 ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1301 if (ret != MESSAGEPORT_ERROR_NONE)
1304 if (port_info->exist == false) {
1306 _LOGI("port exist check !!");
1307 ret = __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1308 if (ret != MESSAGEPORT_ERROR_NONE) {
1310 } else if (!exist) {
1311 ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1316 if (port_info->sock_pair[0] > 0) {
1317 ret = __message_port_send_async(port_info->sock_pair[0], message,
1318 (local_port) ? local_port : "", local_trusted, bi_dir);
1321 bus_name = port_info->encoded_bus_name;
1322 interface_name = bus_name;
1324 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1325 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1329 if (MAX_MESSAGE_SIZE < len) {
1330 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1331 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1334 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1335 remote_appid, remote_port, trusted_message, len, raw);
1338 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1340 /* if message-port fail to get socket pair, communicate using GDBus */
1341 if (aul_request_message_port_socket_pair(port_info->sock_pair) != AUL_R_OK) {
1342 _LOGE("error create socket pair");
1345 _LOGI("sock pair : %d, %d", port_info->sock_pair[0], port_info->sock_pair[1]);
1347 fd_list = g_unix_fd_list_new();
1348 g_unix_fd_list_append(fd_list, port_info->sock_pair[1], &err);
1349 g_unix_fd_list_append(fd_list, port_info->sock_pair[0], &err);
1352 _LOGE("g_unix_fd_list_append [%s]", error->message);
1353 ret = MESSAGEPORT_ERROR_IO_ERROR;
1361 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1363 _LOGE("Can't allocate new method call");
1364 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1368 g_dbus_message_set_unix_fd_list(msg, fd_list);
1369 g_dbus_message_set_body(msg, body);
1370 g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
1371 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1373 _LOGE("No reply. error = %s", err->message);
1375 ret = MESSAGEPORT_ERROR_IO_ERROR;
1384 g_object_unref(msg);
1386 bundle_free_encoded_rawdata(&raw);
1388 g_object_unref(fd_list);
1394 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message)
1396 message_port_local_port_info_s *local_info;
1397 int ret = __get_local_port_info(id, &local_info);
1398 if (ret != MESSAGEPORT_ERROR_NONE)
1401 _LOGI("bidirectional_message %s", local_info->port_name);
1402 return __message_port_send_message(remote_app_id, remote_port,
1403 local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1406 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
1410 char *bus_name = NULL;
1414 _LOGI("unregister : %d", local_port_id);
1416 message_port_local_port_info_s *mi =
1417 (message_port_local_port_info_s *)
1418 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
1420 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1422 if (mi->is_trusted != trusted_port)
1423 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1425 bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
1426 if (bus_name == NULL)
1427 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1429 g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
1431 result = g_dbus_connection_call_sync(
1435 DBUS_INTERFACE_DBUS,
1437 g_variant_new("(s)", bus_name),
1438 G_VARIANT_TYPE("(u)"),
1439 G_DBUS_CALL_FLAGS_NONE,
1448 _LOGE("RequestName fail : %s", err->message);
1450 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1452 g_variant_get(result, "(u)", &ret);
1455 g_variant_unref(result);
1457 if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
1459 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
1460 _LOGE("Port Not exist");
1461 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1462 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
1463 _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
1464 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1469 g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
1471 return MESSAGEPORT_ERROR_NONE;
1474 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
1476 if (!_initialized) {
1477 if (!__initialize())
1478 return MESSAGEPORT_ERROR_IO_ERROR;
1481 return __register_message_port(local_port, false, callback);
1484 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
1486 if (!_initialized) {
1487 if (!__initialize())
1488 return MESSAGEPORT_ERROR_IO_ERROR;
1491 return __register_message_port(local_port, true, callback);
1495 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1497 if (!_initialized) {
1498 if (!__initialize())
1499 return MESSAGEPORT_ERROR_IO_ERROR;
1502 int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
1503 if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1505 ret = MESSAGEPORT_ERROR_NONE;
1511 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1513 if (!_initialized) {
1514 if (!__initialize())
1515 return MESSAGEPORT_ERROR_IO_ERROR;
1518 int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
1519 if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1521 ret = MESSAGEPORT_ERROR_NONE;
1527 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
1529 if (!_initialized) {
1530 if (!__initialize())
1531 return MESSAGEPORT_ERROR_IO_ERROR;
1534 return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
1537 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
1539 if (!_initialized) {
1540 if (!__initialize())
1541 return MESSAGEPORT_ERROR_IO_ERROR;
1544 return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
1547 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
1550 if (!_initialized) {
1551 if (!__initialize())
1552 return MESSAGEPORT_ERROR_IO_ERROR;
1555 return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
1558 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
1561 if (!_initialized) {
1562 if (!__initialize())
1563 return MESSAGEPORT_ERROR_IO_ERROR;
1565 return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
1568 int messageport_get_local_port_name(int id, char **name)
1570 message_port_local_port_info_s *local_info;
1571 int ret = __get_local_port_info(id, &local_info);
1573 if (ret != MESSAGEPORT_ERROR_NONE)
1576 *name = strdup(local_info->port_name);
1579 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1581 return MESSAGEPORT_ERROR_NONE;
1584 int messageport_check_trusted_local_port(int id, bool *trusted)
1586 message_port_local_port_info_s *local_info;
1587 int ret = __get_local_port_info(id, &local_info);
1589 if (ret != MESSAGEPORT_ERROR_NONE)
1592 *trusted = local_info->is_trusted;
1594 return MESSAGEPORT_ERROR_NONE;;