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