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_service.h"
20#include "ipc_skeleton.h"
21#include "bundle_constants.h"
22#include "iremote_object.h"
23#include "net_event_report.h"
24#include "net_manager_center.h"
25#include "net_manager_constants.h"
26#include "net_manager_ext_constants.h"
27#include "netfirewall_default_rule_parser.h"
28#include "netfirewall_db_helper.h"
29#include "netfirewall_hisysevent.h"
30#include "netmanager_base_common_utils.h"
31#include "netmanager_base_permission.h"
32#include "netmanager_hitrace.h"
33#include "netmgr_ext_log_wrapper.h"
34#include "system_ability_definition.h"
35#include "netsys_controller.h"
36#include "netfirewall_intercept_recorder.h"
37
38namespace OHOS {
39namespace NetManagerStandard {
40constexpr int64_t QUERY_USER_ID_DELAY_TIME_MS = 300L;
41constexpr int32_t QUERY_USER_MAX_RETRY_TIMES = 100;
42
43namespace {
44const std::string PUSH_RESULT_SUCCESS = "Success";
45const std::string PUSH_RESULT_FAILD = "Faild";
46const std::string PUSH_RESULT_UNKONW = "Unkonw";
47} // namespace
48
49const bool REGISTER_LOCAL_RESULT_NETFIREWALL =
50    SystemAbility::MakeAndRegisterAbility(DelayedSingleton<NetFirewallService>::GetInstance().get());
51
52std::shared_ptr<ffrt::queue> NetFirewallService::ffrtServiceHandler_;
53
54NetFirewallService::NetFirewallService() : SystemAbility(COMM_FIREWALL_MANAGER_SYS_ABILITY_ID, true)
55{
56    NETMGR_EXT_LOG_I("NetFirewallService()");
57}
58
59NetFirewallService::~NetFirewallService()
60{
61    NETMGR_EXT_LOG_I("~NetFirewallService()");
62}
63
64void NetFirewallService::SetCurrentUserId(int32_t userId)
65{
66    currentUserId_ = userId;
67    NetFirewallPolicyManager::GetInstance().SetCurrentUserId(currentUserId_);
68    NetFirewallInterceptRecorder::GetInstance()->SetCurrentUserId(currentUserId_);
69    // set current userid to native
70    NetFirewallRuleNativeHelper::GetInstance().SetCurrentUserId(currentUserId_);
71}
72
73int32_t NetFirewallService::GetCurrentAccountId()
74{
75    std::vector<int32_t> accountIds;
76    auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(accountIds);
77    if (ret != ERR_OK || accountIds.empty()) {
78        NETMGR_EXT_LOG_E("query active user failed errCode=%{public}d", ret);
79        return FIREWALL_ERR_INTERNAL;
80    }
81    SetCurrentUserId(accountIds.front());
82    return currentUserId_;
83}
84
85/**
86 * Turn on or off the firewall
87 *
88 * @param userId User id
89 * @param policy The firewall status to be set
90 * @return Returns 0 success. Otherwise fail
91 */
92int32_t NetFirewallService::SetNetFirewallPolicy(const int32_t userId, const sptr<NetFirewallPolicy> &policy)
93{
94    NETMGR_EXT_LOG_I("SetNetFirewallPolicy userId=%{public}d isOpen= %{public}d, inAction=%{public}d", userId,
95        policy->isOpen, policy->inAction);
96    int32_t ret = CheckUserExist(userId);
97    if (ret != FIREWALL_SUCCESS) {
98        return ret;
99    }
100    ret = NetFirewallPolicyManager::GetInstance().SetNetFirewallPolicy(userId, policy);
101    if (ret != FIREWALL_SUCCESS) {
102        return ret;
103    }
104
105    if (userId == currentUserId_) {
106        // If the firewall switch status of the current user has changed, determine whether to issue it
107        if (NetFirewallPolicyManager::GetInstance().IsFirewallStatusChange(policy)) {
108            // netfirewall rules to native
109            NetFirewallRuleManager::GetInstance().OpenOrCloseNativeFirewall(policy->isOpen);
110        }
111        if (NetFirewallPolicyManager::GetInstance().IsFirewallActionChange(policy)) {
112            NetsysController::GetInstance().SetFirewallDefaultAction(policy->inAction, policy->outAction);
113        }
114        NetFirewallPolicyManager::GetInstance().SetCurrentUserFirewallPolicy(policy);
115    }
116
117    return ret;
118}
119
120/**
121 * Query firewall status
122 *
123 * @param userId User id
124 * @param status status of user userId
125 * @return Returns 0 success. Otherwise fail
126 */
127int32_t NetFirewallService::GetNetFirewallPolicy(const int32_t userId, sptr<NetFirewallPolicy> &policy)
128{
129    NETMGR_EXT_LOG_I("GetNetFirewallPolicy");
130    int32_t ret = CheckUserExist(userId);
131    if (ret != FIREWALL_SUCCESS) {
132        return ret;
133    }
134    NetFirewallPolicyManager::GetInstance().GetNetFirewallPolicy(userId, policy);
135    return FIREWALL_SUCCESS;
136}
137
138int32_t NetFirewallService::AddNetFirewallRule(const sptr<NetFirewallRule> &rule, int32_t &ruleId)
139{
140    return NetFirewallRuleManager::GetInstance().AddNetFirewallRule(rule, ruleId);
141}
142
143int32_t NetFirewallService::AddDefaultNetFirewallRule(int32_t userId)
144{
145    return NetFirewallRuleManager::GetInstance().AddDefaultNetFirewallRule(userId);
146}
147
148int32_t NetFirewallService::UpdateNetFirewallRule(const sptr<NetFirewallRule> &rule)
149{
150    return NetFirewallRuleManager::GetInstance().UpdateNetFirewallRule(rule);
151}
152
153int32_t NetFirewallService::DeleteNetFirewallRule(const int32_t userId, const int32_t ruleId)
154{
155    return NetFirewallRuleManager::GetInstance().DeleteNetFirewallRule(userId, ruleId);
156}
157
158int32_t NetFirewallService::GetNetFirewallRules(const int32_t userId, const sptr<RequestParam> &requestParam,
159    sptr<FirewallRulePage> &info)
160{
161    return NetFirewallRuleManager::GetInstance().GetNetFirewallRules(userId, requestParam, info);
162}
163
164int32_t NetFirewallService::GetNetFirewallRule(const int32_t userId, const int32_t ruleId, sptr<NetFirewallRule> &rule)
165{
166    return NetFirewallRuleManager::GetInstance().GetNetFirewallRule(userId, ruleId, rule);
167}
168
169int32_t NetFirewallService::GetInterceptRecords(const int32_t userId, const sptr<RequestParam> &requestParam,
170    sptr<InterceptRecordPage> &info)
171{
172    NETMGR_EXT_LOG_I("GetInterceptRecords");
173    int32_t ret = CheckUserExist(userId);
174    if (ret != FIREWALL_SUCCESS) {
175        return ret;
176    }
177    // Cache data writing to avoid not being able to access new data
178    NetFirewallInterceptRecorder::GetInstance()->SyncRecordCache();
179    return NetFirewallInterceptRecorder::GetInstance()->GetInterceptRecords(userId, requestParam, info);
180}
181
182int32_t NetFirewallService::CheckUserExist(const int32_t userId)
183{
184    AccountSA::OsAccountInfo accountInfo;
185    if (AccountSA::OsAccountManager::QueryOsAccountById(userId, accountInfo) != ERR_OK) {
186        NETMGR_EXT_LOG_E("QueryOsAccountById error, userId: %{public}d.", userId);
187        return FIREWALL_ERR_NO_USER;
188    }
189    return FIREWALL_SUCCESS;
190}
191
192int32_t NetFirewallService::Dump(int32_t fd, const std::vector<std::u16string> &args)
193{
194    std::string result;
195    GetDumpMessage(result);
196    NETMGR_EXT_LOG_I("NetFirewall dump fd: %{public}d, content: %{public}s", fd, result.c_str());
197    int32_t ret = dprintf(fd, "%s\n", result.c_str());
198    if (ret < 0) {
199        NETMGR_EXT_LOG_E("dprintf failed, errno[%{public}d]", errno);
200        return FIREWALL_ERR_INTERNAL;
201    }
202    return FIREWALL_SUCCESS;
203}
204
205void NetFirewallService::GetDumpMessage(std::string &message)
206{
207    message.append("NetFirewall Info:\n");
208    message.append("\tServiceRunningState: " + GetServiceState() + "\n");
209    message.append("\tSpendTimeMSec: " + std::to_string(serviceSpendTime_) + "ms" + "\n");
210    std::map<int32_t, bool> firewallStateMap;
211    GetAllUserFirewallState(firewallStateMap);
212    message.append("\t");
213    for (const auto &pair : firewallStateMap) {
214        std::string userId = std::to_string(pair.first);
215        std::string state = pair.second ? "Enable" : "Disable";
216        message.append("UserId: " + userId + " " + state + ", ");
217    }
218    message.append("\n");
219    message.append("\tLastRulePushTime: " + GetLastRulePushTime() + "\n");
220    message.append("\tLastRulePushResult: " + GetLastRulePushResult() + "\n");
221}
222
223std::string NetFirewallService::GetServiceState()
224{
225    return (state_ == ServiceRunningState::STATE_RUNNING) ? "Running" : "Stop";
226}
227
228std::string NetFirewallService::GetLastRulePushTime()
229{
230    currentSetRuleSecond_ = NetFirewallRuleManager::GetInstance().GetCurrentSetRuleSecond();
231    if (currentSetRuleSecond_ == 0) {
232        return PUSH_RESULT_UNKONW;
233    }
234    return std::to_string(currentSetRuleSecond_);
235}
236
237std::string NetFirewallService::GetLastRulePushResult()
238{
239    lastRulePushResult_ = NetFirewallRuleManager::GetInstance().GetLastRulePushResult();
240    if (lastRulePushResult_ == FIREWALL_SUCCESS) {
241        return PUSH_RESULT_SUCCESS;
242    }
243    if (lastRulePushResult_ < 0) {
244        return PUSH_RESULT_UNKONW;
245    }
246    return PUSH_RESULT_FAILD;
247}
248
249int32_t NetFirewallService::GetAllUserFirewallState(std::map<int32_t, bool> &firewallStateMap)
250{
251    std::vector<AccountSA::OsAccountInfo> osAccountInfos;
252    AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos);
253    size_t size = osAccountInfos.size();
254    for (const auto &info : osAccountInfos) {
255        int32_t userId = info.GetLocalId();
256        firewallStateMap[userId] = NetFirewallPolicyManager::GetInstance().IsNetFirewallOpen(userId);
257    }
258    return FIREWALL_SUCCESS;
259}
260
261void NetFirewallService::OnStart()
262{
263    NETMGR_EXT_LOG_I("OnStart()");
264    uint64_t startServiceTime = GetCurrentMilliseconds();
265    if (state_ == ServiceRunningState::STATE_RUNNING) {
266        NETMGR_EXT_LOG_I("PcfirewallService is already running.");
267        return;
268    }
269
270    if (!REGISTER_LOCAL_RESULT_NETFIREWALL) {
271        NETMGR_EXT_LOG_E("Register to local sa manager failed");
272        return;
273    }
274    if (!isServicePublished_) {
275        if (!Publish(DelayedSingleton<NetFirewallService>::GetInstance().get())) {
276            NETMGR_EXT_LOG_E("Register to sa manager failed");
277            return;
278        }
279        isServicePublished_ = true;
280    }
281
282    state_ = ServiceRunningState::STATE_RUNNING;
283
284    AddSystemAbilityListener(COMM_NETSYS_NATIVE_SYS_ABILITY_ID);
285    AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
286    if (OnInit() != FIREWALL_SUCCESS) {
287        NETMGR_EXT_LOG_E("Init data failed");
288        return;
289    }
290    serviceSpendTime_ = GetCurrentMilliseconds() - startServiceTime;
291}
292
293int32_t NetFirewallService::OnInit()
294{
295    InitServiceHandler();
296    InitQueryUserId(QUERY_USER_MAX_RETRY_TIMES);
297    SubscribeCommonEvent();
298    NetFirewallInterceptRecorder::GetInstance()->RegisterInterceptCallback();
299    return FIREWALL_SUCCESS;
300}
301
302void NetFirewallService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
303{
304    NETMGR_EXT_LOG_I("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
305    if (systemAbilityId == COMM_NETSYS_NATIVE_SYS_ABILITY_ID) {
306        if (hasSaRemoved_) {
307            NETMGR_EXT_LOG_I("native reboot, reset firewall rules.");
308            NetFirewallRuleManager::GetInstance().OpenOrCloseNativeFirewall(
309                NetFirewallPolicyManager::GetInstance().IsCurrentFirewallOpen());
310            NetFirewallInterceptRecorder::GetInstance()->RegisterInterceptCallback();
311            hasSaRemoved_ = false;
312        }
313        // After the universal service is launched, you can register for broadcast monitoring
314    } else if (systemAbilityId == COMMON_EVENT_SERVICE_ID && subscriber_ != nullptr) {
315        RegisterSubscribeCommonEvent();
316    }
317}
318
319bool NetFirewallService::InitUsersOnBoot()
320{
321    std::vector<int32_t> userIds;
322    if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds) != ERR_OK || userIds.empty()) {
323        NETMGR_EXT_LOG_E("PcfirewallService: failed to get current userIds");
324        return false;
325    }
326    SetCurrentUserId(userIds.front());
327    NETMGR_EXT_LOG_I("PcfirewallService::get current userIds success, Current userId: %{public}d",
328        currentUserId_.load());
329    InitQueryNetFirewallRules();
330    return true;
331}
332
333void NetFirewallService::InitQueryUserId(int32_t times)
334{
335    times--;
336    bool ret = InitUsersOnBoot();
337    if (!ret && times > 0) {
338        NETMGR_EXT_LOG_I("InitQueryUserId failed");
339        ffrtServiceHandler_->submit([this, times]() { InitQueryUserId(times); },
340            ffrt::task_attr().delay(QUERY_USER_ID_DELAY_TIME_MS).name("InitQueryUserId"));
341    }
342}
343
344void NetFirewallService::InitQueryNetFirewallRules()
345{
346    NetFirewallRuleManager::GetInstance().OpenOrCloseNativeFirewall(
347        NetFirewallPolicyManager::GetInstance().IsCurrentFirewallOpen());
348}
349
350void NetFirewallService::InitServiceHandler()
351{
352    if (ffrtServiceHandler_ != nullptr) {
353        NETMGR_EXT_LOG_E("InitServiceHandler already init.");
354        return;
355    }
356    ffrtServiceHandler_ =
357        std::make_shared<ffrt::queue>("NetFirewallService", ffrt::queue_attr().qos(ffrt::qos_utility));
358    NETMGR_EXT_LOG_I("InitServiceHandler succeeded.");
359}
360
361void NetFirewallService::OnStop()
362{
363    if (state_ != ServiceRunningState::STATE_RUNNING) {
364        return;
365    }
366    NetFirewallInterceptRecorder::GetInstance()->SyncRecordCache();
367    ffrtServiceHandler_.reset();
368    ffrtServiceHandler_ = nullptr;
369    if (subscriber_ != nullptr) {
370        bool unSubscribeResult = OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
371        subscriber_ = nullptr;
372        NETMGR_EXT_LOG_I("UnregisterSubscriber end, unSubscribeResult = %{public}d", unSubscribeResult);
373    }
374    NetFirewallInterceptRecorder::GetInstance()->UnRegisterInterceptCallback();
375    state_ = ServiceRunningState::STATE_NOT_START;
376    NETMGR_EXT_LOG_I("OnStop end.");
377}
378
379void NetFirewallService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
380{
381    NETMGR_EXT_LOG_I("OnRemoveSystemAbility systemAbilityId:%{public}d removed!", systemAbilityId);
382    if (systemAbilityId == COMM_NETSYS_NATIVE_SYS_ABILITY_ID) {
383        hasSaRemoved_ = true;
384    } else if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
385        OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
386        subscriber_ = nullptr;
387    }
388}
389
390void NetFirewallService::SubscribeCommonEvent()
391{
392    EventFwk::MatchingSkills matchingSkills;
393    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
394    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
395    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
396    EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
397    // 1 means CORE_EVENT_PRIORITY
398    subscribeInfo.SetPriority(1);
399    subscriber_ = std::make_shared<ReceiveMessage>(subscribeInfo, shared_from_this());
400    RegisterSubscribeCommonEvent();
401}
402
403void NetFirewallService::RegisterSubscribeCommonEvent()
404{
405    // If the universal service has not been loaded yet, registering for broadcasting will fail
406    if (!EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_)) {
407        NETMGR_EXT_LOG_E("SubscribeCommonEvent fail");
408        subscriber_ = nullptr;
409    }
410}
411
412void NetFirewallService::ReceiveMessage::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
413{
414    const auto &action = eventData.GetWant().GetAction();
415    const auto &data = eventData.GetData();
416    const auto &code = eventData.GetCode();
417    NETMGR_EXT_LOG_I("NetVReceiveMessage::OnReceiveEvent(), event:[%{public}s], data:[%{public}s], code:[%{public}d]",
418        action.c_str(), data.c_str(), code);
419    int32_t userId = code;
420    if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED) {
421        NetFirewallRuleManager::GetInstance().DeleteNetFirewallRuleByUserId(userId);
422        NetFirewallPolicyManager::GetInstance().ClearFirewallPolicy(userId);
423        NetFirewallDbHelper::GetInstance().DeleteInterceptRecord(userId);
424        NetFirewallRuleManager::GetInstance().DeleteUserRuleSize(userId);
425        return;
426    }
427    if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
428        // Old user cache cleaning
429        NetFirewallInterceptRecorder::GetInstance()->SyncRecordCache();
430        NetFirewallPolicyManager::GetInstance().ClearCurrentFirewallPolicy();
431        netfirewallService_->SetCurrentUserId(userId);
432        // Old user native bpf cleaning
433        NetFirewallRuleNativeHelper::GetInstance().ClearFirewallRules(NetFirewallRuleType::RULE_ALL);
434        NetFirewallRuleManager::GetInstance().OpenOrCloseNativeFirewall(
435            NetFirewallPolicyManager::GetInstance().IsCurrentFirewallOpen());
436        return;
437    }
438    if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
439        if (eventData.GetWant().GetIntParam(AppExecFwk::Constants::UID, 0) < 0) {
440            NETMGR_EXT_LOG_E("error:deletedUid < 0!,return");
441            return;
442        }
443        uint32_t deletedUid = static_cast<uint32_t>(eventData.GetWant().GetIntParam(AppExecFwk::Constants::UID, 0));
444        NETMGR_EXT_LOG_I("NetFirewallService: deletedUid %{public}d", deletedUid);
445        NetFirewallRuleManager::GetInstance().DeleteNetFirewallRuleByAppId(deletedUid);
446    }
447}
448} // namespace NetManagerStandard
449} // namespace OHOS
450