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;
720 g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir,
721 &remote_appid, &remote_port, &remote_trusted, &len, &raw);
724 _LOGE("Invalid argument : remote_port is NULL");
728 _LOGE("Invalid argument : remote_appid is NULL");
731 if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
732 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
736 _LOGE("Invalid argument : local_appid");
740 _LOGE("Invalid argument : local_port");
743 if (strcmp(remote_appid, __app_id) != 0) {
744 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
747 if (strcmp(remote_port, mi->port_name) != 0) {
748 _LOGE("Invalid argument : remote_port (%s)", remote_port);
752 _LOGE("Invalid argument : data_len");
755 if (remote_trusted) {
756 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
757 if (!__is_preloaded(local_appid, remote_appid)) {
758 /* Check the certificate */
759 int ret = __check_certificate(local_appid, remote_appid);
760 if (ret == MESSAGEPORT_ERROR_NONE)
761 g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
763 _LOGE("The application (%s) is not signed with the same certificate",
771 callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
772 if (callback_info == NULL)
775 callback_info->local_id = mi->local_id;
776 callback_info->remote_app_id = strdup(local_appid);
777 callback_info->callback = mi->callback;
779 GError *error = NULL;
780 GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation);
782 GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list(msg);
783 int fd = g_unix_fd_list_get(fd_list, 0, &error);
785 LOGE("g_unix_fd_list_get fail : %s", error->message);
789 LOGI("g_unix_fd_list_get fd: [%d]", fd);
793 callback_info->gio_read = g_io_channel_unix_new(fd);
794 if (!callback_info->gio_read) {
795 _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
796 __callback_info_free(callback_info);
800 callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
801 __socket_request_handler, (gpointer)callback_info);
802 if (callback_info->g_src_id == 0) {
803 _LOGE("fail to add watch on socket");
804 __callback_info_free(callback_info);
810 data = bundle_decode(raw, len);
811 bundle_free_encoded_rawdata(&raw);
814 _LOGE("Invalid argument : message");
818 LOGI("call calback %s", local_appid);
820 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
822 mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
829 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
831 _LOGI("Check a remote port : [%s:%s]", remote_app_id, remote_port);
833 GVariant *result = NULL;
835 int ret_val = MESSAGEPORT_ERROR_NONE;
836 char *bus_name = NULL;
837 message_port_remote_app_info_s *remote_app_info = NULL;
838 port_list_info_s *port_info = NULL;
839 int local_reg_id = 0;
840 message_port_local_port_info_s *mi = NULL;
841 gboolean name_exist = false;
843 _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
845 ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
846 if (ret_val != MESSAGEPORT_ERROR_NONE)
851 if (strcmp(remote_app_id, __app_id) == 0) {
853 _LOGI("__is_local_port_registed ");
854 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
859 _LOGI("__is_local_port_registed : %d ", *exist);
860 return MESSAGEPORT_ERROR_NONE;
863 port_info->exist = false;
864 bus_name = port_info->encoded_bus_name;
866 result = g_dbus_connection_call_sync(
872 g_variant_new("(s)", bus_name),
873 G_VARIANT_TYPE("(b)"),
874 G_DBUS_CALL_FLAGS_NONE,
879 if (err || (result == NULL)) {
881 _LOGE("No reply. error = %s", err->message);
884 ret_val = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
886 g_variant_get(result, "(b)", &name_exist);
889 LOGE("Name not exist %s", bus_name);
891 ret_val = MESSAGEPORT_ERROR_NONE;
895 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
896 if (!__is_preloaded(__app_id, remote_app_id)) {
897 if (__check_certificate(__app_id, remote_app_id) != MESSAGEPORT_ERROR_NONE) {
898 ret_val = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
902 remote_app_info->certificate_info = CERTIFICATE_MATCH;
906 port_info->watcher_id = g_bus_watch_name_on_connection(
908 port_info->encoded_bus_name,
909 G_BUS_NAME_WATCHER_FLAGS_NONE,
915 port_info->exist = true;
917 ret_val = MESSAGEPORT_ERROR_NONE;
918 _LOGI("Exist port: %s", bus_name);
924 g_variant_unref(result);
929 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
932 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
933 char *local_appid = NULL;
934 int pid = __get_sender_pid(conn, sender);
936 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
937 retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid);
939 g_variant_get_child(parameters, 0, "s", &local_appid);
940 retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid);
942 if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
943 g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid));
952 static void __dbus_method_call_handler(GDBusConnection *conn,
953 const gchar *sender, const gchar *object_path,
954 const gchar *iface_name, const gchar *method_name,
955 GVariant *parameters, GDBusMethodInvocation *invocation,
958 _LOGI("method_name: %s", method_name);
959 gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
960 if (sender_pid == NULL) {
961 if (!__check_sender_validation(parameters, sender, conn))
965 if (g_strcmp0(method_name, "send_message") == 0)
966 send_message(parameters, invocation);
970 static const GDBusInterfaceVTable interface_vtable = {
971 __dbus_method_call_handler,
976 static int __dbus_init(void)
979 GError *error = NULL;
981 __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
982 if (__gdbus_conn == NULL) {
984 _LOGE("Failed to get dbus [%s]", error->message);
994 g_object_unref(__gdbus_conn);
1001 int __register_dbus_interface(const char *port_name, bool is_trusted)
1004 GDBusNodeInfo *introspection_data = NULL;
1005 int registration_id = 0;
1007 static gchar introspection_prefix[] =
1009 " <interface name='";
1011 static gchar introspection_postfix[] =
1013 " <method name='send_message'>"
1014 " <arg type='s' name='local_appid' direction='in'/>"
1015 " <arg type='s' name='local_port' direction='in'/>"
1016 " <arg type='b' name='local_trusted' direction='in'/>"
1017 " <arg type='b' name='bi_dir' direction='in'/>"
1018 " <arg type='s' name='remote_appid' direction='in'/>"
1019 " <arg type='s' name='remote_port' direction='in'/>"
1020 " <arg type='b' name='remote_trusted' direction='in'/>"
1021 " <arg type='u' name='data_len' direction='in'/>"
1022 " <arg type='s' name='data' direction='in'/>"
1027 char *introspection_xml = NULL;
1028 int introspection_xml_len = 0;
1032 GError *error = NULL;
1033 char *bus_name = NULL;
1034 char *interface_name = NULL;
1035 GVariant *result = NULL;
1037 bus_name = __get_encoded_name(__app_id, port_name, is_trusted);
1039 _LOGE("Fail to get bus name");
1042 interface_name = bus_name;
1044 introspection_xml_len = strlen(introspection_prefix) + strlen(interface_name) +
1045 strlen(introspection_postfix) + 1;
1047 introspection_xml = (char *)calloc(introspection_xml_len, sizeof(char));
1048 if (!introspection_xml) {
1049 _LOGE("out of memory");
1054 result = g_dbus_connection_call_sync(
1058 DBUS_INTERFACE_DBUS,
1060 g_variant_new("(su)", bus_name, G_BUS_NAME_OWNER_FLAGS_NONE),
1061 G_VARIANT_TYPE("(u)"),
1062 G_DBUS_CALL_FLAGS_NONE,
1067 _LOGE("RequestName fail : %s", error->message);
1070 if (result == NULL) {
1071 _LOGE("fail to get name NULL");
1074 g_variant_get(result, "(u)", &owner_id);
1075 if (owner_id == 0) {
1076 _LOGE("Acquiring the own name is failed");
1080 _LOGI("Acquiring the own name : %d", owner_id);
1082 snprintf(introspection_xml, introspection_xml_len, "%s%s%s", introspection_prefix, interface_name, introspection_postfix);
1084 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
1085 if (!introspection_data) {
1086 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
1090 registration_id = g_dbus_connection_register_object(__gdbus_conn,
1091 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
1092 &interface_vtable, NULL, NULL, NULL);
1094 _LOGI("registration_id %d", registration_id);
1096 if (registration_id == 0) {
1097 _LOGE("Failed to g_dbus_connection_register_object");
1102 if (introspection_data)
1103 g_dbus_node_info_unref(introspection_data);
1104 if (introspection_xml)
1105 free(introspection_xml);
1109 g_variant_unref(result);
1112 return registration_id;
1116 void __list_free_port_list(gpointer data)
1118 port_list_info_s *n = (port_list_info_s *)data;
1120 FREE_AND_NULL(n->encoded_bus_name);
1121 FREE_AND_NULL(n->port_name);
1125 static void __hash_destory_local_value(gpointer data)
1127 message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
1129 free(mli->port_name);
1131 static void __hash_destory_remote_value(gpointer data)
1133 message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
1136 FREE_AND_NULL(mri->sender_id);
1137 FREE_AND_NULL(mri->remote_app_id);
1139 g_list_free_full(mri->port_list, __list_free_port_list);
1143 static bool __initialize(void)
1146 #if !GLIB_CHECK_VERSION(2, 35, 0)
1152 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1154 _LOGI("initialize");
1155 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1156 retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1158 __app_id = strdup(buffer);
1159 retvm_if(!__app_id, false, "Malloc failed");
1160 _LOGI("init : %s", __app_id);
1162 if (__local_port_info == NULL) {
1163 __local_port_info = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destory_local_value);
1164 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1167 if (__remote_port_info == NULL) {
1168 __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1169 retvm_if(!__remote_port_info, false, "fail to create __remote_port_info");
1172 if (__sender_appid_hash == NULL) {
1173 __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal);
1174 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1177 if (__trusted_app_list_hash == NULL) {
1178 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1179 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1184 _initialized = true;
1190 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1192 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1193 retvm_if(!mi, false, "Malloc failed");
1195 mi->callback = callback;
1196 mi->is_trusted = is_trusted;
1197 mi->port_name = strdup(local_port);
1198 if (mi->port_name == NULL) {
1199 _LOGE("Malloc failed (%s)", local_port);
1203 mi->local_id = local_id;
1205 g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1209 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1211 _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port);
1215 /* Check the message port is already registed */
1216 if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1219 local_id = __register_dbus_interface(local_port, is_trusted);
1221 _LOGE("register_dbus_interface fail !!");
1222 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1225 if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1226 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1231 int __message_port_send_async(int sockfd, bundle *kb, const char *local_port,
1232 bool local_trusted, bool is_bidirection)
1236 int local_port_len = 0;
1238 bundle_raw *kb_data = NULL;
1240 if (local_port != NULL)
1241 local_port_len = strlen(local_port) + 1;
1243 if (__write_string_to_socket(sockfd, local_port, local_port_len) != MESSAGEPORT_ERROR_NONE) {
1244 _LOGE("write local_port fail");
1245 return MESSAGEPORT_ERROR_IO_ERROR;
1248 if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
1249 _LOGE("write is_bidirection fail");
1250 return MESSAGEPORT_ERROR_IO_ERROR;
1253 if (__write_socket(sockfd, (char *)&local_trusted, sizeof(local_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
1254 _LOGE("write local_trusted fail");
1255 return MESSAGEPORT_ERROR_IO_ERROR;
1258 bundle_encode(kb, &kb_data, &data_len);
1259 if (kb_data == NULL) {
1260 _LOGE("bundle encode fail");
1261 ret = MESSAGEPORT_ERROR_IO_ERROR;
1265 if (data_len > MAX_MESSAGE_SIZE) {
1266 _LOGE("bigger than max size\n");
1267 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1271 if (__write_string_to_socket(sockfd, (void *)kb_data, data_len) != MESSAGEPORT_ERROR_NONE) {
1272 _LOGE("write kb_data fail");
1273 ret = MESSAGEPORT_ERROR_IO_ERROR;
1282 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1283 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1286 int ret = MESSAGEPORT_ERROR_NONE;
1287 GUnixFDList *fd_list = NULL;
1288 GError *error = NULL;
1291 bundle_raw *raw = NULL;
1292 char *bus_name = NULL;
1293 char *interface_name = NULL;
1295 message_port_remote_app_info_s *remote_app_info = NULL;
1296 port_list_info_s *port_info = NULL;
1297 GDBusMessage *msg = NULL;
1299 GVariant *body = NULL;
1301 ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1302 if (ret != MESSAGEPORT_ERROR_NONE)
1305 if (port_info->exist == false) {
1307 _LOGI("port exist check !!");
1308 ret = __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1309 if (ret != MESSAGEPORT_ERROR_NONE) {
1311 } else if (!exist) {
1312 ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1317 if (port_info->sock_pair[0] > 0) {
1318 ret = __message_port_send_async(port_info->sock_pair[0], message,
1319 (local_port) ? local_port : "", local_trusted, bi_dir);
1322 bus_name = port_info->encoded_bus_name;
1323 interface_name = bus_name;
1325 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1326 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1330 if (MAX_MESSAGE_SIZE < len) {
1331 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1332 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1335 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1336 remote_appid, remote_port, trusted_message, len, raw);
1339 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1341 /* if message-port fail to get socket pair, communicate using GDBus */
1342 if (aul_request_message_port_socket_pair(port_info->sock_pair) != AUL_R_OK) {
1343 _LOGE("error create socket pair");
1346 _LOGI("sock pair : %d, %d", port_info->sock_pair[0], port_info->sock_pair[1]);
1348 fd_list = g_unix_fd_list_new();
1349 g_unix_fd_list_append(fd_list, port_info->sock_pair[1], &err);
1350 g_unix_fd_list_append(fd_list, port_info->sock_pair[0], &err);
1353 _LOGE("g_unix_fd_list_append [%s]", error->message);
1354 ret = MESSAGEPORT_ERROR_IO_ERROR;
1362 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1364 _LOGE("Can't allocate new method call");
1365 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1369 g_dbus_message_set_unix_fd_list(msg, fd_list);
1370 g_dbus_message_set_body(msg, body);
1371 g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
1372 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1374 _LOGE("No reply. error = %s", err->message);
1376 ret = MESSAGEPORT_ERROR_IO_ERROR;
1385 g_object_unref(msg);
1387 bundle_free_encoded_rawdata(&raw);
1389 g_object_unref(fd_list);
1395 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message)
1397 message_port_local_port_info_s *local_info;
1398 int ret = __get_local_port_info(id, &local_info);
1399 if (ret != MESSAGEPORT_ERROR_NONE)
1402 _LOGI("bidirectional_message %s", local_info->port_name);
1403 return __message_port_send_message(remote_app_id, remote_port,
1404 local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1407 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
1411 char *bus_name = NULL;
1415 _LOGI("unregister : %d", local_port_id);
1417 message_port_local_port_info_s *mi =
1418 (message_port_local_port_info_s *)
1419 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
1421 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1423 if (mi->is_trusted != trusted_port)
1424 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1426 bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
1427 if (bus_name == NULL)
1428 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1430 g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
1432 result = g_dbus_connection_call_sync(
1436 DBUS_INTERFACE_DBUS,
1438 g_variant_new("(s)", bus_name),
1439 G_VARIANT_TYPE("(u)"),
1440 G_DBUS_CALL_FLAGS_NONE,
1449 _LOGE("RequestName fail : %s", err->message);
1451 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1453 g_variant_get(result, "(u)", &ret);
1456 g_variant_unref(result);
1458 if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
1460 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
1461 _LOGE("Port Not exist");
1462 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1463 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
1464 _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
1465 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1470 g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
1472 return MESSAGEPORT_ERROR_NONE;
1475 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
1477 if (!_initialized) {
1478 if (!__initialize())
1479 return MESSAGEPORT_ERROR_IO_ERROR;
1482 return __register_message_port(local_port, false, callback);
1485 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
1487 if (!_initialized) {
1488 if (!__initialize())
1489 return MESSAGEPORT_ERROR_IO_ERROR;
1492 return __register_message_port(local_port, true, callback);
1496 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1498 if (!_initialized) {
1499 if (!__initialize())
1500 return MESSAGEPORT_ERROR_IO_ERROR;
1503 int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
1504 if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1506 ret = MESSAGEPORT_ERROR_NONE;
1512 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1514 if (!_initialized) {
1515 if (!__initialize())
1516 return MESSAGEPORT_ERROR_IO_ERROR;
1519 int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
1520 if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1522 ret = MESSAGEPORT_ERROR_NONE;
1528 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
1530 if (!_initialized) {
1531 if (!__initialize())
1532 return MESSAGEPORT_ERROR_IO_ERROR;
1535 return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
1538 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
1540 if (!_initialized) {
1541 if (!__initialize())
1542 return MESSAGEPORT_ERROR_IO_ERROR;
1545 return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
1548 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
1551 if (!_initialized) {
1552 if (!__initialize())
1553 return MESSAGEPORT_ERROR_IO_ERROR;
1556 return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
1559 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
1562 if (!_initialized) {
1563 if (!__initialize())
1564 return MESSAGEPORT_ERROR_IO_ERROR;
1566 return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
1569 int messageport_get_local_port_name(int id, char **name)
1571 message_port_local_port_info_s *local_info;
1572 int ret = __get_local_port_info(id, &local_info);
1574 if (ret != MESSAGEPORT_ERROR_NONE)
1577 *name = strdup(local_info->port_name);
1580 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1582 return MESSAGEPORT_ERROR_NONE;
1585 int messageport_check_trusted_local_port(int id, bool *trusted)
1587 message_port_local_port_info_s *local_info;
1588 int ret = __get_local_port_info(id, &local_info);
1590 if (ret != MESSAGEPORT_ERROR_NONE)
1593 *trusted = local_info->is_trusted;
1595 return MESSAGEPORT_ERROR_NONE;;