1 /*
2 * Copyright (C) 2024 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 <arpa/inet.h>
17 #include <fstream>
18
19 #include "netmgr_ext_log_wrapper.h"
20 #include "netfirewall_default_rule_parser.h"
21
22 namespace OHOS {
23 namespace NetManagerStandard {
24 constexpr const char *DEFAULT_RULES = "default_rules";
25
ConvertFirewallRuleToConfig(sptr<NetFirewallRule> & rule,const cJSON * const mem)26 void NetFirewallDefaultRuleParser::ConvertFirewallRuleToConfig(sptr<NetFirewallRule> &rule, const cJSON * const mem)
27 {
28 cJSON *ruleName = cJSON_GetObjectItem(mem, NET_FIREWALL_RULE_NAME.c_str());
29 if (ruleName != nullptr && cJSON_IsString(ruleName)) {
30 rule->ruleName = cJSON_GetStringValue(ruleName);
31 NETMGR_EXT_LOG_D("ruleName = %{public}s", rule->ruleName.c_str());
32 }
33 cJSON *ruleDescription = cJSON_GetObjectItem(mem, NET_FIREWALL_RULE_DESC.c_str());
34 if (ruleDescription != nullptr && cJSON_IsString(ruleDescription)) {
35 rule->ruleDescription = cJSON_GetStringValue(ruleDescription);
36 NETMGR_EXT_LOG_D("ruleDescription = %{public}s", rule->ruleDescription.c_str());
37 }
38 cJSON *ruleDirection = cJSON_GetObjectItem(mem, NET_FIREWALL_RULE_DIR.c_str());
39 if (ruleDirection != nullptr && cJSON_IsNumber(ruleDirection)) {
40 rule->ruleDirection = static_cast<NetFirewallRuleDirection>(cJSON_GetNumberValue(ruleDirection));
41 NETMGR_EXT_LOG_D("mtu = %{public}d", rule->ruleDirection);
42 }
43 cJSON *ruleAction = cJSON_GetObjectItem(mem, NET_FIREWALL_RULE_ACTION.c_str());
44 if (ruleAction != nullptr && cJSON_IsNumber(ruleAction)) {
45 rule->ruleAction = static_cast<FirewallRuleAction>(cJSON_GetNumberValue(ruleAction));
46 NETMGR_EXT_LOG_D("ruleAction = %{public}d", rule->ruleAction);
47 }
48 cJSON *ruleType = cJSON_GetObjectItem(mem, NET_FIREWALL_RULE_TYPE.c_str());
49 if (ruleType != nullptr && cJSON_IsNumber(ruleType)) {
50 rule->ruleType = static_cast<NetFirewallRuleType>(cJSON_GetNumberValue(ruleType));
51 NETMGR_EXT_LOG_D("ruleType = %{public}d", rule->ruleType);
52 }
53 cJSON *isEnabled = cJSON_GetObjectItem(mem, NET_FIREWALL_IS_ENABLED.c_str());
54 if (isEnabled != nullptr && cJSON_IsBool(isEnabled)) {
55 rule->isEnabled = cJSON_IsTrue(isEnabled);
56 NETMGR_EXT_LOG_D("isEnabled = %{public}d", rule->isEnabled);
57 }
58 cJSON *appUid = cJSON_GetObjectItem(mem, NET_FIREWALL_APP_ID.c_str());
59 if (appUid != nullptr && cJSON_IsNumber(appUid)) {
60 rule->appUid = cJSON_GetNumberValue(appUid);
61 NETMGR_EXT_LOG_D("appUid = %{public}d", rule->appUid);
62 }
63 ParseListObject(rule, mem);
64 cJSON *protocol = cJSON_GetObjectItem(mem, NET_FIREWALL_PROTOCOL.c_str());
65 if (protocol != nullptr && cJSON_IsNumber(protocol)) {
66 rule->protocol = static_cast<NetworkProtocol>(cJSON_GetNumberValue(protocol));
67 NETMGR_EXT_LOG_D("protocol = %{public}d", rule->protocol);
68 }
69 ParseDnsObject(rule->dns, mem, NET_FIREWALL_DNS);
70 cJSON *userId = cJSON_GetObjectItem(mem, NET_FIREWALL_USER_ID.c_str());
71 if (userId != nullptr && cJSON_IsNumber(userId)) {
72 rule->userId = cJSON_GetNumberValue(userId);
73 NETMGR_EXT_LOG_D("userId = %{public}d", rule->userId);
74 }
75 }
76
ParseListObject(sptr<NetFirewallRule> & rule,const cJSON * const mem)77 void NetFirewallDefaultRuleParser::ParseListObject(sptr<NetFirewallRule> &rule, const cJSON * const mem)
78 {
79 ParseIpList(rule->localIps, mem, NET_FIREWALL_LOCAL_IP);
80 ParseIpList(rule->remoteIps, mem, NET_FIREWALL_REMOTE_IP);
81 ParsePortList(rule->localPorts, mem, NET_FIREWALL_LOCAL_PORT);
82 ParsePortList(rule->remotePorts, mem, NET_FIREWALL_REMOTE_PORT);
83 ParseDomainList(rule->domains, mem, NET_FIREWALL_RULE_DOMAIN);
84 }
85
ParseIpList(std::vector<NetFirewallIpParam> & ipParamlist,const cJSON * const mem,const std::string jsonKey)86 void NetFirewallDefaultRuleParser::ParseIpList(std::vector<NetFirewallIpParam> &ipParamlist, const cJSON * const mem,
87 const std::string jsonKey)
88 {
89 cJSON *ips = cJSON_GetObjectItem(mem, jsonKey.c_str());
90 if (ips != nullptr && cJSON_IsArray(ips)) {
91 int itemSize = cJSON_GetArraySize(ips);
92 for (int i = 0; i < itemSize; i++) {
93 cJSON *item = cJSON_GetArrayItem(ips, i);
94 if (cJSON_IsObject(item)) {
95 NetFirewallIpParam ipParam;
96 ConvertIpParamToConfig(ipParam, item);
97 ipParamlist.emplace_back(std::move(ipParam));
98 }
99 }
100 }
101 }
102
ParsePortList(std::vector<NetFirewallPortParam> & portParamlist,const cJSON * const mem,const std::string jsonKey)103 void NetFirewallDefaultRuleParser::ParsePortList(std::vector<NetFirewallPortParam> &portParamlist,
104 const cJSON * const mem, const std::string jsonKey)
105 {
106 cJSON *prot = cJSON_GetObjectItem(mem, jsonKey.c_str());
107 if (prot != nullptr && cJSON_IsArray(prot)) {
108 int itemSize = cJSON_GetArraySize(prot);
109 for (int i = 0; i < itemSize; i++) {
110 cJSON *item = cJSON_GetArrayItem(prot, i);
111 if (cJSON_IsObject(item)) {
112 NetFirewallPortParam portParam;
113 ConvertPortParamToConfig(portParam, item);
114 portParamlist.emplace_back(std::move(portParam));
115 }
116 }
117 }
118 }
119
ParseDomainList(std::vector<NetFirewallDomainParam> & domainParamlist,const cJSON * const mem,const std::string jsonKey)120 void NetFirewallDefaultRuleParser::ParseDomainList(std::vector<NetFirewallDomainParam> &domainParamlist,
121 const cJSON * const mem, const std::string jsonKey)
122 {
123 cJSON *domain = cJSON_GetObjectItem(mem, jsonKey.c_str());
124 if (domain != nullptr && cJSON_IsArray(domain)) {
125 int itemSize = cJSON_GetArraySize(domain);
126 for (int i = 0; i < itemSize; i++) {
127 cJSON *item = cJSON_GetArrayItem(domain, i);
128 if (cJSON_IsObject(item)) {
129 NetFirewallDomainParam domainParam;
130 ConvertDomainParamToConfig(domainParam, item);
131 domainParamlist.emplace_back(std::move(domainParam));
132 }
133 }
134 }
135 }
136
ParseDnsObject(NetFirewallDnsParam & dns,const cJSON * const mem,const std::string jsonKey)137 void NetFirewallDefaultRuleParser::ParseDnsObject(NetFirewallDnsParam &dns, const cJSON * const mem,
138 const std::string jsonKey)
139 {
140 cJSON *obj = cJSON_GetObjectItem(mem, jsonKey.c_str());
141 if (obj != nullptr && cJSON_IsObject(obj)) {
142 NetFirewallDnsParam dnsParam;
143 ConvertDnsParamToConfig(dnsParam, obj);
144 dns = dnsParam;
145 }
146 }
147
ConvertIpParamToConfig(NetFirewallIpParam & rule,const cJSON * const mem)148 void NetFirewallDefaultRuleParser::ConvertIpParamToConfig(NetFirewallIpParam &rule, const cJSON * const mem)
149 {
150 cJSON *family = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_FAMILY.c_str());
151 if (family != nullptr && cJSON_IsNumber(family)) {
152 rule.family = static_cast<uint8_t>(cJSON_GetNumberValue(family));
153 }
154 cJSON *type = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_TYPE.c_str());
155 if (type != nullptr && cJSON_IsNumber(type)) {
156 rule.type = static_cast<uint8_t>(cJSON_GetNumberValue(type));
157 }
158 std::string tmp;
159 if (rule.type == SINGLE_IP) {
160 cJSON *address = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_ADDRESS.c_str());
161 if (address != nullptr && cJSON_IsString(address)) {
162 tmp = cJSON_GetStringValue(address);
163 if (rule.family == FAMILY_IPV4) {
164 inet_pton(AF_INET, tmp.c_str(), &rule.ipv4.startIp);
165 } else {
166 inet_pton(AF_INET6, tmp.c_str(), &rule.ipv6.startIp);
167 }
168 }
169 cJSON *mask = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_MASK.c_str());
170 if (mask != nullptr && cJSON_IsNumber(mask)) {
171 rule.mask = static_cast<uint8_t>(cJSON_GetNumberValue(mask));
172 NETMGR_EXT_LOG_D("mask = %{public}d", rule.mask);
173 }
174 return;
175 }
176 cJSON *startIp = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_START.c_str());
177 if (startIp != nullptr && cJSON_IsString(startIp)) {
178 tmp = cJSON_GetStringValue(startIp);
179 if (rule.family == FAMILY_IPV4) {
180 inet_pton(AF_INET, tmp.c_str(), &rule.ipv4.startIp);
181 } else {
182 inet_pton(AF_INET6, tmp.c_str(), &rule.ipv6.startIp);
183 }
184 }
185 cJSON *endIp = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_END.c_str());
186 if (endIp != nullptr && cJSON_IsString(endIp)) {
187 tmp = cJSON_GetStringValue(endIp);
188 if (rule.family == FAMILY_IPV4) {
189 inet_pton(AF_INET, tmp.c_str(), &rule.ipv4.endIp);
190 } else {
191 inet_pton(AF_INET6, tmp.c_str(), &rule.ipv6.endIp);
192 }
193 }
194 }
195
ConvertPortParamToConfig(NetFirewallPortParam & rule,const cJSON * const mem)196 void NetFirewallDefaultRuleParser::ConvertPortParamToConfig(NetFirewallPortParam &rule, const cJSON * const mem)
197 {
198 cJSON *startPort = cJSON_GetObjectItem(mem, NET_FIREWALL_PORT_START.c_str());
199 if (startPort != nullptr && cJSON_IsNumber(startPort)) {
200 rule.startPort = static_cast<uint16_t>(cJSON_GetNumberValue(startPort));
201 NETMGR_EXT_LOG_D("startPort = %{public}d", rule.startPort);
202 }
203 cJSON *endPort = cJSON_GetObjectItem(mem, NET_FIREWALL_PORT_END.c_str());
204 if (endPort != nullptr && cJSON_IsNumber(endPort)) {
205 rule.endPort = static_cast<uint16_t>(cJSON_GetNumberValue(endPort));
206 NETMGR_EXT_LOG_D("endPort = %{public}d", rule.endPort);
207 }
208 }
209
ConvertDomainParamToConfig(NetFirewallDomainParam & rule,const cJSON * const mem)210 void NetFirewallDefaultRuleParser::ConvertDomainParamToConfig(NetFirewallDomainParam &rule, const cJSON * const mem)
211 {
212 cJSON *isWildcard = cJSON_GetObjectItem(mem, NET_FIREWALL_DOMAIN_IS_WILDCARD.c_str());
213 if (isWildcard != nullptr && cJSON_IsBool(isWildcard)) {
214 rule.isWildcard = cJSON_IsTrue(isWildcard);
215 NETMGR_EXT_LOG_D("isWildcard = %{public}d", rule.isWildcard);
216 }
217 cJSON *domain = cJSON_GetObjectItem(mem, NET_FIREWALL_DOMAIN.c_str());
218 if (domain != nullptr && cJSON_IsString(domain)) {
219 rule.domain = cJSON_GetStringValue(domain);
220 NETMGR_EXT_LOG_D("domain = %{public}s", rule.domain.c_str());
221 }
222 }
223
ConvertDnsParamToConfig(NetFirewallDnsParam & rule,const cJSON * const mem)224 void NetFirewallDefaultRuleParser::ConvertDnsParamToConfig(NetFirewallDnsParam &rule, const cJSON * const mem)
225 {
226 cJSON *primaryDns = cJSON_GetObjectItem(mem, NET_FIREWALL_DNS_PRIMARY.c_str());
227 if (primaryDns != nullptr && cJSON_IsString(primaryDns)) {
228 rule.primaryDns = cJSON_GetStringValue(primaryDns);
229 }
230 cJSON *standbyDns = cJSON_GetObjectItem(mem, NET_FIREWALL_DNS_STANDY.c_str());
231 if (standbyDns != nullptr && cJSON_IsString(standbyDns)) {
232 rule.standbyDns = cJSON_GetStringValue(standbyDns);
233 }
234 }
235
GetDefaultRules(std::vector<sptr<NetFirewallRule>> & ruleList)236 bool NetFirewallDefaultRuleParser::GetDefaultRules(std::vector<sptr<NetFirewallRule>> &ruleList)
237 {
238 const auto &jsonString = ReadJsonFile(DEFAULT_RULE_FILE);
239 if (jsonString.length() == 0) {
240 NETMGR_EXT_LOG_E("ReadJsonFile config file is return empty!");
241 return false;
242 }
243
244 NETMGR_EXT_LOG_D("Parse json %{public}s,", jsonString.c_str());
245 cJSON *doc = cJSON_Parse(jsonString.c_str());
246 cJSON *defaultRules = cJSON_GetObjectItem(doc, DEFAULT_RULES);
247 if (defaultRules != nullptr && cJSON_IsArray(defaultRules)) {
248 int itemSize = cJSON_GetArraySize(defaultRules);
249 for (int i = 0; i < itemSize; i++) {
250 cJSON *item = cJSON_GetArrayItem(defaultRules, i);
251 if (cJSON_IsObject(item)) {
252 sptr<NetFirewallRule> rule = new (std::nothrow) NetFirewallRule();
253 ConvertFirewallRuleToConfig(rule, item);
254 ruleList.emplace_back(std::move(rule));
255 }
256 }
257 } else {
258 NETMGR_EXT_LOG_E("Parse json error");
259 cJSON_Delete(doc);
260 return false;
261 }
262 cJSON_Delete(doc);
263 return true;
264 }
265
ReadJsonFile(const std::string & filePath)266 std::string NetFirewallDefaultRuleParser::ReadJsonFile(const std::string &filePath)
267 {
268 std::string strAll;
269 std::error_code error;
270 auto path = std::filesystem::absolute(filePath, error);
271 if (error) {
272 NETMGR_EXT_LOG_E("Failed to obtain the absolute path: %{public}s", error.message().c_str());
273 return strAll;
274 }
275 std::ifstream infile(path);
276 if (!infile.is_open()) {
277 NETMGR_EXT_LOG_E("ReadJsonFile filePath failed");
278 return strAll;
279 }
280 std::string strLine;
281 while (getline(infile, strLine)) {
282 strAll.append(strLine);
283 }
284 infile.close();
285 return strAll;
286 }
287 } // namespace NetManagerStandard
288 } // namespace OHOS
289