1 /*
2 * Copyright (c) 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 #include "permission_definition_parser.h"
16
17 #include <fcntl.h>
18 #include <memory>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include "accesstoken_log.h"
24 #include "access_token.h"
25 #include "access_token_error.h"
26 #include "accesstoken_info_manager.h"
27 #include "data_validator.h"
28 #include "hisysevent_adapter.h"
29 #include "json_parser.h"
30 #include "permission_def.h"
31 #include "permission_definition_cache.h"
32 #include "securec.h"
33
34 namespace OHOS {
35 namespace Security {
36 namespace AccessToken {
37 namespace {
38 std::recursive_mutex g_instanceMutex;
39 static const int32_t EXTENSION_PERMISSION_ID = 0;
40 static const std::string PERMISSION_NAME = "name";
41 static const std::string PERMISSION_GRANT_MODE = "grantMode";
42 static const std::string PERMISSION_AVAILABLE_LEVEL = "availableLevel";
43 static const std::string PERMISSION_AVAILABLE_TYPE = "availableType";
44 static const std::string PERMISSION_PROVISION_ENABLE = "provisionEnable";
45 static const std::string PERMISSION_DISTRIBUTED_SCENE_ENABLE = "distributedSceneEnable";
46 static const std::string PERMISSION_LABEL = "label";
47 static const std::string PERMISSION_DESCRIPTION = "description";
48 static const std::string AVAILABLE_TYPE_NORMAL_HAP = "NORMAL";
49 static const std::string AVAILABLE_TYPE_SYSTEM_HAP = "SYSTEM";
50 static const std::string AVAILABLE_TYPE_MDM = "MDM";
51 static const std::string AVAILABLE_TYPE_SYSTEM_AND_MDM = "SYSTEM_AND_MDM";
52 static const std::string AVAILABLE_TYPE_SERVICE = "SERVICE";
53 static const std::string AVAILABLE_TYPE_ENTERPRISE_NORMAL = "ENTERPRISE_NORMAL";
54 static const std::string AVAILABLE_LEVEL_NORMAL = "normal";
55 static const std::string AVAILABLE_LEVEL_SYSTEM_BASIC = "system_basic";
56 static const std::string AVAILABLE_LEVEL_SYSTEM_CORE = "system_core";
57 static const std::string PERMISSION_GRANT_MODE_SYSTEM_GRANT = "system_grant";
58 static const std::string PERMISSION_GRANT_MODE_USER_GRANT = "user_grant";
59 static const std::string SYSTEM_GRANT_DEFINE_PERMISSION = "systemGrantPermissions";
60 static const std::string USER_GRANT_DEFINE_PERMISSION = "userGrantPermissions";
61 static const std::string DEFINE_PERMISSION_FILE = "/system/etc/access_token/permission_definitions.json";
62 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE,
63 SECURITY_DOMAIN_ACCESSTOKEN, "PermissionDefinitionParser"};
64 }
65
GetPermissionApl(const std::string & apl,AccessToken::ATokenAplEnum & aplNum)66 static bool GetPermissionApl(const std::string &apl, AccessToken::ATokenAplEnum& aplNum)
67 {
68 if (apl == AVAILABLE_LEVEL_SYSTEM_CORE) {
69 aplNum = AccessToken::ATokenAplEnum::APL_SYSTEM_CORE;
70 return true;
71 }
72 if (apl == AVAILABLE_LEVEL_SYSTEM_BASIC) {
73 aplNum = AccessToken::ATokenAplEnum::APL_SYSTEM_BASIC;
74 return true;
75 }
76 if (apl == AVAILABLE_LEVEL_NORMAL) {
77 aplNum = AccessToken::ATokenAplEnum::APL_NORMAL;
78 return true;
79 }
80 ACCESSTOKEN_LOG_ERROR(LABEL, "Apl: %{public}s is invalid.", apl.c_str());
81 return false;
82 }
83
GetPermissionAvailableType(const std::string & availableType,AccessToken::ATokenAvailableTypeEnum & typeNum)84 static bool GetPermissionAvailableType(const std::string &availableType, AccessToken::ATokenAvailableTypeEnum& typeNum)
85 {
86 if (availableType == AVAILABLE_TYPE_NORMAL_HAP) {
87 typeNum = AccessToken::ATokenAvailableTypeEnum::NORMAL;
88 return true;
89 }
90 if (availableType == AVAILABLE_TYPE_SYSTEM_HAP) {
91 typeNum = AccessToken::ATokenAvailableTypeEnum::SYSTEM;
92 return true;
93 }
94 if (availableType == AVAILABLE_TYPE_MDM) {
95 typeNum = AccessToken::ATokenAvailableTypeEnum::MDM;
96 return true;
97 }
98 if (availableType == AVAILABLE_TYPE_SYSTEM_AND_MDM) {
99 typeNum = AccessToken::ATokenAvailableTypeEnum::SYSTEM_AND_MDM;
100 return true;
101 }
102 if (availableType == AVAILABLE_TYPE_SERVICE) {
103 typeNum = AccessToken::ATokenAvailableTypeEnum::SERVICE;
104 return true;
105 }
106 if (availableType == AVAILABLE_TYPE_ENTERPRISE_NORMAL) {
107 typeNum = AccessToken::ATokenAvailableTypeEnum::ENTERPRISE_NORMAL;
108 return true;
109 }
110 typeNum = AccessToken::ATokenAvailableTypeEnum::INVALID;
111 ACCESSTOKEN_LOG_ERROR(LABEL, "AvailableType: %{public}s is invalid.", availableType.c_str());
112 return false;
113 }
114
GetPermissionGrantMode(const std::string & mode)115 static int32_t GetPermissionGrantMode(const std::string &mode)
116 {
117 if (mode == PERMISSION_GRANT_MODE_SYSTEM_GRANT) {
118 return AccessToken::GrantMode::SYSTEM_GRANT;
119 }
120 return AccessToken::GrantMode::USER_GRANT;
121 }
122
from_json(const nlohmann::json & j,PermissionDefParseRet & result)123 void from_json(const nlohmann::json& j, PermissionDefParseRet& result)
124 {
125 result.isSuccessful = false;
126 PermissionDef permDef;
127 if (!JsonParser::GetStringFromJson(j, PERMISSION_NAME, permDef.permissionName) ||
128 !DataValidator::IsProcessNameValid(permDef.permissionName)) {
129 return;
130 }
131 std::string grantModeStr;
132 if (!JsonParser::GetStringFromJson(j, PERMISSION_GRANT_MODE, grantModeStr)) {
133 return;
134 }
135 permDef.grantMode = GetPermissionGrantMode(grantModeStr);
136
137 std::string availableLevelStr;
138 if (!JsonParser::GetStringFromJson(j, PERMISSION_AVAILABLE_LEVEL, availableLevelStr)) {
139 return;
140 }
141 if (!GetPermissionApl(availableLevelStr, permDef.availableLevel)) {
142 return;
143 }
144
145 std::string availableTypeStr;
146 if (!JsonParser::GetStringFromJson(j, PERMISSION_AVAILABLE_TYPE, availableTypeStr)) {
147 return;
148 }
149 if (!GetPermissionAvailableType(availableTypeStr, permDef.availableType)) {
150 return;
151 }
152
153 if (!JsonParser::GetBoolFromJson(j, PERMISSION_PROVISION_ENABLE, permDef.provisionEnable)) {
154 return;
155 }
156 if (!JsonParser::GetBoolFromJson(j, PERMISSION_DISTRIBUTED_SCENE_ENABLE, permDef.distributedSceneEnable)) {
157 return;
158 }
159 permDef.bundleName = "system_ability";
160 if (permDef.grantMode == AccessToken::GrantMode::SYSTEM_GRANT) {
161 result.permDef = permDef;
162 result.isSuccessful = true;
163 return;
164 }
165 if (!JsonParser::GetStringFromJson(j, PERMISSION_LABEL, permDef.label)) {
166 return;
167 }
168 if (!JsonParser::GetStringFromJson(j, PERMISSION_DESCRIPTION, permDef.description)) {
169 return;
170 }
171 result.permDef = permDef;
172 result.isSuccessful = true;
173 return;
174 }
175
CheckPermissionDefRules(const PermissionDef & permDef)176 static bool CheckPermissionDefRules(const PermissionDef& permDef)
177 {
178 // Extension permission support permission for service only.
179 if (permDef.availableType != AccessToken::ATokenAvailableTypeEnum::SERVICE) {
180 ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s is for hap.", permDef.permissionName.c_str());
181 return false;
182 }
183 return true;
184 }
185
GetPermissionDefList(const nlohmann::json & json,const std::string & permsRawData,const std::string & type,std::vector<PermissionDef> & permDefList)186 int32_t PermissionDefinitionParser::GetPermissionDefList(const nlohmann::json& json, const std::string& permsRawData,
187 const std::string& type, std::vector<PermissionDef>& permDefList)
188 {
189 if ((json.find(type) == json.end()) || (!json.at(type).is_array())) {
190 ACCESSTOKEN_LOG_ERROR(LABEL, "Json is not array.");
191 return ERR_PARAM_INVALID;
192 }
193
194 nlohmann::json JsonData = json.at(type).get<nlohmann::json>();
195 for (auto it = JsonData.begin(); it != JsonData.end(); it++) {
196 auto result = it->get<PermissionDefParseRet>();
197 if (!result.isSuccessful) {
198 ACCESSTOKEN_LOG_ERROR(LABEL, "Get permission def failed.");
199 return ERR_PERM_REQUEST_CFG_FAILED;
200 }
201 if (!CheckPermissionDefRules(result.permDef)) {
202 continue;
203 }
204 ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s insert.", result.permDef.permissionName.c_str());
205 permDefList.emplace_back(result.permDef);
206 }
207 return RET_SUCCESS;
208 }
209
ParserPermsRawData(const std::string & permsRawData,std::vector<PermissionDef> & permDefList)210 int32_t PermissionDefinitionParser::ParserPermsRawData(const std::string& permsRawData,
211 std::vector<PermissionDef>& permDefList)
212 {
213 nlohmann::json jsonRes = nlohmann::json::parse(permsRawData, nullptr, false);
214 if (jsonRes.is_discarded()) {
215 ACCESSTOKEN_LOG_ERROR(LABEL, "JsonRes is invalid.");
216 return ERR_PARAM_INVALID;
217 }
218
219 int32_t ret = GetPermissionDefList(jsonRes, permsRawData, SYSTEM_GRANT_DEFINE_PERMISSION, permDefList);
220 if (ret != RET_SUCCESS) {
221 ACCESSTOKEN_LOG_ERROR(LABEL, "Get system_grant permission def list failed.");
222 return ret;
223 }
224 ACCESSTOKEN_LOG_INFO(LABEL, "Get system_grant permission size=%{public}zu.", permDefList.size());
225 ret = GetPermissionDefList(jsonRes, permsRawData, USER_GRANT_DEFINE_PERMISSION, permDefList);
226 if (ret != RET_SUCCESS) {
227 ACCESSTOKEN_LOG_ERROR(LABEL, "Get user_grant permission def list failed.");
228 return ret;
229 }
230 ACCESSTOKEN_LOG_INFO(LABEL, "Get permission size=%{public}zu.", permDefList.size());
231 return RET_SUCCESS;
232 }
233
Init()234 int32_t PermissionDefinitionParser::Init()
235 {
236 ACCESSTOKEN_LOG_INFO(LABEL, "System permission set begin.");
237 if (ready_) {
238 ACCESSTOKEN_LOG_ERROR(LABEL, " system permission has been set.");
239 return RET_SUCCESS;
240 }
241
242 std::string permsRawData;
243 int32_t ret = JsonParser::ReadCfgFile(DEFINE_PERMISSION_FILE, permsRawData);
244 if (ret != RET_SUCCESS) {
245 ACCESSTOKEN_LOG_ERROR(LABEL, "ReadCfgFile failed.");
246 ReportSysEventServiceStartError(INIT_PERM_DEF_JSON_ERROR, "ReadCfgFile fail.", ret);
247 return ERR_FILE_OPERATE_FAILED;
248 }
249 std::vector<PermissionDef> permDefList;
250 ret = ParserPermsRawData(permsRawData, permDefList);
251 if (ret != RET_SUCCESS) {
252 ReportSysEventServiceStartError(INIT_PERM_DEF_JSON_ERROR, "ParserPermsRawData fail.", ret);
253 ACCESSTOKEN_LOG_ERROR(LABEL, "ParserPermsRawData failed.");
254 return ret;
255 }
256
257 for (const auto& perm : permDefList) {
258 PermissionDefinitionCache::GetInstance().Insert(perm, EXTENSION_PERMISSION_ID);
259 }
260 ready_ = true;
261 ACCESSTOKEN_LOG_INFO(LABEL, "Init ok.");
262 return RET_SUCCESS;
263 }
264
GetInstance()265 PermissionDefinitionParser& PermissionDefinitionParser::GetInstance()
266 {
267 static PermissionDefinitionParser* instance = nullptr;
268 if (instance == nullptr) {
269 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
270 if (instance == nullptr) {
271 instance = new PermissionDefinitionParser();
272 }
273 }
274 return *instance;
275 }
276 } // namespace AccessToken
277 } // namespace Security
278 } // namespace OHOS
279