• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "callback_manager.h"
29 #ifdef SUPPORT_SANDBOX_APP
30 #include "dlp_permission_set_manager.h"
31 #endif
32 #include "ipc_skeleton.h"
33 #include "parameter.h"
34 #include "permission_definition_cache.h"
35 #include "permission_validator.h"
36 #ifdef TOKEN_SYNC_ENABLE
37 #include "token_modify_notifier.h"
38 #endif
39 
40 namespace OHOS {
41 namespace Security {
42 namespace AccessToken {
43 namespace {
44 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionManager"};
45 static const char* PERMISSION_STATUS_CHANGE_KEY = "accesstoken.permission.change";
46 static constexpr int32_t VALUE_MAX_LEN = 32;
47 }
48 PermissionManager* PermissionManager::implInstance_ = nullptr;
49 std::recursive_mutex PermissionManager::mutex_;
50 
GetInstance()51 PermissionManager& PermissionManager::GetInstance()
52 {
53     if (implInstance_ == nullptr) {
54         std::lock_guard<std::recursive_mutex> lock_l(mutex_);
55         if (implInstance_ == nullptr) {
56             implInstance_ = new PermissionManager();
57         }
58     }
59     return *implInstance_;
60 }
61 
RegisterImpl(PermissionManager * implInstance)62 void PermissionManager::RegisterImpl(PermissionManager* implInstance)
63 {
64     implInstance_ = implInstance;
65 }
66 
PermissionManager()67 PermissionManager::PermissionManager()
68 {
69     char value[VALUE_MAX_LEN] = {0};
70     int32_t ret = GetParameter(PERMISSION_STATUS_CHANGE_KEY, "", value, VALUE_MAX_LEN - 1);
71     if (ret < 0) {
72         ACCESSTOKEN_LOG_ERROR(LABEL, "return default value, ret=%{public}d", ret);
73         paramValue_ = 0;
74         return;
75     }
76     paramValue_ = static_cast<uint64_t>(std::atoll(value));
77 }
78 
~PermissionManager()79 PermissionManager::~PermissionManager()
80 {
81 }
82 
AddDefPermissions(const std::vector<PermissionDef> & permList,AccessTokenID tokenId,bool updateFlag)83 void PermissionManager::AddDefPermissions(const std::vector<PermissionDef>& permList, AccessTokenID tokenId,
84     bool updateFlag)
85 {
86     std::vector<PermissionDef> permFilterList;
87     PermissionValidator::FilterInvalidPermissionDef(permList, permFilterList);
88 
89     for (const auto& perm : permFilterList) {
90         if (updateFlag) {
91             PermissionDefinitionCache::GetInstance().Update(perm);
92             continue;
93         }
94 
95         if (!PermissionDefinitionCache::GetInstance().HasDefinition(perm.permissionName)) {
96             PermissionDefinitionCache::GetInstance().Insert(perm, tokenId);
97         } else {
98             ACCESSTOKEN_LOG_INFO(LABEL, "permission %{public}s has define",
99                 TransferPermissionDefToString(perm).c_str());
100         }
101     }
102 }
103 
RemoveDefPermissions(AccessTokenID tokenID)104 void PermissionManager::RemoveDefPermissions(AccessTokenID tokenID)
105 {
106     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u", __func__, tokenID);
107     std::shared_ptr<HapTokenInfoInner> tokenInfo =
108         AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
109     if (tokenInfo == nullptr) {
110         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params(tokenID: %{public}u)!", tokenID);
111         return;
112     }
113     std::string bundleName = tokenInfo->GetBundleName();
114     PermissionDefinitionCache::GetInstance().DeleteByBundleName(bundleName);
115 }
116 
VerifyHapAccessToken(AccessTokenID tokenID,const std::string & permissionName)117 int PermissionManager::VerifyHapAccessToken(AccessTokenID tokenID, const std::string& permissionName)
118 {
119     std::shared_ptr<HapTokenInfoInner> tokenInfoPtr =
120         AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
121     if (tokenInfoPtr == nullptr) {
122         ACCESSTOKEN_LOG_ERROR(LABEL, "can not find tokenInfo!");
123         return PERMISSION_DENIED;
124     }
125     std::shared_ptr<PermissionPolicySet> permPolicySet = tokenInfoPtr->GetHapInfoPermissionPolicySet();
126     if (permPolicySet == nullptr) {
127         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
128         return PERMISSION_DENIED;
129     }
130 
131     return permPolicySet->VerifyPermissStatus(permissionName);
132 }
133 
VerifyNativeAccessToken(AccessTokenID tokenID,const std::string & permissionName)134 int PermissionManager::VerifyNativeAccessToken(AccessTokenID tokenID, const std::string& permissionName)
135 {
136     std::shared_ptr<NativeTokenInfoInner> tokenInfoPtr =
137         AccessTokenInfoManager::GetInstance().GetNativeTokenInfoInner(tokenID);
138     if (tokenInfoPtr == nullptr) {
139         ACCESSTOKEN_LOG_ERROR(LABEL, "can not find tokenInfo!");
140         return PERMISSION_DENIED;
141     }
142 
143     NativeTokenInfo info;
144     tokenInfoPtr->TranslateToNativeTokenInfo(info);
145     if (PermissionDefinitionCache::GetInstance().IsPermissionDefEmpty()) {
146         ACCESSTOKEN_LOG_INFO(LABEL, "permission definition set has not been installed!");
147         if (info.apl >= APL_SYSTEM_BASIC) {
148             return PERMISSION_GRANTED;
149         }
150         ACCESSTOKEN_LOG_INFO(LABEL, "native process apl is %{public}d!", info.apl);
151         return PERMISSION_DENIED;
152     }
153     if (!tokenInfoPtr->IsRemote() && !PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
154         ACCESSTOKEN_LOG_ERROR(
155             LABEL, "no definition for permission: %{public}s!", permissionName.c_str());
156         return PERMISSION_DENIED;
157     }
158     std::shared_ptr<PermissionPolicySet> permPolicySet =
159         AccessTokenInfoManager::GetInstance().GetNativePermissionPolicySet(tokenID);
160     if (permPolicySet == nullptr) {
161         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
162         return PERMISSION_DENIED;
163     }
164 
165     return permPolicySet->VerifyPermissStatus(permissionName);
166 }
167 
VerifyAccessToken(AccessTokenID tokenID,const std::string & permissionName)168 int PermissionManager::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName)
169 {
170     if (tokenID == INVALID_TOKENID) {
171         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERMISSION_CHECK",
172             HiviewDFX::HiSysEvent::EventType::FAULT, "CODE", VERIFY_TOKEN_ID_ERROR, "CALLER_TOKENID",
173             static_cast<AccessTokenID>(IPCSkeleton::GetCallingTokenID()), "PERMISSION_NAME", permissionName);
174         ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid");
175         return PERMISSION_DENIED;
176     }
177 
178     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
179         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
180         return PERMISSION_DENIED;
181     }
182 
183     ATokenTypeEnum tokenType = AccessTokenIDManager::GetInstance().GetTokenIdTypeEnum(tokenID);
184     if ((tokenType == TOKEN_NATIVE) || (tokenType == TOKEN_SHELL)) {
185         return VerifyNativeAccessToken(tokenID, permissionName);
186     }
187     if (tokenType == TOKEN_HAP) {
188         return VerifyHapAccessToken(tokenID, permissionName);
189     }
190     ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenType!");
191     return PERMISSION_DENIED;
192 }
193 
GetDefPermission(const std::string & permissionName,PermissionDef & permissionDefResult)194 int PermissionManager::GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult)
195 {
196     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
197         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
198         return AccessTokenError::ERR_PARAM_INVALID;
199     }
200     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
201         ACCESSTOKEN_LOG_ERROR(
202             LABEL, "no definition for permission: %{public}s!", permissionName.c_str());
203         return AccessTokenError::ERR_PERMISSION_NOT_EXIT;
204     }
205     return PermissionDefinitionCache::GetInstance().FindByPermissionName(permissionName, permissionDefResult);
206 }
207 
GetDefPermissions(AccessTokenID tokenID,std::vector<PermissionDef> & permList)208 int PermissionManager::GetDefPermissions(AccessTokenID tokenID, std::vector<PermissionDef>& permList)
209 {
210     std::shared_ptr<PermissionPolicySet> permPolicySet =
211         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
212     if (permPolicySet == nullptr) {
213         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
214         return RET_FAILED;
215     }
216 
217     permPolicySet->GetDefPermissions(permList);
218     return RET_SUCCESS;
219 }
220 
GetReqPermissions(AccessTokenID tokenID,std::vector<PermissionStateFull> & reqPermList,bool isSystemGrant)221 int PermissionManager::GetReqPermissions(
222     AccessTokenID tokenID, std::vector<PermissionStateFull>& reqPermList, bool isSystemGrant)
223 {
224     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u, isSystemGrant: %{public}d",
225         __func__, tokenID, isSystemGrant);
226     std::shared_ptr<PermissionPolicySet> permPolicySet =
227         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
228     if (permPolicySet == nullptr) {
229         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
230         return RET_FAILED;
231     }
232 
233     GrantMode mode = isSystemGrant ? SYSTEM_GRANT : USER_GRANT;
234     std::vector<PermissionStateFull> tmpList;
235     permPolicySet->GetPermissionStateFulls(tmpList);
236     for (const auto& perm : tmpList) {
237         PermissionDef permDef;
238         GetDefPermission(perm.permissionName, permDef);
239         if (permDef.grantMode == mode) {
240             reqPermList.emplace_back(perm);
241         }
242     }
243     return RET_SUCCESS;
244 }
245 
GetSelfPermissionState(std::vector<PermissionStateFull> permsList,PermissionListState & permState,int32_t apiVersion)246 void PermissionManager::GetSelfPermissionState(std::vector<PermissionStateFull> permsList,
247     PermissionListState &permState, int32_t apiVersion)
248 {
249     bool foundGoal = false;
250     int32_t goalGrantStatus;
251     uint32_t goalGrantFlags;
252 
253     // api8 require vague location permission refuse directlty beause there is no vague location permission in api8
254     if ((permState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) &&
255        (apiVersion < ACCURATE_LOCATION_API_VERSION)) {
256         permState.state = INVALID_OPER;
257         return;
258     }
259 
260     auto iter = std::find_if(permsList.begin(), permsList.end(), [permState](const PermissionStateFull& perm) {
261         return permState.permissionName == perm.permissionName;
262     });
263     if (iter != permsList.end()) {
264         ACCESSTOKEN_LOG_DEBUG(LABEL, "find goal permission: %{public}s, status: %{public}d, flag: %{public}d",
265             permState.permissionName.c_str(), iter->grantStatus[0], iter->grantFlags[0]);
266         foundGoal = true;
267         goalGrantStatus = iter->grantStatus[0];
268         goalGrantFlags = static_cast<uint32_t>(iter->grantFlags[0]);
269     }
270 
271     if (foundGoal == false) {
272         ACCESSTOKEN_LOG_WARN(LABEL,
273             "can not find permission: %{public}s define!", permState.permissionName.c_str());
274         permState.state = INVALID_OPER;
275         return;
276     }
277     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permState.permissionName)) {
278         ACCESSTOKEN_LOG_WARN(LABEL,
279             "no definition for permission: %{public}s!", permState.permissionName.c_str());
280         permState.state = INVALID_OPER;
281         return;
282     }
283 
284     if (goalGrantStatus == PERMISSION_DENIED) {
285         if ((goalGrantFlags == PERMISSION_DEFAULT_FLAG) ||
286             ((goalGrantFlags & PERMISSION_USER_SET) != 0)) {
287             permState.state = DYNAMIC_OPER;
288             return;
289         }
290         if ((goalGrantFlags & PERMISSION_USER_FIXED) != 0) {
291             permState.state = SETTING_OPER;
292             return;
293         }
294     }
295 
296     permState.state = PASS_OPER;
297     return;
298 }
299 
GetPermissionFlag(AccessTokenID tokenID,const std::string & permissionName,int & flag)300 int PermissionManager::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName, int& flag)
301 {
302     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u, permissionName: %{public}s",
303         __func__, tokenID, permissionName.c_str());
304     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
305         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
306         return AccessTokenError::ERR_PARAM_INVALID;
307     }
308     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
309         ACCESSTOKEN_LOG_ERROR(
310             LABEL, "no definition for permission: %{public}s!", permissionName.c_str());
311         return AccessTokenError::ERR_PERMISSION_NOT_EXIT;
312     }
313     std::shared_ptr<PermissionPolicySet> permPolicySet =
314         AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
315     if (permPolicySet == nullptr) {
316         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
317         return AccessTokenError::ERR_PARAM_INVALID;
318     }
319     return permPolicySet->QueryPermissionFlag(permissionName, flag);
320 }
321 
ParamUpdate(const std::string & permissionName,uint32_t flag)322 void PermissionManager::ParamUpdate(const std::string& permissionName, uint32_t flag)
323 {
324     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permParamSetLock_);
325     if (PermissionDefinitionCache::GetInstance().IsUserGrantedPermission(permissionName) &&
326         ((flag != PERMISSION_GRANTED_BY_POLICY) && (flag != PERMISSION_SYSTEM_FIXED))) {
327         paramValue_++;
328         int32_t res = SetParameter(PERMISSION_STATUS_CHANGE_KEY, std::to_string(paramValue_).c_str());
329         if (res != 0) {
330             ACCESSTOKEN_LOG_ERROR(LABEL, "SetParameter failed %{public}d", res);
331         }
332     }
333 }
UpdateTokenPermissionState(AccessTokenID tokenID,const std::string & permissionName,bool isGranted,int flag)334 int32_t PermissionManager::UpdateTokenPermissionState(
335     AccessTokenID tokenID, const std::string& permissionName, bool isGranted, int flag)
336 {
337     std::shared_ptr<HapTokenInfoInner> infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
338     if (infoPtr == nullptr) {
339         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
340         return AccessTokenError::ERR_PARAM_INVALID;
341     }
342     if (infoPtr->IsRemote()) {
343         ACCESSTOKEN_LOG_ERROR(LABEL, "remote token can not update");
344         return AccessTokenError::ERR_PERMISSION_OPERATE_FAILED;
345     }
346 
347     std::shared_ptr<PermissionPolicySet> permPolicySet = infoPtr->GetHapInfoPermissionPolicySet();
348     if (permPolicySet == nullptr) {
349         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
350         return AccessTokenError::ERR_PARAM_INVALID;
351     }
352 #ifdef SUPPORT_SANDBOX_APP
353     int32_t dlpType = infoPtr->GetDlpType();
354     if (isGranted && dlpType != DLP_COMMON) {
355         int32_t dlpMode = DlpPermissionSetManager::GetInstance().GetPermDlpMode(permissionName);
356         if (DlpPermissionSetManager::GetInstance().IsPermStateNeedUpdate(dlpType, dlpMode)) {
357             ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}u is not allowed to be granted permissionName %{public}s",
358                 tokenID, permissionName.c_str());
359             return AccessTokenError::ERR_PERMISSION_OPERATE_FAILED;
360         }
361     }
362 #endif
363     bool isUpdated = false;
364     int32_t ret =
365         permPolicySet->UpdatePermissionStatus(permissionName, isGranted, static_cast<uint32_t>(flag), isUpdated);
366     if (ret != RET_SUCCESS) {
367         return ret;
368     }
369     if (isUpdated) {
370         ACCESSTOKEN_LOG_INFO(LABEL, "isUpdated");
371         int32_t changeType = isGranted ? GRANTED : REVOKED;
372         CallbackManager::GetInstance().ExecuteCallbackAsync(tokenID, permissionName, changeType);
373         HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERMISSION_CHECK_EVENT",
374             HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "CODE", USER_GRANT_PERMISSION_EVENT,
375             "CALLER_TOKENID", tokenID, "PERMISSION_NAME", permissionName, "PERMISSION_GRANT_TYPE", changeType);
376         grantEvent_.AddEvent(tokenID, permissionName, infoPtr->permUpdateTimestamp_);
377         ParamUpdate(permissionName, static_cast<uint32_t>(flag));
378     }
379 
380 #ifdef TOKEN_SYNC_ENABLE
381     TokenModifyNotifier::GetInstance().NotifyTokenModify(tokenID);
382 #endif
383     return RET_SUCCESS;
384 }
385 
GrantPermission(AccessTokenID tokenID,const std::string & permissionName,int flag)386 int32_t PermissionManager::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag)
387 {
388     ACCESSTOKEN_LOG_INFO(LABEL,
389         "%{public}s called, tokenID: %{public}u, permissionName: %{public}s, flag: %{public}d",
390         __func__, tokenID, permissionName.c_str(), flag);
391     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
392         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
393         return AccessTokenError::ERR_PARAM_INVALID;
394     }
395     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
396         ACCESSTOKEN_LOG_ERROR(
397             LABEL, "no definition for permission: %{public}s!", permissionName.c_str());
398         return AccessTokenError::ERR_PERMISSION_NOT_EXIT;
399     }
400     if (!PermissionValidator::IsPermissionFlagValid(flag)) {
401         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
402         return AccessTokenError::ERR_PARAM_INVALID;
403     }
404     return UpdateTokenPermissionState(tokenID, permissionName, true, flag);
405 }
406 
RevokePermission(AccessTokenID tokenID,const std::string & permissionName,int flag)407 int32_t PermissionManager::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag)
408 {
409     ACCESSTOKEN_LOG_INFO(LABEL,
410         "%{public}s called, tokenID: %{public}u, permissionName: %{public}s, flag: %{public}d",
411         __func__, tokenID, permissionName.c_str(), flag);
412     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
413         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
414         return AccessTokenError::ERR_PARAM_INVALID;
415     }
416     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
417         ACCESSTOKEN_LOG_ERROR(
418             LABEL, "no definition for permission: %{public}s!", permissionName.c_str());
419         return AccessTokenError::ERR_PERMISSION_NOT_EXIT;
420     }
421     if (!PermissionValidator::IsPermissionFlagValid(flag)) {
422         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
423         return AccessTokenError::ERR_PARAM_INVALID;
424     }
425     return UpdateTokenPermissionState(tokenID, permissionName, false, flag);
426 }
427 
ScopeToString(const std::vector<AccessTokenID> & tokenIDs,const std::vector<std::string> & permList)428 void PermissionManager::ScopeToString(
429     const std::vector<AccessTokenID>& tokenIDs, const std::vector<std::string>& permList)
430 {
431     std::stringstream str;
432     copy(tokenIDs.begin(), tokenIDs.end(), std::ostream_iterator<uint32_t>(str, ", "));
433     std::string tokenidStr = str.str();
434 
435     std::string permStr;
436     permStr = accumulate(permList.begin(), permList.end(), std::string(" "));
437 
438     ACCESSTOKEN_LOG_INFO(LABEL, "tokenidStr = %{public}s permStr =%{public}s",
439         tokenidStr.c_str(), permStr.c_str());
440 }
441 
ScopeFilter(const PermStateChangeScope & scopeSrc,PermStateChangeScope & scopeRes)442 int32_t PermissionManager::ScopeFilter(const PermStateChangeScope& scopeSrc, PermStateChangeScope& scopeRes)
443 {
444     std::set<uint32_t> tokenIdSet;
445     for (const auto& tokenId : scopeSrc.tokenIDs) {
446         if (AccessTokenInfoManager::GetInstance().IsTokenIdExist(tokenId) &&
447             (tokenIdSet.count(tokenId) == 0)) {
448             scopeRes.tokenIDs.emplace_back(tokenId);
449             tokenIdSet.insert(tokenId);
450             continue;
451         }
452         ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId %{public}d invalid!", tokenId);
453     }
454     std::set<std::string> permSet;
455     for (const auto& permissionName : scopeSrc.permList) {
456         if (PermissionDefinitionCache::GetInstance().HasDefinition(permissionName) &&
457             permSet.count(permissionName) == 0) {
458             scopeRes.permList.emplace_back(permissionName);
459             permSet.insert(permissionName);
460             continue;
461         }
462         ACCESSTOKEN_LOG_ERROR(LABEL, "permission %{public}s invalid!", permissionName.c_str());
463     }
464     if ((scopeRes.tokenIDs.empty()) && (!scopeSrc.tokenIDs.empty())) {
465         ACCESSTOKEN_LOG_ERROR(LABEL, "valid tokenid size is 0!");
466         return AccessTokenError::ERR_PARAM_INVALID;
467     }
468     if ((scopeRes.permList.empty()) && (!scopeSrc.permList.empty())) {
469         ACCESSTOKEN_LOG_ERROR(LABEL, "valid permission size is 0!");
470         return AccessTokenError::ERR_PARAM_INVALID;
471     }
472     ScopeToString(scopeRes.tokenIDs, scopeRes.permList);
473     return RET_SUCCESS;
474 }
475 
AddPermStateChangeCallback(const PermStateChangeScope & scope,const sptr<IRemoteObject> & callback)476 int32_t PermissionManager::AddPermStateChangeCallback(
477     const PermStateChangeScope& scope, const sptr<IRemoteObject>& callback)
478 {
479     ACCESSTOKEN_LOG_INFO(LABEL, "called");
480     PermStateChangeScope scopeRes;
481     int32_t result = ScopeFilter(scope, scopeRes);
482     if (result != RET_SUCCESS) {
483         return result;
484     }
485     auto callbackScopePtr = std::make_shared<PermStateChangeScope>(scopeRes);
486     if (callbackScopePtr == nullptr) {
487         ACCESSTOKEN_LOG_ERROR(LABEL, "callbackScopePtr is nullptr");
488         return AccessTokenError::ERR_MALLOC_FAILED;
489     }
490     return CallbackManager::GetInstance().AddCallback(callbackScopePtr, callback);
491 }
492 
RemovePermStateChangeCallback(const sptr<IRemoteObject> & callback)493 int32_t PermissionManager::RemovePermStateChangeCallback(const sptr<IRemoteObject>& callback)
494 {
495     return CallbackManager::GetInstance().RemoveCallback(callback);
496 }
497 
GetApiVersionByTokenId(AccessTokenID tokenID,int32_t & apiVersion)498 bool PermissionManager::GetApiVersionByTokenId(AccessTokenID tokenID, int32_t& apiVersion)
499 {
500     // only hap can do this
501     AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&tokenID);
502     ATokenTypeEnum tokenType = (ATokenTypeEnum)(idInner->type);
503     if (tokenType != TOKEN_HAP) {
504         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid token type %{public}d", tokenType);
505         return false;
506     }
507 
508     HapTokenInfo hapInfo;
509     int ret = AccessTokenInfoManager::GetInstance().GetHapTokenInfo(tokenID, hapInfo);
510     if (ret != RET_SUCCESS) {
511         ACCESSTOKEN_LOG_ERROR(LABEL, "get hap token info error!");
512         return false;
513     }
514 
515     apiVersion = hapInfo.apiVersion;
516 
517     return true;
518 }
519 
GetLocationPermissionIndex(std::vector<PermissionListStateParcel> & reqPermList,uint32_t & vagueIndex,uint32_t & accurateIndex)520 bool PermissionManager::GetLocationPermissionIndex(std::vector<PermissionListStateParcel>& reqPermList,
521     uint32_t& vagueIndex, uint32_t& accurateIndex)
522 {
523     int index = 0;
524     bool hasFound = false;
525 
526     for (const auto& perm : reqPermList) {
527         if (perm.permsState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) {
528             vagueIndex = index;
529             hasFound = true;
530         } else if (perm.permsState.permissionName == ACCURATE_LOCATION_PERMISSION_NAME) {
531             accurateIndex = index;
532             hasFound = true;
533         }
534 
535         index++;
536 
537         if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) {
538             break;
539         }
540     }
541 
542     ACCESSTOKEN_LOG_INFO(LABEL,
543         "vague location permission index is %{public}d, accurate location permission index is %{public}d!",
544         vagueIndex, accurateIndex);
545 
546     return hasFound;
547 }
548 
IsPermissionVaild(const std::string & permissionName)549 bool PermissionManager::IsPermissionVaild(const std::string& permissionName)
550 {
551     if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
552         ACCESSTOKEN_LOG_WARN(LABEL, "invalid permissionName %{public}s", permissionName.c_str());
553         return false;
554     }
555 
556     if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
557         ACCESSTOKEN_LOG_WARN(LABEL, "permission %{public}s has no definition ", permissionName.c_str());
558         return false;
559     }
560     return true;
561 }
562 
GetPermissionStatusAndFlag(const std::string & permissionName,const std::vector<PermissionStateFull> & permsList,int32_t & status,uint32_t & flag)563 bool PermissionManager::GetPermissionStatusAndFlag(const std::string& permissionName,
564     const std::vector<PermissionStateFull>& permsList, int32_t& status, uint32_t& flag)
565 {
566     if (!IsPermissionVaild(permissionName)) {
567         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid permission %{public}s", permissionName.c_str());
568         return false;
569     }
570 
571     auto iter = std::find_if(permsList.begin(), permsList.end(), [permissionName](const PermissionStateFull& perm) {
572         return permissionName == perm.permissionName;
573     });
574     if (iter != permsList.end()) {
575         status = iter->grantStatus[0];
576         flag = static_cast<uint32_t>(iter->grantFlags[0]);
577 
578         ACCESSTOKEN_LOG_DEBUG(LABEL, "permission:%{public}s, status:%{public}d, flag:%{public}d!",
579             permissionName.c_str(), status, flag);
580         return true;
581     }
582 
583     return false;
584 }
585 
AllLocationPermissionHandle(std::vector<PermissionListStateParcel> & reqPermList,std::vector<PermissionStateFull> permsList,uint32_t vagueIndex,uint32_t accurateIndex)586 void PermissionManager::AllLocationPermissionHandle(std::vector<PermissionListStateParcel>& reqPermList,
587     std::vector<PermissionStateFull> permsList, uint32_t vagueIndex, uint32_t accurateIndex)
588 {
589     int32_t vagueStatus = PERMISSION_DENIED;
590     uint32_t vagueFlag = PERMISSION_DEFAULT_FLAG;
591     int32_t vagueState = INVALID_OPER;
592     int32_t accurateStatus = PERMISSION_DENIED;
593     uint32_t accurateFlag = PERMISSION_DEFAULT_FLAG;
594     int32_t accurateState = INVALID_OPER;
595 
596     if (!GetPermissionStatusAndFlag(VAGUE_LOCATION_PERMISSION_NAME, permsList, vagueStatus, vagueFlag) ||
597         !GetPermissionStatusAndFlag(ACCURATE_LOCATION_PERMISSION_NAME, permsList, accurateStatus, accurateFlag)) {
598         return;
599     }
600 
601     // vague location status -1 means vague location permission has been refused
602     if (vagueStatus == PERMISSION_DENIED) {
603         if ((vagueFlag == PERMISSION_DEFAULT_FLAG) || ((vagueFlag & PERMISSION_USER_SET) != 0)) {
604             // vague location flag 0 or 1 means permission has not been operated or valid only once
605             vagueState = DYNAMIC_OPER;
606             accurateState = DYNAMIC_OPER;
607         } else if ((vagueFlag & PERMISSION_USER_FIXED) != 0) {
608             // vague location flag 2 means vague location has been operated, only can be changed by settings
609             // so that accurate location is no need to operate
610             vagueState = SETTING_OPER;
611             accurateState = SETTING_OPER;
612         }
613     } else if (vagueStatus == PERMISSION_GRANTED) {
614         // vague location status 0 means vague location permission has been accepted
615         // now flag 1 is not in use so return PASS_OPER, otherwise should judge by flag
616         vagueState = PASS_OPER;
617 
618         if (accurateStatus == PERMISSION_DENIED) {
619             if ((accurateFlag == PERMISSION_DEFAULT_FLAG) || ((accurateFlag & PERMISSION_USER_SET) != 0)) {
620                 accurateState = DYNAMIC_OPER;
621             } else if ((accurateFlag & PERMISSION_USER_FIXED) != 0) {
622                 accurateState = SETTING_OPER;
623             }
624         } else if (accurateStatus == PERMISSION_GRANTED) {
625             accurateState = PASS_OPER;
626         }
627     }
628 
629     ACCESSTOKEN_LOG_DEBUG(LABEL,
630         "vague location permission state is %{public}d, accurate location permission state is %{public}d",
631         vagueState, accurateState);
632 
633     reqPermList[vagueIndex].permsState.state = vagueState;
634     reqPermList[accurateIndex].permsState.state = accurateState;
635 }
636 
LocationPermissionSpecialHandle(std::vector<PermissionListStateParcel> & reqPermList,int32_t apiVersion,std::vector<PermissionStateFull> permsList,uint32_t vagueIndex,uint32_t accurateIndex)637 bool PermissionManager::LocationPermissionSpecialHandle(std::vector<PermissionListStateParcel>& reqPermList,
638     int32_t apiVersion, std::vector<PermissionStateFull> permsList, uint32_t vagueIndex, uint32_t accurateIndex)
639 {
640     if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex == ELEMENT_NOT_FOUND)) {
641         // only vague location permission
642         GetSelfPermissionState(permsList, reqPermList[vagueIndex].permsState, apiVersion);
643         return (static_cast<PermissionOper>(reqPermList[vagueIndex].permsState.state) == DYNAMIC_OPER);
644     }
645 
646     if ((vagueIndex == ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) {
647         // only accurate location permission refuse directly
648         ACCESSTOKEN_LOG_ERROR(LABEL, "operate invaild, accurate location permission base on vague location permission");
649         reqPermList[accurateIndex].permsState.state = INVALID_OPER;
650         return false;
651     }
652 
653     // all location permissions
654     AllLocationPermissionHandle(reqPermList, permsList, vagueIndex, accurateIndex);
655     return ((static_cast<PermissionOper>(reqPermList[vagueIndex].permsState.state) == DYNAMIC_OPER) ||
656         (static_cast<PermissionOper>(reqPermList[accurateIndex].permsState.state) == DYNAMIC_OPER));
657 }
658 
ClearUserGrantedPermissionState(AccessTokenID tokenID)659 void PermissionManager::ClearUserGrantedPermissionState(AccessTokenID tokenID)
660 {
661     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u", __func__, tokenID);
662     std::shared_ptr<HapTokenInfoInner> infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
663     if (infoPtr == nullptr) {
664         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
665         return;
666     }
667     if (infoPtr->IsRemote()) {
668         ACCESSTOKEN_LOG_ERROR(LABEL, "remote token can not clear.");
669         return;
670     }
671 
672     std::shared_ptr<PermissionPolicySet> permPolicySet = infoPtr->GetHapInfoPermissionPolicySet();
673     if (permPolicySet == nullptr) {
674         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
675         return;
676     }
677 
678     permPolicySet->ResetUserGrantPermissionStatus();
679 }
680 
NotifyPermGrantStoreResult(bool result,uint64_t timestamp)681 void PermissionManager::NotifyPermGrantStoreResult(bool result, uint64_t timestamp)
682 {
683     grantEvent_.NotifyPermGrantStoreResult(result, timestamp);
684 }
685 
TransferPermissionDefToString(const PermissionDef & inPermissionDef)686 std::string PermissionManager::TransferPermissionDefToString(const PermissionDef& inPermissionDef)
687 {
688     std::string infos;
689     infos.append(R"({"permissionName": ")" + inPermissionDef.permissionName + R"(")");
690     infos.append(R"(, "bundleName": ")" + inPermissionDef.bundleName + R"(")");
691     infos.append(R"(, "grantMode": )" + std::to_string(inPermissionDef.grantMode));
692     infos.append(R"(, "availableLevel": )" + std::to_string(inPermissionDef.availableLevel));
693     infos.append(R"(, "provisionEnable": )" + std::to_string(inPermissionDef.provisionEnable));
694     infos.append(R"(, "distributedSceneEnable": )" + std::to_string(inPermissionDef.distributedSceneEnable));
695     infos.append(R"(, "label": ")" + inPermissionDef.label + R"(")");
696     infos.append(R"(, "labelId": )" + std::to_string(inPermissionDef.labelId));
697     infos.append(R"(, "description": ")" + inPermissionDef.description + R"(")");
698     infos.append(R"(, "descriptionId": )" + std::to_string(inPermissionDef.descriptionId));
699     infos.append("}");
700     return infos;
701 }
702 } // namespace AccessToken
703 } // namespace Security
704 } // namespace OHOS
705