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