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>
29 #include <openssl/md5.h>
32 #include <glib-unix.h>
35 #include "message_port_log.h"
36 #include "message_port.h"
37 #include "message_port_common.h"
39 #define MAX_PACKAGE_STR_SIZE 512
40 #define MAX_RETRY_CNT 10
42 static const int MAX_MESSAGE_SIZE = 16 * 1024;
44 int write_socket(int fd,
47 unsigned int *bytes_write,
50 #define SEND_TIMEOUT 500 /* milliseconds */
52 unsigned int left = nbytes;
62 fds[0].events = POLLOUT;
65 ret = poll(fds, 1, SEND_TIMEOUT);
67 LOGE("write_socket: : fd %d poll timeout", fd);
68 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
71 while (left && (retry_cnt < MAX_RETRY_CNT)) {
72 nb = write(fd, buffer, left);
75 LOGE("write_socket: EINTR error continue ...");
79 LOGE("write_socket: ...error fd %d: errno %d\n", fd, errno);
81 if (errno == EWOULDBLOCK || errno == EAGAIN)
82 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
84 return MESSAGE_PORT_ERROR_IO_ERROR;
94 _LOGE("error fd %d: retry_cnt %d", fd, retry_cnt);
95 return MESSAGE_PORT_ERROR_IO_ERROR;
98 return MESSAGE_PORT_ERROR_NONE;
101 int write_string_to_socket(int fd,
104 unsigned int *bytes_write,
109 ret = write_socket(fd, (char *)&string_len, sizeof(string_len),
110 bytes_write, sequence);
111 if (ret != MESSAGE_PORT_ERROR_NONE) {
112 _LOGE("write string_len fail");
116 if (string_len > 0) {
117 ret = write_socket(fd, buffer, string_len, bytes_write, sequence);
118 if (ret != MESSAGE_PORT_ERROR_NONE) {
119 _LOGE("wirte buffer fail");
126 return MESSAGE_PORT_ERROR_NONE;
129 int read_socket(int fd,
132 unsigned int *bytes_read)
134 unsigned int left = nbytes;
137 const struct timespec TRY_SLEEP_TIME = { 0, 500 * 1000 * 1000 };
140 while (left && (retry_cnt < MAX_RETRY_CNT)) {
141 nb = read(fd, buffer, left);
143 LOGE("read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
144 return MESSAGE_PORT_ERROR_IO_ERROR;
145 } else if (nb == -1) {
146 /* wrt(nodejs) could change socket to none-blocking socket :-( */
147 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
148 LOGE("read_socket: %d errno, sleep and retry ...", errno);
150 nanosleep(&TRY_SLEEP_TIME, 0);
153 LOGE("read_socket: ...error fd %d: errno %d\n", fd, errno);
154 return MESSAGE_PORT_ERROR_IO_ERROR;
164 _LOGE("error fd %d: retry_cnt %d", fd, retry_cnt);
165 return MESSAGE_PORT_ERROR_IO_ERROR;
168 return MESSAGE_PORT_ERROR_NONE;
171 int read_string_from_socket(int fd, char **buffer, int *string_len)
174 if (read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGE_PORT_ERROR_NONE) {
175 LOGE("read socket fail");
176 return MESSAGE_PORT_ERROR_IO_ERROR;
178 if (*string_len > 0 && *string_len < MAX_MESSAGE_SIZE) {
179 *buffer = (char *)calloc(*string_len, sizeof(char));
180 if (*buffer == NULL) {
181 LOGE("Out of memory.");
182 return MESSAGE_PORT_ERROR_IO_ERROR;
184 if (read_socket(fd, *buffer, *string_len, &nb) != MESSAGE_PORT_ERROR_NONE) {
185 LOGE("read socket fail");
186 return MESSAGE_PORT_ERROR_IO_ERROR;
189 LOGE("Invalid string len %d", *string_len);
190 return MESSAGE_PORT_ERROR_IO_ERROR;
192 return MESSAGE_PORT_ERROR_NONE;
195 static int __dbus_init(void)
198 GError *error = NULL;
200 gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
201 if (gdbus_conn == NULL) {
203 _LOGE("Failed to get dbus [%s]", error->message);
213 g_object_unref(gdbus_conn);
219 bool initialize_common(void)
222 #if !GLIB_CHECK_VERSION(2, 35, 0)
228 char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
230 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
231 retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
233 app_id = strdup(buffer);
234 retvm_if(!app_id, false, "Malloc failed");
235 _LOGI("init : %s", app_id);
239 initialized_common = true;
244 bool is_preloaded(const char *local_appid, const char *remote_appid)
246 _LOGD("IsPreloaded");
248 bool preload_local = false;
249 bool preload_remote = false;
251 pkgmgrinfo_appinfo_h handle = NULL;
252 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle);
253 if (ret != PMINFO_R_OK) {
254 _LOGE("Failed to get the appinfo. %d", ret);
255 pkgmgrinfo_appinfo_destroy_appinfo(handle);
258 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local);
259 if (ret != PMINFO_R_OK) {
260 _LOGE("Failed to check the preloaded application. %d", ret);
261 pkgmgrinfo_appinfo_destroy_appinfo(handle);
264 pkgmgrinfo_appinfo_destroy_appinfo(handle);
266 ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
267 if (ret != PMINFO_R_OK) {
268 _LOGE("Failed to get the appinfo. %d", ret);
269 pkgmgrinfo_appinfo_destroy_appinfo(handle);
272 ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
273 if (ret != PMINFO_R_OK) {
274 _LOGE("Failed to check the preloaded application. %d", ret);
275 pkgmgrinfo_appinfo_destroy_appinfo(handle);
279 if (preload_local && preload_remote) {
280 pkgmgrinfo_appinfo_destroy_appinfo(handle);
283 pkgmgrinfo_appinfo_destroy_appinfo(handle);
287 int check_certificate(const char *local_appid, const char *remote_appid)
289 _LOGD("CheckCertificate");
291 pkgmgrinfo_cert_compare_result_type_e res;
292 int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, remote_appid, getuid(), &res);
294 _LOGE(":CheckCertificate() Failed");
295 return MESSAGE_PORT_ERROR_IO_ERROR;
297 if (res != PMINFO_CERT_COMPARE_MATCH) {
298 _LOGE("CheckCertificate() Failed : MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH");
299 return MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH;
302 return MESSAGE_PORT_ERROR_NONE;
305 char *get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
308 int prefix_len = strlen(MESSAGEPORT_BUS_NAME_PREFIX);
310 char *postfix = is_trusted ? "1" : "0";
312 unsigned char c[MD5_DIGEST_LENGTH] = {0};
313 char *md5_interface = NULL;
317 int encoded_bus_name_len = prefix_len + postfix_len + (MD5_DIGEST_LENGTH * 2) + 2;
318 int bus_name_len = strlen(remote_app_id) + strlen(port_name) + 2;
319 char *bus_name = (char *)calloc(bus_name_len, sizeof(char));
320 if (bus_name == NULL) {
321 _LOGE("bus_name calloc failed");
325 snprintf(bus_name, bus_name_len, "%s_%s", remote_app_id, port_name);
327 MD5_Init(&mdContext);
328 MD5_Update(&mdContext, bus_name, bus_name_len);
329 MD5_Final(c, &mdContext);
331 md5_interface = (char *)calloc(encoded_bus_name_len , sizeof(char));
332 if (md5_interface == NULL) {
336 _LOGE("md5_interface calloc failed!!");
340 snprintf(md5_interface, encoded_bus_name_len, "%s", MESSAGEPORT_BUS_NAME_PREFIX);
341 temp = md5_interface;
344 for (index = 0; index < MD5_DIGEST_LENGTH; index++) {
345 snprintf(temp, 3, "%02x", c[index]);
349 if (postfix && postfix_len > 0)
350 snprintf(temp, encoded_bus_name_len - (temp - md5_interface), "%s", postfix);
354 _LOGD("encoded_bus_name : %s ", md5_interface);
356 return md5_interface;