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.
26 #include <glib/gstdio.h>
28 #include <tzplatform_config.h>
29 #include <security-manager.h>
30 #include <sys/smack.h>
32 #include <linux/xattr.h>
33 #include <sys/types.h>
36 #include <package_manager.h>
38 #include "notification.h"
39 #include "notification_debug.h"
40 #include "notification_shared_file.h"
41 #include <notification_private.h>
43 #define NOTI_PRIV_DATA_DIR "data/.notification"
44 #define MAX_TIMEOUT 5000
45 #define MAX_RETRY_CNT 3
46 #define ERR_BUFFER_SIZE 1024
49 #define __OOM_CHECK(value, ret_value, free_fun) \
51 if (value == NULL) { \
52 ERR("out of memory"); \
59 typedef struct uid_info {
61 GList *sharing_req_list;
62 GList *target_app_list;
65 typedef struct sharing_req_data {
72 GList *shared_file_list;
73 GList *target_app_table;
76 typedef struct sharing_file_info {
79 time_t modification_time;
80 } sharing_file_info_s;
82 typedef struct target_app_info {
84 char *dbus_sender_name;
88 static const char *__last_index_of(const char *path, const char *search);
89 static bool __make_sharing_dir(const char *dir)
91 GFile *noti_dir = NULL;
94 if (access(dir, R_OK) == 0)
97 noti_dir = g_file_new_for_path(dir);
101 if (g_file_make_directory(noti_dir, NULL, &g_err) == false) {
103 ERR("Failed to make sharing dir[%s]", g_err->message);
106 g_object_unref(noti_dir);
110 g_object_unref(noti_dir);
115 /* LCOV_EXCL_START */
116 static char *__get_data_path_by_pkg_id(const char *pkg_id,
117 const char *file_path, uid_t uid)
120 char dir[PATH_MAX * 2];
121 char rel_file_path[PATH_MAX];
122 const char *pkg_path;
127 tzplatform_set_user(uid);
128 path = tzplatform_getenv(TZ_USER_APP);
129 tzplatform_reset_user();
134 pkg_path = __last_index_of(file_path, pkg_id);
135 if (pkg_path == NULL) {
136 ERR("Wrong file path : cannot find pkgid");
140 snprintf(rel_file_path, sizeof(rel_file_path), "%s",
141 pkg_path + strlen(pkg_id));
143 for (int i = 0; i < strlen(rel_file_path); i++) {
144 if (rel_file_path[i] == '/')
145 rel_file_path[i] = '_';
148 snprintf(dir, sizeof(dir), "%s/%s/%s",
149 path, pkg_id, NOTI_PRIV_DATA_DIR);
150 if (__make_sharing_dir(dir) == false)
153 snprintf(dir, sizeof(dir), "%s/%s/%s/%s", path, pkg_id,
154 NOTI_PRIV_DATA_DIR, rel_file_path);
159 static const char *__last_index_of(const char *path, const char *search)
165 if (path == NULL || search == NULL)
168 search_len = strlen(search);
169 index = path + strlen(path) - search_len;
171 while (index >= path) {
172 for (i = 0; i < search_len; i++) {
173 if (index[i] != search[i])
187 /* Check path that include res directory */
188 /* LCOV_EXCL_START */
189 static bool __is_private_file(const char *smack_label, const char *pkg_id)
191 const char *smack_index;
194 if (smack_label == NULL || pkg_id == NULL)
197 smack_index = __last_index_of(smack_label, pkg_id);
198 if (smack_index != NULL && (strlen(smack_index) == strlen(pkg_id)))
205 /* LCOV_EXCL_START */
206 static bool __is_RO_file(const char *smack_label)
208 #define CHECK_LABEL "::RO"
210 const char *smack_index;
213 smack_index = __last_index_of(smack_label, CHECK_LABEL);
214 if (smack_index != NULL && (strlen(smack_index) == strlen(CHECK_LABEL)))
221 /* file copy from /res to /data */
222 /* LCOV_EXCL_START */
223 int notification_copy_private_file(const char *src_path,
224 const char *dst_path)
226 int ret = NOTIFICATION_ERROR_NONE;
229 GError *g_err = NULL;
230 struct utimbuf ut = {0,};
232 dst = g_file_new_for_path(dst_path);
234 ERR("dst path is wrong [%s]", dst_path);
235 ret = NOTIFICATION_ERROR_IO_ERROR;
239 if (g_file_query_exists(dst, NULL) == true) {
240 ret = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
241 INFO("dst path existed [%s]", dst_path);
245 src = g_file_new_for_path(src_path);
247 ERR("src path is wrong [%s]", src_path);
248 ret = NOTIFICATION_ERROR_IO_ERROR;
252 if (!g_file_copy(src, dst, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL, NULL,
255 ERR("Copying file from [%s] to [%s] is failed [%s]",
256 src_path, dst_path, g_err->message);
259 ret = NOTIFICATION_ERROR_IO_ERROR;
263 ut.modtime = time(NULL);
264 if (g_utime(dst_path, &ut) != 0)
265 DBG("Failed to set g_utime %d ", errno);
277 /* LCOV_EXCL_START */
278 static void __free_file_info(gpointer data)
280 sharing_file_info_s *info = (sharing_file_info_s *)data;
284 free(info->src_path);
286 free(info->dst_path);
292 /* LCOV_EXCL_START */
293 static void __free_req_info(gpointer data)
295 sharing_req_data_s *info = (sharing_req_data_s *)data;
303 if (info->shared_file_list)
304 g_list_free_full(info->shared_file_list, __free_file_info);
305 if (info->target_app_table)
306 g_list_free_full(info->target_app_table, free);
312 /* LCOV_EXCL_START */
313 static char **__convert_list_to_array(GList *list, int *length)
322 len = g_list_length(list);
326 array = (char **)calloc(len + 1, sizeof(char *));
327 __OOM_CHECK(array, NULL, DUMMY_PARAM);
329 for (i = 0, iter = list; iter != NULL; i++, iter = g_list_next(iter))
330 array[i] = ((sharing_file_info_s *)iter->data)->dst_path;
337 static gint __comp_str(gconstpointer a, gconstpointer b)
339 char *new_file = (char *)a;
340 char *file = (char *)b;
342 if (new_file == NULL || file == NULL)
345 return strcmp(new_file, file);
349 /* LCOV_EXCL_START */
350 static gint __comp_file_info(gconstpointer a, gconstpointer b)
352 sharing_file_info_s *file = (sharing_file_info_s *)a;
353 sharing_file_info_s *new_file = (sharing_file_info_s *)b;
355 if (!file || !new_file || !new_file->dst_path || !file->dst_path)
358 return strcmp(new_file->dst_path, file->dst_path);
362 /* LCOV_EXCL_START */
363 static gint __comp_dst_path(gconstpointer a, gconstpointer b)
365 sharing_file_info_s *info = (sharing_file_info_s *)a;
366 char *path = (char *)b;
368 if (!info || !path || !info->dst_path)
371 return strcmp(info->dst_path, path);
375 /* LCOV_EXCL_START */
376 static sharing_file_info_s *__dup_file_info(sharing_file_info_s *src)
378 sharing_file_info_s *file_info;
380 file_info = (sharing_file_info_s *)calloc(1, sizeof(sharing_file_info_s));
381 __OOM_CHECK(file_info, NULL, DUMMY_PARAM);
383 file_info->dst_path = strdup(src->dst_path);
384 __OOM_CHECK(file_info->dst_path, NULL, __free_file_info(file_info));
386 file_info->src_path = strdup(src->src_path);
387 __OOM_CHECK(file_info->src_path, NULL, __free_file_info(file_info));
389 file_info->modification_time = src->modification_time;
395 static void __make_file_info(char *src_path, char *dst_path,
396 GList **new_file_list, GList *shared_file_list, bool *is_overlapping)
400 sharing_file_info_s *file_info;
401 sharing_file_info_s *dup_file_info;
402 struct stat stat_buf = {0,};
405 * If the file copy is successful,
406 * ignore the shared_file_list check for private sharing
408 ret = notification_copy_private_file(src_path, dst_path);
409 if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
410 tmp = g_list_find_custom(shared_file_list, dst_path,
413 file_info = (sharing_file_info_s *)calloc(1,
414 sizeof(sharing_file_info_s));
415 __OOM_CHECK(file_info, DUMMY_PARAM, DUMMY_PARAM);
417 file_info->dst_path = strdup(dst_path);
418 __OOM_CHECK(file_info->dst_path, DUMMY_PARAM,
419 __free_file_info(file_info));
421 file_info->src_path = strdup(src_path);
422 __OOM_CHECK(file_info->src_path, DUMMY_PARAM,
423 __free_file_info(file_info));
425 if (stat(dst_path, &stat_buf) != 0)
426 ERR("Failed to get stat info");
427 file_info->modification_time = stat_buf.st_mtime;
429 *new_file_list = g_list_append(*new_file_list, file_info);
431 file_info = (sharing_file_info_s *)tmp->data;
433 if (stat(file_info->dst_path, &stat_buf) != 0)
434 ERR("Failed to get stat info");
436 if (file_info->modification_time != stat_buf.st_mtime) {
437 dup_file_info = __dup_file_info(file_info);
438 __OOM_CHECK(dup_file_info, DUMMY_PARAM, DUMMY_PARAM);
440 *new_file_list = g_list_append(*new_file_list,
442 *is_overlapping = true;
445 } else if (ret == NOTIFICATION_ERROR_NONE) {
446 *is_overlapping = true;
451 static GList *__get_new_file_list(notification_h noti,
452 GList *shared_file_list,
453 bool *is_overlapping)
455 GList *new_file_list = NULL;
456 char *src_path, *dst_path, *dup_str;
457 char buf_key[32] = { 0, };
458 int i = NOTIFICATION_IMAGE_TYPE_ICON;
461 if (noti->priv_sound_path != NULL && noti->sound_path != NULL) {
462 dst_path = noti->priv_sound_path;
463 src_path = noti->sound_path;
465 dup_str = strdup(dst_path);
466 __OOM_CHECK(dup_str, NULL, DUMMY_PARAM);
468 __make_file_info(src_path, dst_path, &new_file_list,
469 shared_file_list, is_overlapping);
471 free(noti->sound_path);
472 noti->sound_path = dup_str;
475 if (noti->priv_vibration_path != NULL && noti->vibration_path != NULL) {
476 dst_path = noti->priv_vibration_path;
477 src_path = noti->vibration_path;
479 dup_str = strdup(dst_path);
480 __OOM_CHECK(dup_str, NULL,
481 g_list_free_full(new_file_list, __free_file_info));
483 __make_file_info(src_path, dst_path, &new_file_list,
484 shared_file_list, is_overlapping);
486 free(noti->vibration_path);
487 noti->vibration_path = dup_str;
490 if (noti->b_priv_image_path == NULL)
491 return new_file_list;
493 for (; i <= NOTIFICATION_IMAGE_TYPE_MAX; i++) {
496 snprintf(buf_key, sizeof(buf_key), "%d", i);
497 bundle_get_str(noti->b_priv_image_path, buf_key, &dst_path);
498 bundle_get_str(noti->b_image_path, buf_key, &src_path);
499 if (dst_path != NULL && src_path != NULL) {
500 __make_file_info(src_path, dst_path, &new_file_list,
501 shared_file_list, is_overlapping);
503 bundle_del(noti->b_image_path, buf_key);
504 bundle_add_str(noti->b_image_path, buf_key, dst_path);
508 return new_file_list;
511 static char *__get_shared_dir(notification_h noti)
515 char *shared_path = NULL;
517 char buf_key[32] = { 0, };
519 int i = NOTIFICATION_IMAGE_TYPE_ICON, dir_len;
521 if (noti->b_priv_image_path != NULL) {
522 for (; i <= NOTIFICATION_IMAGE_TYPE_MAX; i++) {
523 snprintf(buf_key, sizeof(buf_key), "%d", i);
524 ret = bundle_get_str(noti->b_priv_image_path, buf_key, &path);
525 if (ret == BUNDLE_ERROR_NONE
526 && __last_index_of(path, NOTI_PRIV_DATA_DIR) != NULL) {
533 if (shared_path == NULL && noti->priv_sound_path != NULL
534 && __last_index_of(noti->priv_sound_path, NOTI_PRIV_DATA_DIR) != NULL)
535 shared_path = noti->priv_sound_path;
536 else if (shared_path == NULL && noti->priv_vibration_path != NULL
537 && __last_index_of(noti->priv_vibration_path, NOTI_PRIV_DATA_DIR) != NULL)
538 shared_path = noti->priv_vibration_path;
540 if (shared_path == NULL) {
541 DBG("No private resource");
545 index = __last_index_of(shared_path, "/");
547 ERR("Failed to find directory separator");
551 dir_len = index - shared_path + 1;
552 if (dir_len <= 0 || dir_len > PATH_MAX)
555 dir = (char *)calloc(dir_len, sizeof(char));
556 __OOM_CHECK(dir, NULL, DUMMY_PARAM);
558 snprintf(dir, dir_len, "%s", shared_path);
563 static gint __comp_sharing_req_list(gconstpointer a, gconstpointer b)
565 sharing_req_data_s *req_data = (sharing_req_data_s *)a;
566 char *app_id = (char *)b;
568 if (!req_data || !app_id || !req_data->app_id)
571 if (!strcmp(app_id, req_data->app_id))
577 static gint __comp_uid_info_list(gconstpointer a, gconstpointer b)
579 uid_info_s *uid_info = (uid_info_s *)a;
584 if (uid_info->uid == GPOINTER_TO_INT(b))
590 static gint __comp_priv_id(gconstpointer a, gconstpointer b)
595 if (GPOINTER_TO_INT(a) == GPOINTER_TO_INT(b))
601 static gint __comp_target_app(gconstpointer a, gconstpointer b)
603 target_app_info_s *target = (target_app_info_s *)a;
604 char *sender = (char *)b;
606 if (!target || !sender || !target->dbus_sender_name)
609 return strcmp(sender, target->dbus_sender_name);
612 EXPORT_API void notification_remove_private_sharing_target_id(
613 const char *sender, uid_t uid)
615 target_app_info_s *target_info;
616 uid_info_s *uid_info;
617 GList *sharing_req_list, *target_app;
619 sharing_req_list = g_list_find_custom(__uid_list, GINT_TO_POINTER(uid),
620 __comp_uid_info_list);
621 if (sharing_req_list == NULL)
624 uid_info = sharing_req_list->data;
625 target_app = g_list_find_custom(uid_info->target_app_list, sender,
628 if (target_app != NULL) {
629 target_info = target_app->data;
631 uid_info->target_app_list = g_list_remove(
632 uid_info->target_app_list, target_info);
634 free(target_info->app_id);
635 free(target_info->dbus_sender_name);
642 EXPORT_API void notification_add_private_sharing_target_id(pid_t pid,
643 const char *sender, uid_t uid)
646 target_app_info_s *target_info;
647 uid_info_s *uid_info;
648 GList *sharing_req_list, *target_app;
650 sharing_req_list = g_list_find_custom(__uid_list, GINT_TO_POINTER(uid),
651 __comp_uid_info_list);
652 if (sharing_req_list == NULL) {
653 uid_info = (uid_info_s *)calloc(1, sizeof(uid_info_s));
654 __OOM_CHECK(uid_info, DUMMY_PARAM, DUMMY_PARAM);
657 __uid_list = g_list_append(__uid_list, uid_info);
659 uid_info = sharing_req_list->data;
662 target_app = g_list_find_custom(uid_info->target_app_list, sender,
664 if (target_app == NULL) {
665 app_id = notification_get_app_id_by_pid((int)pid);
666 if (app_id == NULL) {
667 ERR("Failed to get app id by pid");
671 target_info = (target_app_info_s *)calloc(1, sizeof(target_app_info_s));
672 if (target_info == NULL) {
673 ERR("Failed to alloc memory");
678 target_info->app_id = app_id;
679 target_info->dbus_sender_name = strdup(sender);
680 if (target_info->dbus_sender_name == NULL) {
681 ERR("Failed to alloc memory");
687 uid_info->target_app_list = g_list_append(
688 uid_info->target_app_list, target_info);
692 char *notification_check_file_path_is_private(const char *pkg_id,
693 const char *file_path)
695 char *smack_label = NULL;
696 char *dst_path = NULL;
698 uid_t uid = getuid();
699 char err_buf[ERR_BUFFER_SIZE];
703 size = smack_new_label_from_path(file_path, XATTR_NAME_SMACK,
706 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
707 ERR("Failed to get smack info : %d [%s][%s]", errno, err_str,
712 if (__is_RO_file(smack_label))
713 dst_path = __get_data_path_by_pkg_id(pkg_id, file_path, uid);
715 if (dst_path == NULL && __is_private_file(smack_label, pkg_id)) {
716 dst_path = strdup(file_path);
717 if (dst_path == NULL)
718 ERR("Failed to strdup");
725 EXPORT_API bool notification_validate_private_sharing(
726 notification_h updated_noti)
728 char *updated_path = NULL;
729 char *private_path = NULL;
730 char buf_key[32] = { 0, };
731 int i = NOTIFICATION_IMAGE_TYPE_ICON;
733 if (updated_noti->b_image_path && updated_noti->b_priv_image_path) {
734 for (; i <= NOTIFICATION_IMAGE_TYPE_MAX; i++) {
738 snprintf(buf_key, sizeof(buf_key), "%d", i);
739 bundle_get_str(updated_noti->b_image_path, buf_key,
741 if (updated_path == NULL)
744 bundle_get_str(updated_noti->b_priv_image_path,
745 buf_key, &private_path);
746 if (private_path == NULL)
749 if (strcmp(updated_path, private_path) == 0)
754 if (updated_noti->sound_path && updated_noti->priv_sound_path) {
755 if (strcmp(updated_noti->sound_path,
756 updated_noti->priv_sound_path) == 0)
760 if (updated_noti->vibration_path && updated_noti->priv_vibration_path) {
761 if (strcmp(updated_noti->vibration_path,
762 updated_noti->priv_vibration_path) == 0)
769 EXPORT_API void notification_calibrate_private_sharing(
770 notification_h updated_noti, notification_h source_noti)
772 char *updated_path = NULL;
773 char *source_path = NULL;
774 char *private_path = NULL;
775 char buf_key[32] = { 0, };
776 int i = NOTIFICATION_IMAGE_TYPE_ICON;
778 if (updated_noti->b_image_path && updated_noti->b_priv_image_path) {
779 for (; i <= NOTIFICATION_IMAGE_TYPE_MAX; i++) {
784 snprintf(buf_key, sizeof(buf_key), "%d", i);
785 bundle_get_str(updated_noti->b_image_path, buf_key,
787 if (updated_path == NULL)
790 bundle_get_str(updated_noti->b_priv_image_path,
791 buf_key, &private_path);
792 if (private_path == NULL)
795 if (strcmp(updated_path, private_path) == 0) {
796 if (bundle_get_str(source_noti->b_image_path,
797 buf_key, &source_path) == BUNDLE_ERROR_NONE) {
798 bundle_del(updated_noti->b_image_path,
800 bundle_add_str(updated_noti->b_image_path,
801 buf_key, source_path);
807 if (updated_noti->sound_path && updated_noti->priv_sound_path) {
808 if (strcmp(updated_noti->sound_path,
809 updated_noti->priv_sound_path) == 0) {
810 free(updated_noti->sound_path);
811 updated_noti->sound_path = NULL;
813 if (source_noti->sound_path) {
814 updated_noti->sound_path = strdup(source_noti->sound_path);
815 if (updated_noti->sound_path == NULL)
816 ERR("out of memory");
821 if (updated_noti->vibration_path && updated_noti->priv_vibration_path) {
822 if (strcmp(updated_noti->vibration_path,
823 updated_noti->priv_vibration_path) == 0) {
824 free(updated_noti->vibration_path);
825 updated_noti->vibration_path = NULL;
827 if (source_noti->priv_vibration_path) {
828 updated_noti->vibration_path =
829 strdup(source_noti->priv_vibration_path);
830 if (updated_noti->vibration_path == NULL)
831 ERR("out of memory");
838 int __set_sharing_for_new_target(sharing_req_data_s *req_data,
839 GList *target_app_list)
841 char **path_array = NULL;
842 int ret = NOTIFICATION_ERROR_NONE;
844 private_sharing_req *handle = NULL;
846 target_app_info_s *target_info;
847 char *app_info = NULL;
849 iter = target_app_list;
850 for (; iter != NULL; iter = g_list_next(iter)) {
851 target_info = (target_app_info_s *)iter->data;
852 tmp = g_list_find_custom(req_data->target_app_table,
853 target_info->app_id, __comp_str);
857 app_info = strdup(target_info->app_id);
858 if (app_info == NULL) {
859 ERR("out of memory");
860 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
864 if (handle == NULL) {
865 ret = security_manager_private_sharing_req_new(&handle);
866 if (ret != SECURITY_MANAGER_SUCCESS) {
867 ret = NOTIFICATION_ERROR_IO_ERROR;
868 ERR("Failed to create PS handle");
872 ret = security_manager_private_sharing_req_set_owner_appid(
873 handle, req_data->app_id);
874 if (ret != SECURITY_MANAGER_SUCCESS) {
875 ret = NOTIFICATION_ERROR_IO_ERROR;
876 ERR("Failed to set owner appid(%s) %d",
877 req_data->app_id, ret);
880 path_array = __convert_list_to_array(
881 req_data->shared_file_list, &len);
882 if (path_array == NULL) {
883 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
887 ret = security_manager_private_sharing_req_add_paths(
888 handle, (const char **)path_array, len);
889 if (ret != SECURITY_MANAGER_SUCCESS) {
890 ret = NOTIFICATION_ERROR_IO_ERROR;
891 ERR("Failed to add paths %d", ret);
896 ret = security_manager_private_sharing_req_set_target_appid(
897 handle, target_info->app_id);
898 if (ret != SECURITY_MANAGER_SUCCESS) {
899 ret = NOTIFICATION_ERROR_IO_ERROR;
900 ERR("Failed to set target appid(%s)",
901 (const char *)iter->data);
905 ret = security_manager_private_sharing_apply(handle);
906 if (ret != SECURITY_MANAGER_SUCCESS) {
907 ret = NOTIFICATION_ERROR_IO_ERROR;
908 ERR("Failed to apply PS %d", ret);
912 req_data->target_app_table = g_list_append(
913 req_data->target_app_table, app_info);
917 if (ret != NOTIFICATION_ERROR_NONE && app_info)
921 security_manager_private_sharing_req_free(handle);
923 if (path_array != NULL)
930 /* LCOV_EXCL_START */
931 int __set_sharing_for_new_file(sharing_req_data_s *req_data,
932 GList *new_file_list, bool is_overlapping)
934 char **path_array = NULL;
935 int ret = NOTIFICATION_ERROR_NONE;
937 private_sharing_req *handle = NULL;
940 path_array = __convert_list_to_array(new_file_list, &len);
941 if (path_array == NULL) {
942 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
946 ret = security_manager_private_sharing_req_new(&handle);
947 if (ret != SECURITY_MANAGER_SUCCESS) {
948 ERR("Failed to create private sharing request handle[%d]", ret);
949 ret = NOTIFICATION_ERROR_IO_ERROR;
953 ret = security_manager_private_sharing_req_set_owner_appid(handle,
955 if (ret != SECURITY_MANAGER_SUCCESS) {
956 ERR("Failed to set owner appid[%s][%d]", req_data->app_id, ret);
957 ret = NOTIFICATION_ERROR_IO_ERROR;
961 ret = security_manager_private_sharing_req_add_paths(handle,
962 (const char **)path_array, len);
963 if (ret != SECURITY_MANAGER_SUCCESS) {
964 ERR("Failed to add paths [%d]", ret);
965 ret = NOTIFICATION_ERROR_IO_ERROR;
969 if (is_overlapping == true) {
970 iter = req_data->target_app_table;
971 for (; iter != NULL; iter = g_list_next(iter)) {
972 ret = security_manager_private_sharing_req_set_target_appid(
973 handle, (const char *)iter->data);
974 if (ret != SECURITY_MANAGER_SUCCESS) {
975 ERR("Failed to set target appid [%s]",
976 (const char *)iter->data);
977 ret = NOTIFICATION_ERROR_IO_ERROR;
981 ret = security_manager_private_sharing_drop(handle);
982 if (ret != SECURITY_MANAGER_SUCCESS) {
983 ERR("Failed to drop [%d]", ret);
984 ret = NOTIFICATION_ERROR_IO_ERROR;
990 iter = req_data->target_app_table;
991 for (; iter != NULL; iter = g_list_next(iter)) {
992 ret = security_manager_private_sharing_req_set_target_appid(handle,
993 (const char *)iter->data);
994 if (ret != SECURITY_MANAGER_SUCCESS) {
995 ERR("Failed to set target appid [%s]",
996 (const char *)iter->data);
997 ret = NOTIFICATION_ERROR_IO_ERROR;
1001 ret = security_manager_private_sharing_apply(handle);
1002 if (ret != SECURITY_MANAGER_SUCCESS) {
1003 ERR("Failed to apply PS [%d]", ret);
1004 ret = NOTIFICATION_ERROR_IO_ERROR;
1011 security_manager_private_sharing_req_free(handle);
1013 if (path_array != NULL)
1018 /* LCOV_EXCL_STOP */
1020 /* LCOV_EXCL_START */
1021 EXPORT_API int notification_set_private_sharing(notification_h noti,
1024 int ret = NOTIFICATION_ERROR_NONE;
1025 bool is_overlapping = false;
1026 sharing_req_data_s *req_data;
1027 sharing_file_info_s *file_info, *dup_file_info;
1028 uid_info_s *uid_info;
1029 GList *req_list, *iter, *tmp;
1030 GList *new_file_list = NULL;
1032 if (noti == NULL || noti->caller_app_id == NULL)
1033 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1035 tmp = g_list_find_custom(__uid_list, GINT_TO_POINTER(uid),
1036 __comp_uid_info_list);
1038 uid_info = (uid_info_s *)calloc(1, sizeof(uid_info_s));
1039 __OOM_CHECK(uid_info, NOTIFICATION_ERROR_OUT_OF_MEMORY, DUMMY_PARAM);
1041 uid_info->uid = uid;
1042 __uid_list = g_list_append(__uid_list, uid_info);
1044 uid_info = tmp->data;
1047 req_list = g_list_find_custom(uid_info->sharing_req_list,
1048 noti->caller_app_id, __comp_sharing_req_list);
1049 if (req_list == NULL) {
1050 req_data = (sharing_req_data_s *)calloc(1, sizeof(sharing_req_data_s));
1051 __OOM_CHECK(req_data, NOTIFICATION_ERROR_OUT_OF_MEMORY, DUMMY_PARAM);
1053 req_data->app_id = strdup(noti->caller_app_id);
1054 __OOM_CHECK(req_data->app_id, NOTIFICATION_ERROR_OUT_OF_MEMORY,
1055 __free_req_info(req_data));
1057 req_data->dir = __get_shared_dir(noti);
1058 req_data->uid = uid;
1060 uid_info->sharing_req_list = g_list_append(
1061 uid_info->sharing_req_list, req_data);
1063 req_data = (sharing_req_data_s *)req_list->data;
1064 if (req_data->dir == NULL)
1065 req_data->dir = __get_shared_dir(noti);
1067 if (req_data->timer > 0) {
1068 g_source_remove(req_data->timer);
1069 req_data->timer = 0;
1073 if (req_data->dir != NULL)
1074 __make_sharing_dir(req_data->dir);
1076 tmp = g_list_find_custom(req_data->priv_id_list,
1077 GINT_TO_POINTER(noti->priv_id), __comp_priv_id);
1079 req_data->priv_id_list = g_list_append(req_data->priv_id_list,
1080 GINT_TO_POINTER(noti->priv_id));
1082 new_file_list = __get_new_file_list(noti, req_data->shared_file_list,
1084 if (new_file_list != NULL) {
1085 if (__set_sharing_for_new_file(req_data, new_file_list,
1086 is_overlapping) != NOTIFICATION_ERROR_NONE) {
1087 ret = NOTIFICATION_ERROR_IO_ERROR;
1092 for (iter = new_file_list; iter != NULL; iter = g_list_next(iter)) {
1094 file_info = iter->data;
1095 if (is_overlapping) {
1096 tmp = g_list_find_custom(req_data->shared_file_list,
1097 file_info, __comp_file_info);
1101 dup_file_info = __dup_file_info(file_info);
1102 req_data->shared_file_list = g_list_append(
1103 req_data->shared_file_list, dup_file_info);
1107 if (__set_sharing_for_new_target(req_data, uid_info->target_app_list)
1108 != NOTIFICATION_ERROR_NONE) {
1109 ret = NOTIFICATION_ERROR_IO_ERROR;
1112 INFO("PS success priv id[%d] shared file count[%d] target app count[%d]",
1114 g_list_length(req_data->shared_file_list),
1115 g_list_length(req_data->target_app_table));
1118 if (new_file_list != NULL)
1119 g_list_free_full(new_file_list, __free_file_info);
1121 if (ret != NOTIFICATION_ERROR_NONE)
1122 req_data->priv_id_list = g_list_remove(req_data->priv_id_list,
1123 GINT_TO_POINTER(noti->priv_id));
1127 static gboolean __timeout_handler(void *data)
1129 char **path_array = NULL;
1132 sharing_req_data_s *req_data;
1133 private_sharing_req *handle = NULL;
1136 uid_info_s *uid_info;
1137 int ret = SECURITY_MANAGER_SUCCESS;
1140 req_data = (sharing_req_data_s *)data;
1141 if (g_list_length(req_data->priv_id_list) > 0) {
1142 req_data->timer = 0;
1146 req_data->drop_retry_count++;
1148 /* If there is no shared file, the private sharing is not dropped. */
1149 if (req_data->dir != NULL) {
1150 __make_sharing_dir(req_data->dir);
1151 iter = req_data->shared_file_list;
1152 for (; iter != NULL; iter = g_list_next(iter)) {
1153 notification_copy_private_file(
1154 ((sharing_file_info_s *)(iter->data))->src_path,
1155 ((sharing_file_info_s *)(iter->data))->dst_path);
1159 if (g_list_length(req_data->target_app_table) > 0) {
1160 ret = security_manager_private_sharing_req_new(&handle);
1161 if (ret != SECURITY_MANAGER_SUCCESS) {
1162 ERR("Failed to create PS request handle");
1166 ret = security_manager_private_sharing_req_set_owner_appid(
1167 handle, req_data->app_id);
1168 if (ret != SECURITY_MANAGER_SUCCESS) {
1169 ERR("Failed to set owner appid(%s) %d",
1170 req_data->app_id, ret);
1174 path_array = __convert_list_to_array(req_data->shared_file_list, &len);
1175 if (path_array == NULL) {
1176 ERR("path_array is null %d",
1177 g_list_length(req_data->shared_file_list));
1178 ret = SECURITY_MANAGER_ERROR_MEMORY;
1182 ret = security_manager_private_sharing_req_add_paths(handle,
1183 (const char **)path_array, len);
1184 if (ret != SECURITY_MANAGER_SUCCESS) {
1185 ERR("Failed to add paths %d", ret);
1189 iter = req_data->target_app_table;
1190 while(iter != NULL) {
1191 target_appid = (char *)iter->data;
1192 iter = g_list_next(iter);
1194 ret = security_manager_private_sharing_req_set_target_appid(
1195 handle, target_appid);
1196 if (ret != SECURITY_MANAGER_SUCCESS) {
1197 ERR("Failed to set target appid(%s)", target_appid);
1201 ret = security_manager_private_sharing_drop(handle);
1202 if (ret != SECURITY_MANAGER_SUCCESS) {
1203 ERR("Failed to drop %d", ret);
1207 req_data->target_app_table = g_list_remove(
1208 req_data->target_app_table, target_appid);
1215 security_manager_private_sharing_req_free(handle);
1220 if (ret != SECURITY_MANAGER_SUCCESS && req_data->drop_retry_count < MAX_RETRY_CNT) {
1221 ERR("drop_retry_count %d", req_data->drop_retry_count);
1225 if (req_data->dir != NULL) {
1226 iter = req_data->shared_file_list;
1227 for (; iter != NULL; iter = g_list_next(iter)) {
1228 dst_path = ((sharing_file_info_s *)(iter->data))->dst_path;
1229 if (strncmp(req_data->dir, dst_path, strlen(req_data->dir)) != 0)
1232 if (g_remove(dst_path) != 0)
1233 ERR("Failed [%s] [%d]", dst_path, errno);
1235 g_rmdir(req_data->dir);
1238 tmp_list = g_list_find_custom(__uid_list, GINT_TO_POINTER(req_data->uid),
1239 __comp_uid_info_list);
1241 if (tmp_list != NULL) {
1242 uid_info = tmp_list->data;
1243 uid_info->sharing_req_list = g_list_remove(
1244 uid_info->sharing_req_list, req_data);
1246 __free_req_info(req_data);
1251 EXPORT_API void notification_remove_private_sharing(
1252 const char *src_app_id, int priv_id, uid_t uid)
1254 sharing_req_data_s *req_data;
1255 uid_info_s *uid_info;
1257 GList *priv_id_info = NULL;
1258 GList *tmp_list = NULL;
1261 tmp_list = g_list_find_custom(__uid_list, GINT_TO_POINTER(uid),
1262 __comp_uid_info_list);
1263 if (tmp_list == NULL)
1266 uid_info = tmp_list->data;
1268 req_list = g_list_find_custom(uid_info->sharing_req_list, src_app_id,
1269 __comp_sharing_req_list);
1270 if (req_list == NULL)
1273 req_data = (sharing_req_data_s *)req_list->data;
1275 priv_id_info = g_list_find_custom(req_data->priv_id_list,
1276 GINT_TO_POINTER(priv_id), __comp_priv_id);
1277 if (priv_id_info == NULL)
1280 req_data->priv_id_list = g_list_remove(req_data->priv_id_list,
1281 priv_id_info->data);
1282 len = g_list_length(req_data->priv_id_list);
1286 if (req_data->timer > 0)
1287 g_source_remove(req_data->timer);
1289 req_data->timer = g_timeout_add(MAX_TIMEOUT, __timeout_handler, req_data);
1290 req_data->drop_retry_count = 0;
1291 if (req_data->timer == 0) {
1292 ERR("Failed to add timer");
1293 __timeout_handler(req_data);
1297 /* LCOV_EXCL_STOP */