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 "system_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 "data_validator.h"
27 #include "json_parser.h"
28 #include "permission_def.h"
29 #include "permission_definition_cache.h"
30 #include "securec.h"
31
32 namespace OHOS {
33 namespace Security {
34 namespace AccessToken {
35 namespace {
36 static const int32_t EXTENSION_PERMISSION_ID = 0;
37 static const std::string PERMISSION_NAME = "name";
38 static const std::string PERMISSION_GRANT_MODE = "grantMode";
39 static const std::string PERMISSION_AVAILABLE_LEVEL = "availableLevel";
40 static const std::string PERMISSION_PROVISION_ENABLE = "provisionEnable";
41 static const std::string PERMISSION_DISTRIBUTED_SCENE_ENABLE = "distributedSceneEnable";
42 static const std::string PERMISSION_LABEL = "label";
43 static const std::string PERMISSION_DESCRIPTION = "description";
44 static const std::string AVAILABLE_LEVEL_NORMAL = "normal";
45 static const std::string AVAILABLE_LEVEL_SYSTEM_BASIC = "system_basic";
46 static const std::string AVAILABLE_LEVEL_SYSTEM_CORE = "system_core";
47 static const std::string PERMISSION_GRANT_MODE_SYSTEM_GRANT = "system_grant";
48 static const std::string PERMISSION_GRANT_MODE_USER_GRANT = "user_grant";
49 static const std::string DEFINE_PERMISSION = "definePermissions";
50 static const std::string DEFINE_PERMISSION_FILE = "/system/etc/access_token/permission_definitions.json";
51 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE,
52 SECURITY_DOMAIN_ACCESSTOKEN, "SystemPermissionDefinitionParser"};
53 }
54
GetPermissionApl(const std::string & apl,AccessToken::ATokenAplEnum & aplNum)55 static bool GetPermissionApl(const std::string &apl, AccessToken::ATokenAplEnum& aplNum)
56 {
57 if (apl == AVAILABLE_LEVEL_SYSTEM_CORE) {
58 aplNum = AccessToken::ATokenAplEnum::APL_SYSTEM_CORE;
59 return true;
60 }
61 if (apl == AVAILABLE_LEVEL_SYSTEM_BASIC) {
62 aplNum = AccessToken::ATokenAplEnum::APL_SYSTEM_BASIC;
63 return true;
64 }
65 if (apl == AVAILABLE_LEVEL_NORMAL) {
66 aplNum = AccessToken::ATokenAplEnum::APL_NORMAL;
67 return true;
68 }
69 return false;
70 }
71
GetPermissionGrantMode(const std::string & mode)72 static int32_t GetPermissionGrantMode(const std::string &mode)
73 {
74 if (mode == PERMISSION_GRANT_MODE_SYSTEM_GRANT) {
75 return AccessToken::GrantMode::SYSTEM_GRANT;
76 }
77 return AccessToken::GrantMode::USER_GRANT;
78 }
79
from_json(const nlohmann::json & j,PermissionDefParseRet & result)80 void from_json(const nlohmann::json& j, PermissionDefParseRet& result)
81 {
82 result.isSuccessful = false;
83 PermissionDef permDef;
84 if (!JsonParser::GetStringFromJson(j, PERMISSION_NAME, permDef.permissionName) ||
85 !DataValidator::IsProcessNameValid(permDef.permissionName)) {
86 return;
87 }
88 std::string grantModeStr;
89 if (!JsonParser::GetStringFromJson(j, PERMISSION_GRANT_MODE, grantModeStr)) {
90 return;
91 }
92 permDef.grantMode = GetPermissionGrantMode(grantModeStr);
93
94 std::string availableLevelStr;
95 if (!JsonParser::GetStringFromJson(j, PERMISSION_AVAILABLE_LEVEL, availableLevelStr)) {
96 return;
97 }
98 if (!GetPermissionApl(availableLevelStr, permDef.availableLevel)) {
99 return;
100 }
101
102 if (!JsonParser::GetBoolFromJson(j, PERMISSION_PROVISION_ENABLE, permDef.provisionEnable)) {
103 return;
104 }
105 if (!JsonParser::GetBoolFromJson(j, PERMISSION_DISTRIBUTED_SCENE_ENABLE, permDef.distributedSceneEnable)) {
106 return;
107 }
108 permDef.bundleName = "system_ability";
109 if (permDef.grantMode == AccessToken::GrantMode::SYSTEM_GRANT) {
110 result.permDef = permDef;
111 result.isSuccessful = true;
112 return;
113 }
114 if (!JsonParser::GetStringFromJson(j, PERMISSION_LABEL, permDef.label)) {
115 return;
116 }
117 if (!JsonParser::GetStringFromJson(j, PERMISSION_LABEL, permDef.description)) {
118 return;
119 }
120 result.permDef = permDef;
121 result.isSuccessful = true;
122 return;
123 }
124
CheckPermissionDefRules(const PermissionDef & permDef)125 static bool CheckPermissionDefRules(const PermissionDef& permDef)
126 {
127 // Extension permission support system_grant permission only.
128 if (permDef.grantMode != SYSTEM_GRANT) {
129 return false;
130 }
131 return true;
132 }
133
ParserPermsRawData(const std::string & permsRawData,std::vector<PermissionDef> & permDefList)134 int32_t SystemPermissionDefinitionParser::ParserPermsRawData(const std::string& permsRawData,
135 std::vector<PermissionDef>& permDefList)
136 {
137 nlohmann::json jsonRes = nlohmann::json::parse(permsRawData, nullptr, false);
138 if (jsonRes.is_discarded()) {
139 ACCESSTOKEN_LOG_ERROR(LABEL, "jsonRes is invalid.");
140 return ERR_PARAM_INVALID;
141 }
142
143 if ((jsonRes.find(DEFINE_PERMISSION) == jsonRes.end()) || (!jsonRes.at(DEFINE_PERMISSION).is_array())) {
144 ACCESSTOKEN_LOG_ERROR(LABEL, "jsonRes is not array.");
145 return ERR_PARAM_INVALID;
146 }
147 nlohmann::json JsonData = jsonRes.at(DEFINE_PERMISSION).get<nlohmann::json>();
148 for (auto it = JsonData.begin(); it != JsonData.end(); it++) {
149 auto result = it->get<PermissionDefParseRet>();
150 if (result.isSuccessful) {
151 ACCESSTOKEN_LOG_DEBUG(LABEL, "permDef.grantMode %{public}s.", result.permDef.permissionName.c_str());
152 if (!CheckPermissionDefRules(result.permDef)) {
153 continue;
154 }
155 permDefList.emplace_back(result.permDef);
156 }
157 }
158 return RET_SUCCESS;
159 }
160
Init()161 int32_t SystemPermissionDefinitionParser::Init()
162 {
163 ACCESSTOKEN_LOG_ERROR(LABEL, "system permission set begin.");
164 if (ready_) {
165 ACCESSTOKEN_LOG_ERROR(LABEL, " system permission has been set.");
166 return RET_SUCCESS;
167 }
168
169 std::string permsRawData;
170 int32_t ret = JsonParser::ReadCfgFile(DEFINE_PERMISSION_FILE, permsRawData);
171 if (ret != RET_SUCCESS) {
172 ACCESSTOKEN_LOG_ERROR(LABEL, "readCfgFile failed.");
173 return ERR_FILE_OPERATE_FAILED;
174 }
175 std::vector<PermissionDef> permDefList;
176 ret = ParserPermsRawData(permsRawData, permDefList);
177 if (ret != RET_SUCCESS) {
178 ACCESSTOKEN_LOG_ERROR(LABEL, "ParserPermsRawData failed.");
179 return ret;
180 }
181 for (const auto& perm : permDefList) {
182 PermissionDefinitionCache::GetInstance().Insert(perm, EXTENSION_PERMISSION_ID);
183 }
184
185 ready_ = true;
186 ACCESSTOKEN_LOG_INFO(LABEL, "init ok.");
187 return RET_SUCCESS;
188 }
189
GetInstance()190 SystemPermissionDefinitionParser& SystemPermissionDefinitionParser::GetInstance()
191 {
192 static SystemPermissionDefinitionParser instance;
193 return instance;
194 }
195 } // namespace AccessToken
196 } // namespace Security
197 } // namespace OHOS
198