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 uint32_t itemSize = cJSON_GetArraySize(ips);
92 for (uint32_t 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 uint32_t itemSize = cJSON_GetArraySize(prot);
109 for (uint32_t 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 uint32_t itemSize = cJSON_GetArraySize(domain);
126 for (uint32_t 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 NETMGR_EXT_LOG_D("address = %{public}s", tmp.c_str());
169 }
170 cJSON *mask = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_MASK.c_str());
171 if (mask != nullptr && cJSON_IsNumber(mask)) {
172 rule.mask = static_cast<uint8_t>(cJSON_GetNumberValue(mask));
173 NETMGR_EXT_LOG_D("mask = %{public}d", rule.mask);
174 }
175 return;
176 }
177 cJSON *startIp = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_START.c_str());
178 if (startIp != nullptr && cJSON_IsString(startIp)) {
179 tmp = cJSON_GetStringValue(startIp);
180 if (rule.family == FAMILY_IPV4) {
181 inet_pton(AF_INET, tmp.c_str(), &rule.ipv4.startIp);
182 } else {
183 inet_pton(AF_INET6, tmp.c_str(), &rule.ipv6.startIp);
184 }
185 NETMGR_EXT_LOG_D("startIp = %{public}s", tmp.c_str());
186 }
187 cJSON *endIp = cJSON_GetObjectItem(mem, NET_FIREWALL_IP_END.c_str());
188 if (endIp != nullptr && cJSON_IsString(endIp)) {
189 tmp = cJSON_GetStringValue(endIp);
190 if (rule.family == FAMILY_IPV4) {
191 inet_pton(AF_INET, tmp.c_str(), &rule.ipv4.endIp);
192 } else {
193 inet_pton(AF_INET6, tmp.c_str(), &rule.ipv6.endIp);
194 }
195 NETMGR_EXT_LOG_D("endIp = %{public}s", tmp.c_str());
196 }
197 }
198
ConvertPortParamToConfig(NetFirewallPortParam & rule,const cJSON * const mem)199 void NetFirewallDefaultRuleParser::ConvertPortParamToConfig(NetFirewallPortParam &rule, const cJSON * const mem)
200 {
201 cJSON *startPort = cJSON_GetObjectItem(mem, NET_FIREWALL_PORT_START.c_str());
202 if (startPort != nullptr && cJSON_IsNumber(startPort)) {
203 rule.startPort = static_cast<uint16_t>(cJSON_GetNumberValue(startPort));
204 NETMGR_EXT_LOG_D("startPort = %{public}d", rule.startPort);
205 }
206 cJSON *endPort = cJSON_GetObjectItem(mem, NET_FIREWALL_PORT_END.c_str());
207 if (endPort != nullptr && cJSON_IsNumber(endPort)) {
208 rule.endPort = static_cast<uint16_t>(cJSON_GetNumberValue(endPort));
209 NETMGR_EXT_LOG_D("endPort = %{public}d", rule.endPort);
210 }
211 }
212
ConvertDomainParamToConfig(NetFirewallDomainParam & rule,const cJSON * const mem)213 void NetFirewallDefaultRuleParser::ConvertDomainParamToConfig(NetFirewallDomainParam &rule, const cJSON * const mem)
214 {
215 cJSON *isWildcard = cJSON_GetObjectItem(mem, NET_FIREWALL_DOMAIN_IS_WILDCARD.c_str());
216 if (isWildcard != nullptr && cJSON_IsBool(isWildcard)) {
217 rule.isWildcard = cJSON_IsTrue(isWildcard);
218 NETMGR_EXT_LOG_D("isWildcard = %{public}d", rule.isWildcard);
219 }
220 cJSON *domain = cJSON_GetObjectItem(mem, NET_FIREWALL_DOMAIN.c_str());
221 if (domain != nullptr && cJSON_IsString(domain)) {
222 rule.domain = cJSON_GetStringValue(domain);
223 NETMGR_EXT_LOG_D("domain = %{public}s", rule.domain.c_str());
224 }
225 }
226
ConvertDnsParamToConfig(NetFirewallDnsParam & rule,const cJSON * const mem)227 void NetFirewallDefaultRuleParser::ConvertDnsParamToConfig(NetFirewallDnsParam &rule, const cJSON * const mem)
228 {
229 cJSON *primaryDns = cJSON_GetObjectItem(mem, NET_FIREWALL_DNS_PRIMARY.c_str());
230 if (primaryDns != nullptr && cJSON_IsString(primaryDns)) {
231 rule.primaryDns = cJSON_GetStringValue(primaryDns);
232 NETMGR_EXT_LOG_D("primaryDns = %{public}s", rule.primaryDns.c_str());
233 }
234 cJSON *standbyDns = cJSON_GetObjectItem(mem, NET_FIREWALL_DNS_STANDY.c_str());
235 if (standbyDns != nullptr && cJSON_IsString(standbyDns)) {
236 rule.standbyDns = cJSON_GetStringValue(standbyDns);
237 NETMGR_EXT_LOG_D("standbyDns = %{public}s", rule.standbyDns.c_str());
238 }
239 }
240
GetDefaultRules(std::vector<sptr<NetFirewallRule>> & ruleList)241 bool NetFirewallDefaultRuleParser::GetDefaultRules(std::vector<sptr<NetFirewallRule>> &ruleList)
242 {
243 const auto &jsonString = ReadJsonFile(DEFAULT_RULE_FILE);
244 if (jsonString.length() == 0) {
245 NETMGR_EXT_LOG_E("ReadJsonFile config file is return empty!");
246 return false;
247 }
248
249 NETMGR_EXT_LOG_D("Parse json %{public}s,", jsonString.c_str());
250 cJSON *doc = cJSON_Parse(jsonString.c_str());
251 cJSON *defaultRules = cJSON_GetObjectItem(doc, DEFAULT_RULES);
252 if (defaultRules != nullptr && cJSON_IsArray(defaultRules)) {
253 uint32_t itemSize = cJSON_GetArraySize(defaultRules);
254 for (uint32_t i = 0; i < itemSize; i++) {
255 cJSON *item = cJSON_GetArrayItem(defaultRules, i);
256 if (cJSON_IsObject(item)) {
257 sptr<NetFirewallRule> rule = new (std::nothrow) NetFirewallRule();
258 ConvertFirewallRuleToConfig(rule, item);
259 ruleList.emplace_back(std::move(rule));
260 }
261 }
262 } else {
263 NETMGR_EXT_LOG_E("Parse json error");
264 cJSON_Delete(doc);
265 return false;
266 }
267 cJSON_Delete(doc);
268 return true;
269 }
270
ReadJsonFile(const std::string & filePath)271 std::string NetFirewallDefaultRuleParser::ReadJsonFile(const std::string &filePath)
272 {
273 std::ifstream infile;
274 std::string strLine;
275 std::string strAll;
276 infile.open(filePath);
277 if (!infile.is_open()) {
278 NETMGR_EXT_LOG_E("ReadJsonFile filePath failed");
279 return strAll;
280 }
281 while (getline(infile, strLine)) {
282 strAll.append(strLine);
283 }
284 infile.close();
285 return strAll;
286 }
287 } // namespace NetManagerStandard
288 } // namespace OHOS
289