1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "distributed_sched_permission.h"
17
18 #include "accesstoken_kit.h"
19 #include "adapter/dnetwork_adapter.h"
20 #include "bundle/bundle_manager_internal.h"
21 #include "caller_info.h"
22 #include "datetime_ex.h"
23 #include "device_auth_defines.h"
24 #include "device_security_defines.h"
25 #include "device_security_info.h"
26 #include "distributed_sched_adapter.h"
27 #include "dtbschedmgr_log.h"
28 #include "ipc_skeleton.h"
29 #include "json_util.h"
30 #include "os_account_manager.h"
31
32 namespace OHOS {
33 namespace DistributedSchedule {
34 using namespace OHOS::Security;
35 using namespace AAFwk;
36 namespace {
37 const std::string FOUNDATION_PROCESS_NAME = "foundation";
38 const std::string DMS_API_VERSION = "dmsApiVersion";
39 const std::string DMS_IS_CALLER_BACKGROUND = "dmsIsCallerBackGround";
40 const std::string DMS_MISSION_ID = "dmsMissionId";
41 const std::string DMS_VERSION_ID = "dmsVersion";
42 const std::string PARAMS_URI = "ability.verify.uri";
43 const std::string PARAMS_STREAM = "ability.params.stream";
44 const std::string PERMISSION_START_ABILIIES_FROM_BACKGROUND = "ohos.permission.START_ABILIIES_FROM_BACKGROUND";
45 const std::string PERMISSION_START_ABILITIES_FROM_BACKGROUND = "ohos.permission.START_ABILITIES_FROM_BACKGROUND";
46 const std::string PERMISSION_START_INVISIBLE_ABILITY = "ohos.permission.START_INVISIBLE_ABILITY";
47 const std::string DISTRIBUTED_FILES_PATH = "/data/storage/el2/distributedfiles/";
48 const std::string BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
49 constexpr int32_t DEFAULT_DMS_API_VERSION = 9;
50 const int DEFAULT_DMS_MISSION_ID = -1;
51 const int FA_MODULE_ALLOW_MIN_API_VERSION = 8;
52 const int DEFAULT_DEVICE_SECURITY_LEVEL = -1;
53 }
54 IMPLEMENT_SINGLE_INSTANCE(DistributedSchedPermission);
from_json(const nlohmann::json & jsonObject,GroupInfo & groupInfo)55 void from_json(const nlohmann::json& jsonObject, GroupInfo& groupInfo)
56 {
57 const auto &jsonObjectEnd = jsonObject.end();
58 int32_t parseResult = ERR_OK;
59 GetValueIfFindKey<std::string>(jsonObject,
60 jsonObjectEnd,
61 FIELD_GROUP_NAME,
62 groupInfo.groupName,
63 JsonType::STRING,
64 false,
65 parseResult,
66 ArrayType::NOT_ARRAY);
67 GetValueIfFindKey<std::string>(jsonObject,
68 jsonObjectEnd,
69 FIELD_GROUP_ID,
70 groupInfo.groupId,
71 JsonType::STRING,
72 false,
73 parseResult,
74 ArrayType::NOT_ARRAY);
75 GetValueIfFindKey<std::string>(jsonObject,
76 jsonObjectEnd,
77 FIELD_GROUP_OWNER,
78 groupInfo.groupOwner,
79 JsonType::STRING,
80 false,
81 parseResult,
82 ArrayType::NOT_ARRAY);
83 GetValueIfFindKey<int32_t>(jsonObject,
84 jsonObjectEnd,
85 FIELD_GROUP_TYPE,
86 groupInfo.groupType,
87 JsonType::NUMBER,
88 false,
89 parseResult,
90 ArrayType::NOT_ARRAY);
91 GetValueIfFindKey<int32_t>(jsonObject,
92 jsonObjectEnd,
93 FIELD_GROUP_VISIBILITY,
94 groupInfo.groupVisibility,
95 JsonType::NUMBER,
96 false,
97 parseResult,
98 ArrayType::NOT_ARRAY);
99 }
100
CheckSendResultPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility)101 int32_t DistributedSchedPermission::CheckSendResultPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
102 const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
103 {
104 // 1.check account access permission in no account networking environment.
105 if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
106 HILOGE("CheckAccountAccessPermission denied or failed!");
107 return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
108 }
109 // 2.check component access permission, when the ability is not visible.
110 if (!CheckComponentAccessPermission(targetAbility, callerInfo, accountInfo, want)) {
111 HILOGE("CheckComponentAccessPermission denied or failed! the callee component do not have permission");
112 return DMS_COMPONENT_ACCESS_PERMISSION_DENIED;
113 }
114 HILOGI("CheckSendResultPermission success!!");
115 return ERR_OK;
116 }
117
CheckStartPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility)118 int32_t DistributedSchedPermission::CheckStartPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
119 const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
120 {
121 // 1.check account access permission in no account networking environment.
122 if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
123 HILOGE("CheckAccountAccessPermission denied or failed!");
124 return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
125 }
126 // 2.check start control permissions.
127 if (!CheckStartControlPermission(targetAbility, callerInfo, want)) {
128 HILOGE("CheckStartControlPermission denied or failed! the callee component do not have permission");
129 return DMS_START_CONTROL_PERMISSION_DENIED;
130 }
131 HILOGI("CheckDistributedPermission success!!");
132 return ERR_OK;
133 }
134
GetAccountInfo(const std::string & remoteNetworkId,const CallerInfo & callerInfo,AccountInfo & accountInfo)135 int32_t DistributedSchedPermission::GetAccountInfo(const std::string& remoteNetworkId,
136 const CallerInfo& callerInfo, AccountInfo& accountInfo)
137 {
138 if (remoteNetworkId.empty()) {
139 HILOGE("remoteNetworkId is empty");
140 return ERR_NULL_OBJECT;
141 }
142 std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(remoteNetworkId);
143 if (udid.empty()) {
144 HILOGE("udid is empty");
145 return ERR_NULL_OBJECT;
146 }
147 if (!GetRelatedGroups(udid, callerInfo.bundleNames, accountInfo)) {
148 HILOGE("GetRelatedGroups failed");
149 return INVALID_PARAMETERS_ERR;
150 }
151 return ERR_OK;
152 }
153
GetRelatedGroups(const std::string & udid,const std::vector<std::string> & bundleNames,AccountInfo & accountInfo)154 bool DistributedSchedPermission::GetRelatedGroups(const std::string& udid,
155 const std::vector<std::string>& bundleNames, AccountInfo& accountInfo)
156 {
157 for (const auto& bundleName : bundleNames) {
158 std::string returnGroups;
159 if (!DistributedSchedAdapter::GetInstance().GetRelatedGroups(udid, bundleName, returnGroups)) {
160 continue;
161 }
162 std::vector<GroupInfo> groupInfos;
163 if (!ParseGroupInfos(returnGroups, groupInfos)) {
164 continue;
165 }
166 for (const auto& groupInfo : groupInfos) {
167 // check group type is whether (same count or point to point) or not
168 if (groupInfo.groupType != GroupType::IDENTICAL_ACCOUNT_GROUP
169 && groupInfo.groupType != GroupType::PEER_TO_PEER_GROUP) {
170 continue;
171 }
172 accountInfo.groupIdList.push_back(groupInfo.groupId);
173 if (groupInfo.groupType == GroupType::IDENTICAL_ACCOUNT_GROUP
174 && accountInfo.accountType != IDistributedSched::SAME_ACCOUNT_TYPE) {
175 accountInfo.accountType = IDistributedSched::SAME_ACCOUNT_TYPE;
176 }
177 }
178 }
179 if (accountInfo.groupIdList.empty()) {
180 HILOGE("groupIdList is empty");
181 return false;
182 }
183 return true;
184 }
185
ParseGroupInfos(const std::string & returnGroupStr,std::vector<GroupInfo> & groupInfos)186 bool DistributedSchedPermission::ParseGroupInfos(const std::string& returnGroupStr, std::vector<GroupInfo>& groupInfos)
187 {
188 nlohmann::json groupInfoJson = nlohmann::json::parse(returnGroupStr, nullptr, false);
189 if (groupInfoJson.is_discarded()) {
190 HILOGE("returnGroupStr parse failed");
191 return false;
192 }
193 HILOGD("groupInfoJson:%{public}s", groupInfoJson.dump().c_str());
194 groupInfos = groupInfoJson.get<std::vector<GroupInfo>>();
195 if (groupInfos.empty()) {
196 HILOGE("groupInfos is empty");
197 return false;
198 }
199 return true;
200 }
201
GetTargetAbility(const AAFwk::Want & want,AppExecFwk::AbilityInfo & targetAbility,bool needQueryExtension) const202 bool DistributedSchedPermission::GetTargetAbility(const AAFwk::Want& want,
203 AppExecFwk::AbilityInfo& targetAbility, bool needQueryExtension) const
204 {
205 if (BundleManagerInternal::QueryAbilityInfo(want, targetAbility)) {
206 if (want.GetIntParam(DMS_MISSION_ID, DEFAULT_DMS_MISSION_ID) != DEFAULT_DMS_MISSION_ID &&
207 (targetAbility.type == AppExecFwk::AbilityType::SERVICE ||
208 targetAbility.type == AppExecFwk::AbilityType::EXTENSION)) {
209 HILOGE("StartAbilityForResult can not start service and extension ability");
210 return false;
211 }
212 return true;
213 }
214 if (needQueryExtension) {
215 HILOGI("QueryAbilityInfo failed, try to QueryExtensionAbilityInfo");
216 // try to find extension
217 AppExecFwk::ExtensionAbilityInfo extensionAbility;
218 if (BundleManagerInternal::QueryExtensionAbilityInfo(want, extensionAbility)) {
219 // extensionAbilityInfo translates to abilityInfo
220 BundleManagerInternal::InitAbilityInfoFromExtension(extensionAbility, targetAbility);
221 return true;
222 }
223 }
224 HILOGE("QueryAbilityInfo failed, want bundle name=%{public}s, ability name=%{public}s.",
225 want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str());
226 return false;
227 }
228
CheckGetCallerPermission(const AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,AppExecFwk::AbilityInfo & targetAbility)229 int32_t DistributedSchedPermission::CheckGetCallerPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
230 const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
231 {
232 // 1.check account access permission in no account networking environment.
233 if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
234 HILOGE("CheckAccountAccessPermission denied or failed!");
235 return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
236 }
237 // 2. check call with same appid
238 if (!BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
239 HILOGE("the appId is different, check permission denied!");
240 return CALL_PERMISSION_DENIED;
241 }
242 // 3. check background permission
243 if (!CheckBackgroundPermission(targetAbility, callerInfo, want, false)) {
244 HILOGE("Check background permission failed!");
245 return DMS_BACKGROUND_PERMISSION_DENIED;
246 }
247 // 4. check device security level
248 if (!targetAbility.visible &&
249 !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
250 HILOGE("check device security level failed!");
251 return CALL_PERMISSION_DENIED;
252 }
253 HILOGI("CheckGetCallerPermission success!!");
254 return ERR_OK;
255 }
256
IsFoundationCall() const257 bool DistributedSchedPermission::IsFoundationCall() const
258 {
259 uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
260 AccessToken::NativeTokenInfo nativeTokenInfo;
261 int32_t result = AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
262 if (result == ERR_OK && nativeTokenInfo.processName == FOUNDATION_PROCESS_NAME) {
263 return true;
264 }
265 HILOGE("not foundation called, processName:%{private}s", nativeTokenInfo.processName.c_str());
266 return false;
267 }
268
IsSceneBoardCall() const269 bool DistributedSchedPermission::IsSceneBoardCall() const
270 {
271 int32_t activeAccountId = 0;
272 #ifdef OS_ACCOUNT_PART
273 std::vector<int32_t> ids;
274 int32_t errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
275 if (errCode != ERR_OK || ids.empty()) {
276 HILOGE("QueryActiveOsAccountIds failed.");
277 return false;
278 }
279 activeAccountId = ids[0];
280 #endif
281 AppExecFwk::ApplicationInfo appInfo;
282 if (BundleManagerInternal::GetApplicationInfoFromBms(BUNDLE_NAME_SCENEBOARD,
283 AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, activeAccountId, appInfo) != ERR_OK) {
284 HILOGE("get applicationInfo failed.");
285 return false;
286 }
287 auto accessTokenId = IPCSkeleton::GetCallingTokenID();
288 if (accessTokenId != appInfo.accessTokenId) {
289 HILOGE("not sceneBoard called.");
290 return false;
291 }
292 return true;
293 }
294
CheckPermission(uint32_t accessToken,const std::string & permissionName) const295 int32_t DistributedSchedPermission::CheckPermission(uint32_t accessToken, const std::string& permissionName) const
296 {
297 HILOGI("CheckPermission called.");
298 if (VerifyPermission(accessToken, permissionName)) {
299 return ERR_OK;
300 }
301 return DMS_PERMISSION_DENIED;
302 }
303
CheckPermissionAll(uint32_t accessToken,const std::string & permissionName) const304 int32_t DistributedSchedPermission::CheckPermissionAll(uint32_t accessToken, const std::string& permissionName) const
305 {
306 HILOGI("CheckPermissionAll called.");
307 if (VerifyPermission(accessToken, permissionName)) {
308 return ERR_OK;
309 }
310 return DMS_PERMISSION_DENIED;
311 }
312
MarkUriPermission(OHOS::AAFwk::Want & want,uint32_t accessToken)313 void DistributedSchedPermission::MarkUriPermission(OHOS::AAFwk::Want& want, uint32_t accessToken)
314 {
315 if ((want.GetFlags() & (Want::FLAG_AUTH_READ_URI_PERMISSION | Want::FLAG_AUTH_WRITE_URI_PERMISSION)) == 0) {
316 return;
317 }
318 auto bms = BundleManagerInternal::GetBundleManager();
319 if (bms == nullptr) {
320 HILOGW("Failed to get bms.");
321 return;
322 }
323 std::vector<std::string> uriVec = want.GetStringArrayParam(PARAMS_STREAM);
324 std::string uriStr = want.GetUri().ToString();
325 uriVec.emplace_back(uriStr);
326 std::vector<std::string> uriVecPermission;
327 HILOGI("GrantUriPermission uriVec size: %{public}zu", uriVec.size());
328 for (std::string str : uriVec) {
329 Uri uri(str);
330 if (!IsDistributedFile(uri.GetPath())) {
331 continue;
332 }
333 std::string authority = uri.GetAuthority();
334 HILOGI("uri authority is %{public}s.", authority.c_str());
335 AppExecFwk::BundleInfo bundleInfo;
336 int32_t activeAccountId = 0;
337 #ifdef OS_ACCOUNT_PART
338 std::vector<int32_t> ids;
339 int32_t errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
340 if (errCode != ERR_OK || ids.empty()) {
341 return;
342 }
343 activeAccountId = ids[0];
344 #endif
345 if (!bms->GetBundleInfo(authority,
346 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, activeAccountId)) {
347 HILOGW("To fail to get bundle info according to uri.");
348 continue;
349 }
350 if (bundleInfo.applicationInfo.accessTokenId == accessToken) {
351 HILOGI("uri token is true.");
352 uriVecPermission.emplace_back(str);
353 }
354 }
355 want.SetParam(PARAMS_URI, uriVecPermission);
356 }
357
IsDistributedFile(const std::string & path) const358 bool DistributedSchedPermission::IsDistributedFile(const std::string& path) const
359 {
360 if (path.compare(0, DISTRIBUTED_FILES_PATH.size(), DISTRIBUTED_FILES_PATH) == 0) {
361 return true;
362 }
363 HILOGE("uri path is false.");
364 return false;
365 }
366
VerifyPermission(uint32_t accessToken,const std::string & permissionName) const367 bool DistributedSchedPermission::VerifyPermission(uint32_t accessToken, const std::string& permissionName) const
368 {
369 int32_t result = AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionName);
370 if (result == AccessToken::PermissionState::PERMISSION_DENIED) {
371 HILOGE("permission denied, permissionName:%{public}s", permissionName.c_str());
372 return false;
373 }
374 HILOGD("permission matched.");
375 return true;
376 }
377
CheckAccountAccessPermission(const CallerInfo & callerInfo,const AccountInfo & accountInfo,const std::string & targetBundleName)378 bool DistributedSchedPermission::CheckAccountAccessPermission(const CallerInfo& callerInfo,
379 const AccountInfo& accountInfo, const std::string& targetBundleName)
380 {
381 if (accountInfo.accountType == IDistributedSched::SAME_ACCOUNT_TYPE) {
382 HILOGD("no need to check");
383 return true;
384 }
385 if (targetBundleName.empty() || accountInfo.groupIdList.empty()) {
386 HILOGE("targetBundleName or groupIdList is empty");
387 return false;
388 }
389
390 for (const auto& groupId : accountInfo.groupIdList) {
391 HILOGD("groupId:%{public}s targetBundleName:%{public}s", groupId.c_str(), targetBundleName.c_str());
392 if (DistributedSchedAdapter::GetInstance().CheckAccessToGroup(groupId, targetBundleName)) {
393 return true;
394 }
395 }
396 HILOGE("check account permission failed");
397 return false;
398 }
399
CheckComponentAccessPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AccountInfo & accountInfo,const AAFwk::Want & want) const400 bool DistributedSchedPermission::CheckComponentAccessPermission(const AppExecFwk::AbilityInfo& targetAbility,
401 const CallerInfo& callerInfo, const AccountInfo& accountInfo, const AAFwk::Want& want) const
402 {
403 // reject directly when in no account networking environment and target ability is not visible,
404 if (!targetAbility.visible) {
405 HILOGE("target ability is not visible, permission denied!");
406 return false;
407 }
408 HILOGD("check component permission success");
409 return true;
410 }
411
CheckStartControlPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want) const412 bool DistributedSchedPermission::CheckStartControlPermission(const AppExecFwk::AbilityInfo& targetAbility,
413 const CallerInfo& callerInfo, const AAFwk::Want& want) const
414 {
415 // 1. check if continuation with same appid
416 if ((want.GetFlags() & AAFwk::Want::FLAG_ABILITY_CONTINUATION) != 0) {
417 if (!targetAbility.visible &&
418 !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
419 HILOGE("check device security level failed!");
420 return false;
421 }
422 if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
423 HILOGD("the appId is the same, check permission success!");
424 return true;
425 }
426 HILOGE("the appId is different in the migration scenario, permission denied!");
427 return false;
428 }
429 // 2. check background permission
430 if (!CheckBackgroundPermission(targetAbility, callerInfo, want, true)) {
431 HILOGE("Check background permission failed!");
432 return false;
433 }
434 // 3. check device security level
435 if (!targetAbility.visible &&
436 !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
437 HILOGE("check device security level failed!");
438 return false;
439 }
440 // 4. check start or connect ability with same appid
441 if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
442 HILOGD("the appId is the same, check permission success!");
443 return true;
444 }
445 // 5. check if target ability is not visible and without PERMISSION_START_INVISIBLE_ABILITY
446 if (!CheckTargetAbilityVisible(targetAbility, callerInfo)) {
447 HILOGE("target ability is not visible and has no PERMISSION_START_INVISIBLE_ABILITY, permission denied!");
448 return false;
449 }
450 // 6. check if service of fa mode can associatedWakeUp
451 if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
452 !targetAbility.applicationInfo.associatedWakeUp) {
453 HILOGE("target ability is service ability(FA) and associatedWakeUp is false, permission denied!");
454 return false;
455 }
456 HILOGD("CheckStartControlPermission success");
457 return true;
458 }
459
CheckBackgroundPermission(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo,const AAFwk::Want & want,bool needCheckApiVersion) const460 bool DistributedSchedPermission::CheckBackgroundPermission(const AppExecFwk::AbilityInfo& targetAbility,
461 const CallerInfo& callerInfo, const AAFwk::Want& want, bool needCheckApiVersion) const
462 {
463 if (callerInfo.extraInfoJson.empty() ||
464 callerInfo.extraInfoJson.find(DMS_VERSION_ID) == callerInfo.extraInfoJson.end()) {
465 HILOGD("the version is low");
466 return true;
467 }
468 AAFwk::Want* remoteWant = const_cast<Want*>(&want);
469 bool isCallerBackGround = remoteWant->GetBoolParam(DMS_IS_CALLER_BACKGROUND, true);
470 remoteWant->RemoveParam(DMS_IS_CALLER_BACKGROUND);
471 if (!isCallerBackGround) {
472 HILOGD("the app is foreground");
473 return true;
474 }
475 int apiVersion = remoteWant->GetIntParam(DMS_API_VERSION, DEFAULT_DMS_API_VERSION);
476 remoteWant->RemoveParam(DMS_API_VERSION);
477 // service in fa mode(API 8) do not need check
478 if (needCheckApiVersion && CheckMinApiVersion(targetAbility, apiVersion)) {
479 HILOGD("the app is service ability of fa mode and is under api 8");
480 return true;
481 }
482 uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
483 callerInfo.accessToken);
484 if (dAccessToken == 0) {
485 HILOGE("dAccessTokenID is invalid!");
486 return false;
487 }
488 // check if background's ability has PERMISSION_START_ABILITIES_FROM_BACKGROUND
489 if (CheckPermission(dAccessToken, PERMISSION_START_ABILITIES_FROM_BACKGROUND) == ERR_OK ||
490 CheckPermission(dAccessToken, PERMISSION_START_ABILIIES_FROM_BACKGROUND) == ERR_OK) {
491 HILOGD("the app has PERMISSION_START_ABILITIES_FROM_BACKGROUND");
492 return true;
493 }
494 HILOGE("CheckBackgroundPermission failed!");
495 return false;
496 }
497
CheckMinApiVersion(const AppExecFwk::AbilityInfo & targetAbility,int32_t apiVersion) const498 bool DistributedSchedPermission::CheckMinApiVersion(const AppExecFwk::AbilityInfo& targetAbility,
499 int32_t apiVersion) const
500 {
501 if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
502 apiVersion <= FA_MODULE_ALLOW_MIN_API_VERSION) {
503 HILOGD("CheckMinApiVersion pass");
504 return true;
505 }
506 return false;
507 }
508
CheckDeviceSecurityLevel(const std::string & srcDeviceId,const std::string & dstDeviceId) const509 bool DistributedSchedPermission::CheckDeviceSecurityLevel(const std::string& srcDeviceId,
510 const std::string& dstDeviceId) const
511 {
512 std::string srcUdid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(srcDeviceId);
513 if (srcUdid.empty()) {
514 HILOGE("src udid is empty");
515 return false;
516 }
517 std::string dstUdid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(dstDeviceId);
518 if (dstUdid.empty()) {
519 HILOGE("dst udid is empty");
520 return false;
521 }
522 int32_t srcDeviceSecurityLevel = GetDeviceSecurityLevel(srcUdid);
523 int32_t dstDeviceSecurityLevel = GetDeviceSecurityLevel(dstUdid);
524 if (srcDeviceSecurityLevel == DEFAULT_DEVICE_SECURITY_LEVEL ||
525 srcDeviceSecurityLevel < dstDeviceSecurityLevel) {
526 HILOGE("the device security of source device is lower");
527 return false;
528 }
529 return true;
530 }
531
GetDeviceSecurityLevel(const std::string & udid) const532 int32_t DistributedSchedPermission::GetDeviceSecurityLevel(const std::string& udid) const
533 {
534 DeviceIdentify devIdentify;
535 devIdentify.length = DEVICE_ID_MAX_LEN;
536 int32_t ret = memcpy_s(devIdentify.identity, DEVICE_ID_MAX_LEN, udid.c_str(), DEVICE_ID_MAX_LEN);
537 if (ret != 0) {
538 HILOGE("str copy failed %{public}d", ret);
539 return DEFAULT_DEVICE_SECURITY_LEVEL;
540 }
541 DeviceSecurityInfo *info = nullptr;
542 ret = RequestDeviceSecurityInfo(&devIdentify, nullptr, &info);
543 if (ret != SUCCESS) {
544 HILOGE("request device security info failed %{public}d", ret);
545 FreeDeviceSecurityInfo(info);
546 info = nullptr;
547 return DEFAULT_DEVICE_SECURITY_LEVEL;
548 }
549 int32_t level = 0;
550 ret = GetDeviceSecurityLevelValue(info, &level);
551 HILOGD("get device security level, level is %{public}d", level);
552 FreeDeviceSecurityInfo(info);
553 info = nullptr;
554 if (ret != SUCCESS) {
555 HILOGE("get device security level failed %{public}d", ret);
556 return DEFAULT_DEVICE_SECURITY_LEVEL;
557 }
558 return level;
559 }
560
CheckTargetAbilityVisible(const AppExecFwk::AbilityInfo & targetAbility,const CallerInfo & callerInfo) const561 bool DistributedSchedPermission::CheckTargetAbilityVisible(const AppExecFwk::AbilityInfo& targetAbility,
562 const CallerInfo& callerInfo) const
563 {
564 if (targetAbility.visible) {
565 HILOGD("Target ability is visible.");
566 return true;
567 }
568 uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
569 callerInfo.accessToken);
570 if (dAccessToken == 0) {
571 HILOGE("dAccessTokenID is invalid!");
572 return false;
573 }
574 if (CheckPermissionAll(dAccessToken, PERMISSION_START_INVISIBLE_ABILITY) != ERR_OK) {
575 HILOGE("CheckTargetAbilityVisible failed.");
576 return false;
577 }
578 HILOGD("CheckTargetAbilityVisible passed.");
579 return true;
580 }
581 }
582 }