• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "distributed_sched_permission.h"
17 
18 #include "accesstoken_kit.h"
19 #include "datetime_ex.h"
20 #include "device_auth_defines.h"
21 #include "device_manager.h"
22 #include "device_security_defines.h"
23 #include "device_security_info.h"
24 #include "ipc_skeleton.h"
25 #include "ohos_account_kits.h"
26 #include "os_account_manager.h"
27 #include "string_wrapper.h"
28 
29 #include "adapter/dnetwork_adapter.h"
30 #include "bundle/bundle_manager_internal.h"
31 #include "caller_info.h"
32 #include "distributed_sched_adapter.h"
33 #include "distributed_sched_utils.h"
34 #include "dtbschedmgr_device_info_storage.h"
35 #include "dtbschedmgr_log.h"
36 #include "json_util.h"
37 
38 namespace OHOS {
39 namespace DistributedSchedule {
40 using namespace OHOS::Security;
41 using namespace AAFwk;
42 using namespace DistributedHardware;
43 namespace {
44 const std::string FOUNDATION_PROCESS_NAME = "foundation";
45 const std::string DMS_API_VERSION = "dmsApiVersion";
46 const std::string DMS_IS_CALLER_BACKGROUND = "dmsIsCallerBackGround";
47 const std::string DMS_MISSION_ID = "dmsMissionId";
48 const std::string DMS_VERSION_ID = "dmsVersion";
49 const std::string PARAMS_URI = "ability.verify.uri";
50 const std::string PARAMS_STREAM = "ability.params.stream";
51 const std::string PERMISSION_START_ABILIIES_FROM_BACKGROUND = "ohos.permission.START_ABILIIES_FROM_BACKGROUND";
52 const std::string PERMISSION_START_ABILITIES_FROM_BACKGROUND = "ohos.permission.START_ABILITIES_FROM_BACKGROUND";
53 const std::string PERMISSION_START_INVISIBLE_ABILITY = "ohos.permission.START_INVISIBLE_ABILITY";
54 const std::string DISTRIBUTED_FILES_PATH = "/data/storage/el2/distributedfiles/";
55 const std::string BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
56 constexpr int32_t DEFAULT_DMS_API_VERSION = 9;
57 const int DEFAULT_DMS_MISSION_ID = -1;
58 const int FA_MODULE_ALLOW_MIN_API_VERSION = 8;
59 const int DEFAULT_DEVICE_SECURITY_LEVEL = -1;
60 const int HIGH_CONTINUE_ACL_VERSION = 6;
61 const int NUMBER_OF_VERSION_TRUNCATION = 3;
62 }
63 
64 IMPLEMENT_SINGLE_INSTANCE(DistributedSchedPermission);
65 
from_json(const nlohmann::json & jsonObject,GroupInfo & groupInfo)66 void from_json(const nlohmann::json& jsonObject, GroupInfo& groupInfo)
67 {
68     const auto &jsonObjectEnd = jsonObject.end();
69     int32_t parseResult = ERR_OK;
70     GetValueIfFindKey<std::string>(jsonObject,
71         jsonObjectEnd,
72         FIELD_GROUP_NAME,
73         groupInfo.groupName,
74         JsonType::STRING,
75         false,
76         parseResult,
77         ArrayType::NOT_ARRAY);
78     GetValueIfFindKey<std::string>(jsonObject,
79         jsonObjectEnd,
80         FIELD_GROUP_ID,
81         groupInfo.groupId,
82         JsonType::STRING,
83         false,
84         parseResult,
85         ArrayType::NOT_ARRAY);
86     GetValueIfFindKey<std::string>(jsonObject,
87         jsonObjectEnd,
88         FIELD_GROUP_OWNER,
89         groupInfo.groupOwner,
90         JsonType::STRING,
91         false,
92         parseResult,
93         ArrayType::NOT_ARRAY);
94     GetValueIfFindKey<int32_t>(jsonObject,
95         jsonObjectEnd,
96         FIELD_GROUP_TYPE,
97         groupInfo.groupType,
98         JsonType::NUMBER,
99         false,
100         parseResult,
101         ArrayType::NOT_ARRAY);
102     GetValueIfFindKey<int32_t>(jsonObject,
103         jsonObjectEnd,
104         FIELD_GROUP_VISIBILITY,
105         groupInfo.groupVisibility,
106         JsonType::NUMBER,
107         false,
108         parseResult,
109         ArrayType::NOT_ARRAY);
110 }
111 
CheckSendResultPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility)112 int32_t DistributedSchedPermission::CheckSendResultPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
113     const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
114 {
115     // 1.check account access permission in no account networking environment.
116     if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
117         HILOGE("CheckAccountAccessPermission denied or failed!");
118         return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
119     }
120     // 2.check component access permission, when the ability is not visible.
121     if (!CheckComponentAccessPermission(targetAbility, callerInfo, accountInfo, want)) {
122         HILOGE("CheckComponentAccessPermission denied or failed! the callee component do not have permission");
123         return DMS_COMPONENT_ACCESS_PERMISSION_DENIED;
124     }
125     HILOGI("CheckSendResultPermission success!!");
126     return ERR_OK;
127 }
128 
CheckStartPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility,bool isSameBundle)129 int32_t DistributedSchedPermission::CheckStartPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
130     const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility, bool isSameBundle)
131 {
132     // 1.check account access permission in no account networking environment.
133     if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
134         HILOGE("CheckAccountAccessPermission denied or failed!");
135         return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
136     }
137     // 2.check start control permissions.
138     if (!CheckStartControlPermission(targetAbility, callerInfo, want, isSameBundle)) {
139         HILOGE("CheckStartControlPermission denied or failed! the callee component do not have permission");
140         return DMS_START_CONTROL_PERMISSION_DENIED;
141     }
142     HILOGI("CheckDistributedPermission success!");
143     return ERR_OK;
144 }
145 
CheckStartControlPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want,bool isSameBundle)146 bool DistributedSchedPermission::CheckStartControlPermission(const AppExecFwk::AbilityInfo& targetAbility,
147     const CallerInfo& callerInfo, const AAFwk::Want& want, bool isSameBundle)
148 {
149     HILOGD("Check start control permission enter");
150     return ((want.GetFlags() & AAFwk::Want::FLAG_ABILITY_CONTINUATION) != 0) ?
151         CheckMigrateStartCtrlPer(targetAbility, callerInfo, want, isSameBundle) :
152         CheckCollaborateStartCtrlPer(targetAbility, callerInfo, want);
153 }
154 
CheckCollabStartPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility)155 int32_t DistributedSchedPermission::CheckCollabStartPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
156     const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
157 {
158     // 1.check account access permission in no account networking environment.
159     bool isNewCollab = true;
160     if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName, isNewCollab)) {
161         HILOGE("CheckAccountAccessPermission denied or failed!");
162         return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
163     }
164     // 2.check start control permissions.
165     if (!CheckNewCollabStartControlPermission(targetAbility, callerInfo, want)) {
166         HILOGE("CheckNewCollabStartControlPermission denied or failed! the callee component do not have permission");
167         return DMS_START_CONTROL_PERMISSION_DENIED;
168     }
169     HILOGI("CheckDistributedPermission success!");
170     return ERR_OK;
171 }
172 
173 
GetAccountInfo(const std::string & remoteNetworkId,const CallerInfo & callerInfo,AccountInfo & accountInfo)174 int32_t DistributedSchedPermission::GetAccountInfo(const std::string& remoteNetworkId,
175     const CallerInfo& callerInfo, AccountInfo& accountInfo)
176 {
177     if (remoteNetworkId.empty()) {
178         HILOGE("remoteNetworkId is empty");
179         return ERR_NULL_OBJECT;
180     }
181     std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(remoteNetworkId);
182     if (udid.empty()) {
183         HILOGE("udid is empty");
184         return ERR_NULL_OBJECT;
185     }
186     if (!GetOsAccountData(accountInfo)) {
187         HILOGE("Get Os accountId and userId fail.");
188         return INVALID_PARAMETERS_ERR;
189     }
190 
191 #ifdef DMSFWK_SAME_ACCOUNT
192     if (CheckSameAccount(remoteNetworkId, accountInfo, callerInfo, true)) {
193         return ERR_OK;
194     }
195     HILOGI("check same account by DM fail, will try check access Group by hichain");
196 #endif // DMSFWK_SAME_ACCOUNT
197 
198     if (GetRelatedGroups(udid, callerInfo.bundleNames, accountInfo)) {
199         return ERR_OK;
200     }
201     HILOGI("Check access Group by hichain fail, will try check different account ACL by DM.");
202     if (CheckAclList(remoteNetworkId, accountInfo, callerInfo, true)) {
203         return ERR_OK;
204     }
205     HILOGE("Check different account ACL list by DM fail.");
206     return  INVALID_PARAMETERS_ERR;
207 }
208 
GetOsAccountData(AccountInfo & dmsAccountInfo)209 bool DistributedSchedPermission::GetOsAccountData(AccountInfo& dmsAccountInfo)
210 {
211 #ifdef OS_ACCOUNT_PART
212     std::vector<int32_t> ids;
213     ErrCode ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
214     if (ret != ERR_OK || ids.empty()) {
215         HILOGE("Get userId from active Os AccountIds fail, ret : %{public}d", ret);
216         return false;
217     }
218     dmsAccountInfo.userId = ids[0];
219 
220     AccountSA::OhosAccountInfo osAccountInfo;
221     ret = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(osAccountInfo);
222     if (ret != 0 || osAccountInfo.uid_ == "") {
223         HILOGE("Get accountId from Ohos account info fail, ret: %{public}d.", ret);
224         return false;
225     }
226     dmsAccountInfo.activeAccountId = osAccountInfo.uid_;
227     HILOGI("Get caller dmsAccountInfo OK, accountId %{public}s, userId %{public}s.",
228         GetAnonymStr(dmsAccountInfo.activeAccountId).c_str(), GetAnonymInt32(dmsAccountInfo.userId).c_str());
229 #endif
230     return true;
231 }
232 
CheckSameAccount(const std::string & dstNetworkId,const AccountInfo & dmsAccountInfo,const CallerInfo & callerInfo,bool isSrc)233 bool DistributedSchedPermission::CheckSameAccount(const std::string& dstNetworkId,
234     const AccountInfo& dmsAccountInfo, const CallerInfo& callerInfo, bool isSrc)
235 {
236     HILOGI("called");
237     if (IsHigherAclVersion(callerInfo)) {
238         return CheckDstSameAccount(dstNetworkId, dmsAccountInfo, callerInfo, isSrc);
239     } else {
240         return CheckLowVersionSameAccount(dstNetworkId, dmsAccountInfo, callerInfo, isSrc);
241     }
242 }
243 
IsHigherAclVersion(const CallerInfo & callerInfo)244 bool DistributedSchedPermission::IsHigherAclVersion(const CallerInfo& callerInfo)
245 {
246     HILOGI("called");
247     auto extraInfoJson = callerInfo.extraInfoJson;
248     if (extraInfoJson.empty() || extraInfoJson.find(DMS_VERSION_ID) == extraInfoJson.end()) {
249         HILOGW("get dmsVersion failed");
250         return false;
251     }
252     if (extraInfoJson[DMS_VERSION_ID].is_string()) {
253         std::string dmsVersion = extraInfoJson[DMS_VERSION_ID];
254         int32_t major = 0;
255         int32_t minor = 0;
256         int32_t patch = 0;
257         if (sscanf_s(dmsVersion.c_str(), "%d.%d.%d", &major, &minor, &patch) != NUMBER_OF_VERSION_TRUNCATION) {
258             HILOGW("get dmsVersion failed");
259             return false;
260         }
261         HILOGW("major is %{public}d", major);
262         if (major < HIGH_CONTINUE_ACL_VERSION) {
263             HILOGW("dmsVersion is %{public}s", dmsVersion.c_str());
264             return false;
265         }
266     }
267     if (extraInfoJson[DMS_VERSION_ID].is_number() &&
268         extraInfoJson[DMS_VERSION_ID].get<int>() < HIGH_CONTINUE_ACL_VERSION) {
269         HILOGW("dmsVersion is %{public}d", extraInfoJson[DMS_VERSION_ID].get<int>());
270         return false;
271     }
272     return true;
273 }
274 
CheckDstSameAccount(const std::string & dstNetworkId,const AccountInfo & dmsAccountInfo,const CallerInfo & callerInfo,bool isSrc)275 bool DistributedSchedPermission::CheckDstSameAccount(const std::string& dstNetworkId,
276     const AccountInfo& dmsAccountInfo, const CallerInfo& callerInfo, bool isSrc)
277 {
278 #ifdef DMSFWK_SAME_ACCOUNT
279     HILOGI("called");
280     DmAccessCaller dmSrcCaller = {
281         .accountId = dmsAccountInfo.activeAccountId,
282         .networkId = callerInfo.sourceDeviceId,
283         .userId = dmsAccountInfo.userId,
284         .tokenId = callerInfo.accessToken,
285     };
286     DmAccessCallee dmDstCallee = {
287         .networkId = dstNetworkId,
288         .peerId = "",
289     };
290     auto checkIsSameAccountLambda = [&](bool isSink) -> bool {
291         for (const auto& bundleName : callerInfo.bundleNames) {
292             dmSrcCaller.pkgName = bundleName;
293             HILOGI("dmSrcCaller networkId %{public}s, accountId %{public}s, userId %{public}s, pkgName %{public}s; "
294                 "dmDstCallee networkId %{public}s.", GetAnonymStr(dmSrcCaller.networkId).c_str(),
295                 GetAnonymStr(dmSrcCaller.accountId).c_str(), GetAnonymInt32(dmSrcCaller.userId).c_str(),
296                 dmSrcCaller.pkgName.c_str(), GetAnonymStr(dmDstCallee.networkId).c_str());
297             if (isSink ? DeviceManager::GetInstance().CheckSinkIsSameAccount(dmSrcCaller, dmDstCallee)
298                        : DeviceManager::GetInstance().CheckSrcIsSameAccount(dmSrcCaller, dmDstCallee)) {
299                 return true;
300             }
301         }
302         return false;
303     };
304 #ifdef OS_ACCOUNT_PART
305     if (!isSrc) {
306         AccountInfo dstAccountInfo;
307         if (!GetOsAccountData(dstAccountInfo)) {
308             HILOGE("Get Os accountId and userId fail.");
309             return false;
310         }
311         dmDstCallee.accountId = dstAccountInfo.activeAccountId;
312         dmDstCallee.userId = dstAccountInfo.userId;
313         HILOGI("calleeAccountId: %{public}s, callerUserId: %{public}d",
314             GetAnonymStr(dmDstCallee.accountId).c_str(), dmDstCallee.userId);
315         return checkIsSameAccountLambda(true);
316     }
317 #endif
318     return checkIsSameAccountLambda(!isSrc);
319 #else // DMSFWK_SAME_ACCOUNT
320     HILOGI("Not support remote same account check.");
321     return false;
322 #endif // DMSFWK_SAME_ACCOUNT
323 }
324 
CheckLowVersionSameAccount(const std::string & dstNetworkId,const AccountInfo & dmsAccountInfo,const CallerInfo & callerInfo,bool isSrc)325 bool DistributedSchedPermission::CheckLowVersionSameAccount(const std::string& dstNetworkId,
326     const AccountInfo& dmsAccountInfo, const CallerInfo& callerInfo, bool isSrc)
327 {
328 #ifdef DMSFWK_SAME_ACCOUNT
329     HILOGI("called");
330     DmAccessCaller dmSrcCaller = {
331         .accountId = dmsAccountInfo.activeAccountId,
332         .networkId = callerInfo.sourceDeviceId,
333         .userId = dmsAccountInfo.userId,
334         .tokenId = callerInfo.accessToken,
335     };
336     DmAccessCallee dmDstCallee = {
337         .networkId = dstNetworkId,
338         .peerId = "",
339     };
340     for (const auto& bundleName : callerInfo.bundleNames) {
341         dmSrcCaller.pkgName = bundleName;
342         HILOGI("dmSrcCaller networkId %{public}s, accountId %{public}s, userId %{public}s, pkgName %{public}s; "
343             "dmDstCallee networkId %{public}s.", GetAnonymStr(dmSrcCaller.networkId).c_str(),
344             GetAnonymStr(dmSrcCaller.accountId).c_str(), GetAnonymInt32(dmSrcCaller.userId).c_str(),
345             dmSrcCaller.pkgName.c_str(), GetAnonymStr(dmDstCallee.networkId).c_str());
346         if (DeviceManager::GetInstance().CheckIsSameAccount(dmSrcCaller, dmDstCallee)) {
347             return true;
348         }
349     }
350         return false;
351 #else // DMSFWK_SAME_ACCOUNT
352     HILOGI("Not support remote same account check.");
353     return false;
354 #endif // DMSFWK_SAME_ACCOUNT
355 }
356 
CheckAclList(const std::string & dstNetworkId,const AccountInfo & dmsAccountInfo,const CallerInfo & callerInfo,bool isSrc,const std::string & targetBundleName)357 bool DistributedSchedPermission::CheckAclList(const std::string& dstNetworkId, const AccountInfo& dmsAccountInfo,
358     const CallerInfo& callerInfo, bool isSrc, const std::string& targetBundleName)
359 {
360     HILOGI("called");
361     if (IsHigherAclVersion(callerInfo)) {
362         return CheckNewAclList(dstNetworkId, dmsAccountInfo, callerInfo, isSrc, targetBundleName);
363     } else {
364         return CheckLowVersionAclList(dstNetworkId, dmsAccountInfo, callerInfo, isSrc, targetBundleName);
365     }
366 }
367 
CheckNewAclList(const std::string & dstNetworkId,const AccountInfo & dmsAccountInfo,const CallerInfo & callerInfo,bool isSrc,const std::string & targetBundleName)368 bool DistributedSchedPermission::CheckNewAclList(const std::string& dstNetworkId, const AccountInfo& dmsAccountInfo,
369     const CallerInfo& callerInfo, bool isSrc, const std::string& targetBundleName)
370 {
371     HILOGI("called");
372     DmAccessCaller dmSrcCaller = {
373         .accountId = dmsAccountInfo.activeAccountId,
374         .networkId = callerInfo.sourceDeviceId,
375         .userId = dmsAccountInfo.userId,
376         .tokenId = callerInfo.accessToken,
377     };
378     DmAccessCallee dmDstCallee = {
379         .networkId = dstNetworkId,
380         .peerId = "",
381     };
382     auto checkAccessControlLambda = [&](bool isSink) -> bool {
383         HILOGI("dmSrcCaller networkId %{public}s, accountId %{public}s, userId %{public}s",
384             GetAnonymStr(dmSrcCaller.networkId).c_str(), GetAnonymStr(dmSrcCaller.accountId).c_str(),
385             GetAnonymInt32(dmSrcCaller.userId).c_str());
386         for (const auto& bundleName : callerInfo.bundleNames) {
387             dmSrcCaller.pkgName = bundleName;
388             HILOGI("pkgName: %{public}s.", dmSrcCaller.pkgName.c_str());
389             if (isSink ? DeviceManager::GetInstance().CheckSinkAccessControl(dmSrcCaller, dmDstCallee)
390                        : DeviceManager::GetInstance().CheckSrcAccessControl(dmSrcCaller, dmDstCallee)) {
391                 return true;
392             }
393         }
394         dmSrcCaller.pkgName = targetBundleName;
395         HILOGI("targetBundleName: %{public}s.", dmSrcCaller.pkgName.c_str());
396         return isSink ? DeviceManager::GetInstance().CheckSinkAccessControl(dmSrcCaller, dmDstCallee)
397                     : DeviceManager::GetInstance().CheckSrcAccessControl(dmSrcCaller, dmDstCallee);
398     };
399 #ifdef OS_ACCOUNT_PART
400     if (!isSrc) {
401         AccountInfo dstAccountInfo;
402         if (!GetOsAccountData(dstAccountInfo)) {
403             HILOGE("Get Os accountId and userId fail.");
404             return false;
405         }
406         dmDstCallee.accountId = dstAccountInfo.activeAccountId;
407         dmDstCallee.userId = dstAccountInfo.userId;
408         dmDstCallee.tokenId = AccessToken::AccessTokenKit::GetHapTokenID(dmDstCallee.userId, targetBundleName, 0);
409         dmDstCallee.networkId = dstNetworkId;
410         dmDstCallee.pkgName = targetBundleName;
411         HILOGI("calleeAccountId: %{public}s, callerUserId: %{public}d",
412             GetAnonymStr(dmDstCallee.accountId).c_str(), dmDstCallee.userId);
413         return checkAccessControlLambda(true);
414     }
415 #endif
416     return checkAccessControlLambda(!isSrc);
417 }
418 
CheckLowVersionAclList(const std::string & dstNetworkId,const AccountInfo & dmsAccountInfo,const CallerInfo & callerInfo,bool isSrc,const std::string & targetBundleName)419 bool DistributedSchedPermission::CheckLowVersionAclList(const std::string& dstNetworkId,
420     const AccountInfo& dmsAccountInfo, const CallerInfo& callerInfo, bool isSrc, const std::string& targetBundleName)
421 {
422     HILOGI("called");
423     DmAccessCaller dmSrcCaller = {
424         .accountId = dmsAccountInfo.activeAccountId,
425         .networkId = callerInfo.sourceDeviceId,
426         .userId = dmsAccountInfo.userId,
427         .tokenId = callerInfo.accessToken,
428     };
429     DmAccessCallee dmDstCallee = {
430         .networkId = dstNetworkId,
431         .peerId = "",
432     };
433 
434 #ifdef OS_ACCOUNT_PART
435     if (!isSrc) {
436         AccountInfo dstAccountInfo;
437         if (!GetOsAccountData(dstAccountInfo)) {
438             HILOGE("Get Os accountId and userId fail.");
439             return false;
440         }
441         dmDstCallee.accountId = dstAccountInfo.activeAccountId;
442         dmDstCallee.userId = dstAccountInfo.userId;
443         dmDstCallee.tokenId = AccessToken::AccessTokenKit::GetHapTokenID(dmDstCallee.userId, targetBundleName, 0);
444         dmDstCallee.networkId = dstNetworkId;
445         dmDstCallee.pkgName = targetBundleName;
446         HILOGI("calleeAccountId: %{public}s, callerUserId: %{public}d",
447             GetAnonymStr(dmDstCallee.accountId).c_str(), dmDstCallee.userId);
448     }
449 #endif
450     HILOGI("dmSrcCaller networkId %{public}s, accountId %{public}s, userId %{public}s",
451         GetAnonymStr(dmSrcCaller.networkId).c_str(), GetAnonymStr(dmSrcCaller.accountId).c_str(),
452         GetAnonymInt32(dmSrcCaller.userId).c_str());
453     for (const auto& bundleName : callerInfo.bundleNames) {
454         dmSrcCaller.pkgName = bundleName;
455         HILOGI("pkgName: %{public}s.", dmSrcCaller.pkgName.c_str());
456         if (DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee)) {
457             return true;
458         }
459     }
460     dmSrcCaller.pkgName = targetBundleName;
461     HILOGI("targetBundleName: %{public}s.", dmSrcCaller.pkgName.c_str());
462     return DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee);
463 }
464 
GetRelatedGroups(const std::string & udid,const std::vector<std::string> & bundleNames,AccountInfo & accountInfo)465 bool DistributedSchedPermission::GetRelatedGroups(const std::string& udid,
466     const std::vector<std::string>& bundleNames, AccountInfo& accountInfo)
467 {
468     for (const auto& bundleName : bundleNames) {
469         std::string returnGroups;
470         if (!DistributedSchedAdapter::GetInstance().GetRelatedGroups(udid, bundleName, returnGroups)) {
471             continue;
472         }
473         std::vector<GroupInfo> groupInfos;
474         if (!ParseGroupInfos(returnGroups, groupInfos)) {
475             continue;
476         }
477         for (const auto& groupInfo : groupInfos) {
478             // check group type is whether (same count or point to point) or not
479             if (groupInfo.groupType != GroupType::IDENTICAL_ACCOUNT_GROUP
480                 && groupInfo.groupType != GroupType::PEER_TO_PEER_GROUP) {
481                 continue;
482             }
483             accountInfo.groupIdList.push_back(groupInfo.groupId);
484             if (groupInfo.groupType == GroupType::IDENTICAL_ACCOUNT_GROUP
485                 && accountInfo.accountType != IDistributedSched::SAME_ACCOUNT_TYPE) {
486                 accountInfo.accountType = IDistributedSched::SAME_ACCOUNT_TYPE;
487             }
488         }
489     }
490     if (accountInfo.groupIdList.empty()) {
491         HILOGE("groupIdList is empty");
492         return false;
493     }
494     return true;
495 }
496 
ParseGroupInfos(const std::string & returnGroupStr,std::vector<GroupInfo> & groupInfos)497 bool DistributedSchedPermission::ParseGroupInfos(const std::string& returnGroupStr, std::vector<GroupInfo>& groupInfos)
498 {
499     nlohmann::json groupInfoJson = nlohmann::json::parse(returnGroupStr, nullptr, false);
500     if (groupInfoJson.is_discarded()) {
501         HILOGE("returnGroupStr parse failed");
502         return false;
503     }
504     HILOGD("groupInfoJson:%{public}s", groupInfoJson.dump().c_str());
505     groupInfos = groupInfoJson.get<std::vector<GroupInfo>>();
506     if (groupInfos.empty()) {
507         HILOGE("groupInfos is empty");
508         return false;
509     }
510     return true;
511 }
512 
GetTargetAbility(const AAFwk::Want & want,AppExecFwk::AbilityInfo & targetAbility,bool needQueryExtension) const513 bool DistributedSchedPermission::GetTargetAbility(const AAFwk::Want& want,
514     AppExecFwk::AbilityInfo& targetAbility, bool needQueryExtension) const
515 {
516     if (BundleManagerInternal::QueryAbilityInfo(want, targetAbility)) {
517         if (want.GetIntParam(DMS_MISSION_ID, DEFAULT_DMS_MISSION_ID) != DEFAULT_DMS_MISSION_ID &&
518             (targetAbility.type == AppExecFwk::AbilityType::SERVICE ||
519             targetAbility.type == AppExecFwk::AbilityType::EXTENSION)) {
520             HILOGE("StartAbilityForResult can not start service and extension ability");
521             return false;
522         }
523         return true;
524     }
525     if (needQueryExtension) {
526         HILOGI("QueryAbilityInfo failed, try to QueryExtensionAbilityInfo");
527         // try to find extension
528         AppExecFwk::ExtensionAbilityInfo extensionAbility;
529         if (BundleManagerInternal::QueryExtensionAbilityInfo(want, extensionAbility)) {
530             // extensionAbilityInfo translates to abilityInfo
531             BundleManagerInternal::InitAbilityInfoFromExtension(extensionAbility, targetAbility);
532             return true;
533         }
534     }
535     HILOGE("QueryAbilityInfo failed, want bundle name=%{public}s, ability name=%{public}s.",
536         want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str());
537     return false;
538 }
539 
CheckGetCallerPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility)540 int32_t DistributedSchedPermission::CheckGetCallerPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
541     const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
542 {
543     // 1.check account access permission in no account networking environment.
544     if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
545         HILOGE("CheckAccountAccessPermission denied or failed!");
546         return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
547     }
548     // 2. check call with same appid
549     if (!BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
550         HILOGE("the appId is different, check permission denied!");
551         return CALL_PERMISSION_DENIED;
552     }
553     // 3. check background permission
554     if (!CheckBackgroundPermission(targetAbility, callerInfo, want, false)) {
555         HILOGE("Check background permission failed!");
556         return DMS_BACKGROUND_PERMISSION_DENIED;
557     }
558     // 4. check device security level
559     if (!targetAbility.visible &&
560         !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
561         HILOGE("check device security level failed!");
562         return CALL_PERMISSION_DENIED;
563     }
564     HILOGI("CheckGetCallerPermission success!!");
565     return ERR_OK;
566 }
567 
IsFoundationCall() const568 bool DistributedSchedPermission::IsFoundationCall() const
569 {
570     uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
571     AccessToken::NativeTokenInfo nativeTokenInfo;
572     int32_t result = AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
573     if (result == ERR_OK && nativeTokenInfo.processName == FOUNDATION_PROCESS_NAME) {
574         return true;
575     }
576     HILOGE("not foundation called, processName:%{private}s", nativeTokenInfo.processName.c_str());
577     return false;
578 }
579 
IsSceneBoardCall() const580 bool DistributedSchedPermission::IsSceneBoardCall() const
581 {
582     int32_t activeAccountId = 0;
583 #ifdef OS_ACCOUNT_PART
584     std::vector<int32_t> ids;
585     int32_t errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
586     if (errCode != ERR_OK || ids.empty()) {
587         HILOGE("QueryActiveOsAccountIds failed.");
588         return false;
589     }
590     activeAccountId = ids[0];
591 #endif
592     AppExecFwk::ApplicationInfo appInfo;
593     if (BundleManagerInternal::GetApplicationInfoFromBms(BUNDLE_NAME_SCENEBOARD,
594         AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, activeAccountId, appInfo) != ERR_OK) {
595         HILOGE("get applicationInfo failed.");
596         return false;
597     }
598     auto accessTokenId = IPCSkeleton::GetCallingTokenID();
599     if (accessTokenId != appInfo.accessTokenId) {
600         HILOGE("not sceneBoard called.");
601         return false;
602     }
603     return true;
604 }
605 
CheckPermission(uint32_t accessToken,const std::string & permissionName) const606 int32_t DistributedSchedPermission::CheckPermission(uint32_t accessToken, const std::string& permissionName) const
607 {
608     HILOGI("CheckPermission called.");
609     if (VerifyPermission(accessToken, permissionName)) {
610         return ERR_OK;
611     }
612     return DMS_PERMISSION_DENIED;
613 }
614 
CheckPermissionAll(uint32_t accessToken,const std::string & permissionName) const615 int32_t DistributedSchedPermission::CheckPermissionAll(uint32_t accessToken, const std::string& permissionName) const
616 {
617     HILOGI("CheckPermissionAll called.");
618     if (VerifyPermission(accessToken, permissionName)) {
619         return ERR_OK;
620     }
621     return DMS_PERMISSION_DENIED;
622 }
623 
MarkUriPermission(OHOS::AAFwk::Want & want,uint32_t accessToken)624 void DistributedSchedPermission::MarkUriPermission(OHOS::AAFwk::Want& want, uint32_t accessToken)
625 {
626     if ((want.GetFlags() & (Want::FLAG_AUTH_READ_URI_PERMISSION | Want::FLAG_AUTH_WRITE_URI_PERMISSION)) == 0) {
627         return;
628     }
629     auto bms = BundleManagerInternal::GetBundleManager();
630     if (bms == nullptr) {
631         HILOGW("Failed to get bms.");
632         return;
633     }
634     std::vector<std::string> uriVec = want.GetStringArrayParam(PARAMS_STREAM);
635     std::string uriStr = want.GetUri().ToString();
636     uriVec.emplace_back(uriStr);
637     std::vector<std::string> uriVecPermission;
638     HILOGI("GrantUriPermission uriVec size: %{public}zu", uriVec.size());
639     for (std::string str : uriVec) {
640         Uri uri(str);
641         if (!IsDistributedFile(uri.GetPath())) {
642             continue;
643         }
644         std::string authority = uri.GetAuthority();
645         HILOGI("uri authority is %{public}s.", authority.c_str());
646         AppExecFwk::BundleInfo bundleInfo;
647         int32_t activeAccountId = 0;
648 #ifdef OS_ACCOUNT_PART
649         std::vector<int32_t> ids;
650         int32_t errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
651         if (errCode != ERR_OK || ids.empty()) {
652             return;
653         }
654         activeAccountId = ids[0];
655 #endif
656         if (!bms->GetBundleInfo(authority,
657             AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, activeAccountId)) {
658             HILOGW("To fail to get bundle info according to uri.");
659             continue;
660         }
661         if (bundleInfo.applicationInfo.accessTokenId == accessToken) {
662             HILOGI("uri token is true.");
663             uriVecPermission.emplace_back(str);
664         }
665     }
666     want.SetParam(PARAMS_URI, uriVecPermission);
667 }
668 
IsDistributedFile(const std::string & path) const669 bool DistributedSchedPermission::IsDistributedFile(const std::string& path) const
670 {
671     if (path.compare(0, DISTRIBUTED_FILES_PATH.size(), DISTRIBUTED_FILES_PATH) == 0) {
672         return true;
673     }
674     HILOGE("uri path is false.");
675     return false;
676 }
677 
VerifyPermission(uint32_t accessToken,const std::string & permissionName) const678 bool DistributedSchedPermission::VerifyPermission(uint32_t accessToken, const std::string& permissionName) const
679 {
680     int32_t result = AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionName);
681     if (result == AccessToken::PermissionState::PERMISSION_DENIED) {
682         HILOGE("permission denied, permissionName:%{public}s", permissionName.c_str());
683         return false;
684     }
685     HILOGD("permission matched.");
686     return true;
687 }
688 
CheckAccountAccessPermission(const CallerInfo & callerInfo,const AccountInfo & accountInfo,const std::string & targetBundleName,bool isNewCollab)689 bool DistributedSchedPermission::CheckAccountAccessPermission(const CallerInfo& callerInfo,
690     const AccountInfo& accountInfo, const std::string& targetBundleName, bool isNewCollab)
691 {
692     std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(callerInfo.sourceDeviceId);
693     std::string dstNetworkId;
694     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(dstNetworkId)) {
695         HILOGE("GetLocalDeviceId failed");
696         return false;
697     }
698 
699 #ifdef DMSFWK_SAME_ACCOUNT
700     if (CheckSameAccount(dstNetworkId, accountInfo, callerInfo, false)) {
701         return true;
702     }
703     if (isNewCollab && !BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetBundleName)) {
704         HILOGE("the appId isn't the same, check new collab start control permission fail.");
705         return false;
706     }
707     HILOGI("check same account by DM fail, will try check access Group by hichain");
708 #endif
709 
710     if (DistributedSchedAdapter::GetInstance().CheckAccessToGroup(udid, targetBundleName)) {
711         return true;
712     }
713 
714     HILOGI("Check access Group by hichain fail, will try check different account ACL by DM.");
715     if (CheckAclList(dstNetworkId, accountInfo, callerInfo, false, targetBundleName)) {
716         return true;
717     }
718 
719     HILOGE("Check different account ACL by DM fail.");
720     return false;
721 }
722 
CheckComponentAccessPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AccountInfo & accountInfo,const AAFwk::Want & want) const723 bool DistributedSchedPermission::CheckComponentAccessPermission(const AppExecFwk::AbilityInfo& targetAbility,
724     const CallerInfo& callerInfo, const AccountInfo& accountInfo, const AAFwk::Want& want) const
725 {
726     // reject directly when in no account networking environment and target ability is not visible,
727     if (!targetAbility.visible) {
728         HILOGE("target ability is not visible, permission denied!");
729         return false;
730     }
731     HILOGD("check component permission success");
732     return true;
733 }
734 
CheckMigrateStartCtrlPer(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want,bool isSameBundle)735 bool DistributedSchedPermission::CheckMigrateStartCtrlPer(const AppExecFwk::AbilityInfo& targetAbility,
736     const CallerInfo& callerInfo, const AAFwk::Want& want, bool isSameBundle)
737 {
738     std::string bundleName = want.GetBundle();
739     // check if continuation with same appid
740     HILOGI("Check migration start control permission with same appid enter.");
741     if (!isSameBundle) {
742         return true;
743     }
744     if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
745         HILOGD("the appId is the same, check migration start control permission success!");
746         return true;
747     }
748     HILOGE("the appId is different in the migration scenario, permission denied!");
749     return false;
750 }
751 
CheckCollaborateStartCtrlPer(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want) const752 bool DistributedSchedPermission::CheckCollaborateStartCtrlPer(const AppExecFwk::AbilityInfo& targetAbility,
753     const CallerInfo& callerInfo, const AAFwk::Want& want) const
754 {
755     HILOGI("Check collaboration start control permission enter.");
756     // 1. check background permission
757     if (!CheckBackgroundPermission(targetAbility, callerInfo, want, true)) {
758         HILOGE("Check background permission failed!");
759         return false;
760     }
761     // 2. check device security level
762     if (!targetAbility.visible &&
763         !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
764         HILOGE("check device security level failed!");
765         return false;
766     }
767     // 3. check start or connect ability with same appid
768     if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
769         HILOGD("the appId is the same, check permission success!");
770         return true;
771     }
772     // 4. check if target ability is not visible and without PERMISSION_START_INVISIBLE_ABILITY
773     if (!CheckTargetAbilityVisible(targetAbility, callerInfo)) {
774         HILOGE("target ability is not visible and has no PERMISSION_START_INVISIBLE_ABILITY, permission denied!");
775         return false;
776     }
777     // 5. check if service of fa mode can associatedWakeUp
778     if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
779         !targetAbility.applicationInfo.associatedWakeUp) {
780         HILOGE("target ability is service ability(FA) and associatedWakeUp is false, permission denied!");
781         return false;
782     }
783     HILOGD("Check collaboration start control permission success");
784     return true;
785 }
786 
CheckNewCollabStartControlPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want)787 bool DistributedSchedPermission::CheckNewCollabStartControlPermission(const AppExecFwk::AbilityInfo& targetAbility,
788     const CallerInfo& callerInfo, const AAFwk::Want& want)
789 {
790     HILOGI("Check new collaboration start control permission enter.");
791     // 1. check background permission
792     if (!CheckNewCollabBackgroundPermission(callerInfo, want)) {
793         HILOGE("Check background permission failed!");
794         return false;
795     }
796     // 2. check device security level
797     if (!targetAbility.visible &&
798         !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
799         HILOGE("check device security level failed!");
800         return false;
801     }
802     // 3. check start or connect ability with same appid
803     if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
804         HILOGD("the appId is the same, check permission success!");
805         return true;
806     }
807     // 4. check if target ability is not visible and without PERMISSION_START_INVISIBLE_ABILITY
808     if (!CheckTargetAbilityVisible(targetAbility, callerInfo)) {
809         HILOGE("target ability is not visible and has no PERMISSION_START_INVISIBLE_ABILITY, permission denied!");
810         return false;
811     }
812     // 5. check if service of fa mode can associatedWakeUp
813     if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
814         !targetAbility.applicationInfo.associatedWakeUp) {
815         HILOGE("target ability is service ability(FA) and associatedWakeUp is false, permission denied!");
816         return false;
817     }
818     HILOGD("Check collaboration start control permission success");
819     return true;
820 }
821 
CheckNewCollabBackgroundPermission(const CallerInfo & callerInfo,const AAFwk::Want & want)822 bool DistributedSchedPermission::CheckNewCollabBackgroundPermission(const CallerInfo& callerInfo,
823     const AAFwk::Want& want)
824 {
825     bool isCallerForeGround = want.GetBoolParam(DMS_IS_CALLER_FOREGROUND, true);
826     if (isCallerForeGround) {
827         HILOGI("non-background invocation, no need to verify this permission.");
828         return true;
829     }
830     uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
831         callerInfo.accessToken);
832     if (dAccessToken == 0) {
833         HILOGE("dAccessTokenID is invalid!");
834         return false;
835     }
836     // check if background's ability has PERMISSION_START_ABILITIES_FROM_BACKGROUND
837     if (CheckPermission(dAccessToken, PERMISSION_START_ABILITIES_FROM_BACKGROUND) == ERR_OK ||
838         CheckPermission(dAccessToken, PERMISSION_START_ABILIIES_FROM_BACKGROUND) == ERR_OK) {
839         HILOGD("the app has PERMISSION_START_ABILITIES_FROM_BACKGROUND");
840         return true;
841     }
842     HILOGE("CheckBackgroundPermission failed!");
843     return false;
844 }
845 
CheckSrcBackgroundPermission(uint32_t accessTokenId)846 bool DistributedSchedPermission::CheckSrcBackgroundPermission(uint32_t accessTokenId)
847 {
848     HILOGI("called");
849     if (IsAbilityForeground(accessTokenId)) {
850         return true;
851     }
852     // check if background's ability has PERMISSION_START_ABILITIES_FROM_BACKGROUND
853     if (CheckPermission(accessTokenId, PERMISSION_START_ABILITIES_FROM_BACKGROUND) == ERR_OK ||
854         CheckPermission(accessTokenId, PERMISSION_START_ABILIIES_FROM_BACKGROUND) == ERR_OK) {
855         HILOGD("the app has PERMISSION_START_ABILITIES_FROM_BACKGROUND");
856         return true;
857     }
858     HILOGE("CheckBackgroundPermission failed!");
859     return DMS_START_CONTROL_PERMISSION_DENIED;
860 }
861 
IsAbilityForeground(uint32_t accessTokenId)862 bool DistributedSchedPermission::IsAbilityForeground(uint32_t accessTokenId)
863 {
864     HILOGI("called");
865     sptr<AppExecFwk::IAppMgr> appMgr = GetAppManager();
866     if (appMgr == nullptr) {
867         HILOGE("failed to get app manager service");
868         return false;
869     }
870     std::vector<AppExecFwk::AppStateData> list;
871     int32_t ret = appMgr->GetForegroundApplications(list);
872     if (ret != ERR_OK) {
873         HILOGE("error:%{public}d", ret);
874         return false;
875     }
876     for (auto& appStateData : list) {
877         if (appStateData.accessTokenId == accessTokenId) {
878             HILOGI("the ability is foreground, bundleName : %{public}s", appStateData.bundleName.c_str());
879             return true;
880         }
881     }
882     HILOGI("the ability is background");
883     return false;
884 }
GetAppManager() const885 sptr<AppExecFwk::IAppMgr> DistributedSchedPermission::GetAppManager() const
886 {
887     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
888     if (samgr == nullptr) {
889         HILOGE("system ability manager is nullptr.");
890         return nullptr;
891     }
892     sptr<AppExecFwk::IAppMgr> appObject = iface_cast<AppExecFwk::IAppMgr>(samgr->GetSystemAbility(APP_MGR_SERVICE_ID));
893     if (appObject == nullptr) {
894         HILOGE("failed to get app manager service");
895         return nullptr;
896     }
897     return appObject;
898 }
899 
CheckBackgroundPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want,bool needCheckApiVersion) const900 bool DistributedSchedPermission::CheckBackgroundPermission(const AppExecFwk::AbilityInfo& targetAbility,
901     const CallerInfo& callerInfo, const AAFwk::Want& want, bool needCheckApiVersion) const
902 {
903     if (callerInfo.extraInfoJson.empty() ||
904         callerInfo.extraInfoJson.find(DMS_VERSION_ID) == callerInfo.extraInfoJson.end()) {
905         HILOGD("the version is low");
906         return true;
907     }
908     AAFwk::Want* remoteWant = const_cast<Want*>(&want);
909     bool isCallerBackGround = remoteWant->GetBoolParam(DMS_IS_CALLER_BACKGROUND, true);
910     remoteWant->RemoveParam(DMS_IS_CALLER_BACKGROUND);
911     if (!isCallerBackGround) {
912         HILOGD("the app is foreground");
913         return true;
914     }
915     int apiVersion = remoteWant->GetIntParam(DMS_API_VERSION, DEFAULT_DMS_API_VERSION);
916     remoteWant->RemoveParam(DMS_API_VERSION);
917     // service in fa mode(API 8) do not need check
918     if (needCheckApiVersion && CheckMinApiVersion(targetAbility, apiVersion)) {
919         HILOGD("the app is service ability of fa mode and is under api 8");
920         return true;
921     }
922     uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
923         callerInfo.accessToken);
924     if (dAccessToken == 0) {
925         HILOGE("dAccessTokenID is invalid!");
926         return false;
927     }
928     // check if background's ability has PERMISSION_START_ABILITIES_FROM_BACKGROUND
929     if (CheckPermission(dAccessToken, PERMISSION_START_ABILITIES_FROM_BACKGROUND) == ERR_OK ||
930         CheckPermission(dAccessToken, PERMISSION_START_ABILIIES_FROM_BACKGROUND) == ERR_OK) {
931         HILOGD("the app has PERMISSION_START_ABILITIES_FROM_BACKGROUND");
932         return true;
933     }
934     HILOGE("CheckBackgroundPermission failed!");
935     return false;
936 }
937 
CheckMinApiVersion(const AppExecFwk::AbilityInfo & targetAbility,int32_t apiVersion) const938 bool DistributedSchedPermission::CheckMinApiVersion(const AppExecFwk::AbilityInfo& targetAbility,
939     int32_t apiVersion) const
940 {
941     if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
942         apiVersion <= FA_MODULE_ALLOW_MIN_API_VERSION) {
943         HILOGD("CheckMinApiVersion pass");
944         return true;
945     }
946     return false;
947 }
948 
CheckDeviceSecurityLevel(const std::string & srcDeviceId,const std::string & dstDeviceId) const949 bool DistributedSchedPermission::CheckDeviceSecurityLevel(const std::string& srcDeviceId,
950     const std::string& dstDeviceId) const
951 {
952     std::string srcUdid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(srcDeviceId);
953     if (srcUdid.empty()) {
954         HILOGE("src udid is empty");
955         return false;
956     }
957     std::string dstUdid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(dstDeviceId);
958     if (dstUdid.empty()) {
959         HILOGE("dst udid is empty");
960         return false;
961     }
962     int32_t srcDeviceSecurityLevel = GetDeviceSecurityLevel(srcUdid);
963     int32_t dstDeviceSecurityLevel = GetDeviceSecurityLevel(dstUdid);
964     if (srcDeviceSecurityLevel == DEFAULT_DEVICE_SECURITY_LEVEL ||
965         srcDeviceSecurityLevel < dstDeviceSecurityLevel) {
966         HILOGE("the device security of source device is lower");
967         return false;
968     }
969     return true;
970 }
971 
GetDeviceSecurityLevel(const std::string & udid) const972 int32_t DistributedSchedPermission::GetDeviceSecurityLevel(const std::string& udid) const
973 {
974     DeviceIdentify devIdentify;
975     devIdentify.length = DEVICE_ID_MAX_LEN;
976     int32_t ret = memcpy_s(devIdentify.identity, DEVICE_ID_MAX_LEN, udid.c_str(), udid.length());
977     if (ret != 0) {
978         HILOGE("str copy failed %{public}d", ret);
979         return DEFAULT_DEVICE_SECURITY_LEVEL;
980     }
981     DeviceSecurityInfo *info = nullptr;
982     ret = RequestDeviceSecurityInfo(&devIdentify, nullptr, &info);
983     if (ret != SUCCESS) {
984         HILOGE("request device security info failed %{public}d", ret);
985         FreeDeviceSecurityInfo(info);
986         info = nullptr;
987         return DEFAULT_DEVICE_SECURITY_LEVEL;
988     }
989     int32_t level = 0;
990     ret = GetDeviceSecurityLevelValue(info, &level);
991     HILOGD("get device security level, level is %{public}d", level);
992     FreeDeviceSecurityInfo(info);
993     info = nullptr;
994     if (ret != SUCCESS) {
995         HILOGE("get device security level failed %{public}d", ret);
996         return DEFAULT_DEVICE_SECURITY_LEVEL;
997     }
998     return level;
999 }
1000 
CheckTargetAbilityVisible(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo) const1001 bool DistributedSchedPermission::CheckTargetAbilityVisible(const AppExecFwk::AbilityInfo& targetAbility,
1002     const CallerInfo& callerInfo) const
1003 {
1004     if (targetAbility.visible) {
1005         HILOGD("Target ability is visible.");
1006         return true;
1007     }
1008     uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
1009         callerInfo.accessToken);
1010     if (dAccessToken == 0) {
1011         HILOGE("dAccessTokenID is invalid!");
1012         return false;
1013     }
1014     if (CheckPermissionAll(dAccessToken, PERMISSION_START_INVISIBLE_ABILITY) != ERR_OK) {
1015         HILOGE("CheckTargetAbilityVisible failed.");
1016         return false;
1017     }
1018     HILOGD("CheckTargetAbilityVisible passed.");
1019     return true;
1020 }
1021 
RemoveRemoteObjectFromWant(std::shared_ptr<AAFwk::Want> want) const1022 void DistributedSchedPermission::RemoveRemoteObjectFromWant(std::shared_ptr<AAFwk::Want> want) const
1023 {
1024     if (want == nullptr) {
1025         return;
1026     }
1027     WantParams wantParams = want->GetParams();
1028     std::map<std::string, sptr<IInterface>> params = wantParams.GetParams();
1029     for (auto param : params) {
1030         sptr<IInterface> object = param.second;
1031         IWantParams *wp = IWantParams::Query(object);
1032         if (wp == nullptr) {
1033             continue;
1034         }
1035         WantParams value = WantParamWrapper::Unbox(wp);
1036         auto type = value.GetParam(TYPE_PROPERTY);
1037         AAFwk::IString *typeP = AAFwk::IString::Query(type);
1038         if (typeP == nullptr) {
1039             continue;
1040         }
1041         std::string typeValue = AAFwk::String::Unbox(typeP);
1042         if (typeValue == REMOTE_OBJECT) {
1043             wantParams.Remove(param.first);
1044         }
1045     }
1046     want->SetParams(wantParams);
1047 }
1048 }
1049 }
1050