• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, UPDATE_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, GET_ALL_ACL_INCLUDE_LNN_ACL);
140     SetPermissionMap(permissionJson, DELETE_ACCESS_CONTROL_PROFILE);
141     SetPermissionMap(permissionJson, GET_TRUST_DEVICE_PROFILE);
142     SetPermissionMap(permissionJson, GET_ALL_TRUST_DEVICE_PROFILE);
143     SetPermissionMap(permissionJson, PUT_DEVICE_PROFILE_BATCH);
144     SetPermissionMap(permissionJson, DELETE_DEVICE_PROFILE_BATCH);
145     SetPermissionMap(permissionJson, GET_DEVICE_PROFILES);
146     SetPermissionMap(permissionJson, PUT_PRODUCT_INFO_BATCH);
147     SetPermissionMap(permissionJson, PUT_DEVICE_ICON_INFO_BATCH);
148     SetPermissionMap(permissionJson, GET_DEVICE_ICON_INFOS);
149     SetPermissionMap(permissionJson, PUT_SESSION_KEY);
150     SetPermissionMap(permissionJson, GET_SESSION_KEY);
151     SetPermissionMap(permissionJson, UPDATE_SESSION_KEY);
152     SetPermissionMap(permissionJson, DELETE_SESSION_KEY);
153     return;
154 }
155 
SetKVPermissionMap(const cJSON * const permissionJson)156 void PermissionManager::SetKVPermissionMap(const cJSON *const permissionJson)
157 {
158     int size = cJSON_GetArraySize(permissionJson);
159     if (size == 0 || size > MAX_INTERFACE_SIZE) {
160         HILOGE("Permission json size is invalid!size: %{public}d!", size);
161         return;
162     }
163     SetPermissionMap(permissionJson, PUT_SERVICE_PROFILE);
164     SetPermissionMap(permissionJson, PUT_SERVICE_PROFILE_BATCH);
165     SetPermissionMap(permissionJson, PUT_CHARACTERISTIC_PROFILE);
166     SetPermissionMap(permissionJson, PUT_CHARACTERISTIC_PROFILE_BATCH);
167     SetPermissionMap(permissionJson, GET_DEVICE_PROFILE);
168     SetPermissionMap(permissionJson, GET_SERVICE_PROFILE);
169     SetPermissionMap(permissionJson, GET_CHARACTERISTIC_PROFILE);
170     SetPermissionMap(permissionJson, DELETE_SERVICE_PROFILE);
171     SetPermissionMap(permissionJson, DELETE_CHARACTERISTIC_PROFILE);
172     SetPermissionMap(permissionJson, SUBSCRIBE_DEVICE_PROFILE);
173     SetPermissionMap(permissionJson, UNSUBSCRIBE_DEVICE_PROFILE);
174     SetPermissionMap(permissionJson, SYNC_DEVICE_PROFILE);
175     SetPermissionMap(permissionJson, PUT_ALL_TRUSTED_DEVICES);
176     return;
177 }
178 
CheckInterfacePermission(const std::string & interfaceName)179 bool PermissionManager::CheckInterfacePermission(const std::string& interfaceName)
180 {
181     std::string callProcName = GetCallerProcName();
182     std::unordered_set<std::string> permittedProcNames;
183     {
184         std::lock_guard<std::mutex> lockGuard(permissionMutex_);
185         permittedProcNames = permissionMap_[interfaceName];
186     }
187     bool checkResult =  (permittedProcNames.count(callProcName) != 0 || permittedProcNames.count(ALL_PROC) != 0);
188     HILOGD("success interface %{public}s callProc %{public}s!", interfaceName.c_str(), callProcName.c_str());
189     return checkResult;
190 }
191 
IsCallerTrust(const std::string & interfaceName)192 bool PermissionManager::IsCallerTrust(const std::string& interfaceName)
193 {
194     int32_t stageRes = static_cast<int32_t>(StageRes::STAGE_FAIL);
195     auto tokenID = IPCSkeleton::GetCallingTokenID();
196     if (tokenID == INVALID_TOKEN_ID) {
197         HILOGW("invalid token id");
198         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
199         return false;
200     }
201     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID);
202     // currently only support native trusted caller
203     if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) {
204         HILOGE("TokenType is not native");
205         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
206         return false;
207     }
208     if (!CheckInterfacePermission(interfaceName)) {
209         HILOGE("This caller cannot call this interface, interfaceName: %{public}s", interfaceName.c_str());
210         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
211         return false;
212     }
213     stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
214     DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
215     return true;
216 }
217 
CheckCallerPermission()218 bool PermissionManager::CheckCallerPermission()
219 {
220     int32_t stageRes = static_cast<int32_t>(StageRes::STAGE_FAIL);
221     auto tokenID = IPCSkeleton::GetCallingTokenID();
222     if (tokenID == INVALID_TOKEN_ID) {
223         HILOGW("invalid token id");
224         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
225         return false;
226     }
227     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID);
228     if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) {
229         HILOGE("TokenType is not native");
230         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
231         return false;
232     }
233     std::string callProcName = GetCallerProcName();
234     int32_t ret = AccessTokenKit::VerifyAccessToken(tokenID, DP_SERVICE_ACCESS_PERMISSION);
235     if (ret != PermissionState::PERMISSION_GRANTED) {
236         HILOGE("failed callProc %{public}s!", callProcName.c_str());
237         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
238         return false;
239     }
240     stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
241     DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
242     return true;
243 }
244 
CheckCallerSyncPermission()245 bool PermissionManager::CheckCallerSyncPermission()
246 {
247     int32_t stageRes = static_cast<int32_t>(StageRes::STAGE_FAIL);
248     auto tokenID = IPCSkeleton::GetCallingTokenID();
249     if (tokenID == INVALID_TOKEN_ID) {
250         HILOGW("invalid token id");
251         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
252         return false;
253     }
254     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID);
255     if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) {
256         HILOGE("TokenType is not native");
257         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
258         return false;
259     }
260     std::string callProcName = GetCallerProcName();
261     int32_t ret = AccessTokenKit::VerifyAccessToken(tokenID, DP_SERVICE_SYNC_PERMISSION);
262     if (ret != PermissionState::PERMISSION_GRANTED) {
263         HILOGE("failed callProc %{public}s!", callProcName.c_str());
264         DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
265         return false;
266     }
267     stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
268     DpRadarHelper::GetInstance().ReportSaCheckAuth(stageRes);
269     HILOGI("success callProc %{public}s!", callProcName.c_str());
270     return true;
271 }
272 
GetCallerProcName()273 std::string PermissionManager::GetCallerProcName()
274 {
275     // called after CheckCallerTrust, and keep same policy with CheckCallerTrust
276     NativeTokenInfo nativeTokenInfo;
277     auto tokenID = IPCSkeleton::GetCallingTokenID();
278     auto errCode = AccessTokenKit::GetNativeTokenInfo(tokenID, nativeTokenInfo);
279     std::string procName;
280     if (errCode == EOK) {
281         procName = std::move(nativeTokenInfo.processName);
282         HILOGD("procName:%{public}s", procName.c_str());
283     }
284     return procName;
285 }
286 
SetPermissionMap(const cJSON * const permissionJson,const std::string & interfaceName)287 void PermissionManager::SetPermissionMap(const cJSON* const permissionJson, const std::string& interfaceName)
288 {
289     cJSON* item = cJSON_GetObjectItem(permissionJson, interfaceName.c_str());
290     int32_t itemSize = static_cast<int32_t>(cJSON_GetArraySize(item));
291     if (!cJSON_IsArray(item) || itemSize == 0 || itemSize > MAX_INTERFACE_SIZE) {
292         HILOGE("PermissionJson not contains the key, %{public}s!", interfaceName.c_str());
293         return;
294     }
295     std::unordered_set<std::string> interfaceNameSets;
296     item = item->child;
297     while (item != NULL) {
298         if (cJSON_IsString(item)) {
299             interfaceNameSets.emplace(item->valuestring);
300         }
301         item = item->next;
302     }
303     {
304         std::lock_guard<std::mutex> lockGuard(permissionMutex_);
305         permissionMap_[interfaceName] = interfaceNameSets;
306     }
307 }
308 } // namespace DeviceProfile
309 } // namespace OHOS
310