1 /*
2 * Copyright (c) 2023-2025 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_manager.h"
17
18 #include <fstream>
19 #include <string>
20 #include <unordered_set>
21
22 #include "accesstoken_kit.h"
23 #include "file_ex.h"
24 #include "ipc_skeleton.h"
25 #include "securec.h"
26
27 #include "dp_radar_helper.h"
28 #include "distributed_device_profile_log.h"
29 #include "distributed_device_profile_constants.h"
30 #include "distributed_device_profile_errors.h"
31 #include "macro_utils.h"
32 #include "profile_utils.h"
33
34 namespace OHOS {
35 namespace DistributedDeviceProfile {
36 using namespace OHOS::Security::AccessToken;
37
38 namespace {
39 const std::string TAG = "PermissionManager";
40 constexpr uint32_t INVALID_TOKEN_ID = 0;
41 const std::string INTERFACES = "interfacesAuthority";
42 const std::string SERVICES = "servicesAuthority";
43 const std::string SERVICES_ALL = "all";
44 const std::string SERVICES_SPECIFIC = "specific";
45 const std::string SERVICES_PREFIX = "prefix";
46 const std::string PERMISSION_JSON_PATH = "/system/etc/deviceprofile/permission.json";
47 const std::string DP_SERVICE_ACCESS_PERMISSION = "ohos.permission.ACCESS_SERVICE_DP";
48 const std::string DP_SERVICE_SYNC_PERMISSION = "ohos.permission.SYNC_PROFILE_DP";
49 }
50
51 IMPLEMENT_SINGLE_INSTANCE(PermissionManager);
52
Init()53 int32_t PermissionManager::Init()
54 {
55 HILOGI("call!");
56 if (!LoadPermissionCfg(PERMISSION_JSON_PATH)) {
57 return false;
58 }
59 HILOGI("init succeeded");
60 return DP_SUCCESS;
61 }
62
UnInit()63 int32_t PermissionManager::UnInit()
64 {
65 HILOGI("UnInit");
66 std::lock_guard<std::mutex> lockGuard(permissionMutex_);
67 permissionMap_.clear();
68 return DP_SUCCESS;
69 }
70
LoadPermissionCfg(const std::string & filePath)71 int32_t PermissionManager::LoadPermissionCfg(const std::string& filePath)
72 {
73 char path[PATH_MAX + 1] = {0x00};
74 if (filePath.length() == 0 || filePath.length() > PATH_MAX || realpath(filePath.c_str(), path) == nullptr) {
75 HILOGE("File canonicalization failed");
76 return DP_PARSE_PERMISSION_JSON_FAIL;
77 }
78 std::ifstream ifs(path);
79 if (!ifs.is_open()) {
80 HILOGE("load json file failed");
81 return DP_PARSE_PERMISSION_JSON_FAIL;
82 }
83 std::string fileContent(std::istreambuf_iterator<char>{ifs}, std::istreambuf_iterator<char>{});
84 ifs.close();
85
86 cJSON* permissionJson = cJSON_Parse(fileContent.c_str());
87 if (!cJSON_IsObject(permissionJson)) {
88 HILOGE("Permission json parse failed!");
89 cJSON_Delete(permissionJson);
90 return DP_PARSE_PERMISSION_JSON_FAIL;
91 }
92 int32_t parseResult = ParsePermissionJson(permissionJson);
93 HILOGI("permission json load result %{public}d!", parseResult);
94 cJSON_Delete(permissionJson);
95 return parseResult;
96 }
97
ParsePermissionJson(const cJSON * const permissionJson)98 int32_t PermissionManager::ParsePermissionJson(const cJSON* const permissionJson)
99 {
100 int size = cJSON_GetArraySize(permissionJson);
101 if (size == 0 || size > MAX_INTERFACE_SIZE) {
102 HILOGE("Permission json size is invalid!size: %{public}d!", size);
103 return DP_PARSE_PERMISSION_JSON_FAIL;
104 }
105 SetRdbPermissionMap(permissionJson);
106 SetKVPermissionMap(permissionJson);
107 char* jsonChars = cJSON_PrintUnformatted(permissionJson);
108 if (jsonChars == NULL) {
109 HILOGW("cJSON formatted to string failed!");
110 } else {
111 HILOGD("permission json %{public}s parse success!", jsonChars);
112 cJSON_free(jsonChars);
113 }
114 return DP_SUCCESS;
115 }
116
SetRdbPermissionMap(const cJSON * const permissionJson)117 void PermissionManager::SetRdbPermissionMap(const cJSON *const permissionJson)
118 {
119 int size = cJSON_GetArraySize(permissionJson);
120 if (size == 0 || size > MAX_INTERFACE_SIZE) {
121 HILOGE("Permission json size is invalid!size: %{public}d!", size);
122 return;
123 }
124 SetPermissionMap(permissionJson, PUT_SERVICE_INFO_PROFILE);
125 SetPermissionMap(permissionJson, DELETE_SERVICE_INFO_PROFILE);
126 SetPermissionMap(permissionJson, UPDATE_SERVICE_INFO_PROFILE);
127 SetPermissionMap(permissionJson, GET_SERVICE_INFO_PROFILE_BY_UNIQUE_KEY);
128 SetPermissionMap(permissionJson, GET_SERVICE_INFO_PROFILE_LIST_BY_TOKEN_ID);
129 SetPermissionMap(permissionJson, GET_ALL_SERVICE_INFO_PROFILE_LIST);
130 SetPermissionMap(permissionJson, GET_SERVICE_INFO_PROFILE_LIST_BY_BUNDLE_NAME);
131 SetPermissionMap(permissionJson, PUT_LOCAL_SERVICE_INFO);
132 SetPermissionMap(permissionJson, UPDATA_LOCAL_SERVICE_INFO);
133 SetPermissionMap(permissionJson, GET_LOCAL_SERVICE_INFO_BY_BINDLE_AND_PINTYPE);
134 SetPermissionMap(permissionJson, DELETE_LOCAL_SERVICE_INFO);
135 SetPermissionMap(permissionJson, PUT_ACCESS_CONTROL_PROFILE);
136 SetPermissionMap(permissionJson, UPDATE_ACCESS_CONTROL_PROFILE);
137 SetPermissionMap(permissionJson, GET_ACCESS_CONTROL_PROFILE);
138 SetPermissionMap(permissionJson, GET_ALL_ACCESS_CONTROL_PROFILE);
139 SetPermissionMap(permissionJson, DELETE_ACCESS_CONTROL_PROFILE);
140 SetPermissionMap(permissionJson, GET_TRUST_DEVICE_PROFILE);
141 SetPermissionMap(permissionJson, GET_ALL_TRUST_DEVICE_PROFILE);
142 SetPermissionMap(permissionJson, PUT_DEVICE_PROFILE_BATCH);
143 SetPermissionMap(permissionJson, DELETE_DEVICE_PROFILE_BATCH);
144 SetPermissionMap(permissionJson, GET_DEVICE_PROFILES);
145 SetPermissionMap(permissionJson, PUT_PRODUCT_INFO_BATCH);
146 SetPermissionMap(permissionJson, PUT_DEVICE_ICON_INFO_BATCH);
147 SetPermissionMap(permissionJson, GET_DEVICE_ICON_INFOS);
148 SetPermissionMap(permissionJson, PUT_SESSION_KEY);
149 SetPermissionMap(permissionJson, GET_SESSION_KEY);
150 SetPermissionMap(permissionJson, UPDATE_SESSION_KEY);
151 SetPermissionMap(permissionJson, DELETE_SESSION_KEY);
152 return;
153 }
154
SetKVPermissionMap(const cJSON * const permissionJson)155 void PermissionManager::SetKVPermissionMap(const cJSON *const permissionJson)
156 {
157 int size = cJSON_GetArraySize(permissionJson);
158 if (size == 0 || size > MAX_INTERFACE_SIZE) {
159 HILOGE("Permission json size is invalid!size: %{public}d!", size);
160 return;
161 }
162 SetPermissionMap(permissionJson, PUT_SERVICE_PROFILE);
163 SetPermissionMap(permissionJson, PUT_SERVICE_PROFILE_BATCH);
164 SetPermissionMap(permissionJson, PUT_CHARACTERISTIC_PROFILE);
165 SetPermissionMap(permissionJson, PUT_CHARACTERISTIC_PROFILE_BATCH);
166 SetPermissionMap(permissionJson, GET_DEVICE_PROFILE);
167 SetPermissionMap(permissionJson, GET_SERVICE_PROFILE);
168 SetPermissionMap(permissionJson, GET_CHARACTERISTIC_PROFILE);
169 SetPermissionMap(permissionJson, DELETE_SERVICE_PROFILE);
170 SetPermissionMap(permissionJson, DELETE_CHARACTERISTIC_PROFILE);
171 SetPermissionMap(permissionJson, SUBSCRIBE_DEVICE_PROFILE);
172 SetPermissionMap(permissionJson, UNSUBSCRIBE_DEVICE_PROFILE);
173 SetPermissionMap(permissionJson, SYNC_DEVICE_PROFILE);
174 SetPermissionMap(permissionJson, PUT_ALL_TRUSTED_DEVICES);
175 return;
176 }
177
CheckInterfacePermission(const std::string & interfaceName)178 bool PermissionManager::CheckInterfacePermission(const std::string& interfaceName)
179 {
180 std::string callProcName = GetCallerProcName();
181 std::unordered_set<std::string> permittedProcNames;
182 {
183 std::lock_guard<std::mutex> lockGuard(permissionMutex_);
184 permittedProcNames = permissionMap_[interfaceName];
185 }
186 bool checkResult = (permittedProcNames.count(callProcName) != 0 || permittedProcNames.count(ALL_PROC) != 0);
187 HILOGD("success interface %{public}s callProc %{public}s!", interfaceName.c_str(), callProcName.c_str());
188 return checkResult;
189 }
190
IsCallerTrust(const std::string & interfaceName)191 bool PermissionManager::IsCallerTrust(const std::string& interfaceName)
192 {
193 int32_t stageRes = static_cast<int32_t>(StageRes::STAGE_FAIL);
194 auto tokenID = IPCSkeleton::GetCallingTokenID();
195 if (tokenID == INVALID_TOKEN_ID) {
196 HILOGW("invalid token id");
197 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
198 return false;
199 }
200 ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID);
201 // currently only support native trusted caller
202 if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) {
203 HILOGE("TokenType is not native");
204 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
205 return false;
206 }
207 if (!CheckInterfacePermission(interfaceName)) {
208 HILOGE("This caller cannot call this interface, interfaceName: %{public}s", interfaceName.c_str());
209 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
210 return false;
211 }
212 stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
213 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
214 return true;
215 }
216
CheckCallerPermission()217 bool PermissionManager::CheckCallerPermission()
218 {
219 int32_t stageRes = static_cast<int32_t>(StageRes::STAGE_FAIL);
220 auto tokenID = IPCSkeleton::GetCallingTokenID();
221 if (tokenID == INVALID_TOKEN_ID) {
222 HILOGW("invalid token id");
223 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
224 return false;
225 }
226 ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID);
227 if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) {
228 HILOGE("TokenType is not native");
229 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
230 return false;
231 }
232 std::string callProcName = GetCallerProcName();
233 int32_t ret = AccessTokenKit::VerifyAccessToken(tokenID, DP_SERVICE_ACCESS_PERMISSION);
234 if (ret != PermissionState::PERMISSION_GRANTED) {
235 HILOGE("failed callProc %{public}s!", callProcName.c_str());
236 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
237 return false;
238 }
239 stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
240 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
241 return true;
242 }
243
CheckCallerSyncPermission()244 bool PermissionManager::CheckCallerSyncPermission()
245 {
246 int32_t stageRes = static_cast<int32_t>(StageRes::STAGE_FAIL);
247 auto tokenID = IPCSkeleton::GetCallingTokenID();
248 if (tokenID == INVALID_TOKEN_ID) {
249 HILOGW("invalid token id");
250 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
251 return false;
252 }
253 ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID);
254 if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) {
255 HILOGE("TokenType is not native");
256 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
257 return false;
258 }
259 std::string callProcName = GetCallerProcName();
260 int32_t ret = AccessTokenKit::VerifyAccessToken(tokenID, DP_SERVICE_SYNC_PERMISSION);
261 if (ret != PermissionState::PERMISSION_GRANTED) {
262 HILOGE("failed callProc %{public}s!", callProcName.c_str());
263 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
264 return false;
265 }
266 stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
267 DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
268 HILOGI("success callProc %{public}s!", callProcName.c_str());
269 return true;
270 }
271
GetCallerProcName()272 std::string PermissionManager::GetCallerProcName()
273 {
274 // called after CheckCallerTrust, and keep same policy with CheckCallerTrust
275 NativeTokenInfo nativeTokenInfo;
276 auto tokenID = IPCSkeleton::GetCallingTokenID();
277 auto errCode = AccessTokenKit::GetNativeTokenInfo(tokenID, nativeTokenInfo);
278 std::string procName;
279 if (errCode == EOK) {
280 procName = std::move(nativeTokenInfo.processName);
281 HILOGD("procName:%{public}s", procName.c_str());
282 }
283 return procName;
284 }
285
SetPermissionMap(const cJSON * const permissionJson,const std::string & interfaceName)286 void PermissionManager::SetPermissionMap(const cJSON* const permissionJson, const std::string& interfaceName)
287 {
288 cJSON* item = cJSON_GetObjectItem(permissionJson, interfaceName.c_str());
289 int32_t itemSize = static_cast<int32_t>(cJSON_GetArraySize(item));
290 if (!cJSON_IsArray(item) || itemSize == 0 || itemSize > MAX_INTERFACE_SIZE) {
291 HILOGE("PermissionJson not contains the key, %{public}s!", interfaceName.c_str());
292 return;
293 }
294 std::unordered_set<std::string> interfaceNameSets;
295 item = item->child;
296 while (item != NULL) {
297 if (cJSON_IsString(item)) {
298 interfaceNameSets.emplace(item->valuestring);
299 }
300 item = item->next;
301 }
302 {
303 std::lock_guard<std::mutex> lockGuard(permissionMutex_);
304 permissionMap_[interfaceName] = interfaceNameSets;
305 }
306 }
307 } // namespace DeviceProfile
308 } // namespace OHOS
309