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 "net_firewall_rule_parse.h"
17 #include "napi_utils.h"
18 #include "netmanager_ext_log.h"
19 #include "net_manager_constants.h"
20 
21 namespace OHOS {
22 namespace NetManagerStandard {
ParseIpList(napi_env env,napi_value params,std::vector<NetFirewallIpParam> & list)23 void NetFirewallRuleParse::ParseIpList(napi_env env, napi_value params, std::vector<NetFirewallIpParam> &list)
24 {
25     if (!NapiUtils::IsArray(env, params)) {
26         NETMANAGER_EXT_LOGE("ParseIpList get params failed");
27         return;
28     }
29     uint32_t len = NapiUtils::GetArrayLength(env, params);
30     std::vector<NetFirewallIpParam>().swap(list);
31     for (size_t j = 0; j < len; j++) {
32         napi_value valAttr = NapiUtils::GetArrayElement(env, params, j);
33         if (NapiUtils::GetValueType(env, valAttr) != napi_object) {
34             NETMANAGER_EXT_LOGI("valAttr is not napi_number");
35             continue;
36         }
37         NetFirewallIpParam param;
38         param.family = static_cast<uint8_t>(NapiUtils::GetUint32Property(env, valAttr, NET_FIREWALL_IP_FAMILY));
39         // Default IPv4
40         if (param.family == 0) {
41             param.family = FAMILY_IPV4;
42         }
43         param.type = static_cast<uint8_t>(NapiUtils::GetUint32Property(env, valAttr, NET_FIREWALL_IP_TYPE));
44         // Default single IP
45         if (param.type == 0) {
46             param.type = SINGLE_IP;
47         }
48         std::string startIp;
49         std::string endIp;
50         if (param.type == SINGLE_IP) {
51             param.mask = static_cast<uint8_t>(NapiUtils::GetUint32Property(env, valAttr, NET_FIREWALL_IP_MASK));
52             startIp = NapiUtils::GetStringPropertyUtf8(env, valAttr, NET_FIREWALL_IP_ADDRESS);
53             // The default IPv4 mask is 32, The IPv6 prefix is 64
54             if (param.mask == 0 && param.type == SINGLE_IP) {
55                 param.mask = param.family == FAMILY_IPV4 ? IPV4_MASK_MAX : IPV6_MASK_MAX;
56             }
57         } else {
58             startIp = NapiUtils::GetStringPropertyUtf8(env, valAttr, NET_FIREWALL_IP_START);
59             endIp = NapiUtils::GetStringPropertyUtf8(env, valAttr, NET_FIREWALL_IP_END);
60         }
61         if (param.family == FAMILY_IPV4) {
62             inet_pton(AF_INET, startIp.c_str(), &param.ipv4.startIp);
63             if (param.type == MULTIPLE_IP) {
64                 inet_pton(AF_INET, endIp.c_str(), &param.ipv4.endIp);
65             }
66         } else {
67             inet_pton(AF_INET6, startIp.c_str(), &param.ipv6.startIp);
68             if (param.type == MULTIPLE_IP) {
69                 inet_pton(AF_INET6, endIp.c_str(), &param.ipv6.endIp);
70             }
71         }
72         list.emplace_back(param);
73     }
74 }
75 
ParsePortList(napi_env env,napi_value params,std::vector<NetFirewallPortParam> & list)76 void NetFirewallRuleParse::ParsePortList(napi_env env, napi_value params, std::vector<NetFirewallPortParam> &list)
77 {
78     if (!NapiUtils::IsArray(env, params)) {
79         NETMANAGER_EXT_LOGE("ParsePortList get params failed");
80         return;
81     }
82     uint32_t len = NapiUtils::GetArrayLength(env, params);
83     std::vector<NetFirewallPortParam>().swap(list);
84     for (size_t j = 0; j < len; j++) {
85         napi_value valAttr = NapiUtils::GetArrayElement(env, params, j);
86         if (NapiUtils::GetValueType(env, valAttr) != napi_object) {
87             NETMANAGER_EXT_LOGI("valAttr is not napi_number");
88             continue;
89         }
90         NetFirewallPortParam param;
91         param.startPort = static_cast<uint16_t>(NapiUtils::GetUint32Property(env, valAttr, NET_FIREWALL_PORT_START));
92         param.endPort = static_cast<uint16_t>(NapiUtils::GetUint32Property(env, valAttr, NET_FIREWALL_PORT_END));
93         list.emplace_back(param);
94     }
95 }
96 
ParseDomainList(napi_env env,napi_value params,std::vector<NetFirewallDomainParam> & list)97 void NetFirewallRuleParse::ParseDomainList(napi_env env, napi_value params, std::vector<NetFirewallDomainParam> &list)
98 {
99     if (!NapiUtils::IsArray(env, params)) {
100         NETMANAGER_EXT_LOGE("ParseDomainList get params failed");
101         return;
102     }
103     uint32_t len = NapiUtils::GetArrayLength(env, params);
104     std::vector<NetFirewallDomainParam>().swap(list);
105     for (size_t j = 0; j < len; j++) {
106         napi_value valAttr = NapiUtils::GetArrayElement(env, params, j);
107         if (NapiUtils::GetValueType(env, valAttr) != napi_object) {
108             NETMANAGER_EXT_LOGI("valAttr is not napi_number");
109             continue;
110         }
111         NetFirewallDomainParam param;
112         param.isWildcard = NapiUtils::GetBooleanProperty(env, valAttr, NET_FIREWALL_DOMAIN_IS_WILDCARD);
113         param.domain = NapiUtils::GetStringPropertyUtf8(env, valAttr, NET_FIREWALL_DOMAIN);
114         list.emplace_back(param);
115     }
116 }
117 
ParseRuleParams(napi_env env,napi_value object,const sptr<NetFirewallRule> & rule)118 void NetFirewallRuleParse::ParseRuleParams(napi_env env, napi_value object, const sptr<NetFirewallRule> &rule)
119 {
120     rule->ruleId = NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_ID);
121     rule->ruleName = NapiUtils::GetStringPropertyUtf8(env, object, NET_FIREWALL_RULE_NAME);
122     rule->ruleDescription = NapiUtils::GetStringPropertyUtf8(env, object, NET_FIREWALL_RULE_DESC);
123     rule->ruleDirection =
124         static_cast<NetFirewallRuleDirection>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_DIR));
125     rule->ruleAction =
126         static_cast<FirewallRuleAction>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_ACTION));
127     rule->ruleType = static_cast<NetFirewallRuleType>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_TYPE));
128     rule->isEnabled = NapiUtils::GetBooleanProperty(env, object, NET_FIREWALL_IS_ENABLED);
129     rule->appUid = NapiUtils::GetInt32Property(env, object, NET_FIREWALL_APP_ID);
130     if (rule->ruleType == NetFirewallRuleType::RULE_IP) {
131         ParseIpList(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_LOCAL_IP), rule->localIps);
132         ParseIpList(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_REMOTE_IP), rule->remoteIps);
133         rule->protocol = static_cast<NetworkProtocol>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_PROTOCOL));
134         ParsePortList(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_LOCAL_PORT), rule->localPorts);
135         ParsePortList(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_REMOTE_PORT), rule->remotePorts);
136     } else if (rule->ruleType == NetFirewallRuleType::RULE_DOMAIN) {
137         ParseDomainList(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_RULE_DOMAIN), rule->domains);
138     } else {
139         napi_value dns = NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_DNS);
140         rule->dns.primaryDns = NapiUtils::GetStringPropertyUtf8(env, dns, NET_FIREWALL_DNS_PRIMARY);
141         rule->dns.standbyDns = NapiUtils::GetStringPropertyUtf8(env, dns, NET_FIREWALL_DNS_STANDY);
142     }
143     rule->userId = NapiUtils::GetInt32Property(env, object, NET_FIREWALL_USER_ID);
144 }
145 
SetIpList(napi_env env,napi_value object,const std::string & propertyName,const std::vector<NetFirewallIpParam> & list)146 void NetFirewallRuleParse::SetIpList(napi_env env, napi_value object, const std::string &propertyName,
147     const std::vector<NetFirewallIpParam> &list)
148 {
149     uint32_t index = 0;
150     napi_value ipList = NapiUtils::CreateArray(env, list.size());
151     for (const auto &iface : list) {
152         napi_value element = NapiUtils::CreateObject(env);
153         NapiUtils::SetUint32Property(env, element, NET_FIREWALL_IP_FAMILY, static_cast<uint32_t>(iface.family));
154         NapiUtils::SetUint32Property(env, element, NET_FIREWALL_IP_TYPE, static_cast<uint32_t>(iface.type));
155         if (iface.type == SINGLE_IP) {
156             NapiUtils::SetUint32Property(env, element, NET_FIREWALL_IP_MASK, static_cast<uint32_t>(iface.mask));
157             NapiUtils::SetStringPropertyUtf8(env, element, NET_FIREWALL_IP_ADDRESS, iface.GetStartIp());
158         } else {
159             NapiUtils::SetStringPropertyUtf8(env, element, NET_FIREWALL_IP_START, iface.GetStartIp());
160             NapiUtils::SetStringPropertyUtf8(env, element, NET_FIREWALL_IP_END, iface.GetEndIp());
161         }
162         NapiUtils::SetArrayElement(env, ipList, index++, element);
163     }
164     NapiUtils::SetNamedProperty(env, object, propertyName, ipList);
165 }
166 
SetPortList(napi_env env,napi_value object,const std::string & propertyName,const std::vector<NetFirewallPortParam> & list)167 void NetFirewallRuleParse::SetPortList(napi_env env, napi_value object, const std::string &propertyName,
168     const std::vector<NetFirewallPortParam> &list)
169 {
170     uint32_t index = 0;
171     napi_value portList = NapiUtils::CreateArray(env, list.size());
172     for (const auto &iface : list) {
173         napi_value element = NapiUtils::CreateObject(env);
174         NapiUtils::SetUint32Property(env, element, NET_FIREWALL_PORT_START, static_cast<uint32_t>(iface.startPort));
175         NapiUtils::SetUint32Property(env, element, NET_FIREWALL_PORT_END, static_cast<uint32_t>(iface.endPort));
176 
177         NapiUtils::SetArrayElement(env, portList, index++, element);
178     }
179     NapiUtils::SetNamedProperty(env, object, propertyName, portList);
180 }
181 
SetDomainList(napi_env env,napi_value object,const std::string & propertyName,const std::vector<NetFirewallDomainParam> & list)182 void NetFirewallRuleParse::SetDomainList(napi_env env, napi_value object, const std::string &propertyName,
183     const std::vector<NetFirewallDomainParam> &list)
184 {
185     uint32_t index = 0;
186     napi_value domenList = NapiUtils::CreateArray(env, list.size());
187     for (const auto &iface : list) {
188         napi_value element = NapiUtils::CreateObject(env);
189         NapiUtils::SetBooleanProperty(env, element, NET_FIREWALL_DOMAIN_IS_WILDCARD, iface.isWildcard);
190         NapiUtils::SetStringPropertyUtf8(env, element, NET_FIREWALL_DOMAIN, iface.domain);
191 
192         NapiUtils::SetArrayElement(env, domenList, index++, element);
193     }
194     NapiUtils::SetNamedProperty(env, object, propertyName, domenList);
195 }
196 
SetRuleParams(napi_env env,napi_value object,const NetFirewallRule & rule)197 void NetFirewallRuleParse::SetRuleParams(napi_env env, napi_value object, const NetFirewallRule &rule)
198 {
199     NapiUtils::SetInt32Property(env, object, NET_FIREWALL_RULE_ID, rule.ruleId);
200     NapiUtils::SetStringPropertyUtf8(env, object, NET_FIREWALL_RULE_NAME, rule.ruleName);
201     NapiUtils::SetStringPropertyUtf8(env, object, NET_FIREWALL_RULE_DESC, rule.ruleDescription);
202     NapiUtils::SetInt32Property(env, object, NET_FIREWALL_RULE_DIR, static_cast<int32_t>(rule.ruleDirection));
203     NapiUtils::SetInt32Property(env, object, NET_FIREWALL_RULE_ACTION, static_cast<int32_t>(rule.ruleAction));
204     NapiUtils::SetInt32Property(env, object, NET_FIREWALL_RULE_TYPE, static_cast<int32_t>(rule.ruleType));
205     NapiUtils::SetBooleanProperty(env, object, NET_FIREWALL_IS_ENABLED, rule.isEnabled);
206     NapiUtils::SetInt32Property(env, object, NET_FIREWALL_APP_ID, rule.appUid);
207     if (rule.ruleType == NetFirewallRuleType::RULE_IP) {
208         SetIpList(env, object, NET_FIREWALL_LOCAL_IP, rule.localIps);
209         SetIpList(env, object, NET_FIREWALL_REMOTE_IP, rule.remoteIps);
210         NapiUtils::SetInt32Property(env, object, NET_FIREWALL_PROTOCOL, static_cast<int32_t>(rule.protocol));
211         SetPortList(env, object, NET_FIREWALL_LOCAL_PORT, rule.localPorts);
212         SetPortList(env, object, NET_FIREWALL_REMOTE_PORT, rule.remotePorts);
213     } else if (rule.ruleType == NetFirewallRuleType::RULE_DOMAIN) {
214         SetDomainList(env, object, NET_FIREWALL_RULE_DOMAIN, rule.domains);
215     } else {
216         napi_value dns = NapiUtils::CreateObject(env);
217         NapiUtils::SetStringPropertyUtf8(env, dns, NET_FIREWALL_DNS_PRIMARY, rule.dns.primaryDns);
218         NapiUtils::SetStringPropertyUtf8(env, dns, NET_FIREWALL_DNS_STANDY, rule.dns.standbyDns);
219         NapiUtils::SetNamedProperty(env, object, NET_FIREWALL_DNS, dns);
220     }
221     NapiUtils::SetInt32Property(env, object, NET_FIREWALL_USER_ID, rule.userId);
222 }
223 
ParsePageParam(napi_env env,napi_value object,const sptr<RequestParam> & param,bool isRule)224 int32_t NetFirewallRuleParse::ParsePageParam(napi_env env, napi_value object, const sptr<RequestParam> &param,
225     bool isRule)
226 {
227     if (!NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_PAGE) ||
228         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_PAGE_SIZE) ||
229         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_ORDER_FIELD) ||
230         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_ORDER_TYPE)) {
231         NETMANAGER_EXT_LOGE("params can not be empty.");
232         return FIREWALL_ERR_PARAMETER_ERROR;
233     }
234     param->page = NapiUtils::GetInt32Property(env, object, NET_FIREWALL_PAGE);
235     if (param->page < 1 || param->page > FIREWALL_USER_MAX_RULE) {
236         NETMANAGER_EXT_LOGE("ParsePageParam page[%{public}d] is error", param->page);
237         return FIREWALL_ERR_INVALID_PARAMETER;
238     }
239     param->pageSize = NapiUtils::GetInt32Property(env, object, NET_FIREWALL_PAGE_SIZE);
240     if (param->pageSize < 1 || param->pageSize > MAX_PAGE_SIZE) {
241         NETMANAGER_EXT_LOGE("ParsePageParam pageSize[%{public}d] is error", param->pageSize);
242         return FIREWALL_ERR_INVALID_PARAMETER;
243     }
244     param->orderField =
245         static_cast<NetFirewallOrderField>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_ORDER_FIELD));
246     if ((isRule && param->orderField != NetFirewallOrderField::ORDER_BY_RULE_NAME) ||
247         (!isRule && param->orderField != NetFirewallOrderField::ORDER_BY_RECORD_TIME)) {
248         NETMANAGER_EXT_LOGE("params orderField invalid");
249         return FIREWALL_ERR_INVALID_PARAMETER;
250     }
251     param->orderType =
252         static_cast<NetFirewallOrderType>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_ORDER_TYPE));
253     if (param->orderType != NetFirewallOrderType::ORDER_ASC && param->orderType != NetFirewallOrderType::ORDER_DESC) {
254         NETMANAGER_EXT_LOGE("params orderType invalid");
255         return FIREWALL_ERR_INVALID_PARAMETER;
256     }
257     return FIREWALL_SUCCESS;
258 }
259 } // namespace NetManagerStandard
260 } // namespace OHOS