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 "permission_utils.h" 17 18#include "accesstoken_kit.h" 19#include "ipc_skeleton.h" 20#include "iservice_registry.h" 21#include "privacy_kit.h" 22#include "ringtone_log.h" 23#include "ringtone_tracer.h" 24#include "system_ability_definition.h" 25#include "tokenid_kit.h" 26 27namespace OHOS { 28namespace Media { 29using namespace std; 30using namespace OHOS::Security::AccessToken; 31using namespace OHOS::AppExecFwk::Constants; 32 33sptr<AppExecFwk::IBundleMgr> RingtonePermissionUtils::bundleManager_ = nullptr; 34mutex RingtonePermissionUtils::bundleManagerMutex_; 35sptr<AppExecFwk::IBundleMgr> RingtonePermissionUtils::GetSysBundleManager() 36{ 37 if (bundleManager_ != nullptr) { 38 return bundleManager_; 39 } 40 41 lock_guard<mutex> lock(bundleManagerMutex_); 42 if (bundleManager_ != nullptr) { 43 return bundleManager_; 44 } 45 46 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 47 if (systemAbilityManager == nullptr) { 48 RINGTONE_ERR_LOG("Failed to get SystemAbilityManager."); 49 return nullptr; 50 } 51 52 auto bundleObj = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 53 if (bundleObj == nullptr) { 54 RINGTONE_ERR_LOG("Remote object is nullptr."); 55 return nullptr; 56 } 57 58 auto bundleManager = iface_cast<AppExecFwk::IBundleMgr>(bundleObj); 59 if (bundleManager == nullptr) { 60 RINGTONE_ERR_LOG("Failed to iface_cast"); 61 return nullptr; 62 } 63 bundleManager_ = bundleManager; 64 65 return bundleManager_; 66} 67 68void RingtonePermissionUtils::GetClientBundle(const int uid, string &bundleName) 69{ 70 bundleManager_ = GetSysBundleManager(); 71 if (bundleManager_ == nullptr) { 72 bundleName = ""; 73 return; 74 } 75 auto result = bundleManager_->GetBundleNameForUid(uid, bundleName); 76 if (!result) { 77 RINGTONE_ERR_LOG("GetBundleNameForUid fail"); 78 bundleName = ""; 79 } 80} 81 82bool RingtonePermissionUtils::CheckCallerPermission(const string &permission) 83{ 84 RingtoneTracer tracer; 85 tracer.Start("CheckCallerPermission"); 86 87 AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); 88 int result = AccessTokenKit::VerifyAccessToken(tokenCaller, permission); 89 if (result != PermissionState::PERMISSION_GRANTED) { 90 RINGTONE_ERR_LOG("Have no media permission: %{public}s", permission.c_str()); 91 return false; 92 } 93 return true; 94} 95 96/* Check whether caller has at least one of @permsVec */ 97bool RingtonePermissionUtils::CheckHasPermission(const vector<string> &permsVec) 98{ 99 if (permsVec.empty()) { 100 return false; 101 } 102 103 for (const auto &perm : permsVec) { 104 if (CheckCallerPermission(perm)) { 105 return true; 106 } 107 } 108 109 return false; 110} 111 112string RingtonePermissionUtils::GetPackageNameByBundleName(const string &bundleName) 113{ 114 const static int32_t invalidUid = -1; 115 const static int32_t baseUserRange = 200000; 116 117 int uid = IPCSkeleton::GetCallingUid(); 118 if (uid <= invalidUid) { 119 RINGTONE_ERR_LOG("Get invalidUid UID %{public}d", uid); 120 return ""; 121 } 122 int32_t userId = uid / baseUserRange; 123 RINGTONE_DEBUG_LOG("uid:%{private}d, userId:%{private}d", uid, userId); 124 125 AAFwk::Want want; 126 auto bundleManager_ = GetSysBundleManager(); 127 if (bundleManager_ == nullptr) { 128 RINGTONE_ERR_LOG("Get BundleManager failed"); 129 return ""; 130 } 131 int ret = bundleManager_->GetLaunchWantForBundle(bundleName, want, userId); 132 if (ret != ERR_OK) { 133 RINGTONE_ERR_LOG("Can not get bundleName by want, err=%{public}d, userId=%{private}d", 134 ret, userId); 135 return ""; 136 } 137 string abilityName = want.GetOperation().GetAbilityName(); 138 return bundleManager_->GetAbilityLabel(bundleName, abilityName); 139} 140 141/* Check whether caller has all the @permsVec */ 142bool RingtonePermissionUtils::CheckCallerPermission(const vector<string> &permsVec) 143{ 144 if (permsVec.empty()) { 145 return false; 146 } 147 148 for (const auto &perm : permsVec) { 149 if (!CheckCallerPermission(perm)) { 150 return false; 151 } 152 } 153 return true; 154} 155 156uint32_t RingtonePermissionUtils::GetTokenId() 157{ 158 return IPCSkeleton::GetCallingTokenID(); 159} 160 161bool RingtonePermissionUtils::IsSystemApp() 162{ 163 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID(); 164 return TokenIdKit::IsSystemAppByFullTokenID(tokenId); 165} 166 167bool RingtonePermissionUtils::CheckIsSystemAppByUid() 168{ 169 int uid = IPCSkeleton::GetCallingUid(); 170 bundleManager_ = GetSysBundleManager(); 171 if (bundleManager_ == nullptr) { 172 RINGTONE_ERR_LOG("Can not get bundleMgr"); 173 return false; 174 } 175 return bundleManager_->CheckIsSystemAppByUid(uid); 176} 177 178bool RingtonePermissionUtils::IsNativeSAApp() 179{ 180 uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); 181 ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); 182 RINGTONE_DEBUG_LOG("check if native sa token, tokenId:%{public}d, tokenType:%{public}d", tokenId, tokenType); 183 if (tokenType == ATokenTypeEnum::TOKEN_NATIVE) { 184 return true; 185 } 186 return false; 187} 188} // namespace Media 189} // namespace OHOS 190