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 "multi_instance_utils.h"
28 #include "permission_constants.h"
29 #include "permission_verification.h"
30 #include "start_ability_utils.h"
31 #include "utils/app_mgr_util.h"
32 
33 using OHOS::Security::AccessToken::AccessTokenKit;
34 
35 namespace OHOS {
36 namespace AAFwk {
37 namespace {
38 constexpr const char* IS_DELEGATOR_CALL = "isDelegatorCall";
39 constexpr const char* SETTINGS = "settings";
40 constexpr int32_t BASE_USER_RANGE = 200000;
41 }
42 
GetInstance()43 AbilityPermissionUtil &AbilityPermissionUtil::GetInstance()
44 {
45     static AbilityPermissionUtil instance;
46     return instance;
47 }
48 
IsDelegatorCall(const AppExecFwk::RunningProcessInfo &processInfo, const AbilityRequest &abilityRequest) const49 inline bool AbilityPermissionUtil::IsDelegatorCall(const AppExecFwk::RunningProcessInfo &processInfo,
50     const AbilityRequest &abilityRequest) const
51 {
52     /*  To make sure the AbilityDelegator is not counterfeited
53      *   1. The caller-process must be test-process
54      *   2. The callerToken must be nullptr
55      */
56     if (processInfo.isTestProcess &&
57         !abilityRequest.callerToken && abilityRequest.want.GetBoolParam(IS_DELEGATOR_CALL, false)) {
58         return true;
59     }
60     return false;
61 }
62 
IsDominateScreen(const Want &want, bool isPendingWantCaller)63 bool AbilityPermissionUtil::IsDominateScreen(const Want &want, bool isPendingWantCaller)
64 {
65     if (!isPendingWantCaller &&
66         !PermissionVerification::GetInstance()->IsSACall() && !PermissionVerification::GetInstance()->IsShellCall()) {
67         auto callerPid = IPCSkeleton::GetCallingPid();
68         AppExecFwk::RunningProcessInfo processInfo;
69         DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(callerPid, processInfo);
70         bool isDelegatorCall = processInfo.isTestProcess && want.GetBoolParam(IS_DELEGATOR_CALL, false);
71         if (isDelegatorCall || InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
72             TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen.");
73             return false;
74         }
75         // add temporarily
76         std::string bundleName = want.GetElement().GetBundleName();
77         std::string abilityName = want.GetElement().GetAbilityName();
78         bool withoutSettings = bundleName.find(SETTINGS) == std::string::npos &&
79             abilityName.find(SETTINGS) == std::string::npos;
80         if (withoutSettings && AppUtils::GetInstance().IsAllowStartAbilityWithoutCallerToken(bundleName, abilityName)) {
81             TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen, allow.");
82             return false;
83         } else if (AppUtils::GetInstance().IsAllowStartAbilityWithoutCallerToken(bundleName, abilityName)) {
84             auto bms = AbilityUtil::GetBundleManagerHelper();
85             CHECK_POINTER_RETURN_BOOL(bms);
86             int32_t callerUid = IPCSkeleton::GetCallingUid();
87             std::string callerBundleName;
88             if (IN_PROCESS_CALL(bms->GetNameForUid(callerUid, callerBundleName)) != ERR_OK) {
89                 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to get caller bundle name.");
90                 return false;
91             }
92             auto userId = callerUid / BASE_USER_RANGE;
93             AppExecFwk::BundleInfo info;
94             if (!IN_PROCESS_CALL(
95                 bms->GetBundleInfo(callerBundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, info, userId))) {
96                 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to get bundle info.");
97                 return false;
98             }
99             if (info.applicationInfo.needAppDetail) {
100                 TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen, app detail.");
101                 return false;
102             }
103         }
104         TAG_LOGE(AAFwkTag::ABILITYMGR, "dominate screen.");
105         return true;
106     }
107     TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen.");
108     return false;
109 }
110 
CheckMultiInstanceAndAppClone(Want &want, int32_t userId, int32_t appIndex, sptr<IRemoteObject> callerToken)111 int32_t AbilityPermissionUtil::CheckMultiInstanceAndAppClone(Want &want, int32_t userId, int32_t appIndex,
112     sptr<IRemoteObject> callerToken)
113 {
114     auto instanceKey = want.GetStringParam(Want::APP_INSTANCE_KEY);
115     auto isCreating = want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false);
116     AppExecFwk::ApplicationInfo appInfo;
117     auto isSupportMultiInstance = AppUtils::GetInstance().IsSupportMultiInstance();
118     if (isSupportMultiInstance) {
119         if (!StartAbilityUtils::GetApplicationInfo(want.GetBundle(), userId, appInfo)) {
120             TAG_LOGI(AAFwkTag::ABILITYMGR, "implicit start");
121             return ERR_OK;
122         }
123         if (appInfo.multiAppMode.multiAppModeType == AppExecFwk::MultiAppModeType::UNSPECIFIED) {
124             if (!instanceKey.empty() || isCreating ||
125                 (appIndex != 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX)) {
126                 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support multi-instance or appClone");
127                 return ERR_MULTI_APP_NOT_SUPPORTED;
128             }
129         }
130         if (appInfo.multiAppMode.multiAppModeType == AppExecFwk::MultiAppModeType::MULTI_INSTANCE) {
131             if (appIndex != 0) {
132                 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support appClone");
133                 return ERR_NOT_SUPPORT_APP_CLONE;
134             }
135             return CheckMultiInstance(want, callerToken, isCreating, instanceKey, appInfo.multiAppMode.maxCount);
136         }
137     }
138     if (!isSupportMultiInstance || appInfo.multiAppMode.multiAppModeType == AppExecFwk::MultiAppModeType::APP_CLONE) {
139         if (!instanceKey.empty() || isCreating) {
140             TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support multi-instance");
141             return ERR_MULTI_INSTANCE_NOT_SUPPORTED;
142         }
143     }
144     return ERR_OK;
145 }
146 
CheckMultiInstance(Want &want, sptr<IRemoteObject> callerToken, bool isCreating, const std::string &instanceKey, int32_t maxCount)147 int32_t AbilityPermissionUtil::CheckMultiInstance(Want &want, sptr<IRemoteObject> callerToken,
148     bool isCreating, const std::string &instanceKey, int32_t maxCount)
149 {
150     auto appMgr = AppMgrUtil::GetAppMgr();
151     if (appMgr == nullptr) {
152         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null appMgr");
153         return ERR_INVALID_VALUE;
154     }
155     auto callerRecord = Token::GetAbilityRecordByToken(callerToken);
156     std::vector<std::string> instanceKeyArray;
157     auto result = IN_PROCESS_CALL(appMgr->GetAllRunningInstanceKeysByBundleName(want.GetBundle(), instanceKeyArray));
158     if (result != ERR_OK) {
159         TAG_LOGE(AAFwkTag::FREE_INSTALL, "Failed to get instance key");
160         return ERR_INVALID_VALUE;
161     }
162     // in-app launch
163     if (callerRecord != nullptr && callerRecord->GetAbilityInfo().bundleName == want.GetBundle()) {
164         if (isCreating) {
165             if (!instanceKey.empty()) {
166                 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not allow to set instanceKey");
167                 return ERR_APP_INSTANCE_KEY_NOT_SUPPORT;
168             }
169             if (static_cast<int32_t>(instanceKeyArray.size()) == maxCount) {
170                 TAG_LOGE(AAFwkTag::ABILITYMGR, "reach upper limit");
171                 return ERR_UPPER_LIMIT;
172             }
173             return ERR_OK;
174         }
175         return UpdateInstanceKey(want, instanceKey, instanceKeyArray, callerRecord->GetInstanceKey());
176     }
177     // inter-app launch
178     if (isCreating) {
179         TAG_LOGE(AAFwkTag::ABILITYMGR, "not support to create a new instance");
180         return ERR_CREATE_NEW_INSTANCE_NOT_SUPPORT;
181     }
182     std::string defaultInstanceKey = "app_instance_0";
183     return UpdateInstanceKey(want, instanceKey, instanceKeyArray, defaultInstanceKey);
184 }
185 
UpdateInstanceKey(Want &want, const std::string &originInstanceKey, const std::vector<std::string> &instanceKeyArray, const std::string &instanceKey)186 int32_t AbilityPermissionUtil::UpdateInstanceKey(Want &want, const std::string &originInstanceKey,
187     const std::vector<std::string> &instanceKeyArray, const std::string &instanceKey)
188 {
189     if (originInstanceKey.empty()) {
190         want.SetParam(Want::APP_INSTANCE_KEY, instanceKey);
191         return ERR_OK;
192     }
193     for (const auto& key : instanceKeyArray) {
194         if (key == originInstanceKey) {
195             return ERR_OK;
196         }
197     }
198     TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid instanceKey");
199     return ERR_INVALID_APP_INSTANCE_KEY;
200 }
201 
CheckMultiInstanceKeyForExtension(const AbilityRequest &abilityRequest)202 int32_t AbilityPermissionUtil::CheckMultiInstanceKeyForExtension(const AbilityRequest &abilityRequest)
203 {
204     if (abilityRequest.want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false)) {
205         TAG_LOGE(AAFwkTag::ABILITYMGR, "not support to create a new instance");
206         return ERR_CREATE_NEW_INSTANCE_NOT_SUPPORT;
207     }
208     auto instanceKey = MultiInstanceUtils::GetInstanceKey(abilityRequest.want);
209     if (instanceKey.empty()) {
210         return ERR_OK;
211     }
212     TAG_LOGI(AAFwkTag::ABILITYMGR, "instanceKey:%{public}s", instanceKey.c_str());
213     if (!AppUtils::GetInstance().IsSupportMultiInstance()) {
214         TAG_LOGE(AAFwkTag::ABILITYMGR, "not support multi-instance");
215         return ERR_CAPABILITY_NOT_SUPPORT;
216     }
217     if (!MultiInstanceUtils::IsMultiInstanceApp(abilityRequest.appInfo)) {
218         TAG_LOGE(AAFwkTag::ABILITYMGR, "not multi-instance app");
219         return ERR_MULTI_INSTANCE_NOT_SUPPORTED;
220     }
221     if (MultiInstanceUtils::IsDefaultInstanceKey(instanceKey)) {
222         return ERR_OK;
223     }
224     if (!MultiInstanceUtils::IsSupportedExtensionType(abilityRequest.abilityInfo.extensionAbilityType)) {
225         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid extension type");
226         return ERR_INVALID_EXTENSION_TYPE;
227     }
228     if (!MultiInstanceUtils::IsInstanceKeyExist(abilityRequest.want.GetBundle(), instanceKey)) {
229         TAG_LOGE(AAFwkTag::ABILITYMGR, "key not found");
230         return ERR_INVALID_APP_INSTANCE_KEY;
231     }
232     return ERR_OK;
233 }
234 } // AAFwk
235 } // OHOS