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 "utils/ability_permission_util.h"
17 
18 #include "ability_connect_manager.h"
19 #include "ability_info.h"
20 #include "ability_util.h"
21 #include "app_utils.h"
22 #include "accesstoken_kit.h"
23 #include "global_constant.h"
24 #include "hitrace_meter.h"
25 #include "insight_intent_execute_param.h"
26 #include "ipc_skeleton.h"
27 #include "permission_constants.h"
28 #include "permission_verification.h"
29 #include "start_ability_utils.h"
30 #include "utils/app_mgr_util.h"
31 
32 using OHOS::Security::AccessToken::AccessTokenKit;
33 
34 namespace OHOS {
35 namespace AAFwk {
36 namespace {
37 constexpr const char* IS_DELEGATOR_CALL = "isDelegatorCall";
38 constexpr const char* SETTINGS = "settings";
39 constexpr int32_t BASE_USER_RANGE = 200000;
40 }
41 
GetInstance()42 AbilityPermissionUtil &AbilityPermissionUtil::GetInstance()
43 {
44     static AbilityPermissionUtil instance;
45     return instance;
46 }
47 
IsDelegatorCall(const AppExecFwk::RunningProcessInfo & processInfo,const AbilityRequest & abilityRequest) const48 inline bool AbilityPermissionUtil::IsDelegatorCall(const AppExecFwk::RunningProcessInfo &processInfo,
49     const AbilityRequest &abilityRequest) const
50 {
51     /*  To make sure the AbilityDelegator is not counterfeited
52      *   1. The caller-process must be test-process
53      *   2. The callerToken must be nullptr
54      */
55     if (processInfo.isTestProcess &&
56         !abilityRequest.callerToken && abilityRequest.want.GetBoolParam(IS_DELEGATOR_CALL, false)) {
57         return true;
58     }
59     return false;
60 }
61 
IsDominateScreen(const Want & want,bool isPendingWantCaller)62 bool AbilityPermissionUtil::IsDominateScreen(const Want &want, bool isPendingWantCaller)
63 {
64     if (!isPendingWantCaller &&
65         !PermissionVerification::GetInstance()->IsSACall() && !PermissionVerification::GetInstance()->IsShellCall()) {
66         auto callerPid = IPCSkeleton::GetCallingPid();
67         AppExecFwk::RunningProcessInfo processInfo;
68         DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(callerPid, processInfo);
69         bool isDelegatorCall = processInfo.isTestProcess && want.GetBoolParam(IS_DELEGATOR_CALL, false);
70         if (isDelegatorCall || InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
71             TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen.");
72             return false;
73         }
74         // add temporarily
75         std::string bundleName = want.GetElement().GetBundleName();
76         std::string abilityName = want.GetElement().GetAbilityName();
77         bool withoutSettings = bundleName.find(SETTINGS) == std::string::npos &&
78             abilityName.find(SETTINGS) == std::string::npos;
79         if (withoutSettings && AppUtils::GetInstance().IsAllowStartAbilityWithoutCallerToken(bundleName, abilityName)) {
80             TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen, allow.");
81             return false;
82         } else if (AppUtils::GetInstance().IsAllowStartAbilityWithoutCallerToken(bundleName, abilityName)) {
83             auto bms = AbilityUtil::GetBundleManagerHelper();
84             CHECK_POINTER_RETURN_BOOL(bms);
85             int32_t callerUid = IPCSkeleton::GetCallingUid();
86             std::string callerBundleName;
87             if (IN_PROCESS_CALL(bms->GetNameForUid(callerUid, callerBundleName)) != ERR_OK) {
88                 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to get caller bundle name.");
89                 return false;
90             }
91             auto userId = callerUid / BASE_USER_RANGE;
92             AppExecFwk::BundleInfo info;
93             if (!IN_PROCESS_CALL(
94                 bms->GetBundleInfo(callerBundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, info, userId))) {
95                 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to get bundle info.");
96                 return false;
97             }
98             if (info.applicationInfo.needAppDetail) {
99                 TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen, app detail.");
100                 return false;
101             }
102         }
103         TAG_LOGE(AAFwkTag::ABILITYMGR, "dominate screen.");
104         return true;
105     }
106     TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen.");
107     return false;
108 }
109 
CheckMultiInstanceAndAppClone(Want & want,int32_t userId,int32_t appIndex,sptr<IRemoteObject> callerToken)110 int32_t AbilityPermissionUtil::CheckMultiInstanceAndAppClone(Want &want, int32_t userId, int32_t appIndex,
111     sptr<IRemoteObject> callerToken)
112 {
113     auto instanceKey = want.GetStringParam(Want::APP_INSTANCE_KEY);
114     auto isSupportMultiInstance = AppUtils::GetInstance().IsSupportMultiInstance();
115     auto isCreating = want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false);
116     if (!isSupportMultiInstance) {
117         if (!instanceKey.empty() || isCreating) {
118             TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support multi-instance");
119             return ERR_MULTI_INSTANCE_NOT_SUPPORTED;
120         }
121     }
122     return ERR_OK;
123 }
124 } // AAFwk
125 } // OHOS