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