1/* 2 * Copyright (c) 2023 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 <accesstoken_kit.h> 17#include <app_mgr_client.h> 18#include <app_mgr_interface.h> 19#include <bundle_constants.h> 20#include <ipc_skeleton.h> 21#include <bundle_mgr_proxy.h> 22#include <bundle_mgr_interface.h> 23#include <system_ability_definition.h> 24#include <iservice_registry.h> 25#include <tokenid_kit.h> 26#include <input_method_controller.h> 27#include <singleton.h> 28#include <singleton_container.h> 29#include <pwd.h> 30#include "common/include/session_permission.h" 31#include "parameters.h" 32#include "window_manager_hilog.h" 33 34namespace OHOS { 35namespace Rosen { 36namespace { 37constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionPermission"}; 38constexpr int32_t FOUNDATION_UID = 5523; 39 40sptr<AppExecFwk::IBundleMgr> GetBundleManagerProxy() 41{ 42 sptr<ISystemAbilityManager> systemAbilityManager = 43 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 44 if (!systemAbilityManager) { 45 WLOGFE("Failed to get system ability mgr."); 46 return nullptr; 47 } 48 sptr<IRemoteObject> remoteObject 49 = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 50 if (!remoteObject) { 51 WLOGFE("Failed to get bundle manager service."); 52 return nullptr; 53 } 54 auto bundleManagerServiceProxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject); 55 if (!bundleManagerServiceProxy || !bundleManagerServiceProxy->AsObject()) { 56 WLOGFE("Failed to get bundle manager proxy."); 57 return nullptr; 58 } 59 return bundleManagerServiceProxy; 60} 61} 62 63bool SessionPermission::IsSystemServiceCalling(bool needPrintLog) 64{ 65 const auto tokenId = IPCSkeleton::GetCallingTokenID(); 66 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); 67 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE || 68 flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) { 69 TLOGD(WmsLogTag::DEFAULT, "system service calling, tokenId:%{private}u, flag:%{public}u", tokenId, flag); 70 return true; 71 } 72 if (needPrintLog) { 73 TLOGE(WmsLogTag::DEFAULT, "Not system service calling, tokenId:%{private}u, flag:%{public}u", tokenId, flag); 74 } 75 return false; 76} 77 78bool SessionPermission::IsSystemCalling() 79{ 80 const auto tokenId = IPCSkeleton::GetCallingTokenID(); 81 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); 82 TLOGD(WmsLogTag::DEFAULT, "tokenId:%{private}u, flag:%{public}u", tokenId, flag); 83 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE || 84 flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) { 85 return true; 86 } 87 return IsSystemAppCall(); 88} 89 90bool SessionPermission::IsSystemAppCall() 91{ 92 uint64_t callingTokenId = IPCSkeleton::GetCallingFullTokenID(); 93 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callingTokenId); 94} 95 96bool SessionPermission::IsSACalling() 97{ 98 const auto tokenId = IPCSkeleton::GetCallingTokenID(); 99 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); 100 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) { 101 TLOGD(WmsLogTag::DEFAULT, "SA called, tokenId:%{private}u, flag:%{public}u", tokenId, flag); 102 return true; 103 } 104 TLOGI(WmsLogTag::DEFAULT, "Not SA called, tokenId:%{private}u, flag:%{public}u", tokenId, flag); 105 return false; 106} 107 108bool SessionPermission::VerifyCallingPermission(const std::string& permissionName) 109{ 110 auto callerToken = IPCSkeleton::GetCallingTokenID(); 111 TLOGD(WmsLogTag::DEFAULT, "permission %{public}s, callingTokenID:%{private}u", 112 permissionName.c_str(), callerToken); 113 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName); 114 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { 115 TLOGE(WmsLogTag::DEFAULT, 116 "permission %{public}s: PERMISSION_DENIED, callingTokenID:%{private}u, ret:%{public}d", 117 permissionName.c_str(), callerToken, ret); 118 return false; 119 } 120 TLOGI(WmsLogTag::DEFAULT, "Verify AccessToken success. permission %{public}s, callingTokenID:%{private}u", 121 permissionName.c_str(), callerToken); 122 return true; 123} 124 125bool SessionPermission::VerifyPermissionByCallerToken(const uint32_t callerToken, const std::string& permissionName) 126{ 127 TLOGD(WmsLogTag::DEFAULT, "permission %{public}s, callingTokenID:%{private}u", 128 permissionName.c_str(), callerToken); 129 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName); 130 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { 131 TLOGE(WmsLogTag::DEFAULT, 132 "permission %{public}s: PERMISSION_DENIED, callingTokenID:%{private}u, ret:%{public}d", 133 permissionName.c_str(), callerToken, ret); 134 return false; 135 } 136 TLOGI(WmsLogTag::DEFAULT, "Verify AccessToken success. permission %{public}s, callingTokenID:%{private}u", 137 permissionName.c_str(), callerToken); 138 return true; 139} 140 141bool SessionPermission::VerifySessionPermission() 142{ 143 if (IsSACalling()) { 144 WLOGFI("Is SA Call, Permission verified success."); 145 return true; 146 } 147 if (VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) { 148 WLOGFI("MANAGE permission verified success."); 149 return true; 150 } 151 WLOGFW("Permission verified failed."); 152 return false; 153} 154 155bool SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() 156{ 157 if (IsSACalling() || IsShellCall()) { 158 return true; 159 } 160 return IsSystemAppCall(); 161} 162 163bool SessionPermission::IsShellCall() 164{ 165 auto callerToken = IPCSkeleton::GetCallingTokenID(); 166 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken); 167 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) { 168 WLOGFI("TokenType is Shell, verify success"); 169 return true; 170 } 171 TLOGI(WmsLogTag::DEFAULT, "Not Shell called. tokenId:%{private}u, type:%{public}u", callerToken, tokenType); 172 return false; 173} 174 175bool SessionPermission::IsStartByHdcd() 176{ 177 OHOS::Security::AccessToken::NativeTokenInfo info; 178 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(IPCSkeleton::GetCallingTokenID(), info) != 0) { 179 return false; 180 } 181 if (info.processName.compare("hdcd") == 0) { 182 return true; 183 } 184 return false; 185} 186 187bool SessionPermission::IsStartedByInputMethod() 188{ 189 auto imc = MiscServices::InputMethodController::GetInstance(); 190 if (!imc) { 191 TLOGE(WmsLogTag::DEFAULT, "InputMethodController is nullptr"); 192 return false; 193 } 194 int pid = IPCSkeleton::GetCallingPid(); 195 return imc->IsCurrentImeByPid(pid); 196} 197 198bool SessionPermission::IsSameBundleNameAsCalling(const std::string& bundleName) 199{ 200 if (bundleName == "") { 201 return false; 202 } 203 auto bundleManagerServiceProxy_ = GetBundleManagerProxy(); 204 if (!bundleManagerServiceProxy_) { 205 WLOGFE("failed to get BundleManagerServiceProxy"); 206 return false; 207 } 208 int uid = IPCSkeleton::GetCallingUid(); 209 // reset ipc identity 210 std::string identity = IPCSkeleton::ResetCallingIdentity(); 211 std::string callingBundleName; 212 bundleManagerServiceProxy_->GetNameForUid(uid, callingBundleName); 213 IPCSkeleton::SetCallingIdentity(identity); 214 if (callingBundleName == bundleName) { 215 WLOGFD("verify bundle name success"); 216 return true; 217 } else { 218 WLOGFE("verify bundle name failed, calling bundle name %{public}s, but window bundle name %{public}s.", 219 callingBundleName.c_str(), bundleName.c_str()); 220 return false; 221 } 222} 223 224bool SessionPermission::IsSameAppAsCalling(const std::string& bundleName, const std::string& appIdentifier) 225{ 226 if (bundleName == "" || appIdentifier == "") { 227 return false; 228 } 229 auto bundleManagerServiceProxy = GetBundleManagerProxy(); 230 if (!bundleManagerServiceProxy) { 231 TLOGE(WmsLogTag::DEFAULT, "failed to get BundleManagerServiceProxy"); 232 return false; 233 } 234 int uid = IPCSkeleton::GetCallingUid(); 235 // reset ipc identity 236 std::string identity = IPCSkeleton::ResetCallingIdentity(); 237 std::string callingBundleName; 238 bundleManagerServiceProxy->GetNameForUid(uid, callingBundleName); 239 if (callingBundleName != bundleName) { 240 TLOGE(WmsLogTag::DEFAULT, "verify app failed, callingBundleName %{public}s, bundleName %{public}s.", 241 callingBundleName.c_str(), bundleName.c_str()); 242 IPCSkeleton::SetCallingIdentity(identity); 243 return false; 244 } 245 AppExecFwk::BundleInfo bundleInfo; 246 int userId = uid / 200000; // 200000 use uid to caculate userId 247 bool ret = bundleManagerServiceProxy->GetBundleInfoV9( 248 callingBundleName, static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO), 249 bundleInfo, userId); 250 IPCSkeleton::SetCallingIdentity(identity); 251 252 if (ret != ERR_OK) { 253 TLOGE(WmsLogTag::DEFAULT, "failed to query app info, callingBundleName:%{public}s, userId:%{public}d", 254 callingBundleName.c_str(), userId); 255 return false; 256 } 257 258 if (bundleInfo.signatureInfo.appIdentifier == appIdentifier) { 259 TLOGI(WmsLogTag::DEFAULT, "verify app success"); 260 return true; 261 } 262 263 TLOGE(WmsLogTag::DEFAULT, "verify app failed, callingBundleName %{public}s, bundleName %{public}s.", 264 callingBundleName.c_str(), bundleName.c_str()); 265 return false; 266} 267 268bool SessionPermission::IsStartedByUIExtension() 269{ 270 auto bundleManagerServiceProxy = GetBundleManagerProxy(); 271 if (!bundleManagerServiceProxy) { 272 WLOGFE("failed to get BundleManagerServiceProxy"); 273 return false; 274 } 275 276 int uid = IPCSkeleton::GetCallingUid(); 277 // reset ipc identity 278 std::string identity = IPCSkeleton::ResetCallingIdentity(); 279 std::string bundleName; 280 bundleManagerServiceProxy->GetNameForUid(uid, bundleName); 281 AppExecFwk::BundleInfo bundleInfo; 282 int userId = uid / 200000; // 200000 use uid to caculate userId 283 bool result = bundleManagerServiceProxy->GetBundleInfo(bundleName, 284 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); 285 // set ipc identity to raw 286 IPCSkeleton::SetCallingIdentity(identity); 287 if (!result) { 288 WLOGFE("failed to query extension ability info, bundleName:%{public}s, userId:%{public}d", 289 bundleName.c_str(), userId); 290 return false; 291 } 292 293 auto extensionInfo = std::find_if(bundleInfo.extensionInfos.begin(), bundleInfo.extensionInfos.end(), 294 [](AppExecFwk::ExtensionAbilityInfo extensionInfo) { 295 return (extensionInfo.type == AppExecFwk::ExtensionAbilityType::SYS_COMMON_UI); 296 }); 297 return extensionInfo != bundleInfo.extensionInfos.end(); 298} 299 300bool SessionPermission::CheckCallingIsUserTestMode(pid_t pid) 301{ 302 TLOGI(WmsLogTag::DEFAULT, "Calling proxy func"); 303 bool isUserTestMode = false; 304 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance(); 305 if (appMgrClient == nullptr) { 306 TLOGE(WmsLogTag::DEFAULT, "AppMgeClient is null!"); 307 return false; 308 } 309 // reset ipc identity 310 std::string identity = IPCSkeleton::ResetCallingIdentity(); 311 int32_t ret = appMgrClient->CheckCallingIsUserTestMode(pid, isUserTestMode); 312 // set ipc identity to raw 313 IPCSkeleton::SetCallingIdentity(identity); 314 if (ret != ERR_OK) { 315 TLOGE(WmsLogTag::DEFAULT, "Permission denied! ret=%{public}d", ret); 316 return false; 317 } 318 return isUserTestMode; 319} 320 321bool SessionPermission::IsBetaVersion() 322{ 323 std::string betaName = OHOS::system::GetParameter("const.logsystem.versiontype", ""); 324 return betaName.find("beta") != std::string::npos; 325} 326 327bool SessionPermission::IsFoundationCall() 328{ 329 return IPCSkeleton::GetCallingUid() == FOUNDATION_UID; 330} 331 332std::string SessionPermission::GetCallingBundleName() 333{ 334 auto bundleManagerServiceProxy = GetBundleManagerProxy(); 335 if (!bundleManagerServiceProxy) { 336 WLOGFE("failed to get BundleManagerServiceProxy"); 337 return ""; 338 } 339 int uid = IPCSkeleton::GetCallingUid(); 340 // reset ipc identity 341 std::string identity = IPCSkeleton::ResetCallingIdentity(); 342 std::string callingBundleName; 343 bundleManagerServiceProxy->GetNameForUid(uid, callingBundleName); 344 // if bundlename is empty, fill in pw_name 345 if (callingBundleName.empty()) { 346 if (struct passwd* user = getpwuid(uid)) { 347 callingBundleName = user->pw_name; 348 } 349 } 350 IPCSkeleton::SetCallingIdentity(identity); 351 return callingBundleName; 352} 353} // namespace Rosen 354} // namespace OHOS