• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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