2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <bundle_internal.h>
21 #include <pkgmgr-info.h>
24 #include <sys/socket.h>
31 #include <glib-unix.h>
34 #include "message_port_log.h"
35 #include "message_port.h"
36 #include "message_port_common.h"
38 #define MAX_PACKAGE_STR_SIZE 512
39 #define MAX_RETRY_CNT 10
41 bool initialized_common;
42 GDBusConnection *gdbus_conn;
45 static const int MAX_MESSAGE_SIZE = 16 * 1024;
46 static GRecMutex __rec_mutex;
48 #define MESSAGE_PORT_CTOR __attribute__((constructor))
49 #define MESSAGE_PORT_DTOR __attribute__((destructor))
51 int write_socket(int fd,
54 unsigned int *bytes_write,
57 unsigned int left = nbytes;
65 while (left && (retry_cnt < MAX_RETRY_CNT)) {
66 nb = write(fd, buffer, left);
70 LOGW("write_socket: EINTR continue ...");
75 LOGE("write_socket: ...error fd %d: errno %d\n", fd, tmp_errno);
77 if (tmp_errno == EWOULDBLOCK || tmp_errno == EAGAIN)
78 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
80 return MESSAGE_PORT_ERROR_IO_ERROR;
90 _LOGE("error fd %d: retry_cnt %d", fd, retry_cnt);
91 return MESSAGE_PORT_ERROR_IO_ERROR;
94 return MESSAGE_PORT_ERROR_NONE;
97 int write_string_to_socket(int fd,
100 unsigned int *bytes_write,
105 ret = write_socket(fd, (char *)&string_len, sizeof(string_len),
106 bytes_write, sequence);
107 if (ret != MESSAGE_PORT_ERROR_NONE) {
108 _LOGE("write string_len fail");
112 if (string_len > 0) {
113 ret = write_socket(fd, buffer, string_len, bytes_write, sequence);
114 if (ret != MESSAGE_PORT_ERROR_NONE) {
115 _LOGE("wirte buffer fail");
122 return MESSAGE_PORT_ERROR_NONE;
125 int read_socket(int fd,
128 unsigned int *bytes_read)
130 unsigned int left = nbytes;
133 struct timespec TRY_SLEEP_TIME = { 0, 5 * 1000 * 1000 };
136 while (left && (retry_cnt < MAX_RETRY_CNT)) {
137 nb = read(fd, buffer, left);
139 LOGE("read_socket: ...read EOF, socket closed %d: nb %zd\n", fd, nb);
140 return MESSAGE_PORT_ERROR_IO_ERROR;
141 } else if (nb == -1) {
142 /* LCOV_EXCL_START */
143 /* wrt(nodejs) could change socket to none-blocking socket :-( */
144 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
145 LOGW("read_socket: %d , sleep and retry ...", errno);
147 nanosleep(&TRY_SLEEP_TIME, 0);
148 TRY_SLEEP_TIME.tv_nsec *= 2;
151 LOGE("read_socket: ...error fd %d: errno %d\n", fd, errno);
152 return MESSAGE_PORT_ERROR_IO_ERROR;
163 _LOGE("error fd %d: retry_cnt %d", fd, retry_cnt);
164 return MESSAGE_PORT_ERROR_IO_ERROR;
167 return MESSAGE_PORT_ERROR_NONE;
170 int read_string_from_socket(int fd, char **buffer, int *string_len)
173 if (read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGE_PORT_ERROR_NONE) {
174 LOGE("read socket fail");
175 return MESSAGE_PORT_ERROR_IO_ERROR;
177 if (*string_len > 0 && *string_len < MAX_MESSAGE_SIZE) {
178 *buffer = (char *)calloc(*string_len, sizeof(char));
179 if (*buffer == NULL) {
180 /* LCOV_EXCL_START */
181 LOGE("Out of memory.");
182 return MESSAGE_PORT_ERROR_IO_ERROR;
185 if (read_socket(fd, *buffer, *string_len, &nb) != MESSAGE_PORT_ERROR_NONE) {
186 LOGE("read socket fail");
187 return MESSAGE_PORT_ERROR_IO_ERROR;
190 LOGE("Invalid string len %d", *string_len);
191 return MESSAGE_PORT_ERROR_IO_ERROR;
193 return MESSAGE_PORT_ERROR_NONE;
196 static int __dbus_init(void)
199 GError *error = NULL;
201 gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
202 if (gdbus_conn == NULL) {
204 _LOGE("Failed to get dbus [%s]", error->message);
213 bool initialize_common(void)
216 #if !GLIB_CHECK_VERSION(2, 35, 0)
222 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
224 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
225 retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
227 app_id = strdup(buffer);
228 retvm_if(!app_id, false, "Malloc failed");
229 _LOGI("init : %s", app_id);
233 initialized_common = true;
238 bool is_preloaded(const char *local_appid, const char *remote_appid)
240 _LOGD("IsPreloaded");
242 bool preload_local = false;
243 bool preload_remote = false;
245 pkgmgrinfo_appinfo_h handle = NULL;
246 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_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_local);
253 if (ret != PMINFO_R_OK) {
254 _LOGE("Failed to check the preloaded application. %d", ret);
255 pkgmgrinfo_appinfo_destroy_appinfo(handle);
258 pkgmgrinfo_appinfo_destroy_appinfo(handle);
260 ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
261 if (ret != PMINFO_R_OK) {
262 _LOGE("Failed to get the appinfo. %d", ret);
265 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
266 if (ret != PMINFO_R_OK) {
267 _LOGE("Failed to check the preloaded application. %d", ret);
268 pkgmgrinfo_appinfo_destroy_appinfo(handle);
272 if (preload_local && preload_remote) {
273 pkgmgrinfo_appinfo_destroy_appinfo(handle);
276 pkgmgrinfo_appinfo_destroy_appinfo(handle);
280 int check_certificate(const char *local_appid, const char *remote_appid)
282 _LOGD("CheckCertificate");
284 pkgmgrinfo_cert_compare_result_type_e res;
285 int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, remote_appid, getuid(), &res);
287 _LOGE(":CheckCertificate() Failed");
288 return MESSAGE_PORT_ERROR_IO_ERROR;
290 if (res != PMINFO_CERT_COMPARE_MATCH) {
291 _LOGE("CheckCertificate() Failed : MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH");
292 return MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH;
295 return MESSAGE_PORT_ERROR_NONE;
298 char *get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
301 size_t prefix_len = strlen(MESSAGEPORT_BUS_NAME_PREFIX);
303 char *postfix = is_trusted ? "1" : "0";
305 gchar *encoded_bus_name;
306 size_t md5_digest_len = 0;
307 gssize bus_name_len = strlen(remote_app_id) + strlen(port_name) + 2;
308 char *bus_name = (char *)calloc(bus_name_len, sizeof(char));
309 if (bus_name == NULL) {
310 /* LCOV_EXCL_START */
311 _LOGE("bus_name calloc failed");
316 snprintf(bus_name, bus_name_len, "%s_%s", remote_app_id, port_name);
318 encoded_bus_name = g_compute_checksum_for_string(G_CHECKSUM_MD5,
319 bus_name, bus_name_len);
323 if (encoded_bus_name == NULL) {
324 /* LCOV_EXCL_START */
325 _LOGE("g_compute_checksum_for_string failed");
331 md5_digest_len = prefix_len + postfix_len + strlen(encoded_bus_name) + 1;
332 char *md5_digest = (char *)calloc(md5_digest_len, sizeof(char));
333 if (md5_digest == NULL) {
334 /* LCOV_EXCL_START */
335 g_free(encoded_bus_name);
337 _LOGE("calloc failed!!");
342 snprintf(md5_digest, md5_digest_len, "%s%s%s",
343 MESSAGEPORT_BUS_NAME_PREFIX, encoded_bus_name, postfix);
345 _LOGD("md5_encoded_bus_name : %s ", md5_digest);
346 g_free(encoded_bus_name);
351 MESSAGE_PORT_CTOR static void __message_port_init(void)
353 g_rec_mutex_init(&__rec_mutex);
356 MESSAGE_PORT_DTOR static void __message_port_fini(void)
358 if (g_rec_mutex_trylock(&__rec_mutex))
359 g_rec_mutex_unlock(&__rec_mutex);
361 _LOGE("rec_mutex is locked by another thread.");
363 g_rec_mutex_clear(&__rec_mutex);
366 void message_port_lock_mutex()
368 g_rec_mutex_lock(&__rec_mutex);
371 void message_port_unlock_mutex()
373 g_rec_mutex_unlock(&__rec_mutex);