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 <regex>
17 
18 #include "napi_utils.h"
19 #include "net_firewall_param_check.h"
20 #include "net_manager_constants.h"
21 #include "netmanager_base_common_utils.h"
22 #include "netmanager_ext_log.h"
23 
24 namespace OHOS {
25 namespace NetManagerStandard {
26 constexpr int32_t MAX_RULE_PORT = 65535;
27 const std::regex DOMAIN_PATTERN { "^([a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?)$" };
28 const std::regex WILDCARD_DOMAIN_PATTERN {
29     "^(([a-zA-Z0-9][-a-zA-Z0-9]{0,62}|\\*)(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?)$"
30 };
31 
CheckFirewallRulePolicy(napi_env env,napi_value object)32 int32_t NetFirewallParamCheck::CheckFirewallRulePolicy(napi_env env, napi_value object)
33 {
34     if (!NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_IS_OPEN) ||
35         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_IN_ACTION) ||
36         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_OUT_ACTION)) {
37         NETMANAGER_EXT_LOGE("params can not be empty.");
38         return FIREWALL_ERR_PARAMETER_ERROR;
39     }
40 
41     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_IS_OPEN)) {
42         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_IS_OPEN)) !=
43             napi_boolean) {
44             NETMANAGER_EXT_LOGE("params state type invalid");
45             return FIREWALL_ERR_PARAMETER_ERROR;
46         }
47     }
48 
49     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_IN_ACTION)) {
50         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_IN_ACTION)) !=
51             napi_number) {
52             NETMANAGER_EXT_LOGE("params inAction type invalid");
53             return FIREWALL_ERR_PARAMETER_ERROR;
54         }
55         FirewallRuleAction inAction =
56             static_cast<FirewallRuleAction>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_IN_ACTION));
57         if (inAction != FirewallRuleAction::RULE_ALLOW && inAction != FirewallRuleAction::RULE_DENY) {
58             NETMANAGER_EXT_LOGE("params inAction invalid");
59             return FIREWALL_ERR_INVALID_PARAMETER;
60         }
61     }
62 
63     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_OUT_ACTION)) {
64         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_OUT_ACTION)) !=
65             napi_number) {
66             NETMANAGER_EXT_LOGE("params outAction type invalid");
67             return FIREWALL_ERR_PARAMETER_ERROR;
68         }
69         FirewallRuleAction outAction =
70             static_cast<FirewallRuleAction>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_OUT_ACTION));
71         if (outAction != FirewallRuleAction::RULE_ALLOW && outAction != FirewallRuleAction::RULE_DENY) {
72             NETMANAGER_EXT_LOGE("params outAction invalid");
73             return FIREWALL_ERR_INVALID_PARAMETER;
74         }
75     }
76     return FIREWALL_SUCCESS;
77 }
78 
CheckFirewallDns(napi_env env,napi_value object)79 int32_t NetFirewallParamCheck::CheckFirewallDns(napi_env env, napi_value object)
80 {
81     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_DNS_PRIMARY)) {
82         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_DNS_PRIMARY)) !=
83             napi_string) {
84             NETMANAGER_EXT_LOGE("params dns type invalid");
85             return FIREWALL_ERR_PARAMETER_ERROR;
86         }
87         std::string primaryDns =
88             NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_DNS_PRIMARY));
89         if (primaryDns.size() == 0) {
90             NETMANAGER_EXT_LOGE("primary dns is null, params invalid");
91             return FIREWALL_ERR_PARAMETER_ERROR;
92         }
93         int32_t ret = CheckIpAddress(primaryDns);
94         if (ret != FIREWALL_SUCCESS) {
95             return ret;
96         }
97     } else {
98         NETMANAGER_EXT_LOGE("primary dns is null, params invalid");
99         return FIREWALL_ERR_PARAMETER_ERROR;
100     }
101 
102     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_DNS_STANDY)) {
103         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_DNS_STANDY)) !=
104             napi_string) {
105             NETMANAGER_EXT_LOGE("params dns type invalid");
106             return FIREWALL_ERR_PARAMETER_ERROR;
107         }
108         std::string standyDns =
109             NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_DNS_STANDY));
110         int32_t ret = CheckIpAddress(standyDns);
111         if (ret != FIREWALL_SUCCESS) {
112             return ret;
113         }
114     }
115     return FIREWALL_SUCCESS;
116 }
117 
CheckFirewallAction(napi_env env,napi_value object)118 int32_t NetFirewallParamCheck::CheckFirewallAction(napi_env env, napi_value object)
119 {
120     FirewallRuleAction action =
121         static_cast<FirewallRuleAction>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_ACTION));
122     if (action != FirewallRuleAction::RULE_ALLOW && action != FirewallRuleAction::RULE_DENY) {
123         NETMANAGER_EXT_LOGE("params action invalid");
124         return FIREWALL_ERR_INVALID_PARAMETER;
125     }
126     return FIREWALL_SUCCESS;
127 }
128 
CheckFirewallDirection(napi_env env,napi_value object)129 int32_t NetFirewallParamCheck::CheckFirewallDirection(napi_env env, napi_value object)
130 {
131     NetFirewallRuleDirection direction =
132         static_cast<NetFirewallRuleDirection>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_DIR));
133     if (direction != NetFirewallRuleDirection::RULE_IN && direction != NetFirewallRuleDirection::RULE_OUT) {
134         NETMANAGER_EXT_LOGE("params direction invalid");
135         return FIREWALL_ERR_INVALID_PARAMETER;
136     }
137     return FIREWALL_SUCCESS;
138 }
139 
CheckIpAddress(const std::string & ipStr)140 int32_t NetFirewallParamCheck::CheckIpAddress(const std::string &ipStr)
141 {
142     if (ipStr.size() == 0) {
143         return FIREWALL_SUCCESS;
144     }
145     if (CheckIpV4(ipStr) != FIREWALL_SUCCESS && CheckIpV6(ipStr) != FIREWALL_SUCCESS) {
146         NETMANAGER_EXT_LOGE("ip address invalid");
147         return FIREWALL_ERR_INVALID_PARAMETER;
148     }
149     return FIREWALL_SUCCESS;
150 }
151 
CheckIpAddress(const std::string & ipStr,const int32_t family)152 int32_t NetFirewallParamCheck::CheckIpAddress(const std::string &ipStr, const int32_t family)
153 {
154     if ((family == FAMILY_IPV4 && CheckIpV4(ipStr) != FIREWALL_SUCCESS) ||
155         (family == FAMILY_IPV6 && CheckIpV6(ipStr) != FIREWALL_SUCCESS)) {
156         NETMANAGER_EXT_LOGE("ip and family invalid");
157         return FIREWALL_ERR_INVALID_PARAMETER;
158     }
159 
160     return FIREWALL_SUCCESS;
161 }
162 
CheckIpAddress(const std::string & startIp,const std::string & endIp,const int32_t family)163 bool NetFirewallParamCheck::CheckIpAddress(const std::string &startIp, const std::string &endIp, const int32_t family)
164 {
165     int32_t ret = 0;
166     int32_t endRet = 0;
167     if (family == FAMILY_IPV6) {
168         in6_addr in6_addr1;
169         in6_addr in6_addr2;
170         // Convert IPv6 addresses to binary form
171         ret = inet_pton(AF_INET6, startIp.c_str(), &in6_addr1);
172         endRet = inet_pton(AF_INET6, endIp.c_str(), &in6_addr2);
173         if (ret <= 0 || endRet <= 0) {
174             NETMANAGER_EXT_LOGE("CheckIpAddress ipv6: startIp or endIp is invalid");
175             return false;
176         }
177         // Comparing IPv6 addresses in binary form
178         ret = memcmp(&in6_addr1, &in6_addr2, sizeof(in6_addr1));
179         if (ret > 0) {
180             NETMANAGER_EXT_LOGE("CheckIpAddress ipv6: start Ip is larger than endIp");
181             return false;
182         }
183         return true;
184     }
185 
186     in_addr inAddr1;
187     in_addr inAddr2;
188     ret = inet_pton(AF_INET, startIp.c_str(), &inAddr1);
189     endRet = inet_pton(AF_INET, endIp.c_str(), &inAddr2);
190     if (ret <= 0 || endRet <= 0) {
191         NETMANAGER_EXT_LOGE("CheckIpAddress ipv4: startIp or endIp is invalid");
192         return false;
193     }
194     ret = memcmp(&inAddr1, &inAddr2, sizeof(struct in_addr));
195     if (ret > 0) {
196         NETMANAGER_EXT_LOGE("CheckIpAddress ipv4: start Ip is larger than endIp");
197         return false;
198     }
199     return true;
200 }
201 
CheckIpV4(const std::string & ipV4)202 int32_t NetFirewallParamCheck::CheckIpV4(const std::string &ipV4)
203 {
204     in_addr v4Addr;
205     int32_t ret = inet_pton(AF_INET, ipV4.c_str(), &v4Addr);
206     if (ret <= 0) {
207         return FIREWALL_ERR_INVALID_PARAMETER;
208     }
209     return FIREWALL_SUCCESS;
210 }
211 
CheckIpV6(const std::string & ipV6)212 int32_t NetFirewallParamCheck::CheckIpV6(const std::string &ipV6)
213 {
214     in6_addr v6Addr;
215     int32_t ret = inet_pton(AF_INET6, ipV6.c_str(), &v6Addr);
216     if (ret <= 0) {
217         return FIREWALL_ERR_INVALID_PARAMETER;
218     }
219     return FIREWALL_SUCCESS;
220 }
221 
CheckSingeIp(napi_env env,napi_value valAttr,int32_t family)222 int32_t NetFirewallParamCheck::CheckSingeIp(napi_env env, napi_value valAttr, int32_t family)
223 {
224     // Address must be filled if a single IP is used
225     if (!NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_IP_ADDRESS)) {
226         NETMANAGER_EXT_LOGE("params ip type1 but no address");
227         return FIREWALL_ERR_INVALID_PARAMETER;
228     }
229     if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_ADDRESS)) !=
230         napi_string) {
231         return FIREWALL_ERR_PARAMETER_ERROR;
232     }
233     std::string address =
234         NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_ADDRESS));
235     int32_t ret = CheckIpAddress(address, family);
236     if (ret != FIREWALL_SUCCESS) {
237         return ret;
238     }
239 
240     if (NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_IP_MASK)) {
241         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_MASK)) !=
242             napi_number) {
243             return FIREWALL_ERR_PARAMETER_ERROR;
244         }
245         int32_t mask = NapiUtils::GetInt32Property(env, valAttr, NET_FIREWALL_IP_MASK);
246         int32_t maskMax = family == FAMILY_IPV4 ? IPV4_MASK_MAX : IPV6_MASK_MAX;
247         if (mask <= 0 || mask > maskMax) {
248             NETMANAGER_EXT_LOGE("params mask=%{public}d is invalid", mask);
249             return FIREWALL_ERR_INVALID_PARAMETER;
250         }
251     }
252     return FIREWALL_SUCCESS;
253 }
254 
CheckMultipleIp(napi_env env,napi_value valAttr,int32_t family)255 int32_t NetFirewallParamCheck::CheckMultipleIp(napi_env env, napi_value valAttr, int32_t family)
256 {
257     // Starting address must be filled if the multiple IPs are used
258     if (!NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_IP_START) ||
259         !NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_IP_END)) {
260         NETMANAGER_EXT_LOGE("params ip type2 but no startIp or endIp");
261         return FIREWALL_ERR_INVALID_PARAMETER;
262     }
263     if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_START)) != napi_string ||
264         NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_END)) != napi_string) {
265         return FIREWALL_ERR_PARAMETER_ERROR;
266     }
267     std::string startIp =
268         NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_START));
269     std::string endIp =
270         NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_END));
271     if (CheckIpAddress(startIp, endIp, family)) {
272         return FIREWALL_SUCCESS;
273     }
274     return FIREWALL_ERR_INVALID_PARAMETER;
275 }
276 
CheckIpList(napi_env env,napi_value object)277 int32_t NetFirewallParamCheck::CheckIpList(napi_env env, napi_value object)
278 {
279     if (!NapiUtils::IsArray(env, object)) {
280         NETMANAGER_EXT_LOGE("ParseIpList get params failed");
281         return FIREWALL_ERR_PARAMETER_ERROR;
282     }
283     uint32_t len = NapiUtils::GetArrayLength(env, object);
284     for (size_t j = 0; j < len; j++) {
285         napi_value valAttr = NapiUtils::GetArrayElement(env, object, j);
286         if (NapiUtils::GetValueType(env, valAttr) != napi_object) {
287             NETMANAGER_EXT_LOGI("valAttr is not napi_number");
288             continue;
289         }
290         int32_t family = FAMILY_IPV4;
291         if (NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_IP_FAMILY)) {
292             if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_FAMILY)) !=
293                 napi_number) {
294                 return FIREWALL_ERR_PARAMETER_ERROR;
295             }
296             family = NapiUtils::GetInt32Property(env, valAttr, NET_FIREWALL_IP_FAMILY);
297             if (family != FAMILY_IPV4 && family != FAMILY_IPV6) {
298                 NETMANAGER_EXT_LOGE("family param invalid.");
299                 return FIREWALL_ERR_INVALID_PARAMETER;
300             }
301         }
302 
303         int32_t type = SINGLE_IP;
304         if (NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_IP_TYPE)) {
305             if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_IP_TYPE)) !=
306                 napi_number) {
307                 return FIREWALL_ERR_PARAMETER_ERROR;
308             }
309             type = NapiUtils::GetInt32Property(env, valAttr, NET_FIREWALL_IP_TYPE);
310             if (type != SINGLE_IP && type != MULTIPLE_IP) {
311                 NETMANAGER_EXT_LOGE("params ip type invalid");
312                 return FIREWALL_ERR_INVALID_PARAMETER;
313             }
314         }
315         int32_t ret = type == MULTIPLE_IP ? CheckMultipleIp(env, valAttr, family) : CheckSingeIp(env, valAttr, family);
316         if (ret != FIREWALL_SUCCESS) {
317             return ret;
318         }
319     }
320 
321     return FIREWALL_SUCCESS;
322 }
323 
CheckPortList(napi_env env,napi_value object)324 int32_t NetFirewallParamCheck::CheckPortList(napi_env env, napi_value object)
325 {
326     if (!NapiUtils::IsArray(env, object)) {
327         NETMANAGER_EXT_LOGE("ParsePortList get params failed");
328         return FIREWALL_ERR_INVALID_PARAMETER;
329     }
330     uint32_t len = NapiUtils::GetArrayLength(env, object);
331     for (size_t j = 0; j < len; j++) {
332         napi_value valAttr = NapiUtils::GetArrayElement(env, object, j);
333         if (NapiUtils::GetValueType(env, valAttr) != napi_object) {
334             NETMANAGER_EXT_LOGI("valAttr is not napi_number");
335             continue;
336         }
337         int32_t startPort = 0;
338         if (NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_PORT_START)) {
339             if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_PORT_START)) !=
340                 napi_number) {
341                 return FIREWALL_ERR_PARAMETER_ERROR;
342             }
343             startPort = NapiUtils::GetInt32Property(env, valAttr, NET_FIREWALL_PORT_START);
344             if (startPort > MAX_RULE_PORT || startPort < 0) {
345                 NETMANAGER_EXT_LOGE("start port is more then %{public}d", MAX_RULE_PORT);
346                 return FIREWALL_ERR_INVALID_PARAMETER;
347             }
348         }
349         if (NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_PORT_END)) {
350             int32_t endPort = 0;
351             if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_PORT_END)) !=
352                 napi_number) {
353                 return FIREWALL_ERR_PARAMETER_ERROR;
354             }
355             endPort = NapiUtils::GetInt32Property(env, valAttr, NET_FIREWALL_PORT_END);
356             if (endPort > MAX_RULE_PORT || endPort < 0 || endPort < startPort) {
357                 NETMANAGER_EXT_LOGE("end port is more then %{public}d", MAX_RULE_PORT);
358                 return FIREWALL_ERR_INVALID_PARAMETER;
359             }
360         }
361     }
362 
363     return FIREWALL_SUCCESS;
364 }
365 
CheckDomainList(napi_env env,napi_value object)366 int32_t NetFirewallParamCheck::CheckDomainList(napi_env env, napi_value object)
367 {
368     if (!NapiUtils::IsArray(env, object)) {
369         NETMANAGER_EXT_LOGE("ParseDomainList get params failed");
370         return FIREWALL_ERR_INVALID_PARAMETER;
371     }
372     uint32_t len = NapiUtils::GetArrayLength(env, object);
373     for (size_t j = 0; j < len; j++) {
374         napi_value valAttr = NapiUtils::GetArrayElement(env, object, j);
375         if (NapiUtils::GetValueType(env, valAttr) != napi_object) {
376             NETMANAGER_EXT_LOGI("valAttr is not napi_number");
377             continue;
378         }
379         bool isWildCard = false;
380         if (NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_DOMAIN_IS_WILDCARD)) {
381             napi_value value = NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_DOMAIN_IS_WILDCARD);
382             if (NapiUtils::GetValueType(env, value) != napi_boolean) {
383                 return FIREWALL_ERR_PARAMETER_ERROR;
384             }
385             isWildCard = NapiUtils::GetBooleanValue(env, value);
386         }
387         if (!NapiUtils::HasNamedProperty(env, valAttr, NET_FIREWALL_DOMAIN)) {
388             continue;
389         }
390         std::string domain = "";
391         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_DOMAIN)) !=
392             napi_string) {
393             return FIREWALL_ERR_PARAMETER_ERROR;
394         }
395         domain = NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, valAttr, NET_FIREWALL_DOMAIN));
396         int32_t maxSize = isWildCard ? MAX_FUZZY_DOMAIN_NAME_LEN : MAX_EXACT_DOMAIN_NAME_LEN;
397         if (domain.empty() || domain.size() > maxSize) {
398             NETMANAGER_EXT_LOGE("domain is empty or length more than %{public}d", maxSize);
399             return FIREWALL_ERR_INVALID_PARAMETER;
400         }
401         std::regex pattern = isWildCard ? WILDCARD_DOMAIN_PATTERN : DOMAIN_PATTERN;
402         bool isValid = std::regex_match(domain, pattern);
403         if (!isValid) {
404             NETMANAGER_EXT_LOGE("invalid domain address");
405             return FIREWALL_ERR_INVALID_PARAMETER;
406         }
407     }
408     return FIREWALL_SUCCESS;
409 }
410 
CheckUpdateFirewallRule(napi_env env,napi_value object)411 int32_t NetFirewallParamCheck::CheckUpdateFirewallRule(napi_env env, napi_value object)
412 {
413     if (!NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_ID)) {
414         NETMANAGER_EXT_LOGE("params type invalid");
415         return FIREWALL_ERR_PARAMETER_ERROR;
416     }
417     if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_RULE_ID)) != napi_number) {
418         NETMANAGER_EXT_LOGE("params type invalid");
419         return FIREWALL_ERR_PARAMETER_ERROR;
420     }
421     int32_t ruleId = NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_ID);
422     if (ruleId < 0 || ruleId > INT32_MAX) {
423         NETMANAGER_EXT_LOGE("invalid ruleId");
424         return FIREWALL_ERR_INVALID_PARAMETER;
425     }
426     return CheckFirewallRule(env, object);
427 }
428 
CheckAddFirewallRule(napi_env env,napi_value object)429 int32_t NetFirewallParamCheck::CheckAddFirewallRule(napi_env env, napi_value object)
430 {
431     return CheckFirewallRule(env, object);
432 }
433 
CheckFirewallRule(napi_env env,napi_value object)434 int32_t NetFirewallParamCheck::CheckFirewallRule(napi_env env, napi_value object)
435 {
436     if (!NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_NAME) ||
437         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_DIR) ||
438         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_ACTION) ||
439         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_TYPE) ||
440         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_IS_ENABLED) ||
441         !NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_USER_ID)) {
442         NETMANAGER_EXT_LOGE("params can not be empty.");
443         return FIREWALL_ERR_PARAMETER_ERROR;
444     }
445     NetFirewallRuleType ruleType =
446         static_cast<NetFirewallRuleType>(NapiUtils::GetInt32Property(env, object, NET_FIREWALL_RULE_TYPE));
447     if (ruleType != NetFirewallRuleType::RULE_IP && ruleType != NetFirewallRuleType::RULE_DOMAIN &&
448         ruleType != NetFirewallRuleType::RULE_DNS) {
449         NETMANAGER_EXT_LOGE("params ruleType invalid");
450         return FIREWALL_ERR_INVALID_PARAMETER;
451     }
452     std::vector<std::string> numberParam;
453     numberParam.emplace_back(NET_FIREWALL_RULE_ID);
454     numberParam.emplace_back(NET_FIREWALL_RULE_DIR);
455     numberParam.emplace_back(NET_FIREWALL_RULE_ACTION);
456     numberParam.emplace_back(NET_FIREWALL_APP_ID);
457     numberParam.emplace_back(NET_FIREWALL_USER_ID);
458     if (ruleType == NetFirewallRuleType::RULE_IP) {
459         numberParam.emplace_back(NET_FIREWALL_PROTOCOL);
460     }
461     int32_t ret = FIREWALL_SUCCESS;
462     for (std::string &propertyName : numberParam) {
463         ret = CheckRuleNumberParam(env, object, propertyName);
464         if (ret != FIREWALL_SUCCESS) {
465             NETMANAGER_EXT_LOGE("CheckRuleNumberParam %{public}s is error=%{public}d", propertyName.c_str(), ret);
466             return ret;
467         }
468     }
469     ret = CheckRuleName(env, object);
470     if (ret != FIREWALL_SUCCESS) {
471         return ret;
472     }
473     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_IS_ENABLED)) {
474         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_IS_ENABLED)) !=
475             napi_boolean) {
476             NETMANAGER_EXT_LOGE("params enable type invalid");
477             return FIREWALL_ERR_PARAMETER_ERROR;
478         }
479     }
480     return CheckRuleObjectParams(env, object, ruleType);
481 }
482 
CheckRuleObjectParams(napi_env env,napi_value object,const NetFirewallRuleType & type)483 int32_t NetFirewallParamCheck::CheckRuleObjectParams(napi_env env, napi_value object, const NetFirewallRuleType &type)
484 {
485     std::vector<std::string> objectParam;
486     switch (type) {
487         case NetFirewallRuleType::RULE_IP: {
488             objectParam.emplace_back(NET_FIREWALL_LOCAL_IP);
489             objectParam.emplace_back(NET_FIREWALL_REMOTE_IP);
490             objectParam.emplace_back(NET_FIREWALL_LOCAL_PORT);
491             objectParam.emplace_back(NET_FIREWALL_REMOTE_PORT);
492             break;
493         }
494         case NetFirewallRuleType::RULE_DOMAIN:
495             objectParam.emplace_back(NET_FIREWALL_RULE_DOMAIN);
496             break;
497         case NetFirewallRuleType::RULE_DNS:
498             objectParam.emplace_back(NET_FIREWALL_DNS);
499             break;
500         default:
501             break;
502     }
503     int32_t ret;
504     for (const std::string &propertyName : objectParam) {
505         ret = CheckRuleObjectParamValue(env, object, propertyName);
506         if (ret != FIREWALL_SUCCESS) {
507             NETMANAGER_EXT_LOGE("CheckRuleObjectParams %{public}s is error=%{public}d", propertyName.c_str(), ret);
508             return ret;
509         }
510     }
511     return FIREWALL_SUCCESS;
512 }
513 
CheckRuleObjectParamValue(napi_env env,napi_value object,const std::string & propertyName)514 int32_t NetFirewallParamCheck::CheckRuleObjectParamValue(napi_env env, napi_value object,
515     const std::string &propertyName)
516 {
517     if (!NapiUtils::HasNamedProperty(env, object, propertyName)) {
518         return FIREWALL_SUCCESS;
519     }
520     napi_value value = NapiUtils::GetNamedProperty(env, object, propertyName);
521     if (NapiUtils::GetValueType(env, value) != napi_object) {
522         NETMANAGER_EXT_LOGE("CheckRuleObjectParamValue property is not object");
523         return FIREWALL_ERR_PARAMETER_ERROR;
524     }
525     if (propertyName == NET_FIREWALL_LOCAL_IP || propertyName == NET_FIREWALL_REMOTE_IP) {
526         return CheckIpList(env, value);
527     }
528     if (propertyName == NET_FIREWALL_LOCAL_PORT || propertyName == NET_FIREWALL_REMOTE_PORT) {
529         return CheckPortList(env, value);
530     }
531     if (propertyName == NET_FIREWALL_RULE_DOMAIN) {
532         return CheckDomainList(env, value);
533     }
534     if (propertyName == NET_FIREWALL_DNS) {
535         return CheckFirewallDns(env, value);
536     }
537     return FIREWALL_SUCCESS;
538 }
539 
CheckRuleName(napi_env env,napi_value object)540 int32_t NetFirewallParamCheck::CheckRuleName(napi_env env, napi_value object)
541 {
542     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_NAME)) {
543         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_RULE_NAME)) !=
544             napi_string) {
545             NETMANAGER_EXT_LOGE("params ruleName type invalid");
546             return FIREWALL_ERR_PARAMETER_ERROR;
547         }
548         std::string ruleName =
549             NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_RULE_NAME));
550         if (ruleName.size() == 0 || ruleName.size() > MAX_RULE_NAME_LEN) {
551             NETMANAGER_EXT_LOGE("ruleName=[%{public}s] is too long", ruleName.c_str());
552             return FIREWALL_ERR_INVALID_PARAMETER;
553         }
554     }
555 
556     if (NapiUtils::HasNamedProperty(env, object, NET_FIREWALL_RULE_DESC)) {
557         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_RULE_DESC)) !=
558             napi_string) {
559             NETMANAGER_EXT_LOGE("params ruleDescription type invalid");
560             return FIREWALL_ERR_PARAMETER_ERROR;
561         }
562         std::string ruleDescription =
563             NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetNamedProperty(env, object, NET_FIREWALL_RULE_DESC));
564         if (ruleDescription.size() > MAX_RULE_DESCRIPTION_LEN) {
565             NETMANAGER_EXT_LOGE("ruleDescription size=%{public}zu is too long", ruleDescription.size());
566             return FIREWALL_ERR_INVALID_PARAMETER;
567         }
568     }
569     return FIREWALL_SUCCESS;
570 }
571 
CheckRuleNumberParam(napi_env env,napi_value object,const std::string & propertyName)572 int32_t NetFirewallParamCheck::CheckRuleNumberParam(napi_env env, napi_value object, const std::string &propertyName)
573 {
574     if (!NapiUtils::HasNamedProperty(env, object, propertyName)) {
575         return FIREWALL_SUCCESS;
576     }
577     if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, propertyName)) != napi_number) {
578         NETMANAGER_EXT_LOGE("CheckRuleNumberParam property is not number");
579         return FIREWALL_ERR_PARAMETER_ERROR;
580     }
581     if (propertyName == NET_FIREWALL_RULE_DIR) {
582         return CheckFirewallDirection(env, object);
583     }
584     if (propertyName == NET_FIREWALL_RULE_ACTION) {
585         return CheckFirewallAction(env, object);
586     }
587     int32_t value = NapiUtils::GetInt32Property(env, object, propertyName);
588     if (propertyName == NET_FIREWALL_APP_ID) {
589         if (value < 0 || value > INT32_MAX) {
590             NETMANAGER_EXT_LOGE("invalid appUid");
591             return FIREWALL_ERR_INVALID_PARAMETER;
592         }
593     }
594     if (propertyName == NET_FIREWALL_PROTOCOL) {
595         NetworkProtocol ruleProtocol = static_cast<NetworkProtocol>(value);
596         if (ruleProtocol != NetworkProtocol::ICMP && ruleProtocol != NetworkProtocol::TCP &&
597             ruleProtocol != NetworkProtocol::UDP && ruleProtocol != NetworkProtocol::ICMPV6) {
598             NETMANAGER_EXT_LOGE("params protocol invalid");
599             return FIREWALL_ERR_INVALID_PARAMETER;
600         }
601     }
602     if (propertyName == NET_FIREWALL_USER_ID) {
603         return value < 0 ? FIREWALL_ERR_INVALID_PARAMETER : FIREWALL_SUCCESS;
604     }
605     return FIREWALL_SUCCESS;
606 }
607 } // namespace NetManagerStandard
608 } // namespace OHOS