1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "uri_permission_utils.h" 17 18#include "ability_manager_errors.h" 19#include "accesstoken_kit.h" 20#include "bundle_mgr_client.h" 21#include "global_constant.h" 22#include "hilog_tag_wrapper.h" 23#include "in_process_call_wrapper.h" 24#include "ipc_skeleton.h" 25#include "os_account_manager_wrapper.h" 26#include "permission_verification.h" 27#include "tokenid_kit.h" 28 29namespace OHOS { 30namespace AAFwk { 31namespace { 32constexpr int32_t DEFAULT_USER_ID = 0; 33constexpr const char* FOUNDATION_PROCESS_NAME = "foundation"; 34constexpr const char* NET_WORK_ID_MARK = "?networkid="; 35} 36 37std::shared_ptr<AppExecFwk::BundleMgrHelper> UPMSUtils::ConnectManagerHelper() 38{ 39 if (bundleMgrHelper_ == nullptr) { 40 bundleMgrHelper_ = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance(); 41 } 42 return bundleMgrHelper_; 43} 44 45bool UPMSUtils::SendShareUnPrivilegeUriEvent(uint32_t callerTokenId, uint32_t targetTokenId) 46{ 47 std::string callerBundleName; 48 if (!GetBundleNameByTokenId(callerTokenId, callerBundleName)) { 49 return false; 50 } 51 std::string targetBundleName; 52 if (!GetBundleNameByTokenId(targetTokenId, targetBundleName)) { 53 return false; 54 } 55 AAFwk::EventInfo eventInfo; 56 eventInfo.callerBundleName = callerBundleName; 57 eventInfo.bundleName = targetBundleName; 58 TAG_LOGD(AAFwkTag::URIPERMMGR, "Send SHARE_UNPRIVILEGED_FILE_URI Event"); 59 AAFwk::EventReport::SendGrantUriPermissionEvent(AAFwk::EventName::SHARE_UNPRIVILEGED_FILE_URI, eventInfo); 60 return true; 61} 62 63bool UPMSUtils::SendSystemAppGrantUriPermissionEvent(uint32_t callerTokenId, uint32_t targetTokenId, 64 const std::vector<std::string> &uriVec, const std::vector<int32_t> &resVec) 65{ 66 EventInfo eventInfo; 67 if (!CheckAndCreateEventInfo(callerTokenId, targetTokenId, eventInfo)) { 68 return false; 69 } 70 for (size_t i = 0; i < resVec.size(); i++) { 71 if (resVec[i] == 0 || resVec[i] == -EEXIST) { 72 eventInfo.uri = uriVec[i]; 73 EventReport::SendGrantUriPermissionEvent(EventName::GRANT_URI_PERMISSION, eventInfo); 74 } 75 } 76 TAG_LOGD(AAFwkTag::URIPERMMGR, "Send GRANT_URI_PERMISSION Event"); 77 return true; 78} 79 80bool UPMSUtils::CheckAndCreateEventInfo(uint32_t callerTokenId, uint32_t targetTokenId, 81 EventInfo &eventInfo) 82{ 83 std::string callerBundleName; 84 if (!GetBundleNameByTokenId(callerTokenId, callerBundleName)) { 85 TAG_LOGD(AAFwkTag::URIPERMMGR, "get callerBundleName failed"); 86 return false; 87 } 88 if (!CheckIsSystemAppByBundleName(callerBundleName)) { 89 TAG_LOGD(AAFwkTag::URIPERMMGR, "caller not system"); 90 return false; 91 } 92 std::string targetBundleName; 93 if (!GetBundleNameByTokenId(targetTokenId, targetBundleName)) { 94 TAG_LOGD(AAFwkTag::URIPERMMGR, "get targetBundleName failed"); 95 return false; 96 } 97 if (CheckIsSystemAppByBundleName(targetBundleName)) { 98 TAG_LOGD(AAFwkTag::URIPERMMGR, "target is systemApp"); 99 return false; 100 } 101 eventInfo.callerBundleName = callerBundleName; 102 eventInfo.bundleName = targetBundleName; 103 return true; 104} 105 106int32_t UPMSUtils::GetCurrentAccountId() 107{ 108 std::vector<int32_t> osActiveAccountIds; 109 auto ret = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()-> 110 QueryActiveOsAccountIds(osActiveAccountIds); 111 if (ret != ERR_OK) { 112 TAG_LOGE(AAFwkTag::URIPERMMGR, "QueryActiveOsAccountIds error"); 113 return DEFAULT_USER_ID; 114 } 115 if (osActiveAccountIds.empty()) { 116 TAG_LOGE(AAFwkTag::URIPERMMGR, "QueryActiveOsAccountIds empty"); 117 return DEFAULT_USER_ID; 118 } 119 return osActiveAccountIds.front(); 120} 121 122bool UPMSUtils::IsFoundationCall() 123{ 124 auto callerTokenId = IPCSkeleton::GetCallingTokenID(); 125 TAG_LOGD(AAFwkTag::ABILITYMGR, "callerTokenId is %{public}u", callerTokenId); 126 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerTokenId); 127 if (tokenType != Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) { 128 TAG_LOGI(AAFwkTag::ABILITYMGR, "not native call"); 129 return false; 130 } 131 Security::AccessToken::NativeTokenInfo nativeInfo; 132 auto result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(callerTokenId, nativeInfo); 133 if (result != ERR_OK) { 134 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetNativeTokenInfo failed, callerTokenId:%{public}u", callerTokenId); 135 return false; 136 } 137 TAG_LOGD(AAFwkTag::URIPERMMGR, "Caller processName:%{public}s", nativeInfo.processName.c_str()); 138 return nativeInfo.processName == FOUNDATION_PROCESS_NAME; 139} 140 141bool UPMSUtils::IsSAOrSystemAppCall() 142{ 143 return PermissionVerification::GetInstance()->IsSystemAppCall() || 144 PermissionVerification::GetInstance()->IsSACall(); 145} 146 147bool UPMSUtils::IsSystemAppCall(uint32_t tokenId) 148{ 149 if (UPMSUtils::IsFoundationCall()) { 150 return UPMSUtils::CheckIsSystemAppByTokenId(tokenId); 151 } 152 return PermissionVerification::GetInstance()->IsSystemAppCall(); 153} 154 155bool UPMSUtils::CheckIsSystemAppByBundleName(std::string &bundleName) 156{ 157 auto bundleMgrHelper = ConnectManagerHelper(); 158 if (bundleMgrHelper == nullptr) { 159 TAG_LOGW(AAFwkTag::URIPERMMGR, "bundleMgrHelper null"); 160 return false; 161 } 162 AppExecFwk::ApplicationInfo appInfo; 163 if (!IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(bundleName, 164 AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, GetCurrentAccountId(), appInfo))) { 165 TAG_LOGW(AAFwkTag::URIPERMMGR, "GetApplicationInfo failed"); 166 return false; 167 } 168 auto isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(appInfo.accessTokenIdEx); 169 TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName:%{public}s, isSystemApp:%{public}d", bundleName.c_str(), 170 static_cast<int32_t>(isSystemApp)); 171 return isSystemApp; 172} 173 174bool UPMSUtils::CheckIsSystemAppByTokenId(uint32_t tokenId) 175{ 176 std::string bundleName; 177 if (GetBundleNameByTokenId(tokenId, bundleName)) { 178 return CheckIsSystemAppByBundleName(bundleName); 179 } 180 return false; 181} 182 183bool UPMSUtils::GetDirByBundleNameAndAppIndex(const std::string &bundleName, int32_t appIndex, std::string &dirName) 184{ 185 auto bmsClient = DelayedSingleton<AppExecFwk::BundleMgrClient>::GetInstance(); 186 if (bmsClient == nullptr) { 187 TAG_LOGE(AAFwkTag::URIPERMMGR, "bundleMgrClient is nullptr."); 188 return false; 189 } 190 auto bmsRet = bmsClient->GetDirByBundleNameAndAppIndex(bundleName, appIndex, dirName); 191 if (bmsRet != ERR_OK) { 192 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetDirByBundleNameAndAppIndex failed, ret:%{public}d", bmsRet); 193 return false; 194 } 195 return true; 196} 197 198bool UPMSUtils::GetAlterableBundleNameByTokenId(uint32_t tokenId, std::string &bundleName) 199{ 200 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); 201 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) { 202 Security::AccessToken::HapTokenInfo hapInfo; 203 auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo); 204 if (ret != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { 205 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetHapTokenInfo failed, ret:%{public}d", ret); 206 return false; 207 } 208 return GetDirByBundleNameAndAppIndex(hapInfo.bundleName, hapInfo.instIndex, bundleName); 209 } 210 return false; 211} 212 213bool UPMSUtils::GetBundleNameByTokenId(uint32_t tokenId, std::string &bundleName) 214{ 215 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); 216 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) { 217 Security::AccessToken::HapTokenInfo hapInfo; 218 auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo); 219 if (ret != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { 220 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetHapTokenInfo failed, ret:%{public}d", ret); 221 return false; 222 } 223 bundleName = hapInfo.bundleName; 224 return true; 225 } 226 return false; 227} 228 229int32_t UPMSUtils::GetAppIdByBundleName(const std::string &bundleName, std::string &appId) 230{ 231 TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName is %{public}s.", bundleName.c_str()); 232 auto bms = ConnectManagerHelper(); 233 if (bms == nullptr) { 234 TAG_LOGW(AAFwkTag::URIPERMMGR, "The bundleMgrHelper is nullptr."); 235 return GET_BUNDLE_MANAGER_SERVICE_FAILED; 236 } 237 auto userId = GetCurrentAccountId(); 238 appId = IN_PROCESS_CALL(bms->GetAppIdByBundleName(bundleName, userId)); 239 if (appId.empty()) { 240 TAG_LOGW(AAFwkTag::URIPERMMGR, "Get appId by bundle name failed, userId is %{private}d", userId); 241 return INNER_ERR; 242 } 243 return ERR_OK; 244} 245 246int32_t UPMSUtils::GetTokenIdByBundleName(const std::string &bundleName, int32_t appIndex, uint32_t &tokenId) 247{ 248 TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName:%{public}s, appIndex:%{public}d", bundleName.c_str(), appIndex); 249 auto bms = ConnectManagerHelper(); 250 if (bms == nullptr) { 251 TAG_LOGW(AAFwkTag::URIPERMMGR, "null bms"); 252 return GET_BUNDLE_MANAGER_SERVICE_FAILED; 253 } 254 AppExecFwk::BundleInfo bundleInfo; 255 auto userId = GetCurrentAccountId(); 256 if (appIndex == 0) { 257 auto bundleFlag = AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO; 258 if (!IN_PROCESS_CALL(bms->GetBundleInfo(bundleName, bundleFlag, bundleInfo, userId))) { 259 TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetBundleInfo"); 260 return GET_BUNDLE_INFO_FAILED; 261 } 262 tokenId = bundleInfo.applicationInfo.accessTokenId; 263 return ERR_OK; 264 } 265 if (appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) { 266 auto bundleFlag = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION); 267 if (IN_PROCESS_CALL(bms->GetCloneBundleInfo(bundleName, bundleFlag, appIndex, bundleInfo, userId)) != ERR_OK) { 268 TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetCloneBundleInfo"); 269 return GET_BUNDLE_INFO_FAILED; 270 } 271 tokenId = bundleInfo.applicationInfo.accessTokenId; 272 return ERR_OK; 273 } 274 if (IN_PROCESS_CALL(bms->GetSandboxBundleInfo(bundleName, appIndex, userId, bundleInfo) != ERR_OK)) { 275 TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetSandboxBundleInfo"); 276 return GET_BUNDLE_INFO_FAILED; 277 } 278 tokenId = bundleInfo.applicationInfo.accessTokenId; 279 return ERR_OK; 280} 281 282bool UPMSUtils::IsDocsCloudUri(Uri &uri) 283{ 284 return (uri.GetAuthority() == "docs" && uri.ToString().find(NET_WORK_ID_MARK) != std::string::npos); 285} 286 287std::shared_ptr<AppExecFwk::BundleMgrHelper> UPMSUtils::bundleMgrHelper_ = nullptr; 288} // namespace AAFwk 289} // namespace OHOS 290