1b1b8bc3fSopenharmony_ci/*
2b1b8bc3fSopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License.
5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at
6b1b8bc3fSopenharmony_ci *
7b1b8bc3fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b1b8bc3fSopenharmony_ci *
9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and
13b1b8bc3fSopenharmony_ci * limitations under the License.
14b1b8bc3fSopenharmony_ci */
15b1b8bc3fSopenharmony_ci
16b1b8bc3fSopenharmony_ci#include "firewall_manager.h"
17b1b8bc3fSopenharmony_ci
18b1b8bc3fSopenharmony_ci#include <fstream>
19b1b8bc3fSopenharmony_ci#include <sstream>
20b1b8bc3fSopenharmony_ci
21b1b8bc3fSopenharmony_ci#include "iptables_wrapper.h"
22b1b8bc3fSopenharmony_ci#include "net_manager_constants.h"
23b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h"
24b1b8bc3fSopenharmony_ci
25b1b8bc3fSopenharmony_cinamespace OHOS {
26b1b8bc3fSopenharmony_cinamespace nmd {
27b1b8bc3fSopenharmony_ciusing namespace NetManagerStandard;
28b1b8bc3fSopenharmony_cinamespace {
29b1b8bc3fSopenharmony_cistatic constexpr const char *CONFIG_FILE_PATH = "/proc/self/uid_map";
30b1b8bc3fSopenharmony_cibool SetFireWallCommand(const std::string &chainName, std::string command)
31b1b8bc3fSopenharmony_ci{
32b1b8bc3fSopenharmony_ci    bool ret = false;
33b1b8bc3fSopenharmony_ci    ret = ret ||
34b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
35b1b8bc3fSopenharmony_ci
36b1b8bc3fSopenharmony_ci    command = "-t filter -A " + chainName + " -i lo -j RETURN";
37b1b8bc3fSopenharmony_ci    ret = ret ||
38b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
39b1b8bc3fSopenharmony_ci    command = "-t filter -A " + chainName + " -o lo -j RETURN";
40b1b8bc3fSopenharmony_ci    ret = ret ||
41b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
42b1b8bc3fSopenharmony_ci    command = "-t filter -A " + chainName + " -p tcp --tcp-flags RST RST -j RETURN";
43b1b8bc3fSopenharmony_ci    ret = ret ||
44b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
45b1b8bc3fSopenharmony_ci    return ret;
46b1b8bc3fSopenharmony_ci}
47b1b8bc3fSopenharmony_ci} // namespace
48b1b8bc3fSopenharmony_ci
49b1b8bc3fSopenharmony_cistatic constexpr uint32_t SYSTEM_UID_RANGE = 9999;
50b1b8bc3fSopenharmony_cistatic constexpr uint32_t DEFAULT_MAX_UID_RANGE = UINT_MAX;
51b1b8bc3fSopenharmony_ciFirewallManager::FirewallManager() : chainInitFlag_(false), firewallType_(FirewallType::TYPE_ALLOWED_LIST)
52b1b8bc3fSopenharmony_ci{
53b1b8bc3fSopenharmony_ci    strMaxUid_ = ReadMaxUidConfig();
54b1b8bc3fSopenharmony_ci    FirewallChainStatus status = {};
55b1b8bc3fSopenharmony_ci    status.enable = false;
56b1b8bc3fSopenharmony_ci    status.type = FirewallType::TYPE_ALLOWED_LIST;
57b1b8bc3fSopenharmony_ci    firewallChainStatus_[ChainType::CHAIN_OHFW_DOZABLE] = status;
58b1b8bc3fSopenharmony_ci    firewallChainStatus_[ChainType::CHAIN_OHFW_POWERSAVING] = status;
59b1b8bc3fSopenharmony_ci    firewallChainStatus_[ChainType::CHAIN_OHFW_UNDOZABLE] = status;
60b1b8bc3fSopenharmony_ci    firewallChainStatus_[ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX] = status;
61b1b8bc3fSopenharmony_ci}
62b1b8bc3fSopenharmony_ci
63b1b8bc3fSopenharmony_ciFirewallManager::~FirewallManager()
64b1b8bc3fSopenharmony_ci{
65b1b8bc3fSopenharmony_ci    DeInitChain();
66b1b8bc3fSopenharmony_ci}
67b1b8bc3fSopenharmony_ci
68b1b8bc3fSopenharmony_ciinline void FirewallManager::CheckChainInitialization()
69b1b8bc3fSopenharmony_ci{
70b1b8bc3fSopenharmony_ci    if (chainInitFlag_ == false) {
71b1b8bc3fSopenharmony_ci        InitChain();
72b1b8bc3fSopenharmony_ci        InitDefaultRules();
73b1b8bc3fSopenharmony_ci    }
74b1b8bc3fSopenharmony_ci}
75b1b8bc3fSopenharmony_ci
76b1b8bc3fSopenharmony_cistd::string FirewallManager::ReadMaxUidConfig()
77b1b8bc3fSopenharmony_ci{
78b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("ReadMaxUidConfig");
79b1b8bc3fSopenharmony_ci    std::string maxUid;
80b1b8bc3fSopenharmony_ci    std::string content;
81b1b8bc3fSopenharmony_ci
82b1b8bc3fSopenharmony_ci    std::ifstream file(CONFIG_FILE_PATH);
83b1b8bc3fSopenharmony_ci    if (!file.is_open()) {
84b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("ReadMaxUidConfig fstream failed");
85b1b8bc3fSopenharmony_ci        return std::to_string(DEFAULT_MAX_UID_RANGE);
86b1b8bc3fSopenharmony_ci    }
87b1b8bc3fSopenharmony_ci
88b1b8bc3fSopenharmony_ci    std::ostringstream oss;
89b1b8bc3fSopenharmony_ci    oss << file.rdbuf();
90b1b8bc3fSopenharmony_ci    content = oss.str();
91b1b8bc3fSopenharmony_ci    auto index = content.find_last_of(' ');
92b1b8bc3fSopenharmony_ci    maxUid = content.substr(index + 1);
93b1b8bc3fSopenharmony_ci    // if unavailable value use default value
94b1b8bc3fSopenharmony_ci    if (maxUid.size() == 0) {
95b1b8bc3fSopenharmony_ci        return std::to_string(DEFAULT_MAX_UID_RANGE);
96b1b8bc3fSopenharmony_ci    }
97b1b8bc3fSopenharmony_ci
98b1b8bc3fSopenharmony_ci    return maxUid;
99b1b8bc3fSopenharmony_ci}
100b1b8bc3fSopenharmony_ci
101b1b8bc3fSopenharmony_ciint32_t FirewallManager::IsFirewallChian(ChainType chain)
102b1b8bc3fSopenharmony_ci{
103b1b8bc3fSopenharmony_ci    if (chain != ChainType::CHAIN_OHFW_DOZABLE && chain != ChainType::CHAIN_OHFW_POWERSAVING
104b1b8bc3fSopenharmony_ci        && chain != ChainType::CHAIN_OHFW_UNDOZABLE && chain != ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) {
105b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
106b1b8bc3fSopenharmony_ci    }
107b1b8bc3fSopenharmony_ci    return NETMANAGER_SUCCESS;
108b1b8bc3fSopenharmony_ci}
109b1b8bc3fSopenharmony_ci
110b1b8bc3fSopenharmony_cistd::string FirewallManager::FetchChainName(ChainType chain)
111b1b8bc3fSopenharmony_ci{
112b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager FetchChainName: chain=%{public}d", chain);
113b1b8bc3fSopenharmony_ci    std::string chainName;
114b1b8bc3fSopenharmony_ci    switch (chain) {
115b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_INPUT:
116b1b8bc3fSopenharmony_ci            chainName = "ohfw_INPUT";
117b1b8bc3fSopenharmony_ci            break;
118b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_OUTPUT:
119b1b8bc3fSopenharmony_ci            chainName = "ohfw_OUTPUT";
120b1b8bc3fSopenharmony_ci            break;
121b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_FORWARD:
122b1b8bc3fSopenharmony_ci            chainName = "ohfw_FORWARD";
123b1b8bc3fSopenharmony_ci            break;
124b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_DOZABLE:
125b1b8bc3fSopenharmony_ci            chainName = "ohfw_dozable";
126b1b8bc3fSopenharmony_ci            break;
127b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX:
128b1b8bc3fSopenharmony_ci            chainName = "ohfw_allowed_list_box";
129b1b8bc3fSopenharmony_ci            break;
130b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_POWERSAVING:
131b1b8bc3fSopenharmony_ci            chainName = "ohfw_powersaving";
132b1b8bc3fSopenharmony_ci            break;
133b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_UNDOZABLE:
134b1b8bc3fSopenharmony_ci            chainName = "ohfw_undozable";
135b1b8bc3fSopenharmony_ci            break;
136b1b8bc3fSopenharmony_ci        default:
137b1b8bc3fSopenharmony_ci            chainName = "oh_unusable";
138b1b8bc3fSopenharmony_ci            break;
139b1b8bc3fSopenharmony_ci    }
140b1b8bc3fSopenharmony_ci    return chainName;
141b1b8bc3fSopenharmony_ci}
142b1b8bc3fSopenharmony_ci
143b1b8bc3fSopenharmony_ciFirewallType FirewallManager::FetchChainType(ChainType chain)
144b1b8bc3fSopenharmony_ci{
145b1b8bc3fSopenharmony_ci    FirewallType firewallType;
146b1b8bc3fSopenharmony_ci    switch (chain) {
147b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_DOZABLE:
148b1b8bc3fSopenharmony_ci            firewallType = FirewallType::TYPE_ALLOWED_LIST;
149b1b8bc3fSopenharmony_ci            break;
150b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_POWERSAVING:
151b1b8bc3fSopenharmony_ci            firewallType = FirewallType::TYPE_ALLOWED_LIST;
152b1b8bc3fSopenharmony_ci            break;
153b1b8bc3fSopenharmony_ci        case ChainType::CHAIN_OHFW_UNDOZABLE:
154b1b8bc3fSopenharmony_ci            firewallType = FirewallType::TYPE_DENIDE_LIST;
155b1b8bc3fSopenharmony_ci            break;
156b1b8bc3fSopenharmony_ci        default:
157b1b8bc3fSopenharmony_ci            firewallType = FirewallType::TYPE_ALLOWED_LIST;
158b1b8bc3fSopenharmony_ci            break;
159b1b8bc3fSopenharmony_ci    }
160b1b8bc3fSopenharmony_ci    return firewallType;
161b1b8bc3fSopenharmony_ci}
162b1b8bc3fSopenharmony_ci
163b1b8bc3fSopenharmony_ciint32_t FirewallManager::InitChain()
164b1b8bc3fSopenharmony_ci{
165b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager InitChain");
166b1b8bc3fSopenharmony_ci    bool ret = false;
167b1b8bc3fSopenharmony_ci    ret = (IptablesNewChain(ChainType::CHAIN_OHFW_INPUT) == NETMANAGER_ERROR) ||
168b1b8bc3fSopenharmony_ci          (IptablesNewChain(ChainType::CHAIN_OHFW_OUTPUT) == NETMANAGER_ERROR) ||
169b1b8bc3fSopenharmony_ci          (IptablesNewChain(ChainType::CHAIN_OHFW_FORWARD) == NETMANAGER_ERROR) ||
170b1b8bc3fSopenharmony_ci          (IptablesNewChain(ChainType::CHAIN_OHFW_DOZABLE) == NETMANAGER_ERROR) ||
171b1b8bc3fSopenharmony_ci          (IptablesNewChain(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) == NETMANAGER_ERROR) ||
172b1b8bc3fSopenharmony_ci          (IptablesNewChain(ChainType::CHAIN_OHFW_POWERSAVING) == NETMANAGER_ERROR) ||
173b1b8bc3fSopenharmony_ci          (IptablesNewChain(ChainType::CHAIN_OHFW_UNDOZABLE) == NETMANAGER_ERROR);
174b1b8bc3fSopenharmony_ci    chainInitFlag_ = true;
175b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
176b1b8bc3fSopenharmony_ci}
177b1b8bc3fSopenharmony_ci
178b1b8bc3fSopenharmony_ciint32_t FirewallManager::DeInitChain()
179b1b8bc3fSopenharmony_ci{
180b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager DeInitChain");
181b1b8bc3fSopenharmony_ci    bool ret = false;
182b1b8bc3fSopenharmony_ci    ret = (IptablesDeleteChain(ChainType::CHAIN_OHFW_INPUT) == NETMANAGER_ERROR) ||
183b1b8bc3fSopenharmony_ci          (IptablesDeleteChain(ChainType::CHAIN_OHFW_OUTPUT) == NETMANAGER_ERROR) ||
184b1b8bc3fSopenharmony_ci          (IptablesDeleteChain(ChainType::CHAIN_OHFW_FORWARD) == NETMANAGER_ERROR) ||
185b1b8bc3fSopenharmony_ci          (IptablesDeleteChain(ChainType::CHAIN_OHFW_DOZABLE) == NETMANAGER_ERROR) ||
186b1b8bc3fSopenharmony_ci          (IptablesDeleteChain(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) == NETMANAGER_ERROR) ||
187b1b8bc3fSopenharmony_ci          (IptablesDeleteChain(ChainType::CHAIN_OHFW_POWERSAVING) == NETMANAGER_ERROR) ||
188b1b8bc3fSopenharmony_ci          (IptablesDeleteChain(ChainType::CHAIN_OHFW_UNDOZABLE) == NETMANAGER_ERROR);
189b1b8bc3fSopenharmony_ci    chainInitFlag_ = false;
190b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
191b1b8bc3fSopenharmony_ci}
192b1b8bc3fSopenharmony_ci
193b1b8bc3fSopenharmony_ciint32_t FirewallManager::InitDefaultRules()
194b1b8bc3fSopenharmony_ci{
195b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager InitDefaultRules");
196b1b8bc3fSopenharmony_ci    bool ret = false;
197b1b8bc3fSopenharmony_ci    std::string chainName = FetchChainName(ChainType::CHAIN_OHFW_INPUT);
198b1b8bc3fSopenharmony_ci    std::string command = "-t filter -A INPUT -j " + chainName;
199b1b8bc3fSopenharmony_ci    ret = ret ||
200b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
201b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT);
202b1b8bc3fSopenharmony_ci    command = "-t filter -A OUTPUT -j " + chainName;
203b1b8bc3fSopenharmony_ci    ret = ret ||
204b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
205b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
206b1b8bc3fSopenharmony_ci}
207b1b8bc3fSopenharmony_ci
208b1b8bc3fSopenharmony_ciint32_t FirewallManager::ClearAllRules()
209b1b8bc3fSopenharmony_ci{
210b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager ClearAllRules");
211b1b8bc3fSopenharmony_ci    bool ret = false;
212b1b8bc3fSopenharmony_ci
213b1b8bc3fSopenharmony_ci    std::string chainName = FetchChainName(ChainType::CHAIN_OHFW_DOZABLE);
214b1b8bc3fSopenharmony_ci    std::string command = "-t filter -F " + chainName;
215b1b8bc3fSopenharmony_ci    ret = ret ||
216b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
217b1b8bc3fSopenharmony_ci
218b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_POWERSAVING);
219b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
220b1b8bc3fSopenharmony_ci    ret =
221b1b8bc3fSopenharmony_ci        ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
222b1b8bc3fSopenharmony_ci
223b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_UNDOZABLE);
224b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
225b1b8bc3fSopenharmony_ci    ret =
226b1b8bc3fSopenharmony_ci        ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
227b1b8bc3fSopenharmony_ci
228b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_INPUT);
229b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
230b1b8bc3fSopenharmony_ci    ret =
231b1b8bc3fSopenharmony_ci        ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
232b1b8bc3fSopenharmony_ci
233b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT);
234b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
235b1b8bc3fSopenharmony_ci    ret = ret ||
236b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
237b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_FORWARD);
238b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
239b1b8bc3fSopenharmony_ci    ret = ret ||
240b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
241b1b8bc3fSopenharmony_ci    chainName = FetchChainName(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX);
242b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
243b1b8bc3fSopenharmony_ci    ret = ret ||
244b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
245b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
246b1b8bc3fSopenharmony_ci}
247b1b8bc3fSopenharmony_ci
248b1b8bc3fSopenharmony_ciint32_t FirewallManager::IptablesNewChain(ChainType chain)
249b1b8bc3fSopenharmony_ci{
250b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager NewChain: chain=%{public}d", chain);
251b1b8bc3fSopenharmony_ci    std::string command = "-t filter -N " + FetchChainName(chain);
252b1b8bc3fSopenharmony_ci    return IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command);
253b1b8bc3fSopenharmony_ci}
254b1b8bc3fSopenharmony_ci
255b1b8bc3fSopenharmony_ciint32_t FirewallManager::IptablesDeleteChain(ChainType chain)
256b1b8bc3fSopenharmony_ci{
257b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager DeleteChain: chain=%{public}d", chain);
258b1b8bc3fSopenharmony_ci    bool ret = false;
259b1b8bc3fSopenharmony_ci    std::string command = "-t filter -F " + FetchChainName(chain);
260b1b8bc3fSopenharmony_ci    ret = ret ||
261b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
262b1b8bc3fSopenharmony_ci    command = "-t filter -X " + FetchChainName(chain);
263b1b8bc3fSopenharmony_ci    ret = ret ||
264b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
265b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
266b1b8bc3fSopenharmony_ci}
267b1b8bc3fSopenharmony_ci
268b1b8bc3fSopenharmony_ciint32_t FirewallManager::IptablesSetRule(const std::string &chainName, const std::string &option,
269b1b8bc3fSopenharmony_ci                                         const std::string &target, uint32_t uid)
270b1b8bc3fSopenharmony_ci{
271b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager IptablesSetRule");
272b1b8bc3fSopenharmony_ci    std::string command =
273b1b8bc3fSopenharmony_ci        "-t filter " + option + " " + chainName + " -m owner --uid-owner " + std::to_string(uid) + " -j " + target;
274b1b8bc3fSopenharmony_ci    return IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command);
275b1b8bc3fSopenharmony_ci}
276b1b8bc3fSopenharmony_ci
277b1b8bc3fSopenharmony_ciint32_t FirewallManager::SetUidsAllowedListChain(ChainType chain, const std::vector<uint32_t> &uids)
278b1b8bc3fSopenharmony_ci{
279b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager SetUidsAllowedListChain: chain=%{public}d", chain);
280b1b8bc3fSopenharmony_ci    if (chain != ChainType::CHAIN_OHFW_DOZABLE && chain != ChainType::CHAIN_OHFW_POWERSAVING) {
281b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
282b1b8bc3fSopenharmony_ci    }
283b1b8bc3fSopenharmony_ci
284b1b8bc3fSopenharmony_ci    bool ret = false;
285b1b8bc3fSopenharmony_ci    std::unique_lock<std::mutex> lock(firewallMutex_);
286b1b8bc3fSopenharmony_ci    CheckChainInitialization();
287b1b8bc3fSopenharmony_ci
288b1b8bc3fSopenharmony_ci    std::string command;
289b1b8bc3fSopenharmony_ci    const auto &chainName = FetchChainName(chain);
290b1b8bc3fSopenharmony_ci
291b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
292b1b8bc3fSopenharmony_ci    ret = ret ||
293b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
294b1b8bc3fSopenharmony_ci
295b1b8bc3fSopenharmony_ci    std::string  allowedListChainName = FetchChainName(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX);
296b1b8bc3fSopenharmony_ci    command = "-t filter -A " + chainName + " -j " + allowedListChainName;
297b1b8bc3fSopenharmony_ci    ret = ret ||
298b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
299b1b8bc3fSopenharmony_ci    std::for_each(uids.begin(), uids.end(), [&command, &chainName, &ret](uint32_t uid) {
300b1b8bc3fSopenharmony_ci        std::string strUid = std::to_string(uid);
301b1b8bc3fSopenharmony_ci        command = "-t filter -A " + chainName + " -m owner --uid-owner " + strUid + " -j RETURN";
302b1b8bc3fSopenharmony_ci        ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) ==
303b1b8bc3fSopenharmony_ci                      NETMANAGER_ERROR);
304b1b8bc3fSopenharmony_ci    });
305b1b8bc3fSopenharmony_ci
306b1b8bc3fSopenharmony_ci    command =
307b1b8bc3fSopenharmony_ci        "-t filter -A " + chainName + " -m owner --uid-owner 0-" + std::to_string(SYSTEM_UID_RANGE) + " -j RETURN";
308b1b8bc3fSopenharmony_ci    ret = ret ||
309b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
310b1b8bc3fSopenharmony_ci    command = "-t filter -A " + chainName + " -m owner ! --uid-owner 0-" + strMaxUid_ + " -j RETURN";
311b1b8bc3fSopenharmony_ci
312b1b8bc3fSopenharmony_ci    ret = SetFireWallCommand(chainName, command);
313b1b8bc3fSopenharmony_ci
314b1b8bc3fSopenharmony_ci    command = "-t filter -A " + chainName + " -j DROP";
315b1b8bc3fSopenharmony_ci    ret = ret ||
316b1b8bc3fSopenharmony_ci          (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR);
317b1b8bc3fSopenharmony_ci    if (ret == false) {
318b1b8bc3fSopenharmony_ci        FirewallChainStatus status = firewallChainStatus_[chain];
319b1b8bc3fSopenharmony_ci        status.uids = uids;
320b1b8bc3fSopenharmony_ci        firewallChainStatus_[chain] = status;
321b1b8bc3fSopenharmony_ci    }
322b1b8bc3fSopenharmony_ci
323b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
324b1b8bc3fSopenharmony_ci}
325b1b8bc3fSopenharmony_ci
326b1b8bc3fSopenharmony_ciint32_t FirewallManager::SetUidsDeniedListChain(ChainType chain, const std::vector<uint32_t> &uids)
327b1b8bc3fSopenharmony_ci{
328b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager SetUidsDeniedListChain: chain=%{public}d", chain);
329b1b8bc3fSopenharmony_ci    if (chain != ChainType::CHAIN_OHFW_UNDOZABLE) {
330b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
331b1b8bc3fSopenharmony_ci    }
332b1b8bc3fSopenharmony_ci
333b1b8bc3fSopenharmony_ci    std::unique_lock<std::mutex> lock(firewallMutex_);
334b1b8bc3fSopenharmony_ci    bool ret = false;
335b1b8bc3fSopenharmony_ci    CheckChainInitialization();
336b1b8bc3fSopenharmony_ci
337b1b8bc3fSopenharmony_ci    std::string command;
338b1b8bc3fSopenharmony_ci    const auto &chainName = FetchChainName(chain);
339b1b8bc3fSopenharmony_ci
340b1b8bc3fSopenharmony_ci    command = "-t filter -F " + chainName;
341b1b8bc3fSopenharmony_ci
342b1b8bc3fSopenharmony_ci    ret = SetFireWallCommand(chainName, command);
343b1b8bc3fSopenharmony_ci
344b1b8bc3fSopenharmony_ci    std::for_each(uids.begin(), uids.end(), [&command, &chainName, &ret](uint32_t uid) {
345b1b8bc3fSopenharmony_ci        std::string strUid = std::to_string(uid);
346b1b8bc3fSopenharmony_ci        command = "-t filter -A " + chainName + " -m owner --uid-owner " + strUid + " -j DROP";
347b1b8bc3fSopenharmony_ci        ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) ==
348b1b8bc3fSopenharmony_ci                      NETMANAGER_ERROR);
349b1b8bc3fSopenharmony_ci    });
350b1b8bc3fSopenharmony_ci
351b1b8bc3fSopenharmony_ci    if (ret == false) {
352b1b8bc3fSopenharmony_ci        FirewallChainStatus status = firewallChainStatus_[chain];
353b1b8bc3fSopenharmony_ci        status.uids = uids;
354b1b8bc3fSopenharmony_ci        firewallChainStatus_[chain] = status;
355b1b8bc3fSopenharmony_ci    }
356b1b8bc3fSopenharmony_ci
357b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
358b1b8bc3fSopenharmony_ci}
359b1b8bc3fSopenharmony_ci
360b1b8bc3fSopenharmony_ciint32_t FirewallManager::EnableChain(ChainType chain, bool enable)
361b1b8bc3fSopenharmony_ci{
362b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("FirewallManager EnableChain: chain=%{public}d, enable=%{public}d", chain, enable);
363b1b8bc3fSopenharmony_ci    if (IsFirewallChian(chain) == NETMANAGER_ERROR) {
364b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
365b1b8bc3fSopenharmony_ci    }
366b1b8bc3fSopenharmony_ci
367b1b8bc3fSopenharmony_ci    bool ret = false;
368b1b8bc3fSopenharmony_ci    std::unique_lock<std::mutex> lock(firewallMutex_);
369b1b8bc3fSopenharmony_ci    CheckChainInitialization();
370b1b8bc3fSopenharmony_ci
371b1b8bc3fSopenharmony_ci    std::string chainName;
372b1b8bc3fSopenharmony_ci    std::string fChainName;
373b1b8bc3fSopenharmony_ci    chainName = FetchChainName(chain);
374b1b8bc3fSopenharmony_ci    std::string command;
375b1b8bc3fSopenharmony_ci
376b1b8bc3fSopenharmony_ci    if (enable == true && firewallChainStatus_[chain].enable == false) {
377b1b8bc3fSopenharmony_ci        fChainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT);
378b1b8bc3fSopenharmony_ci        command = "-t filter -A " + fChainName + " -j " + chainName;
379b1b8bc3fSopenharmony_ci        ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) ==
380b1b8bc3fSopenharmony_ci                      NETMANAGER_ERROR);
381b1b8bc3fSopenharmony_ci    } else if (enable == false && firewallChainStatus_[chain].enable == true) {
382b1b8bc3fSopenharmony_ci        fChainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT);
383b1b8bc3fSopenharmony_ci        command = "-t filter -D " + fChainName + " -j " + chainName;
384b1b8bc3fSopenharmony_ci        ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) ==
385b1b8bc3fSopenharmony_ci                      NETMANAGER_ERROR);
386b1b8bc3fSopenharmony_ci    } else {
387b1b8bc3fSopenharmony_ci        NETNATIVE_LOGI("FirewallManager::EnableChain chain was %{public}s, do not repeat",
388b1b8bc3fSopenharmony_ci                       enable == true ? "true" : "false");
389b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
390b1b8bc3fSopenharmony_ci    }
391b1b8bc3fSopenharmony_ci
392b1b8bc3fSopenharmony_ci    if (ret == false) {
393b1b8bc3fSopenharmony_ci        firewallType_ = FetchChainType(chain);
394b1b8bc3fSopenharmony_ci        firewallChainStatus_[chain].enable = enable;
395b1b8bc3fSopenharmony_ci    }
396b1b8bc3fSopenharmony_ci
397b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
398b1b8bc3fSopenharmony_ci}
399b1b8bc3fSopenharmony_ci
400b1b8bc3fSopenharmony_ciint32_t FirewallManager::SetUidRule(ChainType chain, uint32_t uid, FirewallRule firewallRule)
401b1b8bc3fSopenharmony_ci{
402b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("FirewallManager SetUidRule: chain=%{public}d, uid=%{public}d, firewallRule=%{public}d", chain,
403b1b8bc3fSopenharmony_ci                   uid, firewallRule);
404b1b8bc3fSopenharmony_ci    if (IsFirewallChian(chain) == NETMANAGER_ERROR) {
405b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
406b1b8bc3fSopenharmony_ci    }
407b1b8bc3fSopenharmony_ci
408b1b8bc3fSopenharmony_ci    bool ret = false;
409b1b8bc3fSopenharmony_ci    std::unique_lock<std::mutex> lock(firewallMutex_);
410b1b8bc3fSopenharmony_ci    CheckChainInitialization();
411b1b8bc3fSopenharmony_ci
412b1b8bc3fSopenharmony_ci    std::string op;
413b1b8bc3fSopenharmony_ci    std::string target;
414b1b8bc3fSopenharmony_ci    std::string chainName = FetchChainName(chain);
415b1b8bc3fSopenharmony_ci    FirewallType firewallType = FetchChainType(chain);
416b1b8bc3fSopenharmony_ci    if (firewallType == FirewallType::TYPE_DENIDE_LIST) {
417b1b8bc3fSopenharmony_ci        target = "DROP";
418b1b8bc3fSopenharmony_ci        op = (firewallRule == FirewallRule::RULE_DENY) ? "-A" : "-D";
419b1b8bc3fSopenharmony_ci    } else {
420b1b8bc3fSopenharmony_ci        if (chain != ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) {
421b1b8bc3fSopenharmony_ci            target = "RETURN";
422b1b8bc3fSopenharmony_ci        } else {
423b1b8bc3fSopenharmony_ci            target = "ACCEPT";
424b1b8bc3fSopenharmony_ci        }
425b1b8bc3fSopenharmony_ci        op = (firewallRule == FirewallRule::RULE_ALLOW) ? "-I" : "-D";
426b1b8bc3fSopenharmony_ci    }
427b1b8bc3fSopenharmony_ci
428b1b8bc3fSopenharmony_ci    FirewallChainStatus status = firewallChainStatus_[chain];
429b1b8bc3fSopenharmony_ci    std::vector<uint32_t>::iterator iter = std::find(status.uids.begin(), status.uids.end(), uid);
430b1b8bc3fSopenharmony_ci    if (op != "-D" && iter == status.uids.end()) {
431b1b8bc3fSopenharmony_ci        status.uids.push_back(uid);
432b1b8bc3fSopenharmony_ci        ret = ret || (IptablesSetRule(chainName, op, target, uid) == NETMANAGER_ERROR);
433b1b8bc3fSopenharmony_ci    } else if (op == "-D" && iter != status.uids.end()) {
434b1b8bc3fSopenharmony_ci        status.uids.erase(iter);
435b1b8bc3fSopenharmony_ci        ret = ret || (IptablesSetRule(chainName, op, target, uid) == NETMANAGER_ERROR);
436b1b8bc3fSopenharmony_ci    } else {
437b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("FirewallManager::SetUidRule error");
438b1b8bc3fSopenharmony_ci        return NETMANAGER_ERROR;
439b1b8bc3fSopenharmony_ci    }
440b1b8bc3fSopenharmony_ci
441b1b8bc3fSopenharmony_ci    if (ret == false) {
442b1b8bc3fSopenharmony_ci        firewallChainStatus_[chain] = status;
443b1b8bc3fSopenharmony_ci    }
444b1b8bc3fSopenharmony_ci
445b1b8bc3fSopenharmony_ci    return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
446b1b8bc3fSopenharmony_ci}
447b1b8bc3fSopenharmony_ci} // namespace nmd
448b1b8bc3fSopenharmony_ci} // namespace OHOS
449