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 #include "permission_validator.h"
16
17 #include <set>
18
19 #include "access_token.h"
20 #include "accesstoken_log.h"
21 #include "data_validator.h"
22 #include "permission_definition_cache.h"
23
24 namespace OHOS {
25 namespace Security {
26 namespace AccessToken {
27 namespace {
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionValidator"};
29 }
30
IsGrantModeValid(int grantMode)31 bool PermissionValidator::IsGrantModeValid(int grantMode)
32 {
33 return grantMode == GrantMode::SYSTEM_GRANT || grantMode == GrantMode::USER_GRANT;
34 }
35
IsGrantStatusValid(int grantStatus)36 bool PermissionValidator::IsGrantStatusValid(int grantStatus)
37 {
38 return grantStatus == PermissionState::PERMISSION_GRANTED || grantStatus == PermissionState::PERMISSION_DENIED;
39 }
40
IsPermissionFlagValid(uint32_t flag)41 bool PermissionValidator::IsPermissionFlagValid(uint32_t flag)
42 {
43 return DataValidator::IsPermissionFlagValid(flag);
44 }
45
IsPermissionNameValid(const std::string & permissionName)46 bool PermissionValidator::IsPermissionNameValid(const std::string& permissionName)
47 {
48 return DataValidator::IsPermissionNameValid(permissionName);
49 }
50
IsPermissionDefValid(const PermissionDef & permDef)51 bool PermissionValidator::IsPermissionDefValid(const PermissionDef& permDef)
52 {
53 if (!DataValidator::IsLabelValid(permDef.label)) {
54 ACCESSTOKEN_LOG_ERROR(LABEL, "label invalid.");
55 return false;
56 }
57 if (!DataValidator::IsDescValid(permDef.description)) {
58 ACCESSTOKEN_LOG_ERROR(LABEL, "desc invalid.");
59 return false;
60 }
61 if (!DataValidator::IsBundleNameValid(permDef.bundleName)) {
62 ACCESSTOKEN_LOG_ERROR(LABEL, "bundleName invalid.");
63 return false;
64 }
65 if (!DataValidator::IsPermissionNameValid(permDef.permissionName)) {
66 ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName invalid.");
67 return false;
68 }
69 if (!IsGrantModeValid(permDef.grantMode)) {
70 ACCESSTOKEN_LOG_ERROR(LABEL, "grantMode invalid.");
71 return false;
72 }
73 if (!DataValidator::IsAvailableTypeValid(permDef.availableType)) {
74 ACCESSTOKEN_LOG_ERROR(LABEL, "availableType invalid.");
75 return false;
76 }
77 if (!DataValidator::IsAplNumValid(permDef.availableLevel)) {
78 ACCESSTOKEN_LOG_ERROR(LABEL, "availableLevel invalid.");
79 return false;
80 }
81 return true;
82 }
83
IsPermissionAvailable(ATokenTypeEnum tokenType,const std::string & permissionName)84 bool PermissionValidator::IsPermissionAvailable(ATokenTypeEnum tokenType, const std::string& permissionName)
85 {
86 ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenType is %{public}d.", tokenType);
87 if (tokenType == TOKEN_HAP) {
88 if (!PermissionDefinitionCache::GetInstance().HasHapPermissionDefinitionForHap(permissionName)) {
89 ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s is not defined for hap.", permissionName.c_str());
90 return false;
91 }
92 }
93 // permission request for TOKEN_NATIVE process is going to be check when the permission request way is normalized.
94 return true;
95 }
96
IsPermissionStateValid(const PermissionStateFull & permState)97 bool PermissionValidator::IsPermissionStateValid(const PermissionStateFull& permState)
98 {
99 if (!DataValidator::IsPermissionNameValid(permState.permissionName)) {
100 return false;
101 }
102 size_t resDevIdSize = permState.resDeviceID.size();
103 size_t grantStatSize = permState.grantStatus.size();
104 size_t grantFlagSize = permState.grantFlags.size();
105 if ((grantStatSize != resDevIdSize) || (grantFlagSize != resDevIdSize)) {
106 ACCESSTOKEN_LOG_ERROR(LABEL,
107 "list size is invalid, grantStatSize %{public}zu, grantFlagSize %{public}zu, resDevIdSize %{public}zu.",
108 grantStatSize, grantFlagSize, resDevIdSize);
109 return false;
110 }
111 for (uint32_t i = 0; i < resDevIdSize; i++) {
112 if (!IsGrantStatusValid(permState.grantStatus[i]) ||
113 !IsPermissionFlagValid(permState.grantFlags[i])) {
114 ACCESSTOKEN_LOG_ERROR(LABEL, "grantStatus or grantFlags is invalid");
115 return false;
116 }
117 }
118 return true;
119 }
120
FilterInvalidPermissionDef(const std::vector<PermissionDef> & permList,std::vector<PermissionDef> & result)121 void PermissionValidator::FilterInvalidPermissionDef(
122 const std::vector<PermissionDef>& permList, std::vector<PermissionDef>& result)
123 {
124 std::set<std::string> permDefSet;
125 for (auto it = permList.begin(); it != permList.end(); ++it) {
126 std::string permName = it->permissionName;
127 if (!IsPermissionDefValid(*it) || permDefSet.count(permName) != 0) {
128 continue;
129 }
130 permDefSet.insert(permName);
131 result.emplace_back(*it);
132 }
133 }
134
DeduplicateResDevID(const PermissionStateFull & permState,PermissionStateFull & result)135 void PermissionValidator::DeduplicateResDevID(const PermissionStateFull& permState, PermissionStateFull& result)
136 {
137 std::set<std::string> resDevId;
138 auto stateIter = permState.grantStatus.begin();
139 auto flagIter = permState.grantFlags.begin();
140 for (auto it = permState.resDeviceID.begin(); it != permState.resDeviceID.end(); ++it, ++stateIter, ++flagIter) {
141 if (resDevId.count(*it) != 0) {
142 continue;
143 }
144 resDevId.insert(*it);
145 result.resDeviceID.emplace_back(*it);
146 result.grantStatus.emplace_back(*stateIter);
147 result.grantFlags.emplace_back(*flagIter);
148 }
149 result.permissionName = permState.permissionName;
150 result.isGeneral = permState.isGeneral;
151 }
152
FilterInvalidPermissionState(ATokenTypeEnum tokenType,bool doPermAvailableCheck,const std::vector<PermissionStateFull> & permList,std::vector<PermissionStateFull> & result)153 void PermissionValidator::FilterInvalidPermissionState(ATokenTypeEnum tokenType, bool doPermAvailableCheck,
154 const std::vector<PermissionStateFull>& permList, std::vector<PermissionStateFull>& result)
155 {
156 std::set<std::string> permStateSet;
157 for (auto it = permList.begin(); it != permList.end(); ++it) {
158 std::string permName = it->permissionName;
159 PermissionStateFull res;
160 if (!IsPermissionStateValid(*it) || permStateSet.count(permName) != 0) {
161 continue;
162 }
163 if (doPermAvailableCheck && !IsPermissionAvailable(tokenType, permName)) {
164 continue;
165 }
166 DeduplicateResDevID(*it, res);
167 permStateSet.insert(permName);
168 result.emplace_back(res);
169 }
170 }
171 } // namespace AccessToken
172 } // namespace Security
173 } // namespace OHOS
174