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_policy_set.h"
17
18 #include "accesstoken_log.h"
19 #include "access_token_error.h"
20 #include "data_storage.h"
21 #include "data_translator.h"
22 #include "token_field_const.h"
23 #include "permission_definition_cache.h"
24 #include "permission_validator.h"
25
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 namespace {
30 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionPolicySet"};
31 }
32
~PermissionPolicySet()33 PermissionPolicySet::~PermissionPolicySet()
34 {
35 ACCESSTOKEN_LOG_DEBUG(LABEL,
36 "%{public}s called, tokenID: 0x%{public}x destruction", __func__, tokenId_);
37 }
38
BuildPermissionPolicySet(AccessTokenID tokenId,const std::vector<PermissionStateFull> & permStateList)39 std::shared_ptr<PermissionPolicySet> PermissionPolicySet::BuildPermissionPolicySet(
40 AccessTokenID tokenId, const std::vector<PermissionStateFull>& permStateList)
41 {
42 std::shared_ptr<PermissionPolicySet> policySet = std::make_shared<PermissionPolicySet>();
43 if (policySet != nullptr) {
44 PermissionValidator::FilterInvalidPermissionState(permStateList, policySet->permStateList_);
45 policySet->tokenId_ = tokenId;
46 }
47 return policySet;
48 }
49
UpdatePermStateFull(const PermissionStateFull & permOld,PermissionStateFull & permNew)50 void PermissionPolicySet::UpdatePermStateFull(const PermissionStateFull& permOld, PermissionStateFull& permNew)
51 {
52 if (permNew.isGeneral == permOld.isGeneral) {
53 permNew.resDeviceID = permOld.resDeviceID;
54 permNew.grantStatus = permOld.grantStatus;
55 permNew.grantFlags = permOld.grantFlags;
56 }
57 }
58
Update(const std::vector<PermissionStateFull> & permStateList)59 void PermissionPolicySet::Update(const std::vector<PermissionStateFull>& permStateList)
60 {
61 std::vector<PermissionStateFull> permStateFilterList;
62 PermissionValidator::FilterInvalidPermissionState(permStateList, permStateFilterList);
63
64 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
65
66 for (PermissionStateFull& permStateNew : permStateFilterList) {
67 auto iter = std::find_if(permStateList_.begin(), permStateList_.end(),
68 [permStateNew](const PermissionStateFull& permStateOld) {
69 return permStateNew.permissionName == permStateOld.permissionName;
70 });
71 if (iter != permStateList_.end()) {
72 UpdatePermStateFull(*iter, permStateNew);
73 break;
74 }
75 }
76 permStateList_ = permStateFilterList;
77 }
78
RestorePermissionPolicy(AccessTokenID tokenId,const std::vector<GenericValues> & permStateRes)79 std::shared_ptr<PermissionPolicySet> PermissionPolicySet::RestorePermissionPolicy(AccessTokenID tokenId,
80 const std::vector<GenericValues>& permStateRes)
81 {
82 std::shared_ptr<PermissionPolicySet> policySet = std::make_shared<PermissionPolicySet>();
83 if (policySet == nullptr) {
84 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x new failed.", tokenId);
85 return nullptr;
86 }
87 policySet->tokenId_ = tokenId;
88
89 for (const GenericValues& stateValue : permStateRes) {
90 if ((AccessTokenID)stateValue.GetInt(TokenFiledConst::FIELD_TOKEN_ID) == tokenId) {
91 PermissionStateFull state;
92 int ret = DataTranslator::TranslationIntoPermissionStateFull(stateValue, state);
93 if (ret == RET_SUCCESS) {
94 MergePermissionStateFull(policySet->permStateList_, state);
95 } else {
96 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x permState is wrong.", tokenId);
97 }
98 }
99 }
100 return policySet;
101 }
102
MergePermissionStateFull(std::vector<PermissionStateFull> & permStateList,const PermissionStateFull & state)103 void PermissionPolicySet::MergePermissionStateFull(std::vector<PermissionStateFull>& permStateList,
104 const PermissionStateFull& state)
105 {
106 for (auto iter = permStateList.begin(); iter != permStateList.end(); iter++) {
107 if (state.permissionName == iter->permissionName) {
108 iter->resDeviceID.emplace_back(state.resDeviceID[0]);
109 iter->grantStatus.emplace_back(state.grantStatus[0]);
110 iter->grantFlags.emplace_back(state.grantFlags[0]);
111 return;
112 }
113 }
114 permStateList.emplace_back(state);
115 }
116
StorePermissionState(std::vector<GenericValues> & valueList) const117 void PermissionPolicySet::StorePermissionState(std::vector<GenericValues>& valueList) const
118 {
119 for (const auto& permissionState : permStateList_) {
120 if (permissionState.isGeneral) {
121 GenericValues genericValues;
122 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(tokenId_));
123 DataTranslator::TranslationIntoGenericValues(permissionState, 0, genericValues);
124 valueList.emplace_back(genericValues);
125 continue;
126 }
127
128 unsigned int stateSize = permissionState.resDeviceID.size();
129 for (unsigned int i = 0; i < stateSize; i++) {
130 GenericValues genericValues;
131 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(tokenId_));
132 DataTranslator::TranslationIntoGenericValues(permissionState, i, genericValues);
133 valueList.emplace_back(genericValues);
134 }
135 }
136 }
137
StorePermissionPolicySet(std::vector<GenericValues> & permStateValueList)138 void PermissionPolicySet::StorePermissionPolicySet(std::vector<GenericValues>& permStateValueList)
139 {
140 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
141 StorePermissionState(permStateValueList);
142 }
143
VerifyPermissStatus(const std::string & permissionName)144 int PermissionPolicySet::VerifyPermissStatus(const std::string& permissionName)
145 {
146 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
147 for (const auto& perm : permStateList_) {
148 if (perm.permissionName == permissionName) {
149 if (perm.isGeneral) {
150 return perm.grantStatus[0];
151 } else {
152 return PERMISSION_DENIED;
153 }
154 }
155 }
156 return PERMISSION_DENIED;
157 }
158
GetDefPermissions(std::vector<PermissionDef> & permList)159 void PermissionPolicySet::GetDefPermissions(std::vector<PermissionDef>& permList)
160 {
161 PermissionDefinitionCache::GetInstance().GetDefPermissionsByTokenId(permList, tokenId_);
162 }
163
GetPermissionStateFulls(std::vector<PermissionStateFull> & permList)164 void PermissionPolicySet::GetPermissionStateFulls(std::vector<PermissionStateFull>& permList)
165 {
166 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
167 permList.assign(permStateList_.begin(), permStateList_.end());
168 }
169
QueryPermissionFlag(const std::string & permissionName,int & flag)170 int PermissionPolicySet::QueryPermissionFlag(const std::string& permissionName, int& flag)
171 {
172 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
173 for (const auto& perm : permStateList_) {
174 if (perm.permissionName == permissionName) {
175 if (perm.isGeneral) {
176 uint32_t oldFlag = static_cast<uint32_t>(perm.grantFlags[0]);
177 uint32_t unmaskedFlag = (oldFlag) & (~PERMISSION_GRANTED_BY_POLICY);
178 flag = static_cast<int32_t>(unmaskedFlag);
179 return RET_SUCCESS;
180 } else {
181 return AccessTokenError::ERR_PARAM_INVALID;
182 }
183 }
184 }
185 return AccessTokenError::ERR_PARAM_INVALID;
186 }
187
UpdatePermissionStatus(const std::string & permissionName,bool isGranted,uint32_t flag,bool & isUpdated)188 int32_t PermissionPolicySet::UpdatePermissionStatus(
189 const std::string& permissionName, bool isGranted, uint32_t flag, bool& isUpdated)
190 {
191 ACCESSTOKEN_LOG_DEBUG(LABEL, "permissionName %{public}s.", permissionName.c_str());
192
193 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
194 auto iter = std::find_if(permStateList_.begin(), permStateList_.end(),
195 [permissionName](const PermissionStateFull& permState) {
196 return permissionName == permState.permissionName;
197 });
198 if (iter != permStateList_.end()) {
199 if (iter->isGeneral) {
200 int32_t oldStatus = iter->grantStatus[0];
201 iter->grantStatus[0] = isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED;
202 uint32_t currFlag = static_cast<uint32_t>(iter->grantFlags[0]);
203 uint32_t newFlag = flag | (currFlag & PERMISSION_GRANTED_BY_POLICY);
204 iter->grantFlags[0] = static_cast<int32_t>(newFlag);
205 isUpdated = (oldStatus == iter->grantStatus[0]) ? false : true;
206 } else {
207 ACCESSTOKEN_LOG_WARN(LABEL, "perm isGeneral is false.");
208 }
209 } else {
210 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
211 return AccessTokenError::ERR_PARAM_INVALID;
212 }
213
214 return RET_SUCCESS;
215 }
216
ResetUserGrantPermissionStatus(void)217 void PermissionPolicySet::ResetUserGrantPermissionStatus(void)
218 {
219 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
220 for (auto& perm : permStateList_) {
221 if (perm.isGeneral) {
222 uint32_t oldFlag = static_cast<uint32_t>(perm.grantFlags[0]);
223 if ((oldFlag & PERMISSION_SYSTEM_FIXED) != 0) {
224 continue;
225 }
226 if ((oldFlag & PERMISSION_GRANTED_BY_POLICY) != 0) {
227 perm.grantStatus[0] = PERMISSION_GRANTED;
228 perm.grantFlags[0] = PERMISSION_GRANTED_BY_POLICY;
229 continue;
230 }
231 perm.grantStatus[0] = PERMISSION_DENIED;
232 perm.grantFlags[0] = PERMISSION_DEFAULT_FLAG;
233 } else {
234 continue;
235 }
236 }
237 }
238
GetPermissionStateList(std::vector<PermissionStateFull> & stateList)239 void PermissionPolicySet::GetPermissionStateList(std::vector<PermissionStateFull>& stateList)
240 {
241 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
242 for (const auto& state : permStateList_) {
243 stateList.emplace_back(state);
244 }
245 }
246
PermDefToString(const PermissionDef & def,std::string & info) const247 void PermissionPolicySet::PermDefToString(const PermissionDef& def, std::string& info) const
248 {
249 info.append(R"( {)");
250 info.append("\n");
251 info.append(R"( "permissionName": ")" + def.permissionName + R"(")" + ",\n");
252 info.append(R"( "bundleName": ")" + def.bundleName + R"(")" + ",\n");
253 info.append(R"( "grantMode": )" + std::to_string(def.grantMode) + ",\n");
254 info.append(R"( "availableLevel": )" + std::to_string(def.availableLevel) + ",\n");
255 info.append(R"( "provisionEnable": )" + std::to_string(def.provisionEnable) + ",\n");
256 info.append(R"( "distributedSceneEnable": )" + std::to_string(def.distributedSceneEnable) + ",\n");
257 info.append(R"( "label": ")" + def.label + R"(")" + ",\n");
258 info.append(R"( "labelId": )" + std::to_string(def.labelId) + ",\n");
259 info.append(R"( "description": ")" + def.description + R"(")" + ",\n");
260 info.append(R"( "descriptionId": )" + std::to_string(def.descriptionId) + ",\n");
261 info.append(R"( })");
262 }
263
PermStateFullToString(const PermissionStateFull & state,std::string & info) const264 void PermissionPolicySet::PermStateFullToString(const PermissionStateFull& state, std::string& info) const
265 {
266 info.append(R"( {)");
267 info.append("\n");
268 info.append(R"( "permissionName": ")" + state.permissionName + R"(")" + ",\n");
269 info.append(R"( "isGeneral": )" + std::to_string(state.isGeneral) + ",\n");
270 info.append(R"( "resDeviceIDList": [ )");
271 for (auto iter = state.resDeviceID.begin(); iter != state.resDeviceID.end(); iter++) {
272 info.append("\n");
273 info.append(R"( { "resDeviceID": ")" + *iter + R"(")" + " }");
274 if (iter != (state.resDeviceID.end() - 1)) {
275 info.append(",");
276 }
277 }
278 info.append("\n ],\n");
279
280 info.append(R"( "grantStatusList": [)");
281 for (auto iter = state.grantStatus.begin(); iter != state.grantStatus.end(); iter++) {
282 info.append("\n");
283 info.append(R"( { "grantStatus": )" + std::to_string(*iter) + " }");
284 if (iter != (state.grantStatus.end() - 1)) {
285 info.append(",");
286 }
287 }
288 info.append("\n ],\n");
289
290 info.append(R"( "grantFlagsList": [)");
291 for (auto iter = state.grantFlags.begin(); iter != state.grantFlags.end(); iter++) {
292 info.append("\n");
293 info.append(R"( { "grantFlag": )" + std::to_string(*iter) + " }");
294 if (iter != (state.grantFlags.end() - 1)) {
295 info.append(",");
296 }
297 }
298 info.append("\n ],\n");
299
300 info.append(R"( })");
301 }
302
ToString(std::string & info)303 void PermissionPolicySet::ToString(std::string& info)
304 {
305 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
306 info.append(R"( "permDefList": [)");
307 info.append("\n");
308 std::vector<PermissionDef> permList;
309 PermissionDefinitionCache::GetInstance().GetDefPermissionsByTokenId(permList, tokenId_);
310 for (auto iter = permList.begin(); iter != permList.end(); iter++) {
311 PermDefToString(*iter, info);
312 if (iter != (permList.end() - 1)) {
313 info.append(",\n");
314 }
315 }
316 info.append("\n ],\n");
317
318 info.append(R"( "permStateList": [)");
319 info.append("\n");
320 for (auto iter = permStateList_.begin(); iter != permStateList_.end(); iter++) {
321 PermStateFullToString(*iter, info);
322 if (iter != (permStateList_.end() - 1)) {
323 info.append(",\n");
324 }
325 }
326 info.append("\n ]\n");
327 }
328
IsPermissionReqValid(int32_t tokenApl,const std::string & permissionName,const std::vector<std::string> & nativeAcls)329 bool PermissionPolicySet::IsPermissionReqValid(int32_t tokenApl, const std::string& permissionName,
330 const std::vector<std::string>& nativeAcls)
331 {
332 PermissionDef permissionDef;
333 int ret = PermissionDefinitionCache::GetInstance().FindByPermissionName(
334 permissionName, permissionDef);
335 if (ret != RET_SUCCESS) {
336 return false;
337 }
338 if (tokenApl >= permissionDef.availableLevel) {
339 return true;
340 }
341
342 auto iter = std::find(nativeAcls.begin(), nativeAcls.end(), permissionName);
343 if (iter != nativeAcls.end()) {
344 return true;
345 }
346 return false;
347 }
348
PermStateToString(int32_t tokenApl,const std::vector<std::string> & nativeAcls,std::string & info)349 void PermissionPolicySet::PermStateToString(int32_t tokenApl,
350 const std::vector<std::string>& nativeAcls, std::string& info)
351 {
352 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permPolicySetLock_);
353
354 std::vector<std::string> invalidPermList = {};
355 info.append(R"( "permStateList": [)");
356 info.append("\n");
357 for (auto iter = permStateList_.begin(); iter != permStateList_.end(); iter++) {
358 if (!IsPermissionReqValid(tokenApl, iter->permissionName, nativeAcls)) {
359 invalidPermList.emplace_back(iter->permissionName);
360 continue;
361 }
362 PermStateFullToString(*iter, info);
363 if (iter != (permStateList_.end() - 1)) {
364 info.append(",\n");
365 }
366 }
367 info.append("\n ]\n");
368
369 if (invalidPermList.empty()) {
370 return;
371 }
372
373 info.append(R"( "invalidPermList": [)");
374 info.append("\n");
375 for (auto iter = invalidPermList.begin(); iter != invalidPermList.end(); iter++) {
376 info.append(R"( "permissionName": ")" + *iter + R"(")" + ",\n");
377 }
378 info.append("\n ]\n");
379 }
380 } // namespace AccessToken
381 } // namespace Security
382 } // namespace OHOS
383