From: Ilho Kim Date: Wed, 13 Jan 2021 08:05:48 +0000 (+0900) Subject: Add rpk package handling logic X-Git-Tag: submit/tizen/20210617.070222~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=564f51a425120c3e25b46b09fd1d2c5598d8e6ca;p=platform%2Fcore%2Fappfw%2Famd.git Add rpk package handling logic When launching an app with res-control find an appropriate resource package and set the path of the resource package to be mounted in bundle Requires: - https://review.tizen.org/gerrit/#/c/platform/core/appfw/pkgmgr-info/+/251170/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/aul-1/+/253786/ Change-Id: I482451534de7f23fcd399c02a2e8a4128f6df6cf Signed-off-by: Ilho Kim --- diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index a0a6b5ab..258b144f 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -12,6 +12,8 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/common LIB_COMMON_SRCS) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/lifecycle LIB_LIFECYCLE_SRCS) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/res_info + LIB_RES_INFO_SRCS) ADD_LIBRARY(${TARGET_LIB_AMD} SHARED ${LIB_SRCS} @@ -21,6 +23,7 @@ ADD_LIBRARY(${TARGET_LIB_AMD} SHARED ${LIB_APP_INFO_SRCS} ${LIB_COMMON_SRCS} ${LIB_LIFECYCLE_SRCS} + ${LIB_RES_INFO_SRCS} ) SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES SOVERSION ${MAJORVER}) SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES VERSION ${FULLVER}) diff --git a/src/lib/amd_appinfo.c b/src/lib/amd_appinfo.c index f3eec56d..f8852b8d 100644 --- a/src/lib/amd_appinfo.c +++ b/src/lib/amd_appinfo.c @@ -1186,8 +1186,10 @@ static struct user_appinfo *__add_user_appinfo(uid_t uid) g_hash_table_insert(user_tbl, GINT_TO_POINTER(uid), info); - option = PMINFO_APPINFO_GET_CATEGORY | PMINFO_APPINFO_GET_APP_CONTROL | - PMINFO_APPINFO_GET_SPLASH_SCREEN; + option = PMINFO_APPINFO_GET_CATEGORY | + PMINFO_APPINFO_GET_APP_CONTROL | + PMINFO_APPINFO_GET_SPLASH_SCREEN | + PMINFO_APPINFO_GET_RES_CONTROL; r = pkgmgrinfo_appinfo_get_usr_installed_list_full( __appinfo_insert_handler, uid, option, info); if (r != PMINFO_R_OK) { @@ -1576,8 +1578,11 @@ static int __package_event_cb(uid_t target_uid, int req_id, if (!strcasecmp(val, "uninstall") || !strcasecmp(val, "update") || - !strcasecmp(val, "move")) + !strcasecmp(val, "move")) { __set_blocking(&info); + _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_START, + target_uid, 0, (void *)pkgid, NULL); + } g_hash_table_insert(pkg_pending, strdup(pkgid), strdup(val)); } @@ -1870,8 +1875,10 @@ static void __reload_appinfo(gpointer key, gpointer value, gpointer user_data) g_hash_table_remove_all(info->tbl); - option = PMINFO_APPINFO_GET_CATEGORY | PMINFO_APPINFO_GET_APP_CONTROL | - PMINFO_APPINFO_GET_SPLASH_SCREEN; + option = PMINFO_APPINFO_GET_CATEGORY | + PMINFO_APPINFO_GET_APP_CONTROL | + PMINFO_APPINFO_GET_SPLASH_SCREEN | + PMINFO_APPINFO_GET_RES_CONTROL; r = pkgmgrinfo_appinfo_get_usr_installed_list_full( __appinfo_insert_handler, info->uid, option, info); if (r != PMINFO_R_OK) { diff --git a/src/lib/amd_launch.c b/src/lib/amd_launch.c index 72958b78..8d1f5b49 100644 --- a/src/lib/amd_launch.c +++ b/src/lib/amd_launch.c @@ -59,6 +59,7 @@ #include "amd_noti.h" #include "amd_proc.h" #include "amd_request.h" +#include "amd_res_info.h" #include "amd_signal.h" #include "amd_socket.h" #include "amd_suspend.h" @@ -2512,6 +2513,64 @@ static void __set_caller_appinfo(const char *caller_appid, int caller_pid, } } +static int __add_res_paths(GList *list, bundle *kb, const char *key) +{ + char **paths; + int len; + int i; + + bundle_del(kb, key); + + len = g_list_length(list); + if (!g_list_length(list)) + return 0; + + paths = calloc(len, sizeof(char *)); + if (!paths) { + _E("out of memory"); + return -1; + } + + for (i = 0; i < len; i++) + paths[i] = g_list_nth_data(list, i); + + bundle_add_str_array(kb, key, (const char **)paths, len); + free(paths); + + return 0; +} + +static int __set_res_packages_path(const char *appid, uid_t uid, bundle *kb) +{ + int r; + GList *allowed_path_list = NULL; + GList *global_path_list = NULL; + + if (_resinfo_get_res_package_paths(appid, uid, &allowed_path_list, + &global_path_list) < 0) { + _E("Fail to get res packages"); + return -1; + } + + r = __add_res_paths(allowed_path_list, kb, AUL_K_MOUNT_ALLOWED_RES_DIR); + if (r < 0) { + g_list_free_full(allowed_path_list, free); + g_list_free_full(global_path_list, free); + return -1; + } + r = __add_res_paths(global_path_list, kb, AUL_K_MOUNT_GLOBAL_RES_DIR); + if (r < 0) { + g_list_free_full(allowed_path_list, free); + g_list_free_full(global_path_list, free); + return -1; + } + + g_list_free_full(allowed_path_list, free); + g_list_free_full(global_path_list, free); + + return 0; +} + static const char *__get_caller_appid(int caller_pid, uid_t caller_uid) { app_status_h app_status; @@ -2992,6 +3051,12 @@ static int __prepare_starting_app(struct launch_s *handle, request_h req, } __set_caller_appinfo(caller_appid, caller_pid, caller_uid, kb); + ret = __set_res_packages_path(appid, target_uid, kb); + if (ret < 0) { + _E("Fail to set res package path"); + return ret; + } + ret = __compare_signature(handle->ai, cmd, target_uid, appid, caller_appid); if (ret < 0) diff --git a/src/lib/amd_main.c b/src/lib/amd_main.c index d6031f4a..e89e3c19 100644 --- a/src/lib/amd_main.c +++ b/src/lib/amd_main.c @@ -53,6 +53,7 @@ #include "amd_main.h" #include "amd_noti.h" #include "amd_request.h" +#include "amd_res_info.h" #include "amd_signal.h" #include "amd_socket.h" #include "amd_suspend.h" @@ -336,6 +337,7 @@ static int __init(void) _noti_init(); _compinfo_init(); _direct_launch_init(); + _resinfo_init(); if (_appinfo_init()) { _E("_appinfo_init failed"); return -1; diff --git a/src/lib/amd_res_info.cc b/src/lib/amd_res_info.cc new file mode 100644 index 00000000..0af59f95 --- /dev/null +++ b/src/lib/amd_res_info.cc @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "lib/amd_login_monitor.h" +#include "lib/amd_noti.h" +#include "lib/amd_res_info.h" +#include "lib/amd_util.h" +#include "lib/res_info/res_app_info.hh" +#include "lib/res_info/res_info.hh" +#include "lib/res_info/res_info_manager.hh" +#include "lib/res_info/res_pkg_info.hh" + +using namespace amd; + +static int __on_login_monitor_login_start(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + uid_t uid = (uid_t)arg1; + ResInfoManager& manager = ResInfoManager::GetInst(); + + if (manager.IsUserExist(uid)) + return NOTI_CONTINUE; + + if (!manager.CreateNewUser(uid)) + _E("Fail to create new user"); + + return NOTI_CONTINUE; +} + +static int __on_login_monitor_logout(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + ResInfoManager& manager = ResInfoManager::GetInst(); + manager.RemoveUserResInfo((uid_t)arg1); + + return NOTI_CONTINUE; +} + +static int __on_appinfo_insert(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + pkgmgrinfo_appinfo_h handle = (pkgmgrinfo_appinfo_h)arg3; + uid_t uid = (uid_t)arg1; + int res_control_cnt = 0; + + if (pkgmgrinfo_appinfo_foreach_res_control(handle, + [](const char*, const char*, const char*, + const char*, void* user_data) -> int { + int* cnt = reinterpret_cast(user_data); + (*cnt)++; + + return 0; + }, &res_control_cnt) != PMINFO_R_OK) + return NOTI_CONTINUE; + + if (!res_control_cnt) + return NOTI_CONTINUE; + + ResInfoManager& manager = ResInfoManager::GetInst(); + + manager.AddUserResAppInfo(handle, uid); + + return NOTI_CONTINUE; +} + +static int __on_appinfo_remove(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + uid_t uid = (uid_t)arg1; + char* appid = reinterpret_cast(arg3); + ResInfoManager& manager = ResInfoManager::GetInst(); + + manager.RemoveUserResAppInfo(appid, uid); + std::shared_ptr resinfo = manager.GetUserResInfo(uid); + if (!resinfo) + return NOTI_CONTINUE; + + resinfo->DeleteAppInfo(appid); + + return NOTI_CONTINUE; +} + +static int __on_package_update_start(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + uid_t uid = (uid_t)arg1; + uid_t* uids = NULL; + char* pkgid = reinterpret_cast(arg3); + int r; + ResInfoManager& manager = ResInfoManager::GetInst(); + + if (uid < REGULAR_UID_MIN) { + r = _login_monitor_get_uids(&uids); + if (r <= 0) + return NOTI_CONTINUE; + + for (int i = 0; i < r; i++) { + std::shared_ptr res_pkginfo = + manager.GetUserResPkgInfo(pkgid, uids[i]); + if (!res_pkginfo) + continue; + + res_pkginfo->SetBlocking(); + } + free(uids); + return NOTI_CONTINUE; + } + + std::shared_ptr res_pkginfo = + manager.GetUserResPkgInfo(pkgid, uid); + if (!res_pkginfo) + return NOTI_CONTINUE; + + res_pkginfo->SetBlocking(); + + return NOTI_CONTINUE; +} + +static int __on_package_uninstall_end(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + uid_t uid = (uid_t)arg1; + uid_t* uids = NULL; + char* pkgid = reinterpret_cast(arg3); + int r; + ResInfoManager& manager = ResInfoManager::GetInst(); + + if (uid < REGULAR_UID_MIN) { + r = _login_monitor_get_uids(&uids); + if (r <= 0) + return NOTI_CONTINUE; + + for (int i = 0; i < r; i++) + manager.RemoveUserResPkgInfo(pkgid, uids[i]); + + free(uids); + return NOTI_CONTINUE; + } + + manager.RemoveUserResPkgInfo(pkgid, uid); + + return NOTI_CONTINUE; +} + +static int __on_package_install_end(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + int r; + uid_t uid = (uid_t)arg1; + uid_t* uids = NULL; + char* pkgid = reinterpret_cast(arg3); + ResInfoManager& manager = ResInfoManager::GetInst(); + + if (uid < REGULAR_UID_MIN) { + r = _login_monitor_get_uids(&uids); + if (r <= 0) + return NOTI_CONTINUE; + + for (int i = 0; i < r; i++) + manager.AddUserResPkgInfo(pkgid, uids[i]); + + free(uids); + return NOTI_CONTINUE; + } + + manager.AddUserResPkgInfo(pkgid, uid); + + return NOTI_CONTINUE; +} + +static int __on_package_update_end(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + int r; + uid_t uid = (uid_t)arg1; + uid_t* uids = NULL; + char* pkgid = reinterpret_cast(arg3); + ResInfoManager& manager = ResInfoManager::GetInst(); + + if (uid < REGULAR_UID_MIN) { + r = _login_monitor_get_uids(&uids); + if (r <= 0) + return NOTI_CONTINUE; + + for (int i = 0; i < r; i++) { + if (!manager.RemoveUserResPkgInfo(pkgid, uids[i])) + continue; + + manager.AddUserResPkgInfo(pkgid, uids[i]); + } + + free(uids); + + return NOTI_CONTINUE; + } + + if (!manager.RemoveUserResPkgInfo(pkgid, uid)) + return NOTI_CONTINUE; + + manager.AddUserResPkgInfo(pkgid, uid); + + return NOTI_CONTINUE; +} + +static int __on_package_update_error(const char* msg, int arg1, int arg2, + void* arg3, bundle* b) { + uid_t uid = (uid_t)arg1; + uid_t* uids = NULL; + char* pkgid = reinterpret_cast(arg3); + int r; + ResInfoManager& manager = ResInfoManager::GetInst(); + + if (uid < REGULAR_UID_MIN) { + r = _login_monitor_get_uids(&uids); + if (r <= 0) + return NOTI_CONTINUE; + + for (int i = 0; i < r; i++) { + std::shared_ptr res_pkginfo = + manager.GetUserResPkgInfo(pkgid, uids[i]); + if (!res_pkginfo) + continue; + + res_pkginfo->UnsetBlocking(); + } + free(uids); + return NOTI_CONTINUE; + } + + std::shared_ptr res_pkginfo = + manager.GetUserResPkgInfo(pkgid, uid); + if (!res_pkginfo) + return NOTI_CONTINUE; + + res_pkginfo->UnsetBlocking(); + + return NOTI_CONTINUE; +} + +int _resinfo_init(void) { + _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START, + __on_login_monitor_login_start); + _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT, + __on_login_monitor_logout); + _noti_listen(AMD_NOTI_MSG_APPINFO_INSERT, + __on_appinfo_insert); + _noti_listen(AMD_NOTI_MSG_APPINFO_REMOVE, + __on_appinfo_remove); + _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_START, + __on_package_update_start); + _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END, + __on_package_uninstall_end); + _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END, + __on_package_install_end); + _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END, + __on_package_update_end); + _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR, + __on_package_update_error); + + return 0; +} + +int _resinfo_get_res_package_paths(const char* appid, uid_t uid, + GList** allowed_paths, GList** global_paths) { + ResInfoManager& manager = ResInfoManager::GetInst(); + std::vector allowed_p, global_p; + + std::shared_ptr resinfo = manager.GetUserResInfo(uid); + if (!resinfo) + return -1; + + std::shared_ptr res_appinfo = resinfo->GetResAppInfo(appid); + if (!res_appinfo) + return 0; + + res_appinfo->ClearResControlMountInfo(); + res_appinfo->UpdateResControlMountInfo(resinfo->GetResPkgs()); + res_appinfo->GetMountPackagePaths(&allowed_p, &global_p); + + for (const std::string& root_path : allowed_p) { + std::string p = root_path + "/res/allowed/"; + *allowed_paths = g_list_append(*allowed_paths, strdup(p.c_str())); + } + + for (const std::string& root_path : global_p) { + std::string p = root_path + "/res/global/"; + *global_paths = g_list_append(*global_paths, strdup(p.c_str())); + } + + return 0; +} diff --git a/src/lib/amd_res_info.h b/src/lib/amd_res_info.h new file mode 100644 index 00000000..48be7b1c --- /dev/null +++ b/src/lib/amd_res_info.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AMD_RES_INFO_H__ +#define __AMD_RES_INFO_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int _resinfo_init(void); + +int _resinfo_get_res_package_paths(const char *appid, uid_t uid, + GList **allowed_paths, GList **global_paths); + +#ifdef __cplusplus +} +#endif + +#endif /* __AMD_RES_INFO_H__ */ diff --git a/src/lib/api/amd_api_noti_msg.h b/src/lib/api/amd_api_noti_msg.h index 8b97ad63..9fe74b97 100644 --- a/src/lib/api/amd_api_noti_msg.h +++ b/src/lib/api/amd_api_noti_msg.h @@ -971,6 +971,17 @@ extern "C" { #define AMD_NOTI_MSG_APP_STATUS_SET_REAL_PID \ "app_status.set_real_pid" +/** + * @brief Definition for the notification message: The package starts updating + * @details Input: arg1(uid_t) The user ID.\n + * Input: arg3(const char *) The package ID.\n + * @since_tizen 6.5 + * + * @see __package_event_cb() + */ +#define AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_START \ + "appinfo.package.update.start" + #ifdef __cplusplus } #endif diff --git a/src/lib/res_info/res_app_info.cc b/src/lib/res_info/res_app_info.cc new file mode 100644 index 00000000..c9a72731 --- /dev/null +++ b/src/lib/res_info/res_app_info.cc @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/common/log_private.hh" +#include "lib/res_info/res_app_info.hh" + +namespace amd { + +std::shared_ptr ResAppInfo::CreateResAppInfo( + const pkgmgrinfo_appinfo_h handle, uid_t uid) { + char* appid; + char* pkgid; + pkgmgrinfo_pkginfo_h p_handle; + std::vector res_control_list; + std::set privilege_set; + + if (pkgmgrinfo_appinfo_get_appid(handle, &appid) != PMINFO_R_OK) { + _E("Fail to get appid"); + return nullptr; + } + + if (pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid) != PMINFO_R_OK) + return nullptr; + + if (pkgmgrinfo_appinfo_foreach_res_control(handle, + [](const char* res_type, const char* min_res_version, + const char* max_res_version, const char* auto_close, + void* user_data) -> int { + if (!res_type) + return 0; + std::vector* res_control_list = + reinterpret_cast*>(user_data); + + res_control_list->emplace_back(res_type, + min_res_version ? min_res_version : "", + max_res_version ? max_res_version : "", + auto_close ? auto_close : ""); + + return 0; + }, &res_control_list) != PMINFO_R_OK) + return nullptr; + + if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, + uid, &p_handle) != PMINFO_R_OK) { + _E("Fail to get pkginfo pkgid : %s, uid : %d", pkgid, uid); + return nullptr; + } + + std::unique_ptr::type, + decltype(pkgmgrinfo_pkginfo_destroy_pkginfo)*>handle_auto( + p_handle, pkgmgrinfo_pkginfo_destroy_pkginfo); + + if (pkgmgrinfo_pkginfo_foreach_privilege(handle_auto.get(), + [](const char* privilege_name, void* user_data) -> int { + if (!privilege_name) + return 0; + + std::set* privilege_set = + reinterpret_cast*>(user_data); + privilege_set->insert(privilege_name); + + return 0; + }, &privilege_set) != PMINFO_R_OK) + return nullptr; + + return std::shared_ptr(new ResAppInfo(appid, + std::move(res_control_list), std::move(privilege_set))); +} + +const std::string& ResAppInfo::GetAppId() { + return appid_; +} + +void ResAppInfo::ClearResControlMountInfo() { + for (auto& res_control : res_control_list_) { + res_control.allowed_package.reset(); + res_control.global_package.reset(); + } +} + +void ResAppInfo::UpdateResControlMountInfo( + const std::map>& res_pkgs) { + for (const auto& it : res_pkgs) + UpdateResControlMountInfo(it.second); +} + +void ResAppInfo::UpdateResControlMountInfo( + std::shared_ptr res_pkginfo) { + if (res_pkginfo->IsBlocked()) + return; + + pkgmgrinfo_version_compare_type ver_comp; + + for (auto& res_control : res_control_list_) { + if (res_control.res_type != res_pkginfo->GetResType()) + continue; + + if (!res_control.min_res_version.empty()) { + if (pkgmgrinfo_compare_package_version( + res_control.min_res_version.c_str(), + res_pkginfo->GetResVersion().c_str(), + &ver_comp) != PMINFO_R_OK) + continue; + + if (ver_comp == PMINFO_VERSION_OLD) + continue; + } + + if (!res_control.max_res_version.empty()) { + if (pkgmgrinfo_compare_package_version( + res_pkginfo->GetResVersion().c_str(), + res_control.max_res_version.c_str(), + &ver_comp) != PMINFO_R_OK) + continue; + + if (ver_comp == PMINFO_VERSION_OLD) + continue; + } + + if (!res_control.global_package) { + res_control.global_package = res_pkginfo; + } else { + if (pkgmgrinfo_compare_package_version( + res_control.global_package->GetResVersion().c_str(), + res_pkginfo->GetResVersion().c_str(), + &ver_comp) != PMINFO_R_OK) + continue; + + if (ver_comp == PMINFO_VERSION_NEW) + res_control.global_package = res_pkginfo; + } + + if (!res_pkginfo->IsAllowedApp(appid_, privilege_set_)) + continue; + + if (!res_control.allowed_package) { + res_control.allowed_package = res_pkginfo; + } else { + if (pkgmgrinfo_compare_package_version( + res_control.allowed_package->GetResVersion().c_str(), + res_pkginfo->GetResVersion().c_str(), + &ver_comp) != PMINFO_R_OK) + continue; + + if (ver_comp == PMINFO_VERSION_NEW) + res_control.allowed_package = res_pkginfo; + } + } +} + +void ResAppInfo::GetMountPackagePaths(std::vector* allowed_paths, + std::vector* global_paths) { + for (const auto& res_control : res_control_list_) { + if (res_control.allowed_package) + allowed_paths->push_back(res_control.allowed_package->GetRootPath()); + if (res_control.global_package) + global_paths->push_back(res_control.global_package->GetRootPath()); + } +} + +} // namespace amd diff --git a/src/lib/res_info/res_app_info.hh b/src/lib/res_info/res_app_info.hh new file mode 100644 index 00000000..5af5a58c --- /dev/null +++ b/src/lib/res_info/res_app_info.hh @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_RES_INFO_RES_APP_INFO_HH_ +#define LIB_RES_INFO_RES_APP_INFO_HH_ + +#include + +#include +#include +#include +#include +#include + +#include "res_pkg_info.hh" + +namespace amd { + +class ResAppInfo; + +struct ResControl { + public: + ResControl(std::string res_type, std::string min_res_version, + std::string max_res_version, std::string auto_close) + : res_type(std::move(res_type)), + min_res_version(std::move(min_res_version)), + max_res_version(std::move(max_res_version)), + auto_close(std::move(auto_close)), + allowed_package(nullptr), + global_package(nullptr) {} + + private: + std::string res_type; + std::string min_res_version; + std::string max_res_version; + std::string auto_close; + std::shared_ptr allowed_package; + std::shared_ptr global_package; + + friend class ResAppInfo; +}; + +class ResAppInfo { + public: + static std::shared_ptr CreateResAppInfo( + const pkgmgrinfo_appinfo_h handle, uid_t uid); + + const std::string& GetAppId(); + void ClearResControlMountInfo(); + void UpdateResControlMountInfo( + const std::map>& res_pkgs); + void UpdateResControlMountInfo(std::shared_ptr res_pkginfo); + void GetMountPackagePaths(std::vector* allowed_paths, + std::vector* global_paths); + + private: + ResAppInfo(std::string appid, + std::vector res_control_list, + std::set privilege_set) + : appid_(std::move(appid)), + res_control_list_(std::move(res_control_list)), + privilege_set_(std::move(privilege_set)) {} + + std::string appid_; + std::vector res_control_list_; + std::set privilege_set_; +}; + +} // namespace amd + +#endif // LIB_RES_INFO_RES_APP_INFO_HH_ diff --git a/src/lib/res_info/res_info.cc b/src/lib/res_info/res_info.cc new file mode 100644 index 00000000..04cd12aa --- /dev/null +++ b/src/lib/res_info/res_info.cc @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/common/log_private.hh" +#include "lib/res_info/res_app_info.hh" +#include "lib/res_info/res_info.hh" + +namespace amd { + +std::shared_ptr ResInfo::GetResAppInfo(const std::string& appid) { + if (!res_appinfo_.count(appid)) + return nullptr; + + return res_appinfo_.at(appid); +} + +std::shared_ptr ResInfo::GetResPkgInfo(const std::string& pkgid) { + if (!res_pkginfo_.count(pkgid)) + return nullptr; + + return res_pkginfo_.at(pkgid); +} + +void ResInfo::InsertAppInfo(std::shared_ptr res_appinfo) { + res_appinfo_[res_appinfo->GetAppId()] = std::move(res_appinfo); +} + +void ResInfo::InsertPkgInfo(std::shared_ptr res_pkginfo) { + res_pkginfo_[res_pkginfo->GetPkgId()] = std::move(res_pkginfo); +} + +bool ResInfo::DeleteAppInfo(const std::string& appid) { + if (!res_appinfo_.count(appid)) + return false; + + res_appinfo_.erase(appid); + + return true; +} + +bool ResInfo::DeletePkgInfo(const std::string& pkgid) { + if (!res_pkginfo_.count(pkgid)) + return false; + + res_pkginfo_.erase(pkgid); + + return true; +} + +const std::map>& + ResInfo::GetResPkgs() { + return res_pkginfo_; +} + +bool ResInfo::ResPkgInit() { + pkgmgrinfo_pkginfo_filter_h filter; + + if (pkgmgrinfo_pkginfo_filter_create(&filter) != PMINFO_R_OK) { + _E("out of memory"); + return false; + } + + std::unique_ptr::type, + decltype(pkgmgrinfo_pkginfo_filter_destroy)*>handle_auto( + filter, pkgmgrinfo_pkginfo_filter_destroy); + + if (pkgmgrinfo_pkginfo_filter_add_string(handle_auto.get(), + PMINFO_PKGINFO_PROP_PACKAGE_RES_TYPE, "") != PMINFO_R_OK) { + _E("pkgmgrinfo_pkginfo_filter_add_string() failed"); + return false; + } + + if (pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle_auto.get(), + [](const pkgmgrinfo_pkginfo_h handle, void* data) -> int { + ResInfo* resinfo = reinterpret_cast(data); + + std::shared_ptr res_pkg_info = + ResPkgInfo::CreateResPkgInfo(handle); + if (!res_pkg_info) + return 0; + + resinfo->InsertPkgInfo(std::move(res_pkg_info)); + + return 0; + }, this, uid_) != PMINFO_R_OK) { + _E("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo() failed"); + return false; + } + + return true; +} + +} // namespace amd diff --git a/src/lib/res_info/res_info.hh b/src/lib/res_info/res_info.hh new file mode 100644 index 00000000..a8c8b85a --- /dev/null +++ b/src/lib/res_info/res_info.hh @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_RES_INFO_RES_INFO_HH_ +#define LIB_RES_INFO_RES_INFO_HH_ + +#include +#include +#include + +#include "lib/res_info/res_app_info.hh" +#include "lib/res_info/res_pkg_info.hh" + +namespace amd { + +class ResInfo { + public: + explicit ResInfo(uid_t uid) : uid_(uid) {} + std::shared_ptr GetResAppInfo(const std::string& appid); + std::shared_ptr GetResPkgInfo(const std::string& pkgid); + bool ResPkgInit(); + void InsertAppInfo(std::shared_ptr res_appinfo); + void InsertPkgInfo(std::shared_ptr res_pkginfo); + bool DeleteAppInfo(const std::string& appid); + bool DeletePkgInfo(const std::string& pkgid); + const std::map>& GetResPkgs(); + + private: + uid_t uid_; + std::map> res_pkginfo_; + std::map> res_appinfo_; +}; + +} // namespace amd + +#endif // LIB_RES_INFO_RES_INFO_HH_ diff --git a/src/lib/res_info/res_info_manager.cc b/src/lib/res_info/res_info_manager.cc new file mode 100644 index 00000000..5fa51635 --- /dev/null +++ b/src/lib/res_info/res_info_manager.cc @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/common/log_private.hh" +#include "lib/res_info/res_info_manager.hh" +#include "lib/res_info/res_info.hh" + +namespace amd { + +bool ResInfoManager::CreateNewUser(uid_t uid) { + auto resinfo = std::make_shared(uid); + if (!resinfo->ResPkgInit()) { + _E("Failed to initialize res pkg info for uid(%d)", uid); + return false; + } + + resinfo_map_[uid] = std::move(resinfo); + + return true; +} + +bool ResInfoManager::IsUserExist(uid_t uid) { + if (!resinfo_map_.count(uid)) + return false; + + return true; +} + +std::shared_ptr ResInfoManager::GetUserResInfo(uid_t uid) { + if (!resinfo_map_.count(uid)) + return nullptr; + + return resinfo_map_.at(uid); +} + +std::shared_ptr ResInfoManager::GetUserResAppInfo( + const std::string& appid, uid_t uid) { + std::shared_ptr resinfo = GetUserResInfo(uid); + if (!resinfo) + return nullptr; + + return resinfo->GetResAppInfo(appid); +} + +std::shared_ptr ResInfoManager::GetUserResPkgInfo( + const std::string& pkgid, uid_t uid) { + std::shared_ptr resinfo = GetUserResInfo(uid); + if (!resinfo) + return nullptr; + + return resinfo->GetResPkgInfo(pkgid); +} + +void ResInfoManager::RemoveUserResInfo(uid_t uid) { + resinfo_map_.erase(uid); +} + +bool ResInfoManager::RemoveUserResPkgInfo(std::string pkgid, uid_t uid) { + std::shared_ptr resinfo = GetUserResInfo(uid); + if (!resinfo) + return false; + + return resinfo->DeletePkgInfo(pkgid); +} + +bool ResInfoManager::AddUserResPkgInfo(std::string pkgid, uid_t uid) { + std::shared_ptr resinfo = GetUserResInfo(uid); + if (!resinfo) + return false; + + std::shared_ptr res_pkginfo = + ResPkgInfo::CreateResPkgInfo(pkgid, uid); + if (!res_pkginfo) + return false; + + resinfo->InsertPkgInfo(std::move(res_pkginfo)); + + return true; +} + +bool ResInfoManager::AddUserResAppInfo( + pkgmgrinfo_appinfo_h handle, uid_t uid) { + std::shared_ptr resinfo = GetUserResInfo(uid); + if (!resinfo) + return false; + + std::shared_ptr res_appinfo = + ResAppInfo::CreateResAppInfo(handle, uid); + if (!res_appinfo) + return false; + + resinfo->InsertAppInfo(std::move(res_appinfo)); + + return true; +} + +bool ResInfoManager::RemoveUserResAppInfo(std::string appid, uid_t uid) { + std::shared_ptr resinfo = GetUserResInfo(uid); + if (!resinfo) + return false; + + resinfo->DeleteAppInfo(appid); + + return true; +} + +} // namespace amd diff --git a/src/lib/res_info/res_info_manager.hh b/src/lib/res_info/res_info_manager.hh new file mode 100644 index 00000000..15cf9d48 --- /dev/null +++ b/src/lib/res_info/res_info_manager.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_RES_INFO_RES_INFO_MANAGER_HH_ +#define LIB_RES_INFO_RES_INFO_MANAGER_HH_ + +#include + +#include +#include + +#include "lib/res_info/res_info.hh" + +namespace amd { + +class ResInfoManager { + private: + ResInfoManager() = default; + ~ResInfoManager() = default; + + public: + static ResInfoManager& GetInst() { + static ResInfoManager inst; + return inst; + } + + bool CreateNewUser(uid_t uid); + bool IsUserExist(uid_t uid); + std::shared_ptr GetUserResInfo(uid_t uid); + std::shared_ptr GetUserResAppInfo( + const std::string& appid, uid_t uid); + std::shared_ptr GetUserResPkgInfo( + const std::string& pkgid, uid_t uid); + void RemoveUserResInfo(uid_t uid); + bool RemoveUserResPkgInfo(std::string pkgid, uid_t uid); + bool AddUserResPkgInfo(std::string pkgid, uid_t uid); + bool AddUserResAppInfo(pkgmgrinfo_appinfo_h handle, uid_t uid); + bool RemoveUserResAppInfo(std::string appid, uid_t uid); + + private: + std::map> resinfo_map_; +}; + +} // namespace amd + +#endif // LIB_RES_INFO_RES_INFO_MANAGER_HH_ diff --git a/src/lib/res_info/res_pkg_info.cc b/src/lib/res_info/res_pkg_info.cc new file mode 100644 index 00000000..9984b324 --- /dev/null +++ b/src/lib/res_info/res_pkg_info.cc @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/res_info/res_app_info.hh" +#include "lib/common/log_private.hh" + +namespace amd { + +const std::string& ResPkgInfo::GetPkgId() { + return pkgid_; +} + +const std::string& ResPkgInfo::GetResType() { + return res_type_; +} + +const std::string& ResPkgInfo::GetResVersion() { + return res_version_; +} + +const std::string& ResPkgInfo::GetRootPath() { + return root_path_; +} + +bool ResPkgInfo::IsBlocked() { + return is_blocked_; +} + +bool ResPkgInfo::IsAllowedApp(const std::string& appid, + const std::set& app_priv) { + if (!allowed_pkg_priv_map_.count(appid)) + return false; + + for (const std::string& required_priv : allowed_pkg_priv_map_[appid]) { + if (!app_priv.count(required_priv)) + return false; + } + + return true; +} + +void ResPkgInfo::SetBlocking() { + is_blocked_ = true; +} + +void ResPkgInfo::UnsetBlocking() { + is_blocked_ = false; +} + +std::shared_ptr ResPkgInfo::CreateResPkgInfo( + const pkgmgrinfo_pkginfo_h handle) { + char* pkgid; + char* res_type; + char* res_version; + char* root_path; + AllowedPkgPrivMap allowed_pkg_priv_map; + + if (pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid) != PMINFO_R_OK) + return nullptr; + + if (pkgmgrinfo_pkginfo_get_res_type(handle, &res_type) != PMINFO_R_OK) + return nullptr; + + if (pkgmgrinfo_pkginfo_get_res_version(handle, &res_version) != PMINFO_R_OK) + return nullptr; + + if (pkgmgrinfo_pkginfo_get_root_path(handle, &root_path) != PMINFO_R_OK) + return nullptr; + + if (pkgmgrinfo_pkginfo_foreach_res_allowed_package(handle, + [](const char* allowed_package, required_privilege_h privilege_handle, + void* user_data) -> int { + if (!allowed_package) + return 0; + + AllowedPkgPrivMap* allowed_pkg_priv_map = + reinterpret_cast(user_data); + + std::set priv_set; + + if (pkgmgrinfo_pkginfo_foreach_required_privilege(privilege_handle, + [](const char* privilege_name, void* user_data) -> int { + if (!privilege_name) + return 0; + + auto priv_set = + reinterpret_cast*>(user_data); + priv_set->insert(privilege_name); + + return 0; + }, &priv_set) != PMINFO_R_OK) + return 0; + + (*allowed_pkg_priv_map)[allowed_package] = std::move(priv_set); + return 0; + }, &allowed_pkg_priv_map) != PMINFO_R_OK) + return nullptr; + + return std::shared_ptr(new ResPkgInfo(pkgid, res_type, + res_version, root_path, std::move(allowed_pkg_priv_map))); +} + +std::shared_ptr ResPkgInfo::CreateResPkgInfo( + const std::string pkgid, uid_t uid) { + pkgmgrinfo_pkginfo_h handle; + + if (pkgmgrinfo_pkginfo_get_usr_pkginfo( + pkgid.c_str(), uid, &handle) != PMINFO_R_OK) + return nullptr; + + std::unique_ptr::type, + decltype(pkgmgrinfo_pkginfo_destroy_pkginfo)*>handle_auto( + handle, pkgmgrinfo_pkginfo_destroy_pkginfo); + + std::shared_ptr res_pkginfo = CreateResPkgInfo(handle_auto.get()); + + return res_pkginfo; +} + +} // namespace amd diff --git a/src/lib/res_info/res_pkg_info.hh b/src/lib/res_info/res_pkg_info.hh new file mode 100644 index 00000000..afa82c8a --- /dev/null +++ b/src/lib/res_info/res_pkg_info.hh @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_RES_INFO_RES_PKG_INFO_HH_ +#define LIB_RES_INFO_RES_PKG_INFO_HH_ + +#include + +#include +#include +#include + +using AllowedPkgPrivMap = std::map>; + +namespace amd { + +class ResPkgInfo { + public: + static std::shared_ptr CreateResPkgInfo( + const pkgmgrinfo_pkginfo_h handle); + static std::shared_ptr CreateResPkgInfo( + const std::string pkgid, uid_t uid); + + const std::string& GetPkgId(); + const std::string& GetResType(); + const std::string& GetResVersion(); + const std::string& GetRootPath(); + bool IsBlocked(); + bool IsAllowedApp(const std::string& appid, + const std::set& app_priv); + void SetBlocking(); + void UnsetBlocking(); + + private: + ResPkgInfo(std::string pkgid, std::string res_type, std::string res_version, + std::string root_path, AllowedPkgPrivMap priv_map) + : pkgid_(std::move(pkgid)), + res_type_(std::move(res_type)), + res_version_(std::move(res_version)), + root_path_(std::move(root_path)), + allowed_pkg_priv_map_(std::move(priv_map)), + is_blocked_(false) {} + + std::string pkgid_; + std::string res_type_; + std::string res_version_; + std::string root_path_; + AllowedPkgPrivMap allowed_pkg_priv_map_; + bool is_blocked_; +}; + +} // namespace amd + +#endif // LIB_RES_INFO_RES_PKG_INFO_HH_