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 <sys/socket.h>
17 #include <sys/types.h>
18 
19 #include "netfirewall_rule_native_helper.h"
20 #include "net_manager_constants.h"
21 #include "netfirewall_db_helper.h"
22 #include "netmgr_ext_log_wrapper.h"
23 #include "netfirewall_rule_manager.h"
24 #include "netfirewall_policy_manager.h"
25 #include "netfirewall_default_rule_parser.h"
26 #include "netmanager_hitrace.h"
27 #include "os_account_manager.h"
28 
29 
30 namespace OHOS {
31 namespace NetManagerStandard {
GetInstance()32 NetFirewallRuleManager &NetFirewallRuleManager::GetInstance()
33 {
34     static NetFirewallRuleManager instance;
35     return instance;
36 }
37 
NetFirewallRuleManager()38 NetFirewallRuleManager::NetFirewallRuleManager()
39 {
40     NETMGR_EXT_LOG_I("NetFirewallRuleManager()");
41 }
42 
~NetFirewallRuleManager()43 NetFirewallRuleManager::~NetFirewallRuleManager()
44 {
45     NETMGR_EXT_LOG_I("~NetFirewallRuleManager()");
46 }
47 
AddNetFirewallRule(const sptr<NetFirewallRule> & rule,int32_t & ruleId)48 int32_t NetFirewallRuleManager::AddNetFirewallRule(const sptr<NetFirewallRule> &rule, int32_t &ruleId)
49 {
50     if (rule == nullptr) {
51         NETMGR_EXT_LOG_E("AddNetFirewallRule rule is null");
52         return FIREWALL_ERR_PARAMETER_ERROR;
53     }
54     return AddNetFirewallRule(rule, true, ruleId);
55 }
56 
AddNetFirewallRule(const sptr<NetFirewallRule> & rule,bool isNotify,int32_t & ruleId)57 int32_t NetFirewallRuleManager::AddNetFirewallRule(const sptr<NetFirewallRule> &rule, bool isNotify, int32_t &ruleId)
58 {
59     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
60     int32_t ret = CheckRuleConstraint(rule);
61     if (ret != FIREWALL_OK) {
62         NETMGR_EXT_LOG_E("addNetFirewallRule error code=%{public}d", ret);
63     } else {
64         ruleId = NetFirewallDbHelper::GetInstance().AddFirewallRuleRecord(*rule);
65         NETMGR_EXT_LOG_I("AddNetFirewallRule:: dbRuleId: %{public}d.", ruleId);
66         if (ruleId < 0) {
67             ret = FIREWALL_ERR_INTERNAL;
68         } else {
69             allUserRule_++;
70             UpdateUserRuleSize(rule->userId, true);
71         }
72     }
73     if (ret == FIREWALL_OK && isNotify && rule->isEnabled) {
74         ret = DistributeRulesToNative(rule->ruleType);
75     }
76     return ret;
77 }
78 
AddDefaultNetFirewallRule(int32_t userId)79 int32_t NetFirewallRuleManager::AddDefaultNetFirewallRule(int32_t userId)
80 {
81     if (!userRuleSize_.empty() && userRuleSize_.count(userId) && userRuleSize_.at(userId) > 0) {
82         NETMGR_EXT_LOG_W("AddDefaultNetFirewallRule , current user rule is exist.");
83         return 0;
84     }
85     std::vector<sptr<NetFirewallRule>> rules;
86     NetFirewallDefaultRuleParser::GetDefaultRules(rules);
87     if (rules.empty()) {
88         return FIREWALL_SUCCESS;
89     }
90     maxDefaultRuleSize_ = rules.size();
91 
92     int32_t ret = FIREWALL_OK;
93     int32_t ruleId = 0;
94     for (const auto &rule : rules) {
95         ret = AddNetFirewallRule(rule, false, ruleId);
96         if (ret != FIREWALL_SUCCESS) {
97             NETMGR_EXT_LOG_W("AddDefaultNetFirewallRule error, ret=%{public}d", ret);
98             return ret;
99         }
100     }
101     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
102     return DistributeRulesToNative();
103 }
104 
UpdateNetFirewallRule(const sptr<NetFirewallRule> & rule)105 int32_t NetFirewallRuleManager::UpdateNetFirewallRule(const sptr<NetFirewallRule> &rule)
106 {
107     if (rule == nullptr) {
108         NETMGR_EXT_LOG_E("UpdateNetFirewallRule rule is null");
109         return FIREWALL_ERR_PARAMETER_ERROR;
110     }
111     NETMGR_EXT_LOG_I("UpdateNetFirewallRule");
112     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
113     NetFirewallRule oldRule;
114     int32_t ret = CheckRuleConstraint(rule);
115     if (ret == FIREWALL_SUCCESS) {
116         ret = CheckRuleExist(rule->ruleId, oldRule);
117         if (ret == FIREWALL_SUCCESS) {
118             ret = NetFirewallDbHelper::GetInstance().UpdateFirewallRuleRecord(*rule);
119         }
120     }
121     if (ret != FIREWALL_SUCCESS) {
122         return ret;
123     }
124     if (oldRule.ruleId <= 0 || (!oldRule.isEnabled && !rule->isEnabled)) {
125         return FIREWALL_SUCCESS;
126     }
127     if (oldRule.isEnabled && (rule->ruleType != oldRule.ruleType || !rule->isEnabled)) {
128         ret = DistributeRulesToNative(oldRule.ruleType);
129     }
130     if (rule->isEnabled) {
131         ret += DistributeRulesToNative(rule->ruleType);
132     }
133     return ret;
134 }
135 
DeleteNetFirewallRule(const int32_t userId,const int32_t ruleId)136 int32_t NetFirewallRuleManager::DeleteNetFirewallRule(const int32_t userId, const int32_t ruleId)
137 {
138     NETMGR_EXT_LOG_I("DeleteNetFirewallRule");
139     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
140     int32_t ret = CheckUserExist(userId);
141     if (ret != FIREWALL_SUCCESS) {
142         return ret;
143     }
144 
145     NetFirewallRule oldRule;
146     ret = CheckRuleExist(ruleId, oldRule);
147     if (ret != FIREWALL_SUCCESS) {
148         return ret;
149     }
150     ret = NetFirewallDbHelper::GetInstance().DeleteFirewallRuleRecord(userId, ruleId);
151     if (ret != FIREWALL_SUCCESS) {
152         NETMGR_EXT_LOG_E("DeleteFirewallRuleRecord error");
153         return FIREWALL_ERR_INTERNAL;
154     }
155     allUserRule_--;
156     if (oldRule.ruleId > 0) {
157         UpdateUserRuleSize(userId, false);
158     }
159     if (oldRule.ruleId <= 0 || !oldRule.isEnabled) {
160         return FIREWALL_SUCCESS;
161     }
162     return DistributeRulesToNative(oldRule.ruleType);
163 }
164 
DeleteNetFirewallRuleByUserId(const int32_t userId)165 int32_t NetFirewallRuleManager::DeleteNetFirewallRuleByUserId(const int32_t userId)
166 {
167     NETMGR_EXT_LOG_I("DeleteNetFirewallRule");
168     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
169     int32_t ret = NetFirewallDbHelper::GetInstance().DeleteFirewallRuleRecordByUserId(userId);
170     if (ret != FIREWALL_SUCCESS) {
171         NETMGR_EXT_LOG_E("DeleteFirewallRuleRecord error");
172         return FIREWALL_ERR_INTERNAL;
173     }
174     // reset
175     allUserRule_ = userRuleSize_.count(userId) ? (allUserRule_ - userRuleSize_.at(userId)) : 0;
176     DeleteUserRuleSize(userId);
177     return FIREWALL_SUCCESS;
178 }
179 
DeleteNetFirewallRuleByAppId(const int32_t appUid)180 int32_t NetFirewallRuleManager::DeleteNetFirewallRuleByAppId(const int32_t appUid)
181 {
182     NETMGR_EXT_LOG_I("DeleteNetFirewallRuleByAppId");
183     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
184     std::vector<NetFirewallRule> rules;
185     NetFirewallDbHelper::GetInstance().QueryEnabledFirewallRules(GetCurrentAccountId(), appUid, rules);
186     if (rules.empty()) {
187         NETMGR_EXT_LOG_I("DeleteNetFirewallRuleByAppId: current appUid has no rule");
188         return FIREWALL_SUCCESS;
189     }
190     int32_t ret = NetFirewallDbHelper::GetInstance().DeleteFirewallRuleRecordByAppId(appUid);
191     if (ret != FIREWALL_SUCCESS) {
192         NETMGR_EXT_LOG_E("DeleteNetFirewallRuleByAppId error");
193         return FIREWALL_ERR_INTERNAL;
194     }
195     allUserRule_ = 0;
196     userRuleSize_.clear();
197     bool hasEnabledIpRule = false;
198     bool hasEnabledDomainRule = false;
199     bool hasEnabledDnsRule = false;
200     for (const auto &rule : rules) {
201         if (!rule.isEnabled) {
202             continue;
203         }
204         if (rule.ruleType == NetFirewallRuleType::RULE_DNS) {
205             hasEnabledDnsRule = true;
206         } else if (rule.ruleType == NetFirewallRuleType::RULE_DOMAIN) {
207             hasEnabledDomainRule = true;
208         } else if (rule.ruleType == NetFirewallRuleType::RULE_IP) {
209             hasEnabledIpRule = true;
210         }
211     }
212     if (hasEnabledDnsRule) {
213         ret = DistributeRulesToNative(NetFirewallRuleType::RULE_DNS);
214     }
215     if (hasEnabledDomainRule) {
216         ret += DistributeRulesToNative(NetFirewallRuleType::RULE_DOMAIN);
217     }
218     if (hasEnabledIpRule) {
219         ret += DistributeRulesToNative(NetFirewallRuleType::RULE_IP);
220     }
221     return ret;
222 }
223 
GetEnabledNetFirewallRules(const int32_t userId,std::vector<NetFirewallRule> & ruleList,NetFirewallRuleType type)224 int32_t NetFirewallRuleManager::GetEnabledNetFirewallRules(const int32_t userId, std::vector<NetFirewallRule> &ruleList,
225     NetFirewallRuleType type)
226 {
227     NETMGR_EXT_LOG_I("GetEnabledNetFirewallRules:: type=%{public}d", static_cast<int32_t>(type));
228     int32_t ret = CheckUserExist(userId);
229     if (ret != FIREWALL_SUCCESS) {
230         return ret;
231     }
232     ret = NetFirewallDbHelper::GetInstance().QueryAllUserEnabledFirewallRules(ruleList, type);
233     if (ret < 0) {
234         NETMGR_EXT_LOG_E("GetEnabledNetFirewallRules error");
235         return FIREWALL_ERR_INTERNAL;
236     }
237     return FIREWALL_SUCCESS;
238 }
239 
GetNetFirewallRules(const int32_t userId,const sptr<RequestParam> & requestParam,sptr<FirewallRulePage> & info)240 int32_t NetFirewallRuleManager::GetNetFirewallRules(const int32_t userId, const sptr<RequestParam> &requestParam,
241     sptr<FirewallRulePage> &info)
242 {
243     if (requestParam == nullptr) {
244         NETMGR_EXT_LOG_E("GetNetFirewallRules requestParam is null");
245         return FIREWALL_ERR_PARAMETER_ERROR;
246     }
247     if (info == nullptr) {
248         NETMGR_EXT_LOG_E("GetNetFirewallRules info is null");
249         return FIREWALL_ERR_INTERNAL;
250     }
251     NETMGR_EXT_LOG_I("GetNetFirewallRules");
252     std::shared_lock<std::shared_mutex> locker(setFirewallRuleMutex_);
253     int32_t ret = CheckUserExist(userId);
254     if (ret != FIREWALL_SUCCESS) {
255         return ret;
256     }
257     info->page = requestParam->page;
258     info->pageSize = requestParam->pageSize;
259     ret = NetFirewallDbHelper::GetInstance().QueryFirewallRule(userId, requestParam, info);
260     if (ret < 0) {
261         NETMGR_EXT_LOG_E("QueryAllFirewallRuleRecord error");
262         return FIREWALL_ERR_INTERNAL;
263     }
264     return FIREWALL_SUCCESS;
265 }
266 
GetNetFirewallRule(const int32_t userId,const int32_t ruleId,sptr<NetFirewallRule> & rule)267 int32_t NetFirewallRuleManager::GetNetFirewallRule(const int32_t userId, const int32_t ruleId,
268     sptr<NetFirewallRule> &rule)
269 {
270     if (rule == nullptr) {
271         NETMGR_EXT_LOG_E("GetNetFirewallRule rule is null");
272         return FIREWALL_ERR_INTERNAL;
273     }
274     NETMGR_EXT_LOG_I("GetNetFirewallRule userId=%{public}d ruleId=%{public}d", userId, ruleId);
275     std::shared_lock<std::shared_mutex> locker(setFirewallRuleMutex_);
276     int32_t ret = CheckUserExist(userId);
277     if (ret != FIREWALL_SUCCESS) {
278         return ret;
279     }
280 
281     std::vector<struct NetFirewallRule> outRules;
282     ret = NetFirewallDbHelper::GetInstance().QueryFirewallRuleRecord(ruleId, userId, outRules);
283     if (ret < 0) {
284         NETMGR_EXT_LOG_E("QueryFirewallRuleRecord error");
285         return FIREWALL_ERR_INTERNAL;
286     }
287     if (outRules.size() > 0) {
288         const NetFirewallRule &outRule = outRules[0];
289         rule->userId = outRule.userId;
290         rule->ruleId = outRule.ruleId;
291         rule->ruleName = outRule.ruleName;
292         rule->ruleDescription = outRule.ruleDescription;
293         rule->ruleAction = outRule.ruleAction;
294         rule->ruleDirection = outRule.ruleDirection;
295         rule->ruleType = outRule.ruleType;
296         rule->appUid = outRule.appUid;
297         rule->protocol = outRule.protocol;
298         rule->dns = outRule.dns;
299         rule->localIps.assign(outRule.localIps.begin(), outRule.localIps.end());
300         rule->remoteIps.assign(outRule.remoteIps.begin(), outRule.remoteIps.end());
301         rule->localPorts.assign(outRule.localPorts.begin(), outRule.localPorts.end());
302         rule->remotePorts.assign(outRule.remotePorts.begin(), outRule.remotePorts.end());
303     } else {
304         NETMGR_EXT_LOG_E("QueryFirewallRuleRecord size is 0");
305         return FIREWALL_ERR_NO_RULE;
306     }
307     return FIREWALL_SUCCESS;
308 }
309 
CheckUserExist(const int32_t userId)310 int32_t NetFirewallRuleManager::CheckUserExist(const int32_t userId)
311 {
312     AccountSA::OsAccountInfo accountInfo;
313     if (AccountSA::OsAccountManager::QueryOsAccountById(userId, accountInfo) != ERR_OK) {
314         NETMGR_EXT_LOG_E("QueryOsAccountById error, userId: %{public}d.", userId);
315         return FIREWALL_ERR_NO_USER;
316     }
317     return FIREWALL_SUCCESS;
318 }
319 
CheckRuleExist(const int32_t ruleId,NetFirewallRule & oldRule)320 int32_t NetFirewallRuleManager::CheckRuleExist(const int32_t ruleId, NetFirewallRule &oldRule)
321 {
322     bool isExist = NetFirewallDbHelper::GetInstance().IsFirewallRuleExist(ruleId, oldRule);
323     if (!isExist) {
324         NETMGR_EXT_LOG_E("Query ruleId: %{public}d is not exist.", ruleId);
325         return FIREWALL_ERR_NO_RULE;
326     }
327     return FIREWALL_SUCCESS;
328 }
329 
GetAllRuleConstraint(const int32_t userId)330 int32_t NetFirewallRuleManager::GetAllRuleConstraint(const int32_t userId)
331 {
332     int64_t rowCount = 0;
333     if (allUserRule_ <= 0) {
334         NetFirewallDbHelper::GetInstance().QueryFirewallRuleAllCount(rowCount);
335         allUserRule_ = rowCount;
336     }
337     if (!userRuleSize_.count(userId)) {
338         rowCount = 0;
339         NetFirewallDbHelper::GetInstance().QueryFirewallRuleByUserIdCount(userId, rowCount);
340         userRuleSize_.insert({ userId, rowCount });
341     }
342     allUserDomain_ = NetFirewallDbHelper::GetInstance().QueryFirewallRuleAllDomainCount();
343     NETMGR_EXT_LOG_I(
344         "GetAllRuleConstraint userId=%{public}d rowCount=%{public}d allUserRule=%{public}d allUserDomain=%{public}d",
345         userId, static_cast<int32_t>(userRuleSize_.at(userId)), static_cast<int32_t>(allUserRule_), allUserDomain_);
346     return FIREWALL_SUCCESS;
347 }
348 
CheckRuleConstraint(const sptr<NetFirewallRule> & rule)349 int32_t NetFirewallRuleManager::CheckRuleConstraint(const sptr<NetFirewallRule> &rule)
350 {
351     int32_t ret = CheckUserExist(rule->userId);
352     if (ret != FIREWALL_SUCCESS) {
353         return ret;
354     }
355     int32_t userId = rule->userId;
356     GetAllRuleConstraint(userId);
357     if (userRuleSize_.at(userId) < maxDefaultRuleSize_) {
358         NETMGR_EXT_LOG_I("current user db size is not max than default rule size, ignore check.");
359         return FIREWALL_SUCCESS;
360     }
361 
362     if (allUserRule_ + 1 > FIREWALL_ALL_USER_MAX_RULE || userRuleSize_.at(userId) + 1 > FIREWALL_USER_MAX_RULE) {
363         NETMGR_EXT_LOG_E("check rule constraint error, rule is large.");
364         return FIREWALL_ERR_EXCEED_MAX_RULE;
365     }
366     int32_t domainsCount = NetFirewallDbHelper::GetInstance().QueryFirewallRuleDomainByUserIdCount(userId);
367     size_t size = rule->domains.size();
368     if (domainsCount + size > FIREWALL_SINGLE_USER_MAX_DOMAIN) {
369         return FIREWALL_ERR_EXCEED_MAX_DOMAIN;
370     }
371     domainsCount = NetFirewallDbHelper::GetInstance().QueryFirewallRuleAllFuzzyDomainCount();
372     if (allUserDomain_ + size > FIREWALL_ALL_USER_MAX_DOMAIN ||
373         domainsCount + size > FIREWALL_ALL_USER_MAX_FUZZY_DOMAIN) {
374         NETMGR_EXT_LOG_E(
375             "check rule constraint domain number is more than max, all domain=%{public}d all fuzzy=%{public}d",
376             allUserDomain_, static_cast<int32_t>(domainsCount));
377         return FIREWALL_ERR_EXCEED_ALL_MAX_DOMAIN;
378     }
379     // DNS rule check duplicate
380     if (NetFirewallDbHelper::GetInstance().IsDnsRuleExist(rule)) {
381         NETMGR_EXT_LOG_E("check rule constraint, the dns rule is exist");
382         return FIREWALL_ERR_DNS_RULE_DUPLICATION;
383     }
384     return FIREWALL_SUCCESS;
385 }
386 
CheckAccountExist(int32_t userId)387 bool NetFirewallRuleManager::CheckAccountExist(int32_t userId)
388 {
389     AccountSA::OsAccountInfo accountInfo;
390     if (AccountSA::OsAccountManager::QueryOsAccountById(userId, accountInfo) != ERR_OK) {
391         NETMGR_EXT_LOG_E("QueryOsAccountById error, userId: %{public}d.", userId);
392         return false;
393     }
394 
395     if (accountInfo.GetType() == AccountSA::OsAccountType::GUEST) {
396         NETMGR_EXT_LOG_W("The guest account.");
397     }
398     return true;
399 }
400 
ExtractIpRules(const std::vector<NetFirewallRule> & rules,std::vector<sptr<NetFirewallIpRule>> & ipRules)401 bool NetFirewallRuleManager::ExtractIpRules(const std::vector<NetFirewallRule> &rules,
402     std::vector<sptr<NetFirewallIpRule>> &ipRules)
403 {
404     if (rules.empty()) {
405         return false;
406     }
407     for (const auto &rule : rules) {
408         if (rule.ruleType != NetFirewallRuleType::RULE_IP) {
409             continue;
410         }
411         sptr<NetFirewallIpRule> ipRule = new (std::nothrow) NetFirewallIpRule();
412         if (ipRule == nullptr) {
413             NETMGR_EXT_LOG_E("ExtractIpRules ipRule is null");
414             return false;
415         }
416         ipRule->userId = rule.userId;
417         ipRule->ruleDirection = rule.ruleDirection;
418         ipRule->ruleAction = rule.ruleAction;
419         ipRule->appUid = rule.appUid;
420         ipRule->localIps = rule.localIps;
421         ipRule->remoteIps = rule.remoteIps;
422         ipRule->protocol = rule.protocol;
423         ipRule->localPorts = rule.localPorts;
424         ipRule->remotePorts = rule.remotePorts;
425         ipRules.emplace_back(std::move(ipRule));
426     }
427     return ipRules.size() > 0;
428 }
429 
ExtractDomainRules(const std::vector<NetFirewallRule> & rules,std::vector<sptr<NetFirewallDomainRule>> & domainRules)430 bool NetFirewallRuleManager::ExtractDomainRules(const std::vector<NetFirewallRule> &rules,
431     std::vector<sptr<NetFirewallDomainRule>> &domainRules)
432 {
433     if (rules.empty()) {
434         return false;
435     }
436     for (const auto &rule : rules) {
437         if (rule.ruleType != NetFirewallRuleType::RULE_DOMAIN) {
438             continue;
439         }
440         sptr<NetFirewallDomainRule> domainRule = new (std::nothrow) NetFirewallDomainRule();
441         if (domainRule == nullptr) {
442             NETMGR_EXT_LOG_E("ExtractDomainRules domainRule is null");
443             return false;
444         }
445         domainRule->userId = rule.userId;
446         domainRule->appUid = rule.appUid;
447         domainRule->ruleAction = rule.ruleAction;
448         domainRule->domains = rule.domains;
449         domainRules.emplace_back(std::move(domainRule));
450     }
451     return domainRules.size() > 0;
452 }
453 
ExtractDnsRules(const std::vector<NetFirewallRule> & rules,std::vector<sptr<NetFirewallDnsRule>> & dnsRules)454 bool NetFirewallRuleManager::ExtractDnsRules(const std::vector<NetFirewallRule> &rules,
455     std::vector<sptr<NetFirewallDnsRule>> &dnsRules)
456 {
457     if (rules.empty()) {
458         return false;
459     }
460     for (const auto &rule : rules) {
461         if (rule.ruleType != NetFirewallRuleType::RULE_DNS) {
462             continue;
463         }
464         sptr<NetFirewallDnsRule> dnsRule = new (std::nothrow) NetFirewallDnsRule();
465         if (dnsRule == nullptr) {
466             NETMGR_EXT_LOG_E("ExtractDnsRules dnsRule is null");
467             return false;
468         }
469         dnsRule->userId = rule.userId;
470         dnsRule->appUid = rule.appUid;
471         dnsRule->primaryDns = rule.dns.primaryDns;
472         dnsRule->standbyDns = rule.dns.standbyDns;
473         dnsRules.emplace_back(std::move(dnsRule));
474     }
475     return dnsRules.size() > 0;
476 }
477 
HandleIpTypeForDistributeRules(std::vector<NetFirewallRule> & rules)478 int32_t NetFirewallRuleManager::HandleIpTypeForDistributeRules(std::vector<NetFirewallRule> &rules)
479 {
480     std::vector<sptr<NetFirewallIpRule>> ipRules;
481     if (ExtractIpRules(rules, ipRules)) {
482         NetFirewallRuleNativeHelper::GetInstance().SetFirewallIpRules(ipRules);
483     } else {
484         NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_IP);
485     }
486     return FIREWALL_SUCCESS;
487 }
488 
HandleDnsTypeForDistributeRules(std::vector<NetFirewallRule> & rules)489 int32_t NetFirewallRuleManager::HandleDnsTypeForDistributeRules(std::vector<NetFirewallRule> &rules)
490 {
491     std::vector<sptr<NetFirewallDnsRule>> dnsRules;
492     if (ExtractDnsRules(rules, dnsRules)) {
493         NetFirewallRuleNativeHelper::GetInstance().SetFirewallDnsRules(dnsRules);
494     } else {
495         NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_DNS);
496     }
497     return FIREWALL_SUCCESS;
498 }
499 
HandleDomainTypeForDistributeRules(std::vector<NetFirewallRule> & rules)500 int32_t NetFirewallRuleManager::HandleDomainTypeForDistributeRules(std::vector<NetFirewallRule> &rules)
501 {
502     std::vector<sptr<NetFirewallDomainRule>> domainRules;
503     if (ExtractDomainRules(rules, domainRules)) {
504         NetFirewallRuleNativeHelper::GetInstance().SetFirewallDomainRules(domainRules);
505     } else {
506         NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_DOMAIN);
507     }
508     return FIREWALL_SUCCESS;
509 }
510 
GetCurrentAccountId()511 int32_t NetFirewallRuleManager::GetCurrentAccountId()
512 {
513     std::vector<int32_t> accountIds;
514     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(accountIds);
515     if (ret != ERR_OK || accountIds.empty()) {
516         NETMGR_EXT_LOG_E("query active user failed errCode=%{public}d", ret);
517         return FIREWALL_ERR_INTERNAL;
518     }
519     return accountIds.front();
520 }
521 
OpenOrCloseNativeFirewall(bool isOpen)522 int32_t NetFirewallRuleManager::OpenOrCloseNativeFirewall(bool isOpen)
523 {
524     std::lock_guard<std::shared_mutex> locker(setFirewallRuleMutex_);
525     NETMGR_EXT_LOG_I("OpenOrCloseNativeFirewall: isOpen=%{public}d", isOpen);
526     NetmanagerHiTrace::NetmanagerStartSyncTrace("OpenOrCloseNativeFirewall");
527     auto userId = GetCurrentAccountId();
528     if (!isOpen) {
529         NETMGR_EXT_LOG_I("OpenOrCloseNativeFirewall: current userid %{public}d firewall disabled", userId);
530         NetFirewallRuleNativeHelper::GetInstance().SetFirewallDefaultAction(FirewallRuleAction::RULE_ALLOW,
531             FirewallRuleAction::RULE_ALLOW);
532         NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_ALL);
533         return FIREWALL_SUCCESS;
534     }
535 
536     NetFirewallRuleNativeHelper::GetInstance().SetFirewallDefaultAction(
537         NetFirewallPolicyManager::GetInstance().GetFirewallPolicyInAction(),
538         NetFirewallPolicyManager::GetInstance().GetFirewallPolicyOutAction());
539     int32_t ret = SetRulesToNativeByType(userId, NetFirewallRuleType::RULE_ALL);
540     SetNetFirewallDumpMessage(ret);
541     NetmanagerHiTrace::NetmanagerFinishSyncTrace("OpenOrCloseNativeFirewall");
542     return ret;
543 }
544 
DistributeRulesToNative(NetFirewallRuleType type)545 int32_t NetFirewallRuleManager::DistributeRulesToNative(NetFirewallRuleType type)
546 {
547     NETMGR_EXT_LOG_I("DistributeRulesToNative: type=%{public}d", (int)type);
548     NetmanagerHiTrace::NetmanagerStartSyncTrace("DistributeRulesToNative");
549     auto userId = GetCurrentAccountId();
550     if (!NetFirewallPolicyManager::GetInstance().IsCurrentFirewallOpen()) {
551         NETMGR_EXT_LOG_I("DistributeRulesToNative: current userid %{public}d firewall disabled", userId);
552         NetFirewallRuleNativeHelper::GetInstance().SetFirewallDefaultAction(FirewallRuleAction::RULE_ALLOW,
553             FirewallRuleAction::RULE_ALLOW);
554         NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_ALL);
555         return FIREWALL_SUCCESS;
556     }
557 
558     NetFirewallRuleNativeHelper::GetInstance().SetFirewallDefaultAction(
559         NetFirewallPolicyManager::GetInstance().GetFirewallPolicyInAction(),
560         NetFirewallPolicyManager::GetInstance().GetFirewallPolicyOutAction());
561     int32_t ret = SetRulesToNativeByType(userId, type);
562     NetmanagerHiTrace::NetmanagerFinishSyncTrace("DistributeRulesToNative");
563     SetNetFirewallDumpMessage(ret);
564     return ret;
565 }
566 
SetRulesToNativeByType(const int32_t userId,const NetFirewallRuleType type)567 int32_t NetFirewallRuleManager::SetRulesToNativeByType(const int32_t userId, const NetFirewallRuleType type)
568 {
569     int32_t ret = FIREWALL_SUCCESS;
570     std::vector<NetFirewallRule> rules;
571     GetEnabledNetFirewallRules(userId, rules, type);
572     switch (type) {
573         case NetFirewallRuleType::RULE_IP:
574             ret = HandleIpTypeForDistributeRules(rules);
575             break;
576         case NetFirewallRuleType::RULE_DNS:
577             ret = HandleDnsTypeForDistributeRules(rules);
578             break;
579         case NetFirewallRuleType::RULE_DOMAIN:
580             ret = HandleDomainTypeForDistributeRules(rules);
581             break;
582         case NetFirewallRuleType::RULE_ALL: {
583             if (rules.empty()) {
584                 break;
585             }
586             NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_ALL);
587             ret = HandleIpTypeForDistributeRules(rules);
588             ret += HandleDnsTypeForDistributeRules(rules);
589             ret += HandleDomainTypeForDistributeRules(rules);
590             break;
591         }
592         default:
593             break;
594     }
595     return ret;
596 }
597 
UpdateUserRuleSize(const int32_t userId,bool isInc)598 void NetFirewallRuleManager::UpdateUserRuleSize(const int32_t userId, bool isInc)
599 {
600     if (!userRuleSize_.count(userId)) {
601         return;
602     }
603     int64_t old = userRuleSize_.at(userId);
604     userRuleSize_.at(userId) = isInc ? (old + 1) : (old - 1);
605 }
606 
DeleteUserRuleSize(const int32_t userId)607 void NetFirewallRuleManager::DeleteUserRuleSize(const int32_t userId)
608 {
609     if (!userRuleSize_.empty() && userRuleSize_.count(userId)) {
610         userRuleSize_.erase(userId);
611     }
612 }
613 
SetNetFirewallDumpMessage(const int32_t result)614 void NetFirewallRuleManager::SetNetFirewallDumpMessage(const int32_t result)
615 {
616     if (result == FIREWALL_SUCCESS) {
617         currentSetRuleSecond_ = GetCurrentMilliseconds();
618     }
619     lastRulePushResult_ = result;
620 }
621 
GetCurrentSetRuleSecond()622 uint64_t NetFirewallRuleManager::GetCurrentSetRuleSecond()
623 {
624     return currentSetRuleSecond_;
625 }
626 
GetLastRulePushResult()627 int64_t NetFirewallRuleManager::GetLastRulePushResult()
628 {
629     return lastRulePushResult_;
630 }
631 } // namespace NetManagerStandard
632 } // namespace OHOS
633