• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "nearlink_config_utils.h"
17 
18 #include <unistd.h>
19 
20 #include "directory_ex.h"
21 
22 #include "edm_log.h"
23 #include "nearlink_protocol_utils.h"
24 
25 namespace OHOS {
26 namespace EDM {
27 const std::string CONFIG_PATH = "/data/service/el1/public/edm/config/system/all/nearlink/config.json";
28 const std::string CONFIG_SYSTEM_ALL_DIR = "/data/service/el1/public/edm/config/system/all";
29 const std::string NEARLINK_DIR = "nearlink";
30 const std::string SEPARATOR = "/";
31 const char *const PROTOCOL_DENY_LIST = "ProtocolDenyList";
32 constexpr int32_t EDM_UID = 3057;
33 constexpr int32_t EDM_GID = 3057;
34 
NearlinkConfigUtils()35 NearlinkConfigUtils::NearlinkConfigUtils()
36 {
37     EDMLOGI("NearlinkConfigUtils::NearlinkConfigUtils()");
38     std::vector<std::string> files;
39     OHOS::GetDirFiles(CONFIG_SYSTEM_ALL_DIR, files);
40     if (std::find(files.begin(), files.end(), NEARLINK_DIR) == files.end()) {
41         CreateNearlinkConfigDir(CONFIG_SYSTEM_ALL_DIR + SEPARATOR + NEARLINK_DIR);
42     }
43     LoadConfig();
44 }
45 
~NearlinkConfigUtils()46 NearlinkConfigUtils::~NearlinkConfigUtils()
47 {
48     EDMLOGI("NearlinkConfigUtils::~NearlinkConfigUtils()");
49     if (root_) {
50         cJSON_Delete(root_);
51     }
52 }
53 
UpdateProtocol(const std::string & userId,const std::string & protocol,bool isAdd)54 bool NearlinkConfigUtils::UpdateProtocol(const std::string &userId, const std::string &protocol, bool isAdd)
55 {
56     EDMLOGI("NearlinkConfigUtils::UpdateProtocol() - isAdd: %d", isAdd);
57 
58     // 通用前置检查
59     if (!root_ && !LoadConfig()) {
60         EDMLOGE("Failed to load config before update protocol");
61         return false;
62     }
63     if (!CheckProtocolDenyListExists()) {
64         EDMLOGE("Failed to ensure PROTOCOL_DENY_LIST exists");
65         return false;
66     }
67 
68     // 获取 denyList 和 userItem
69     cJSON *denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
70     if (!denyList) {
71         EDMLOGE("PROTOCOL_DENY_LIST not found in config");
72         return false;
73     }
74     cJSON *userItem = cJSON_GetObjectItem(denyList, userId.c_str());
75 
76     // 调用子函数处理增删逻辑
77     if (isAdd) {
78         return AddProtocol(protocol, userId, denyList, userItem);
79     } else {
80         return RemoveProtocol(protocol, userId, denyList, userItem);
81     }
82 }
83 
AddProtocol(const std::string & protocol,const std::string & userId,cJSON * denyList,cJSON * userItem)84 bool NearlinkConfigUtils::AddProtocol(
85     const std::string &protocol, const std::string &userId, cJSON *denyList, cJSON *userItem)
86 {
87     if (userItem && IsProtocolExist(protocol, userItem)) {
88         EDMLOGI("Protocol %s already exists", protocol.c_str());
89         return true;  // 协议已存在,无需添加
90     }
91 
92     cJSON *protocols = cJSON_CreateString(protocol.c_str());
93     if (!protocols) {
94         EDMLOGE("Failed to create protocol string item");
95         return false;
96     }
97 
98     if (!userItem) {
99         // 新增用户条目
100         CJSON_CREATE_ARRAY_AND_CHECK(userItem, false);
101         CJSON_ADD_ITEM_TO_ARRAY_AND_CHECK_AND_CLEAR(protocols, userItem, false);
102         if (!cJSON_AddItemToObject(denyList, userId.c_str(), userItem)) {
103             EDMLOGE("cJSON_AddItemToObject Error");
104             cJSON_Delete(userItem);
105             return false;
106         }
107     } else {
108         // 直接添加到现有数组
109         CJSON_ADD_ITEM_TO_ARRAY_AND_CHECK_AND_CLEAR(protocols, userItem, false);
110     }
111     return SaveConfig();
112 }
113 
RemoveProtocol(const std::string & protocol,const std::string & userId,cJSON * denyList,cJSON * userItem)114 bool NearlinkConfigUtils::RemoveProtocol(
115     const std::string &protocol, const std::string &userId, cJSON *denyList, cJSON *userItem)
116 {
117     if (!userItem) {
118         EDMLOGI("User entry does not exist, nothing to remove");
119         return true;
120     }
121 
122     int indexToRemove = -1;
123     for (int i = 0; i < cJSON_GetArraySize(userItem); ++i) {
124         cJSON *item = cJSON_GetArrayItem(userItem, i);
125         if (item && item->valuestring && strcmp(item->valuestring, protocol.c_str()) == 0) {
126             indexToRemove = i;
127             break;
128         }
129     }
130 
131     if (indexToRemove < 0) {
132         EDMLOGI("Protocol %s not found", protocol.c_str());
133         return true;  // 协议不存在,无需删除
134     }
135 
136     cJSON_DeleteItemFromArray(userItem, indexToRemove);
137     if (cJSON_GetArraySize(userItem) == 0) {
138         cJSON_DeleteItemFromObject(denyList, userId.c_str());  // 删除空用户条目
139     }
140     return SaveConfig();
141 }
142 
IsProtocolExist(const std::string & protocol,cJSON * userItem)143 bool NearlinkConfigUtils::IsProtocolExist(const std::string &protocol, cJSON *userItem)
144 {
145     cJSON *protocolItem = nullptr;
146     cJSON_ArrayForEach(protocolItem, userItem) {
147         if (strcmp(protocolItem->valuestring, protocol.c_str()) == 0) {
148             return true;
149         }
150     }
151     return false;
152 }
153 
CreateNearlinkConfigDir(const std::string & dir)154 bool NearlinkConfigUtils::CreateNearlinkConfigDir(const std::string &dir)
155 {
156     EDMLOGI("NearlinkConfigUtils::CreateNearlinkConfigDir");
157     if (!OHOS::ForceCreateDirectory(dir)) {
158         EDMLOGE("mkdir dir failed");
159         return false;
160     }
161     if (chown(dir.c_str(), EDM_UID, EDM_GID) != 0) {
162         EDMLOGE("fail to change dir ownership");
163         return false;
164     }
165     mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
166     if (!OHOS::ChangeModeFile(dir, mode)) {
167         EDMLOGE("change mode failed, temp install dir");
168         return false;
169     }
170     return true;
171 }
172 
QueryProtocols(const std::string & userId,std::vector<int32_t> & protocols)173 bool NearlinkConfigUtils::QueryProtocols(const std::string &userId, std::vector<int32_t> &protocols)
174 {
175     if (!root_ && !LoadConfig()) {
176         return false;
177     }
178     cJSON *denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
179     if (!denyList) {
180         return true;
181     }
182     cJSON *userItem = cJSON_GetObjectItem(denyList, userId.c_str());
183     if (!userItem) {
184         return true;
185     }
186     cJSON *protocolItem = nullptr;
187     cJSON_ArrayForEach(protocolItem, userItem) {
188         int32_t protocol = 0;
189         NearlinkProtocolUtils::StrToProtocolInt(protocolItem->valuestring, protocol);
190         protocols.push_back(protocol);
191     }
192     return true;
193 }
194 
RemoveUserIdItem(const std::string & userId)195 bool NearlinkConfigUtils::RemoveUserIdItem(const std::string &userId)
196 {
197     EDMLOGI("NearlinkConfigUtils::RemoveUserIdItem");
198     if (!root_ && !LoadConfig()) {
199         return false;
200     }
201     cJSON *denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
202     if (!denyList) {
203         return true;
204     }
205     cJSON_DeleteItemFromObject(denyList, userId.c_str());
206     return SaveConfig();
207 }
208 
RemoveProtocolDenyList()209 bool NearlinkConfigUtils::RemoveProtocolDenyList()
210 {
211     EDMLOGI("NearlinkConfigUtils::RemoveProtocolDenyList");
212     if (!root_ && !LoadConfig()) {
213         return false;
214     }
215     cJSON_DeleteItemFromObject(root_, PROTOCOL_DENY_LIST);
216     return SaveConfig();
217 }
218 
LoadConfig()219 bool NearlinkConfigUtils::LoadConfig()
220 {
221     EDMLOGI("NearlinkConfigUtils::LoadConfig");
222     std::ifstream inFile(CONFIG_PATH, std::ios::binary);
223     if (inFile.good()) {
224         EDMLOGI("NearlinkConfigUtils::LoadConfig inFile.good");
225         inFile.seekg(0, std::ios::end);
226         size_t size = inFile.tellg();
227         if (size == 0) {
228             inFile.close();
229             CJSON_CREATE_OBJECT_AND_CHECK(root_, false);
230             return true;
231         }
232         inFile.seekg(0, std::ios::beg);
233         std::string jsonStr(size, ' ');
234         inFile.read(&jsonStr[0], size);
235         inFile.close();
236         root_ = cJSON_Parse(jsonStr.c_str());
237         return root_ != nullptr;
238     }
239     EDMLOGI("NearlinkConfigUtils::LoadConfig inFile fail");
240     inFile.close();
241     CJSON_CREATE_OBJECT_AND_CHECK(root_, false);
242     return true;
243 }
244 
SaveConfig()245 bool NearlinkConfigUtils::SaveConfig()
246 {
247     EDMLOGI("NearlinkConfigUtils::saveConfig");
248     if (!root_) {
249         return false;
250     }
251     char *jsonStr = cJSON_Print(root_);
252     if (!jsonStr) {
253         return false;
254     }
255     std::ofstream file(CONFIG_PATH);
256     if (!file.is_open()) {
257         cJSON_free(jsonStr);
258         return false;
259     }
260     file << jsonStr;
261     file.close();
262     cJSON_free(jsonStr);
263     return true;
264 }
265 
CheckProtocolDenyListExists()266 bool NearlinkConfigUtils::CheckProtocolDenyListExists()
267 {
268     if (!root_) {
269         CJSON_CREATE_OBJECT_AND_CHECK(root_, false);
270     }
271     cJSON *denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
272     if (!denyList) {
273         cJSON *protocolDenyList = nullptr;
274         CJSON_CREATE_OBJECT_AND_CHECK(protocolDenyList, false);
275         if (!cJSON_AddItemToObject(root_, PROTOCOL_DENY_LIST, protocolDenyList)) {
276             EDMLOGE("NearlinkConfigUtils::cJSON_AddItemToObject Root Error");
277             cJSON_Delete(protocolDenyList);
278             return false;
279         }
280     }
281     return true;
282 }
283 }  // namespace EDM
284 }  // namespace OHOS