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 "permission_manager.h"
17 
18 #include <iostream>
19 #include <numeric>
20 #include <sstream>
21 
22 #include "access_token.h"
23 #include "access_token_error.h"
24 #include "accesstoken_dfx_define.h"
25 #include "accesstoken_id_manager.h"
26 #include "accesstoken_info_manager.h"
27 #include "accesstoken_log.h"
28 #include "access_token_db.h"
29 #include "app_manager_access_client.h"
30 #include "callback_manager.h"
31 #ifdef SUPPORT_SANDBOX_APP
32 #include "dlp_permission_set_manager.h"
33 #endif
34 #include "ipc_skeleton.h"
35 #include "parameter.h"
36 #include "permission_definition_cache.h"
37 #include "short_grant_manager.h"
38 #include "permission_map.h"
39 #include "permission_validator.h"
40 #include "perm_setproc.h"
41 #include "token_field_const.h"
42 #ifdef TOKEN_SYNC_ENABLE
43 #include "token_modify_notifier.h"
44 #endif
45 
46 namespace OHOS {
47 namespace Security {
48 namespace AccessToken {
49 namespace {
50 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionManager"};
51 static const char* PERMISSION_STATUS_CHANGE_KEY = "accesstoken.permission.change";
52 static constexpr int32_t VALUE_MAX_LEN = 32;
53 static constexpr int32_t BASE_USER_RANGE = 200000;
54 static const std::vector<std::string> g_notDisplayedPerms = {
55     "ohos.permission.ANSWER_CALL",
56     "ohos.permission.MANAGE_VOICEMAIL",
57     "ohos.permission.READ_CELL_MESSAGES",
58     "ohos.permission.READ_MESSAGES",
59     "ohos.permission.RECEIVE_MMS",
60     "ohos.permission.RECEIVE_SMS",
61     "ohos.permission.RECEIVE_WAP_MESSAGES",
62     "ohos.permission.SEND_MESSAGES",
63     "ohos.permission.READ_CALL_LOG",
64     "ohos.permission.WRITE_CALL_LOG",
65     "ohos.permission.SHORT_TERM_WRITE_IMAGEVIDEO"
66 };
67 constexpr const char* APP_DISTRIBUTION_TYPE_ENTERPRISE_MDM = "enterprise_mdm";
68 }
69 PermissionManager* PermissionManager::implInstance_ = nullptr;
70 std::recursive_mutex PermissionManager::mutex_;
71 
GetInstance()72 PermissionManager& PermissionManager::GetInstance()
73 {
74     if (implInstance_ == nullptr) {
75         std::lock_guard<std::recursive_mutex> lock_l(mutex_);
76         if (implInstance_ == nullptr) {
77             implInstance_ = new PermissionManager();
78         }
79     }
80     return *implInstance_;
81 }
82 
RegisterImpl(PermissionManager* implInstance)83 void PermissionManager::RegisterImpl(PermissionManager* implInstance)
84 {
85     implInstance_ = implInstance;
86 }
87 
PermissionManager()88 PermissionManager::PermissionManager()
89 {
90     char value[VALUE_MAX_LEN] = {0};
91     int32_t ret = GetParameter(PERMISSION_STATUS_CHANGE_KEY, "", value, VALUE_MAX_LEN - 1);
92     if (ret < 0) {
93         ACCESSTOKEN_LOG_ERROR(LABEL, "Return default value, ret=%{public}d", ret);
94         paramValue_ = 0;
95         return;
96     }
97     paramValue_ = static_cast<uint64_t>(std::atoll(value));
98 }
99 
~PermissionManager()100 PermissionManager::~PermissionManager()
101 {}
102 
ClearAllSecCompGrantedPerm(const std::vector<AccessTokenID>& tokenIdList)103 void PermissionManager::ClearAllSecCompGrantedPerm(const std::vector<AccessTokenID>& tokenIdList)
104 {
105     for (const auto& tokenId : tokenIdList) {
106         std::shared_ptr<HapTokenInfoInner> tokenInfoPtr =
107             AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenId);
108         if (tokenInfoPtr == nullptr) {
109             ACCESSTOKEN_LOG_ERROR(LABEL, "tokenInfo is null, tokenId=%{public}u", tokenId);
110             continue;
111         }
112         std::shared_ptr<PermissionPolicySet> permPolicySet = tokenInfoPtr->GetHapInfoPermissionPolicySet();
113         if (permPolicySet != nullptr) {
114             permPolicySet->ClearSecCompGrantedPerm();
115         }
116     }
117 }
118 
AddDefPermissions(const std::vector<PermissionDef>& permList, AccessTokenID tokenId, bool updateFlag)119 void PermissionManager::AddDefPermissions(const std::vector<PermissionDef>& permList, AccessTokenID tokenId,
120     bool updateFlag)
121 {
122     std::vector<PermissionDef> permFilterList;
123     PermissionValidator::FilterInvalidPermissionDef(permList, permFilterList);
124     ACCESSTOKEN_LOG_INFO(LABEL, "PermFilterList size: %{public}zu", permFilterList.size());
125     for (const auto& perm : permFilterList) {
126         if (updateFlag) {
127             PermissionDefinitionCache::GetInstance().Update(perm, tokenId);
128             continue;
129         }
130 
131         if (!PermissionDefinitionCache::GetInstance().HasDefinition(perm.permissionName)) {
132             PermissionDefinitionCache::GetInstance().Insert(perm, tokenId);
133         } else {
134             PermissionDefinitionCache::GetInstance().Update(perm, tokenId);
135             ACCESSTOKEN_LOG_INFO(LABEL, "Permission %{public}s has define", perm.permissionName.c_str());
136         }
137     }
138 }
139 
RemoveDefPermissions(AccessTokenID tokenID)140 void PermissionManager::RemoveDefPermissions(AccessTokenID tokenID)
141 {
142     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u", __func__, tokenID);
143     PermissionDefinitionCache::GetInstance().DeleteByToken(tokenID);
144 }
145 
VerifyHapAccessToken(AccessTokenID tokenID, const std::string& permissionName)146 int PermissionManager::VerifyHapAccessToken(AccessTokenID tokenID, const std::string& permissionName)
147 {
148     std::shared_ptr<HapTokenInfoInner> tokenInfoPtr =
149         AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
150     if (tokenInfoPtr == nullptr) {
151         ACCESSTOKEN_LOG_ERROR(LABEL, "tokenInfo is null, tokenId=%{public}u", tokenID);
152         return PERMISSION_DENIED;
153     }
154     std::shared_ptr<PermissionPolicySet> permPolicySet = tokenInfoPtr->GetHapInfoPermissionPolicySet();
155     if (permPolicySet == nullptr) {
156         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", tokenID);
157         return PERMISSION_DENIED;
158     }
159 
160     return permPolicySet->VerifyPermissionStatus(permissionName);
161 }
162 
GetPermissionUsedType( AccessTokenID tokenID, const std::string& permissionName)163 PermUsedTypeEnum PermissionManager::GetPermissionUsedType(
164     AccessTokenID tokenID, const std::string& permissionName)
165 {
166     if ((tokenID == INVALID_TOKENID) ||
167         (TOKEN_HAP != AccessTokenIDManager::GetInstance().GetTokenIdTypeEnum(tokenID))) {
168         ACCESSTOKEN_LOG_ERROR(LABEL, "TokenID: %{public}d is invalid.", tokenID);
169         return PermUsedTypeEnum::INVALID_USED_TYPE;
170     }
171 
172     PermissionDef permissionDefResult;
173     int ret = GetDefPermission(permissionName, permissionDefResult);
174     if (RET_SUCCESS != ret) {
175         ACCESSTOKEN_LOG_ERROR(LABEL, "Query permission info of %{public}s failed.", permissionName.c_str());
176         return PermUsedTypeEnum::INVALID_USED_TYPE;
177     }
178 
179     std::shared_ptr<PermissionPolicySet> permPolicySet =
180         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
181     if (permPolicySet == nullptr) {
182         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", tokenID);
183         return PermUsedTypeEnum::INVALID_USED_TYPE;
184     }
185 
186     return permPolicySet->GetPermissionUsedType(permissionName);
187 }
188 
GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult)189 int PermissionManager::GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult)
190 {
191     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
192         ACCESSTOKEN_LOG_ERROR(LABEL, "Invalid params!");
193         return AccessTokenError::ERR_PARAM_INVALID;
194     }
195     return PermissionDefinitionCache::GetInstance().FindByPermissionName(permissionName, permissionDefResult);
196 }
197 
GetDefPermissions(AccessTokenID tokenID, std::vector<PermissionDef>& permList)198 int PermissionManager::GetDefPermissions(AccessTokenID tokenID, std::vector<PermissionDef>& permList)
199 {
200     std::shared_ptr<PermissionPolicySet> permPolicySet =
201         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
202     if (permPolicySet == nullptr) {
203         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", tokenID);
204         return AccessTokenError::ERR_TOKENID_NOT_EXIST;
205     }
206 
207     permPolicySet->GetDefPermissions(permList);
208     return RET_SUCCESS;
209 }
210 
GetReqPermissions( AccessTokenID tokenID, std::vector<PermissionStateFull>& reqPermList, bool isSystemGrant)211 int PermissionManager::GetReqPermissions(
212     AccessTokenID tokenID, std::vector<PermissionStateFull>& reqPermList, bool isSystemGrant)
213 {
214     ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, tokenID: %{public}u, isSystemGrant: %{public}d",
215         __func__, tokenID, isSystemGrant);
216     std::shared_ptr<PermissionPolicySet> permPolicySet =
217         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
218     if (permPolicySet == nullptr) {
219         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", tokenID);
220         return AccessTokenError::ERR_TOKENID_NOT_EXIST;
221     }
222 
223     GrantMode mode = isSystemGrant ? SYSTEM_GRANT : USER_GRANT;
224     std::vector<PermissionStateFull> tmpList;
225     permPolicySet->GetPermissionStateFulls(tmpList);
226     for (const auto& perm : tmpList) {
227         PermissionDef permDef;
228         GetDefPermission(perm.permissionName, permDef);
229         if (permDef.grantMode == mode) {
230             reqPermList.emplace_back(perm);
231         }
232     }
233     return RET_SUCCESS;
234 }
235 
IsPermissionRequestedInHap(const std::vector<PermissionStateFull>& permsList, const std::string &permission, int32_t& status, uint32_t& flag)236 static bool IsPermissionRequestedInHap(const std::vector<PermissionStateFull>& permsList,
237     const std::string &permission, int32_t& status, uint32_t& flag)
238 {
239     if (!PermissionDefinitionCache::GetInstance().HasHapPermissionDefinitionForHap(permission)) {
240         ACCESSTOKEN_LOG_ERROR(LABEL, "No definition for hap permission: %{public}s!", permission.c_str());
241         return false;
242     }
243     auto iter = std::find_if(permsList.begin(), permsList.end(), [permission](const PermissionStateFull& perm) {
244         return permission == perm.permissionName;
245     });
246     if (iter == permsList.end()) {
247         ACCESSTOKEN_LOG_WARN(LABEL, "Can not find permission: %{public}s define!", permission.c_str());
248         return false;
249     }
250     ACCESSTOKEN_LOG_DEBUG(LABEL, "Find goal permission: %{public}s, status: %{public}d, flag: %{public}d",
251         permission.c_str(), iter->grantStatus[0], iter->grantFlags[0]);
252     status = iter->grantStatus[0];
253     flag = static_cast<uint32_t>(iter->grantFlags[0]);
254     return true;
255 }
256 
IsPermissionRestrictedByRules(const std::string& permission)257 static bool IsPermissionRestrictedByRules(const std::string& permission)
258 {
259     // Several permission is not available to common apps.
260     // Specified apps can get the permission by pre-authorization instead of Pop-ups.
261     auto iterator = std::find(g_notDisplayedPerms.begin(), g_notDisplayedPerms.end(), permission);
262     if (iterator != g_notDisplayedPerms.end()) {
263         ACCESSTOKEN_LOG_WARN(LABEL, "Permission is not available to common apps: %{public}s!", permission.c_str());
264         return true;
265     }
266 
267 #ifdef SUPPORT_SANDBOX_APP
268     // Specified dlp permissions are limited to specified dlp type hap.
269     AccessTokenID callingTokenId = IPCSkeleton::GetCallingTokenID();
270     int32_t dlpType = AccessTokenInfoManager::GetInstance().GetHapTokenDlpType(callingTokenId);
271     if ((dlpType != DLP_COMMON) &&
272         !DlpPermissionSetManager::GetInstance().IsPermissionAvailableToDlpHap(dlpType, permission)) {
273         ACCESSTOKEN_LOG_WARN(LABEL,
274             "callingTokenId is not allowed to grant dlp permission: %{public}s!", permission.c_str());
275         return true;
276     }
277 #endif
278 
279     return false;
280 }
281 
GetSelfPermissionState(const std::vector<PermissionStateFull>& permsList, PermissionListState& permState, int32_t apiVersion)282 void PermissionManager::GetSelfPermissionState(const std::vector<PermissionStateFull>& permsList,
283     PermissionListState& permState, int32_t apiVersion)
284 {
285     int32_t goalGrantStatus;
286     uint32_t goalGrantFlag;
287 
288     // api8 require vague location permission refuse directly because there is no vague location permission in api8
289     if ((permState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) && (apiVersion < ACCURATE_LOCATION_API_VERSION)) {
290         permState.state = INVALID_OPER;
291         return;
292     }
293     if (!IsPermissionRequestedInHap(permsList, permState.permissionName, goalGrantStatus, goalGrantFlag)) {
294         permState.state = INVALID_OPER;
295         return;
296     }
297     if (IsPermissionRestrictedByRules(permState.permissionName)) {
298         permState.state = INVALID_OPER;
299         return;
300     }
301     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s: status: %{public}d, flag: %{public}d",
302         permState.permissionName.c_str(), goalGrantStatus, goalGrantFlag);
303     if (goalGrantStatus == PERMISSION_DENIED) {
304         if ((goalGrantFlag & PERMISSION_POLICY_FIXED) != 0) {
305             permState.state = SETTING_OPER;
306             return;
307         }
308 
309         if ((goalGrantFlag == PERMISSION_DEFAULT_FLAG) || ((goalGrantFlag & PERMISSION_USER_SET) != 0) ||
310             ((goalGrantFlag & PERMISSION_COMPONENT_SET) != 0) || ((goalGrantFlag & PERMISSION_ALLOW_THIS_TIME) != 0)) {
311             permState.state = DYNAMIC_OPER;
312             return;
313         }
314         if ((goalGrantFlag & PERMISSION_USER_FIXED) != 0) {
315             permState.state = SETTING_OPER;
316             return;
317         }
318     }
319     permState.state = PASS_OPER;
320     return;
321 }
322 
GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName, uint32_t& flag)323 int PermissionManager::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName, uint32_t& flag)
324 {
325     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u, permissionName: %{public}s",
326         __func__, tokenID, permissionName.c_str());
327     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
328         ACCESSTOKEN_LOG_ERROR(LABEL, "PermissionName:%{public}s invalid!", permissionName.c_str());
329         return AccessTokenError::ERR_PARAM_INVALID;
330     }
331     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
332         ACCESSTOKEN_LOG_ERROR(
333             LABEL, "No definition for permission: %{public}s!", permissionName.c_str());
334         return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
335     }
336     std::shared_ptr<PermissionPolicySet> permPolicySet =
337         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
338     if (permPolicySet == nullptr) {
339         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", tokenID);
340         return AccessTokenError::ERR_TOKENID_NOT_EXIST;
341     }
342     int32_t fullFlag;
343     int32_t ret = permPolicySet->QueryPermissionFlag(permissionName, fullFlag);
344     if (ret == RET_SUCCESS) {
345         flag = permPolicySet->GetFlagWithoutSpecifiedElement(fullFlag, PERMISSION_GRANTED_BY_POLICY);
346     }
347     return ret;
348 }
349 
FindPermRequestToggleStatusFromDb(int32_t userID, const std::string& permissionName)350 int32_t PermissionManager::FindPermRequestToggleStatusFromDb(int32_t userID, const std::string& permissionName)
351 {
352     std::vector<GenericValues> permRequestToggleStatusRes;
353     GenericValues conditionValue;
354     conditionValue.Put(TokenFiledConst::FIELD_USER_ID, userID);
355     conditionValue.Put(TokenFiledConst::FIELD_PERMISSION_NAME, permissionName);
356 
357     AccessTokenDb::GetInstance().Find(AtmDataType::ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS,
358         conditionValue, permRequestToggleStatusRes);
359     if (permRequestToggleStatusRes.empty()) {
360         // never set, return default status: CLOSED if APP_TRACKING_CONSENT
361         return (permissionName == "ohos.permission.APP_TRACKING_CONSENT") ?
362             PermissionRequestToggleStatus::CLOSED : PermissionRequestToggleStatus::OPEN;
363     }
364     return permRequestToggleStatusRes[0].GetInt(TokenFiledConst::FIELD_REQUEST_TOGGLE_STATUS);
365 }
366 
AddPermRequestToggleStatusToDb( int32_t userID, const std::string& permissionName, int32_t status)367 void PermissionManager::AddPermRequestToggleStatusToDb(
368     int32_t userID, const std::string& permissionName, int32_t status)
369 {
370     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permToggleStateLock_);
371     GenericValues value;
372     value.Put(TokenFiledConst::FIELD_USER_ID, userID);
373     value.Put(TokenFiledConst::FIELD_PERMISSION_NAME, permissionName);
374     AccessTokenDb::GetInstance().Remove(AtmDataType::ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS, value);
375 
376     std::vector<GenericValues> permRequestToggleStatusValues;
377     value.Put(TokenFiledConst::FIELD_REQUEST_TOGGLE_STATUS, status);
378     permRequestToggleStatusValues.emplace_back(value);
379     AccessTokenDb::GetInstance().Add(AtmDataType::ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS,
380         permRequestToggleStatusValues);
381 }
382 
SetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t status, int32_t userID)383 int32_t PermissionManager::SetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t status,
384     int32_t userID)
385 {
386     if (userID == 0) {
387         userID = IPCSkeleton::GetCallingUid() / BASE_USER_RANGE;
388     }
389 
390     ACCESSTOKEN_LOG_INFO(LABEL, "UserID=%{public}u, permissionName=%{public}s, status=%{public}d", userID,
391         permissionName.c_str(), status);
392     if (!PermissionValidator::IsUserIdValid(userID)) {
393         ACCESSTOKEN_LOG_ERROR(LABEL, "UserID is invalid.");
394         return AccessTokenError::ERR_PARAM_INVALID;
395     }
396     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
397         ACCESSTOKEN_LOG_ERROR(LABEL, "Permission name is invalid.");
398         return AccessTokenError::ERR_PARAM_INVALID;
399     }
400     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
401         ACCESSTOKEN_LOG_ERROR(
402             LABEL, "Permission=%{public}s is not defined.", permissionName.c_str());
403         return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
404     }
405     if (PermissionDefinitionCache::GetInstance().IsSystemGrantedPermission(permissionName)) {
406         ACCESSTOKEN_LOG_ERROR(LABEL, "Only support permissions of user_grant to set.");
407         return AccessTokenError::ERR_PARAM_INVALID;
408     }
409     if (!PermissionValidator::IsToggleStatusValid(status)) {
410         ACCESSTOKEN_LOG_ERROR(LABEL, "Status is invalid.");
411         return AccessTokenError::ERR_PARAM_INVALID;
412     }
413 
414     AddPermRequestToggleStatusToDb(userID, permissionName, status);
415 
416     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERM_DIALOG_STATUS_INFO",
417         HiviewDFX::HiSysEvent::EventType::STATISTIC, "USERID", userID, "PERMISSION_NAME", permissionName,
418         "TOGGLE_STATUS", status);
419 
420     return 0;
421 }
422 
GetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t& status, int32_t userID)423 int32_t PermissionManager::GetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t& status,
424     int32_t userID)
425 {
426     if (userID == 0) {
427         userID = IPCSkeleton::GetCallingUid() / BASE_USER_RANGE;
428     }
429 
430     ACCESSTOKEN_LOG_INFO(LABEL, "UserID=%{public}u, permissionName=%{public}s", userID, permissionName.c_str());
431     if (!PermissionValidator::IsUserIdValid(userID)) {
432         ACCESSTOKEN_LOG_ERROR(LABEL, "UserID is invalid.");
433         return AccessTokenError::ERR_PARAM_INVALID;
434     }
435     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
436         ACCESSTOKEN_LOG_ERROR(LABEL, "Permission name is invalid.");
437         return AccessTokenError::ERR_PARAM_INVALID;
438     }
439     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
440         ACCESSTOKEN_LOG_ERROR(
441             LABEL, "Permission=%{public}s is not defined.", permissionName.c_str());
442         return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
443     }
444     if (PermissionDefinitionCache::GetInstance().IsSystemGrantedPermission(permissionName)) {
445         ACCESSTOKEN_LOG_ERROR(LABEL, "Only support permissions of user_grant to get.");
446         return AccessTokenError::ERR_PARAM_INVALID;
447     }
448 
449     status = static_cast<uint32_t>(FindPermRequestToggleStatusFromDb(userID, permissionName));
450 
451     return 0;
452 }
453 
ParamUpdate(const std::string& permissionName, uint32_t flag, bool filtered)454 void PermissionManager::ParamUpdate(const std::string& permissionName, uint32_t flag, bool filtered)
455 {
456     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permParamSetLock_);
457     if (filtered || (PermissionDefinitionCache::GetInstance().IsUserGrantedPermission(permissionName) &&
458         ((flag != PERMISSION_GRANTED_BY_POLICY) && (flag != PERMISSION_SYSTEM_FIXED)))) {
459         paramValue_++;
460         ACCESSTOKEN_LOG_DEBUG(LABEL,
461             "paramValue_ change %{public}llu", static_cast<unsigned long long>(paramValue_));
462         int32_t res = SetParameter(PERMISSION_STATUS_CHANGE_KEY, std::to_string(paramValue_).c_str());
463         if (res != 0) {
464             ACCESSTOKEN_LOG_ERROR(LABEL, "SetParameter failed %{public}d", res);
465         }
466     }
467 }
468 
NotifyWhenPermissionStateUpdated(AccessTokenID tokenID, const std::string& permissionName, bool isGranted, uint32_t flag, const std::shared_ptr<HapTokenInfoInner>& infoPtr)469 void PermissionManager::NotifyWhenPermissionStateUpdated(AccessTokenID tokenID, const std::string& permissionName,
470     bool isGranted, uint32_t flag, const std::shared_ptr<HapTokenInfoInner>& infoPtr)
471 {
472     ACCESSTOKEN_LOG_INFO(LABEL, "IsUpdated");
473     int32_t changeType = isGranted ? STATE_CHANGE_GRANTED : STATE_CHANGE_REVOKED;
474 
475     // set to kernel(grant/revoke)
476     SetPermToKernel(tokenID, permissionName, isGranted);
477 
478     // To notify the listener register.
479     CallbackManager::GetInstance().ExecuteCallbackAsync(tokenID, permissionName, changeType);
480 
481     // To notify the client cache to update by resetting paramValue_.
482     ParamUpdate(permissionName, flag, false);
483 
484     // DFX.
485     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERMISSION_CHECK_EVENT",
486         HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "CODE", USER_GRANT_PERMISSION_EVENT,
487         "CALLER_TOKENID", tokenID, "PERMISSION_NAME", permissionName, "FLAG", flag,
488         "PERMISSION_GRANT_TYPE", changeType);
489     grantEvent_.AddEvent(tokenID, permissionName, infoPtr->permUpdateTimestamp_);
490 }
491 
UpdateTokenPermissionState( AccessTokenID id, const std::string& permission, bool isGranted, uint32_t flag, bool needKill)492 int32_t PermissionManager::UpdateTokenPermissionState(
493     AccessTokenID id, const std::string& permission, bool isGranted, uint32_t flag, bool needKill)
494 {
495     std::shared_ptr<HapTokenInfoInner> infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(id);
496     if (infoPtr == nullptr) {
497         ACCESSTOKEN_LOG_ERROR(LABEL, "tokenInfo is null, tokenId=%{public}u", id);
498         return AccessTokenError::ERR_TOKENID_NOT_EXIST;
499     }
500     if (infoPtr->IsRemote()) {
501         ACCESSTOKEN_LOG_ERROR(LABEL, "Remote token can not update");
502         return AccessTokenError::ERR_IDENTITY_CHECK_FAILED;
503     }
504     if ((flag == PERMISSION_ALLOW_THIS_TIME) && isGranted) {
505         if (!TempPermissionObserver::GetInstance().IsAllowGrantTempPermission(id, permission)) {
506             ACCESSTOKEN_LOG_ERROR(LABEL, "Id:%{public}d fail to grant permission:%{public}s", id, permission.c_str());
507             return ERR_IDENTITY_CHECK_FAILED;
508         }
509     }
510     std::shared_ptr<PermissionPolicySet> permPolicySet = infoPtr->GetHapInfoPermissionPolicySet();
511     if (permPolicySet == nullptr) {
512         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", id);
513         return AccessTokenError::ERR_PARAM_INVALID;
514     }
515 #ifdef SUPPORT_SANDBOX_APP
516     int32_t hapDlpType = infoPtr->GetDlpType();
517     if (hapDlpType != DLP_COMMON) {
518         int32_t permDlpMode = DlpPermissionSetManager::GetInstance().GetPermDlpMode(permission);
519         if (!DlpPermissionSetManager::GetInstance().IsPermDlpModeAvailableToDlpHap(hapDlpType, permDlpMode)) {
520             ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s cannot to be granted to %{public}u", permission.c_str(), id);
521             return AccessTokenError::ERR_IDENTITY_CHECK_FAILED;
522         }
523     }
524 #endif
525     int32_t statusBefore = permPolicySet->VerifyPermissionStatus(permission);
526     bool isSecCompGrantedBefore = permPolicySet->IsPermissionGrantedWithSecComp(permission);
527     int32_t ret = permPolicySet->UpdatePermissionStatus(permission, isGranted, flag);
528     if (ret != RET_SUCCESS) {
529         return ret;
530     }
531     int32_t statusAfter = permPolicySet->VerifyPermissionStatus(permission);
532     if (statusAfter != statusBefore) {
533         NotifyWhenPermissionStateUpdated(id, permission, isGranted, flag, infoPtr);
534         // To notify kill process when perm is revoke
535         if (needKill && (!isGranted && !isSecCompGrantedBefore)) {
536             ACCESSTOKEN_LOG_INFO(LABEL, "(%{public}s) is revoked, kill process(%{public}u).", permission.c_str(), id);
537             if ((ret = AppManagerAccessClient::GetInstance().KillProcessesByAccessTokenId(id)) != ERR_OK) {
538                 ACCESSTOKEN_LOG_ERROR(LABEL, "kill process failed, ret=%{public}d.", ret);
539             }
540         }
541     }
542 
543 #ifdef TOKEN_SYNC_ENABLE
544     TokenModifyNotifier::GetInstance().NotifyTokenModify(id);
545 #endif
546     if (!ShortGrantManager::GetInstance().IsShortGrantPermission(permission)) {
547         return AccessTokenInfoManager::GetInstance().ModifyHapPermStateFromDb(id, permission, infoPtr);
548     }
549     return RET_SUCCESS;
550 }
551 
UpdatePermission(AccessTokenID tokenID, const std::string& permissionName, bool isGranted, uint32_t flag, bool needKill)552 int32_t PermissionManager::UpdatePermission(AccessTokenID tokenID, const std::string& permissionName,
553     bool isGranted, uint32_t flag, bool needKill)
554 {
555     int32_t ret = UpdateTokenPermissionState(tokenID, permissionName, isGranted, flag, needKill);
556     if (ret != RET_SUCCESS) {
557         return ret;
558     }
559 
560 #ifdef SUPPORT_SANDBOX_APP
561     // The action of sharing would be taken place only if the grant operation or revoke operation equals to success.
562     std::vector<AccessTokenID> tokenIdList;
563     AccessTokenInfoManager::GetInstance().GetRelatedSandBoxHapList(tokenID, tokenIdList);
564     for (const auto& id : tokenIdList) {
565         (void)UpdateTokenPermissionState(id, permissionName, isGranted, flag, needKill);
566     }
567 #endif
568 
569     // DFX
570     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "UPDATE_PERMISSION",
571         HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "TOKENID", tokenID, "PERMISSION_NAME",
572         permissionName, "PERMISSION_FLAG", flag, "GRANTED_FLAG", isGranted);
573     return RET_SUCCESS;
574 }
575 
CheckAndUpdatePermission(AccessTokenID tokenID, const std::string& permissionName, bool isGranted, uint32_t flag)576 int32_t PermissionManager::CheckAndUpdatePermission(AccessTokenID tokenID, const std::string& permissionName,
577     bool isGranted, uint32_t flag)
578 {
579     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
580         ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName: %{public}s, Invalid params!", permissionName.c_str());
581         return AccessTokenError::ERR_PARAM_INVALID;
582     }
583     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
584         ACCESSTOKEN_LOG_ERROR(
585             LABEL, "No definition for permission: %{public}s!", permissionName.c_str());
586         return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
587     }
588     if (!PermissionValidator::IsPermissionFlagValid(flag)) {
589         ACCESSTOKEN_LOG_ERROR(LABEL, "flag: %{public}d, Invalid params!", flag);
590         return AccessTokenError::ERR_PARAM_INVALID;
591     }
592     bool needKill = false;
593     // To kill process when perm is revoke
594     if (!isGranted && (flag != PERMISSION_ALLOW_THIS_TIME) && (flag != PERMISSION_COMPONENT_SET)) {
595         ACCESSTOKEN_LOG_INFO(LABEL, "Perm(%{public}s) is revoked, kill process(%{public}u).",
596             permissionName.c_str(), tokenID);
597         needKill = true;
598     }
599 
600     return UpdatePermission(tokenID, permissionName, isGranted, flag, needKill);
601 }
602 
GrantPermission(AccessTokenID tokenID, const std::string& permissionName, uint32_t flag)603 int32_t PermissionManager::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, uint32_t flag)
604 {
605     ACCESSTOKEN_LOG_INFO(LABEL,
606         "%{public}s called, tokenID: %{public}u, permissionName: %{public}s, flag: %{public}d",
607         __func__, tokenID, permissionName.c_str(), flag);
608     return CheckAndUpdatePermission(tokenID, permissionName, true, flag);
609 }
610 
RevokePermission(AccessTokenID tokenID, const std::string& permissionName, uint32_t flag)611 int32_t PermissionManager::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, uint32_t flag)
612 {
613     ACCESSTOKEN_LOG_INFO(LABEL,
614         "%{public}s called, tokenID: %{public}u, permissionName: %{public}s, flag: %{public}d",
615         __func__, tokenID, permissionName.c_str(), flag);
616     return CheckAndUpdatePermission(tokenID, permissionName, false, flag);
617 }
618 
GrantPermissionForSpecifiedTime( AccessTokenID tokenID, const std::string& permissionName, uint32_t onceTime)619 int32_t PermissionManager::GrantPermissionForSpecifiedTime(
620     AccessTokenID tokenID, const std::string& permissionName, uint32_t onceTime)
621 {
622     ACCESSTOKEN_LOG_INFO(LABEL,
623         "%{public}s called, tokenID: %{public}u, permissionName: %{public}s, onceTime: %{public}d",
624         __func__, tokenID, permissionName.c_str(), onceTime);
625     return ShortGrantManager::GetInstance().RefreshPermission(tokenID, permissionName, onceTime);
626 }
627 
ScopeToString( const std::vector<AccessTokenID>& tokenIDs, const std::vector<std::string>& permList)628 void PermissionManager::ScopeToString(
629     const std::vector<AccessTokenID>& tokenIDs, const std::vector<std::string>& permList)
630 {
631     std::stringstream str;
632     copy(tokenIDs.begin(), tokenIDs.end(), std::ostream_iterator<uint32_t>(str, ", "));
633     std::string tokenidStr = str.str();
634 
635     std::string permStr;
636     permStr = accumulate(permList.begin(), permList.end(), std::string(" "));
637 
638     ACCESSTOKEN_LOG_INFO(LABEL, "TokenidStr = %{public}s permStr =%{public}s",
639         tokenidStr.c_str(), permStr.c_str());
640 }
641 
ScopeFilter(const PermStateChangeScope& scopeSrc, PermStateChangeScope& scopeRes)642 int32_t PermissionManager::ScopeFilter(const PermStateChangeScope& scopeSrc, PermStateChangeScope& scopeRes)
643 {
644     std::set<uint32_t> tokenIdSet;
645     for (const auto& tokenId : scopeSrc.tokenIDs) {
646         if (AccessTokenInfoManager::GetInstance().IsTokenIdExist(tokenId) &&
647             (tokenIdSet.count(tokenId) == 0)) {
648             scopeRes.tokenIDs.emplace_back(tokenId);
649             tokenIdSet.insert(tokenId);
650             continue;
651         }
652         ACCESSTOKEN_LOG_ERROR(LABEL, "TokenId %{public}d invalid!", tokenId);
653     }
654     std::set<std::string> permSet;
655     for (const auto& permissionName : scopeSrc.permList) {
656         if (PermissionDefinitionCache::GetInstance().HasDefinition(permissionName) &&
657             permSet.count(permissionName) == 0) {
658             scopeRes.permList.emplace_back(permissionName);
659             permSet.insert(permissionName);
660             continue;
661         }
662         ACCESSTOKEN_LOG_ERROR(LABEL, "Permission %{public}s invalid!", permissionName.c_str());
663     }
664     if ((scopeRes.tokenIDs.empty()) && (!scopeSrc.tokenIDs.empty())) {
665         ACCESSTOKEN_LOG_ERROR(LABEL, "Valid tokenid size is 0!");
666         return AccessTokenError::ERR_PARAM_INVALID;
667     }
668     if ((scopeRes.permList.empty()) && (!scopeSrc.permList.empty())) {
669         ACCESSTOKEN_LOG_ERROR(LABEL, "Valid permission size is 0!");
670         return AccessTokenError::ERR_PARAM_INVALID;
671     }
672     ScopeToString(scopeRes.tokenIDs, scopeRes.permList);
673     return RET_SUCCESS;
674 }
675 
AddPermStateChangeCallback( const PermStateChangeScope& scope, const sptr<IRemoteObject>& callback)676 int32_t PermissionManager::AddPermStateChangeCallback(
677     const PermStateChangeScope& scope, const sptr<IRemoteObject>& callback)
678 {
679     ACCESSTOKEN_LOG_INFO(LABEL, "Called");
680     PermStateChangeScope scopeRes;
681     int32_t result = ScopeFilter(scope, scopeRes);
682     if (result != RET_SUCCESS) {
683         return result;
684     }
685     return CallbackManager::GetInstance().AddCallback(scope, callback);
686 }
687 
RemovePermStateChangeCallback(const sptr<IRemoteObject>& callback)688 int32_t PermissionManager::RemovePermStateChangeCallback(const sptr<IRemoteObject>& callback)
689 {
690     ACCESSTOKEN_LOG_INFO(LABEL, "Called");
691     return CallbackManager::GetInstance().RemoveCallback(callback);
692 }
693 
GetApiVersionByTokenId(AccessTokenID tokenID, int32_t& apiVersion)694 bool PermissionManager::GetApiVersionByTokenId(AccessTokenID tokenID, int32_t& apiVersion)
695 {
696     // only hap can do this
697     AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&tokenID);
698     ATokenTypeEnum tokenType = (ATokenTypeEnum)(idInner->type);
699     if (tokenType != TOKEN_HAP) {
700         ACCESSTOKEN_LOG_ERROR(LABEL, "Invalid token type %{public}d", tokenType);
701         return false;
702     }
703 
704     HapTokenInfo hapInfo;
705     int ret = AccessTokenInfoManager::GetInstance().GetHapTokenInfo(tokenID, hapInfo);
706     if (ret != RET_SUCCESS) {
707         ACCESSTOKEN_LOG_ERROR(LABEL, "Get hap token info error!");
708         return false;
709     }
710 
711     apiVersion = hapInfo.apiVersion;
712 
713     return true;
714 }
715 
IsPermissionVaild(const std::string& permissionName)716 bool PermissionManager::IsPermissionVaild(const std::string& permissionName)
717 {
718     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
719         ACCESSTOKEN_LOG_WARN(LABEL, "Invalid permissionName %{public}s", permissionName.c_str());
720         return false;
721     }
722 
723     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
724         ACCESSTOKEN_LOG_WARN(LABEL, "Permission %{public}s has no definition ", permissionName.c_str());
725         return false;
726     }
727     return true;
728 }
729 
GetLocationPermissionIndex(std::vector<PermissionListStateParcel>& reqPermList, LocationIndex& locationIndex)730 bool PermissionManager::GetLocationPermissionIndex(std::vector<PermissionListStateParcel>& reqPermList,
731     LocationIndex& locationIndex)
732 {
733     uint32_t index = 0;
734     bool hasFound = false;
735 
736     for (const auto& perm : reqPermList) {
737         if (perm.permsState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) {
738             locationIndex.vagueIndex = index;
739             hasFound = true;
740         } else if (perm.permsState.permissionName == ACCURATE_LOCATION_PERMISSION_NAME) {
741             locationIndex.accurateIndex = index;
742             hasFound = true;
743         } else if (perm.permsState.permissionName == BACKGROUND_LOCATION_PERMISSION_NAME) {
744             locationIndex.backIndex = index;
745             hasFound = true;
746         }
747 
748         index++;
749 
750         if ((locationIndex.vagueIndex != PERMISSION_NOT_REQUSET) &&
751             (locationIndex.accurateIndex != PERMISSION_NOT_REQUSET) &&
752             (locationIndex.backIndex != PERMISSION_NOT_REQUSET)) {
753             break;
754         }
755     }
756 
757     ACCESSTOKEN_LOG_INFO(LABEL,
758         "vague index is %{public}d, accurate index is %{public}d, background index is %{public}d!",
759         locationIndex.vagueIndex, locationIndex.accurateIndex, locationIndex.backIndex);
760 
761     return hasFound;
762 }
763 
GetLocationPermissionState(AccessTokenID tokenID, std::vector<PermissionListStateParcel>& reqPermList, std::vector<PermissionStateFull>& permsList, int32_t apiVersion, const LocationIndex& locationIndex)764 bool PermissionManager::GetLocationPermissionState(AccessTokenID tokenID,
765     std::vector<PermissionListStateParcel>& reqPermList, std::vector<PermissionStateFull>& permsList,
766     int32_t apiVersion, const LocationIndex& locationIndex)
767 {
768     bool needVagueDynamic = false;
769     bool needAccurateDynamic = false; // needVagueDynamic-false, 1. not request;2. request but not equal to DYNAMIC_OPER
770     if (locationIndex.vagueIndex != PERMISSION_NOT_REQUSET) {
771         GetSelfPermissionState(permsList, reqPermList[locationIndex.vagueIndex].permsState, apiVersion);
772         needVagueDynamic = reqPermList[locationIndex.vagueIndex].permsState.state == DYNAMIC_OPER;
773     }
774 
775     if (locationIndex.accurateIndex != PERMISSION_NOT_REQUSET) {
776         bool isVagueGranted = VerifyHapAccessToken(tokenID, VAGUE_LOCATION_PERMISSION_NAME) == PERMISSION_GRANTED;
777         // request accurate and vague permission, if vague has been set or invalid, accurate can't be requested
778         GetSelfPermissionState(permsList, reqPermList[locationIndex.accurateIndex].permsState, apiVersion);
779         needAccurateDynamic = reqPermList[locationIndex.accurateIndex].permsState.state == DYNAMIC_OPER;
780 
781         // update permsState
782         if (needAccurateDynamic) {
783             // vague permissoion is not pop and permission status os not granted
784             if (!needVagueDynamic && !isVagueGranted) {
785                 reqPermList[locationIndex.accurateIndex].permsState.state = INVALID_OPER;
786                 needAccurateDynamic = false;
787             }
788         }
789     }
790 
791     if (locationIndex.backIndex != PERMISSION_NOT_REQUSET) {
792         if (apiVersion >= BACKGROUND_LOCATION_API_VERSION) {
793             // background permission
794             // with back and vague permission, request back can not pop dynamic dialog
795             if (locationIndex.vagueIndex != PERMISSION_NOT_REQUSET) {
796                 reqPermList[locationIndex.vagueIndex].permsState.state = INVALID_OPER;
797             }
798             if (locationIndex.accurateIndex != PERMISSION_NOT_REQUSET) {
799                 reqPermList[locationIndex.accurateIndex].permsState.state = INVALID_OPER;
800             }
801             reqPermList[locationIndex.backIndex].permsState.state = INVALID_OPER;
802             return false;
803         }
804         // with back and vague permission
805         // back state is SETTING_OPER when dynamic pop-up dialog appears and INVALID_OPER when it doesn't
806         GetSelfPermissionState(permsList, reqPermList[locationIndex.backIndex].permsState, apiVersion);
807         if (reqPermList[locationIndex.backIndex].permsState.state == DYNAMIC_OPER) {
808             if (needAccurateDynamic || needVagueDynamic) {
809                 reqPermList[locationIndex.backIndex].permsState.state = SETTING_OPER;
810             } else {
811                 reqPermList[locationIndex.backIndex].permsState.state = INVALID_OPER;
812             }
813         }
814     }
815     return needVagueDynamic || needAccurateDynamic;
816 }
817 
LocationPermissionSpecialHandle( AccessTokenID tokenID, std::vector<PermissionListStateParcel>& reqPermList, std::vector<PermissionStateFull>& permsList, int32_t apiVersion)818 bool PermissionManager::LocationPermissionSpecialHandle(
819     AccessTokenID tokenID,
820     std::vector<PermissionListStateParcel>& reqPermList,
821     std::vector<PermissionStateFull>& permsList, int32_t apiVersion)
822 {
823     struct LocationIndex locationIndex;
824     if (!GetLocationPermissionIndex(reqPermList, locationIndex)) {
825         return false;
826     }
827     return GetLocationPermissionState(tokenID, reqPermList, permsList, apiVersion, locationIndex);
828 }
829 
NotifyUpdatedPermList(const std::vector<std::string>& grantedPermListBefore, const std::vector<std::string>& grantedPermListAfter, AccessTokenID tokenID)830 void PermissionManager::NotifyUpdatedPermList(const std::vector<std::string>& grantedPermListBefore,
831     const std::vector<std::string>& grantedPermListAfter, AccessTokenID tokenID)
832 {
833     for (uint32_t i = 0; i < grantedPermListBefore.size(); i++) {
834         auto it = find(grantedPermListAfter.begin(), grantedPermListAfter.end(), grantedPermListBefore[i]);
835         if (it == grantedPermListAfter.end()) {
836             CallbackManager::GetInstance().ExecuteCallbackAsync(
837                 tokenID, grantedPermListBefore[i], STATE_CHANGE_REVOKED);
838             ParamUpdate(grantedPermListBefore[i], 0, true);
839         }
840     }
841     for (uint32_t i = 0; i < grantedPermListAfter.size(); i++) {
842         auto it = find(grantedPermListBefore.begin(), grantedPermListBefore.end(), grantedPermListAfter[i]);
843         if (it == grantedPermListBefore.end()) {
844             CallbackManager::GetInstance().ExecuteCallbackAsync(
845                 tokenID, grantedPermListAfter[i], STATE_CHANGE_GRANTED);
846             ParamUpdate(grantedPermListAfter[i], 0, false);
847         }
848     }
849 }
850 
IsPermissionStateOrFlagMatched(const PermissionStateFull& state1, const PermissionStateFull& state2)851 bool PermissionManager::IsPermissionStateOrFlagMatched(const PermissionStateFull& state1,
852     const PermissionStateFull& state2)
853 {
854     return ((state1.grantStatus[0] == state2.grantStatus[0]) && (state1.grantFlags[0] == state2.grantFlags[0]));
855 }
856 
GetStateOrFlagChangedList(std::vector<PermissionStateFull>& stateListBefore, std::vector<PermissionStateFull>& stateListAfter, std::vector<PermissionStateFull>& stateChangeList)857 void PermissionManager::GetStateOrFlagChangedList(std::vector<PermissionStateFull>& stateListBefore,
858     std::vector<PermissionStateFull>& stateListAfter, std::vector<PermissionStateFull>& stateChangeList)
859 {
860     uint32_t size = stateListBefore.size();
861 
862     for (uint32_t i = 0; i < size; ++i) {
863         PermissionStateFull state1 = stateListBefore[i];
864         PermissionStateFull state2 = stateListAfter[i];
865 
866         if (!IsPermissionStateOrFlagMatched(state1, state2)) {
867             stateChangeList.emplace_back(state2);
868         }
869     }
870 }
871 
NotifyPermGrantStoreResult(bool result, uint64_t timestamp)872 void PermissionManager::NotifyPermGrantStoreResult(bool result, uint64_t timestamp)
873 {
874     grantEvent_.NotifyPermGrantStoreResult(result, timestamp);
875 }
876 
AddPermToKernel(AccessTokenID tokenID, const std::shared_ptr<PermissionPolicySet>& policy)877 void PermissionManager::AddPermToKernel(AccessTokenID tokenID, const std::shared_ptr<PermissionPolicySet>& policy)
878 {
879     if (policy == nullptr) {
880         return;
881     }
882     std::vector<uint32_t> opCodeList;
883     std::vector<bool> statusList;
884     policy->GetPermissionStateList(opCodeList, statusList);
885     int32_t ret = AddPermissionToKernel(tokenID, opCodeList, statusList);
886     if (ret != ACCESS_TOKEN_OK) {
887         ACCESSTOKEN_LOG_ERROR(LABEL, "AddPermissionToKernel(token=%{public}d), size=%{public}zu, err=%{public}d",
888             tokenID, opCodeList.size(), ret);
889     }
890 }
891 
AddPermToKernel(AccessTokenID tokenID, const std::shared_ptr<PermissionPolicySet>& policy, const std::vector<std::string>& permList)892 void PermissionManager::AddPermToKernel(AccessTokenID tokenID, const std::shared_ptr<PermissionPolicySet>& policy,
893     const std::vector<std::string>& permList)
894 {
895     if (policy == nullptr) {
896         return;
897     }
898 
899     std::vector<uint32_t> permCodeList;
900     for (const auto &permission : permList) {
901         uint32_t code;
902         if (!TransferPermissionToOpcode(permission, code)) {
903             continue;
904         }
905         permCodeList.emplace_back(code);
906     }
907 
908     std::vector<uint32_t> opCodeList;
909     std::vector<bool> statusList;
910     bool isUserActive = false;
911     policy->GetPermissionStateList(opCodeList, statusList);
912     for (uint32_t i = 0; i < opCodeList.size(); i++) {
913         if (std::find(permCodeList.begin(), permCodeList.end(), opCodeList[i]) == permCodeList.end()) {
914             continue;
915         }
916         statusList[i] = statusList[i] && isUserActive;
917     }
918     int32_t ret = AddPermissionToKernel(tokenID, opCodeList, statusList);
919     if (ret != ACCESS_TOKEN_OK) {
920         ACCESSTOKEN_LOG_ERROR(LABEL, "AddPermissionToKernel(token=%{public}d), size=%{public}zu, err=%{public}d",
921             tokenID, opCodeList.size(), ret);
922     }
923 }
924 
RemovePermFromKernel(AccessTokenID tokenID)925 void PermissionManager::RemovePermFromKernel(AccessTokenID tokenID)
926 {
927     int32_t ret = RemovePermissionFromKernel(tokenID);
928     ACCESSTOKEN_LOG_INFO(LABEL,
929         "RemovePermissionFromKernel(token=%{public}d), err=%{public}d", tokenID, ret);
930 }
931 
SetPermToKernel(AccessTokenID tokenID, const std::string& permissionName, bool isGranted)932 void PermissionManager::SetPermToKernel(AccessTokenID tokenID, const std::string& permissionName, bool isGranted)
933 {
934     uint32_t code;
935     if (!TransferPermissionToOpcode(permissionName, code)) {
936         return;
937     }
938     int32_t ret = SetPermissionToKernel(tokenID, code, isGranted);
939     ACCESSTOKEN_LOG_INFO(LABEL,
940         "SetPermissionToKernel(token=%{public}d, permission=(%{public}s), err=%{public}d",
941         tokenID, permissionName.c_str(), ret);
942 }
943 
IsAclSatisfied(const PermissionDef& permDef, const HapPolicyParams& policy)944 bool IsAclSatisfied(const PermissionDef& permDef, const HapPolicyParams& policy)
945 {
946     if (policy.apl < permDef.availableLevel) {
947         if (!permDef.provisionEnable) {
948             ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s provisionEnable is false.", permDef.permissionName.c_str());
949             return false;
950         }
951         auto isAclExist = std::any_of(
952             policy.aclRequestedList.begin(), policy.aclRequestedList.end(), [permDef](const auto &perm) {
953             return permDef.permissionName == perm;
954         });
955         if (!isAclExist) {
956             ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s need acl.", permDef.permissionName.c_str());
957             return false;
958         }
959     }
960     return true;
961 }
962 
IsPermAvailableRangeSatisfied(const PermissionDef& permDef, const std::string& appDistributionType)963 bool IsPermAvailableRangeSatisfied(const PermissionDef& permDef, const std::string& appDistributionType)
964 {
965     if (permDef.availableType == ATokenAvailableTypeEnum::MDM) {
966         if (appDistributionType == "none") {
967             ACCESSTOKEN_LOG_INFO(LABEL, "Debug app use permission: %{public}s.",
968                 permDef.permissionName.c_str());
969             return true;
970         }
971         if (appDistributionType != APP_DISTRIBUTION_TYPE_ENTERPRISE_MDM) {
972             ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s is a mdm permission, the hap is not a mdm application.",
973                 permDef.permissionName.c_str());
974             return false;
975         }
976     }
977     return true;
978 }
979 
IsUserGrantPermPreAuthorized(const std::vector<PreAuthorizationInfo> &list, const std::string &permissionName, bool &userCancelable)980 bool IsUserGrantPermPreAuthorized(const std::vector<PreAuthorizationInfo> &list,
981     const std::string &permissionName, bool &userCancelable)
982 {
983     auto iter = std::find_if(list.begin(), list.end(), [&permissionName](const auto &info) {
984             return info.permissionName == permissionName;
985         });
986     if (iter == list.end()) {
987         ACCESSTOKEN_LOG_INFO(LABEL, "Permission(%{public}s) is not in the list", permissionName.c_str());
988         return false;
989     }
990 
991     userCancelable = iter->userCancelable;
992     return true;
993 }
994 
InitDlpPermissionList(const std::string& bundleName, int32_t userId, std::vector<PermissionStateFull>& initializedList)995 bool PermissionManager::InitDlpPermissionList(const std::string& bundleName, int32_t userId,
996     std::vector<PermissionStateFull>& initializedList)
997 {
998     // get dlp original app
999     AccessTokenIDEx tokenId = AccessTokenInfoManager::GetInstance().GetHapTokenID(userId, bundleName, 0);
1000     std::shared_ptr<PermissionPolicySet> permPolicySet =
1001         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenId.tokenIdExStruct.tokenID);
1002     if (permPolicySet == nullptr) {
1003         ACCESSTOKEN_LOG_ERROR(LABEL, "PolicySet is null, TokenID=%{public}d.", tokenId.tokenIdExStruct.tokenID);
1004         return false;
1005     }
1006     permPolicySet->GetPermissionStateFulls(initializedList);
1007     return true;
1008 }
1009 
InitPermissionList(const std::string& appDistributionType, const HapPolicyParams& policy, std::vector<PermissionStateFull>& initializedList)1010 bool PermissionManager::InitPermissionList(const std::string& appDistributionType,
1011     const HapPolicyParams& policy, std::vector<PermissionStateFull>& initializedList)
1012 {
1013     ACCESSTOKEN_LOG_INFO(LABEL, "Before, request perm list size: %{public}zu, preAuthorizationInfo size %{public}zu, "
1014         "ACLRequestedList size %{public}zu.",
1015         policy.permStateList.size(), policy.preAuthorizationInfo.size(), policy.aclRequestedList.size());
1016 
1017     for (auto state : policy.permStateList) {
1018         PermissionDef permDef;
1019         int32_t ret = PermissionManager::GetInstance().GetDefPermission(
1020             state.permissionName, permDef);
1021         if (ret != AccessToken::AccessTokenKitRet::RET_SUCCESS) {
1022             ACCESSTOKEN_LOG_ERROR(LABEL, "Get definition of %{public}s failed, ret = %{public}d.",
1023                 state.permissionName.c_str(), ret);
1024             continue;
1025         }
1026         if (!IsAclSatisfied(permDef, policy)) {
1027             ACCESSTOKEN_LOG_ERROR(LABEL, "Acl of %{public}s is invalid.", permDef.permissionName.c_str());
1028             return false;
1029         }
1030 
1031         // edm check
1032         if (!IsPermAvailableRangeSatisfied(permDef, appDistributionType)) {
1033             ACCESSTOKEN_LOG_ERROR(LABEL, "Available range of %{public}s is invalid.", permDef.permissionName.c_str());
1034             return false;
1035         }
1036         state.grantFlags[0] = PERMISSION_DEFAULT_FLAG;
1037         state.grantStatus[0] = PERMISSION_DENIED;
1038 
1039         if (permDef.grantMode == AccessToken::GrantMode::SYSTEM_GRANT) {
1040             state.grantFlags[0] = PERMISSION_SYSTEM_FIXED;
1041             state.grantStatus[0] = PERMISSION_GRANTED;
1042             initializedList.emplace_back(state);
1043             continue;
1044         }
1045         if (policy.preAuthorizationInfo.size() == 0) {
1046             initializedList.emplace_back(state);
1047             continue;
1048         }
1049         bool userCancelable = true;
1050         if (IsUserGrantPermPreAuthorized(policy.preAuthorizationInfo, state.permissionName, userCancelable)) {
1051             state.grantFlags[0] = userCancelable ? PERMISSION_GRANTED_BY_POLICY : PERMISSION_SYSTEM_FIXED;
1052             state.grantStatus[0] = PERMISSION_GRANTED;
1053         }
1054         initializedList.emplace_back(state);
1055     }
1056     ACCESSTOKEN_LOG_INFO(LABEL, "After, request perm list size: %{public}zu.", initializedList.size());
1057     return true;
1058 }
1059 
1060 } // namespace AccessToken
1061 } // namespace Security
1062 } // namespace OHOS
1063