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
30namespace OHOS {
31namespace NetManagerStandard {
32NetFirewallRuleManager &NetFirewallRuleManager::GetInstance()
33{
34    static NetFirewallRuleManager instance;
35    return instance;
36}
37
38NetFirewallRuleManager::NetFirewallRuleManager()
39{
40    NETMGR_EXT_LOG_I("NetFirewallRuleManager()");
41}
42
43NetFirewallRuleManager::~NetFirewallRuleManager()
44{
45    NETMGR_EXT_LOG_I("~NetFirewallRuleManager()");
46}
47
48int32_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
57int32_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
79int32_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_ = static_cast<int64_t>(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
105int32_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
136int32_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
165int32_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
180int32_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
224int32_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
240int32_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
267int32_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
310int32_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
320int32_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
330int32_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
349int32_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    int32_t size = static_cast<int32_t>(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
387bool 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
401bool 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
430bool 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
454bool 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
478int32_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
489int32_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
500int32_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
511int32_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
522int32_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
545int32_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
567int32_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
598void 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
607void NetFirewallRuleManager::DeleteUserRuleSize(const int32_t userId)
608{
609    if (!userRuleSize_.empty() && userRuleSize_.count(userId)) {
610        userRuleSize_.erase(userId);
611    }
612}
613
614void NetFirewallRuleManager::SetNetFirewallDumpMessage(const int32_t result)
615{
616    if (result == FIREWALL_SUCCESS) {
617        currentSetRuleSecond_ = GetCurrentMilliseconds();
618    }
619    lastRulePushResult_ = result;
620}
621
622uint64_t NetFirewallRuleManager::GetCurrentSetRuleSecond()
623{
624    return currentSetRuleSecond_;
625}
626
627int64_t NetFirewallRuleManager::GetLastRulePushResult()
628{
629    return lastRulePushResult_;
630}
631} // namespace NetManagerStandard
632} // namespace OHOS
633